summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/Makefile.nmake1
-rw-r--r--src/test/bench.c5
-rw-r--r--src/test/fakechans.h1
-rw-r--r--src/test/fuzz/fuzzing_common.c3
-rw-r--r--src/test/include.am3
-rw-r--r--src/test/test-memwipe.c3
-rw-r--r--src/test/test-timers.c2
-rw-r--r--src/test/test.c9
-rw-r--r--src/test/test.h3
-rw-r--r--src/test/test_accounting.c3
-rw-r--r--src/test/test_address.c16
-rw-r--r--src/test/test_buffers.c24
-rw-r--r--src/test/test_cell_queue.c4
-rw-r--r--src/test/test_channel.c1765
-rw-r--r--src/test/test_channelpadding.c115
-rw-r--r--src/test/test_circuitlist.c28
-rw-r--r--src/test/test_circuitstats.c199
-rw-r--r--src/test/test_config.c117
-rw-r--r--src/test/test_conscache.c12
-rw-r--r--src/test/test_consdiffmgr.c8
-rw-r--r--src/test/test_controller.c168
-rw-r--r--src/test/test_dir.c113
-rw-r--r--src/test/test_dir_handle_get.c97
-rw-r--r--src/test/test_dns.c9
-rw-r--r--src/test/test_entryconn.c34
-rw-r--r--src/test/test_entrynodes.c4
-rw-r--r--src/test/test_extorport.c10
-rw-r--r--src/test/test_handles.c2
-rw-r--r--src/test/test_hs.c15
-rw-r--r--src/test/test_hs_cache.c2
-rw-r--r--src/test/test_hs_client.c12
-rw-r--r--src/test/test_hs_control.c199
-rw-r--r--src/test/test_hs_intropoint.c38
-rw-r--r--src/test/test_hs_service.c28
-rwxr-xr-xsrc/test/test_keygen.sh109
-rw-r--r--src/test/test_link_handshake.c14
-rw-r--r--src/test/test_microdesc.c36
-rw-r--r--src/test/test_oom.c38
-rw-r--r--src/test/test_policy.c8
-rw-r--r--src/test/test_protover.c73
-rw-r--r--src/test/test_relay.c4
-rw-r--r--src/test/test_rendcache.c8
-rw-r--r--src/test/test_replay.c2
-rw-r--r--src/test/test_routerkeys.c9
-rw-r--r--src/test/test_routerlist.c116
-rw-r--r--src/test/test_routerset.c59
-rw-r--r--src/test/test_rust.c31
-rwxr-xr-xsrc/test/test_rust.sh15
-rw-r--r--src/test/test_scheduler.c12
-rw-r--r--src/test/test_shared_random.c5
-rw-r--r--src/test/test_status.c3
-rw-r--r--src/test/test_util.c68
-rw-r--r--src/test/testing_common.c9
53 files changed, 2195 insertions, 1476 deletions
diff --git a/src/test/Makefile.nmake b/src/test/Makefile.nmake
index 605f1a92c3..cfbe281b94 100644
--- a/src/test/Makefile.nmake
+++ b/src/test/Makefile.nmake
@@ -18,6 +18,7 @@ TEST_OBJECTS = test.obj test_addr.obj test_channel.obj test_channeltls.obj \
test_config.obj test_connection.obj \
test_cell_formats.obj test_relay.obj test_replay.obj \
test_channelpadding.obj \
+ test_circuitstats.obj \
test_scheduler.obj test_introduce.obj test_hs.obj tinytest.obj
tinytest.obj: ..\ext\tinytest.c
diff --git a/src/test/bench.c b/src/test/bench.c
index b7b123eee2..f30b609900 100644
--- a/src/test/bench.c
+++ b/src/test/bench.c
@@ -3,11 +3,6 @@
* Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-extern const char tor_git_revision[];
-/* Ordinarily defined in tor_main.c; this bit is just here to provide one
- * since we're not linking to tor_main.c */
-const char tor_git_revision[] = "";
-
/**
* \file bench.c
* \brief Benchmarks for lower level Tor modules.
diff --git a/src/test/fakechans.h b/src/test/fakechans.h
index c0de430e3d..ab5d8461b6 100644
--- a/src/test/fakechans.h
+++ b/src/test/fakechans.h
@@ -20,7 +20,6 @@ void scheduler_release_channel_mock(channel_t *ch);
/* Query some counters used by the exposed mocks */
int get_mock_scheduler_has_waiting_cells_count(void);
-int get_mock_scheduler_release_channel_count(void);
#endif /* !defined(TOR_FAKECHANS_H) */
diff --git a/src/test/fuzz/fuzzing_common.c b/src/test/fuzz/fuzzing_common.c
index 1e98eb6c85..1d54e41dbd 100644
--- a/src/test/fuzz/fuzzing_common.c
+++ b/src/test/fuzz/fuzzing_common.c
@@ -9,9 +9,6 @@
#include "crypto.h"
#include "crypto_ed25519.h"
-extern const char tor_git_revision[];
-const char tor_git_revision[] = "";
-
static or_options_t *mock_options = NULL;
static const or_options_t *
mock_get_options(void)
diff --git a/src/test/include.am b/src/test/include.am
index 610918e9da..a4b9705fdd 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -98,6 +98,7 @@ src_test_test_SOURCES = \
src/test/test_circuitmux.c \
src/test/test_circuitbuild.c \
src/test/test_circuituse.c \
+ src/test/test_circuitstats.c \
src/test/test_compat_libevent.c \
src/test/test_config.c \
src/test/test_connection.c \
@@ -125,6 +126,7 @@ src_test_test_SOURCES = \
src/test/test_hs_service.c \
src/test/test_hs_client.c \
src/test/test_hs_intropoint.c \
+ src/test/test_hs_control.c \
src/test/test_handles.c \
src/test/test_hs_cache.c \
src/test/test_hs_descriptor.c \
@@ -152,7 +154,6 @@ src_test_test_SOURCES = \
src/test/test_routerkeys.c \
src/test/test_routerlist.c \
src/test/test_routerset.c \
- src/test/test_rust.c \
src/test/test_scheduler.c \
src/test/test_shared_random.c \
src/test/test_socks.c \
diff --git a/src/test/test-memwipe.c b/src/test/test-memwipe.c
index 484f13dd05..89d946d506 100644
--- a/src/test/test-memwipe.c
+++ b/src/test/test-memwipe.c
@@ -1,3 +1,6 @@
+/* Copyright (c) 2015-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
#include "orconfig.h"
#include <string.h>
#include <stdio.h>
diff --git a/src/test/test-timers.c b/src/test/test-timers.c
index 99715f4333..a0b5b535c2 100644
--- a/src/test/test-timers.c
+++ b/src/test/test-timers.c
@@ -133,7 +133,7 @@ main(int argc, char **argv)
ret = 0;
}
- timer_free(NULL);
+ timer_free_(NULL);
for (i = 0; i < N_TIMERS; ++i) {
timer_free(timers[i]);
diff --git a/src/test/test.c b/src/test/test.c
index da4f7a0553..f225fd277d 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -345,8 +345,8 @@ test_onion_queues(void *arg)
tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
done:
- circuit_free(TO_CIRCUIT(circ1));
- circuit_free(TO_CIRCUIT(circ2));
+ circuit_free_(TO_CIRCUIT(circ1));
+ circuit_free_(TO_CIRCUIT(circ2));
tor_free(create1);
tor_free(create2);
tor_free(onionskin);
@@ -616,7 +616,7 @@ test_rend_fns(void *arg)
done:
if (descs) {
for (i = 0; i < smartlist_len(descs); i++)
- rend_encoded_v2_service_descriptor_free(smartlist_get(descs, i));
+ rend_encoded_v2_service_descriptor_free_(smartlist_get(descs, i));
smartlist_free(descs);
}
if (parsed)
@@ -1178,6 +1178,7 @@ struct testgroup_t testgroups[] = {
{ "circuitlist/", circuitlist_tests },
{ "circuitmux/", circuitmux_tests },
{ "circuituse/", circuituse_tests },
+ { "circuitstats/", circuitstats_tests },
{ "compat/libevent/", compat_libevent_tests },
{ "config/", config_tests },
{ "connection/", connection_tests },
@@ -1201,6 +1202,7 @@ struct testgroup_t testgroups[] = {
{ "hs_cell/", hs_cell_tests },
{ "hs_common/", hs_common_tests },
{ "hs_config/", hs_config_tests },
+ { "hs_control/", hs_control_tests },
{ "hs_descriptor/", hs_descriptor },
{ "hs_ntor/", hs_ntor_tests },
{ "hs_service/", hs_service_tests },
@@ -1227,7 +1229,6 @@ struct testgroup_t testgroups[] = {
{ "routerkeys/", routerkeys_tests },
{ "routerlist/", routerlist_tests },
{ "routerset/" , routerset_tests },
- { "rust/", rust_tests },
{ "scheduler/", scheduler_tests },
{ "socks/", socks_tests },
{ "shared-random/", sr_tests },
diff --git a/src/test/test.h b/src/test/test.h
index 634f3e7b02..93d527ba17 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -188,6 +188,7 @@ extern struct testcase_t circuitbuild_tests[];
extern struct testcase_t circuitlist_tests[];
extern struct testcase_t circuitmux_tests[];
extern struct testcase_t circuituse_tests[];
+extern struct testcase_t circuitstats_tests[];
extern struct testcase_t compat_libevent_tests[];
extern struct testcase_t config_tests[];
extern struct testcase_t connection_tests[];
@@ -210,6 +211,7 @@ extern struct testcase_t hs_cache[];
extern struct testcase_t hs_cell_tests[];
extern struct testcase_t hs_common_tests[];
extern struct testcase_t hs_config_tests[];
+extern struct testcase_t hs_control_tests[];
extern struct testcase_t hs_descriptor[];
extern struct testcase_t hs_ntor_tests[];
extern struct testcase_t hs_service_tests[];
@@ -239,7 +241,6 @@ extern struct testcase_t router_tests[];
extern struct testcase_t routerkeys_tests[];
extern struct testcase_t routerlist_tests[];
extern struct testcase_t routerset_tests[];
-extern struct testcase_t rust_tests[];
extern struct testcase_t scheduler_tests[];
extern struct testcase_t storagedir_tests[];
extern struct testcase_t socks_tests[];
diff --git a/src/test/test_accounting.c b/src/test/test_accounting.c
index 7edba988a6..b0d37b2989 100644
--- a/src/test/test_accounting.c
+++ b/src/test/test_accounting.c
@@ -1,3 +1,6 @@
+/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
#include "or.h"
#include "test.h"
#define HIBERNATE_PRIVATE
diff --git a/src/test/test_address.c b/src/test/test_address.c
index f36ff6998b..9c88d37a41 100644
--- a/src/test/test_address.c
+++ b/src/test/test_address.c
@@ -763,7 +763,7 @@ test_address_get_if_addrs_list_internal(void *arg)
tt_assert(!smartlist_contains_ipv6_tor_addr(results));
done:
- free_interface_address_list(results);
+ interface_address_list_free(results);
return;
}
@@ -792,7 +792,7 @@ test_address_get_if_addrs_list_no_internal(void *arg)
tt_assert(!smartlist_contains_ipv6_tor_addr(results));
done:
- free_interface_address_list(results);
+ interface_address_list_free(results);
return;
}
@@ -834,7 +834,7 @@ test_address_get_if_addrs6_list_internal(void *arg)
}
done:
- free_interface_address6_list(results);
+ interface_address6_list_free(results);
teardown_capture_of_logs();
return;
}
@@ -878,7 +878,7 @@ test_address_get_if_addrs6_list_no_internal(void *arg)
done:
teardown_capture_of_logs();
- free_interface_address6_list(results);
+ interface_address6_list_free(results);
return;
}
@@ -943,8 +943,8 @@ test_address_get_if_addrs_internal_fail(void *arg)
done:
UNMOCK(get_interface_addresses_raw);
UNMOCK(get_interface_address6_via_udp_socket_hack);
- free_interface_address6_list(results1);
- free_interface_address6_list(results2);
+ interface_address6_list_free(results1);
+ interface_address6_list_free(results2);
return;
}
@@ -971,8 +971,8 @@ test_address_get_if_addrs_no_internal_fail(void *arg)
done:
UNMOCK(get_interface_addresses_raw);
UNMOCK(get_interface_address6_via_udp_socket_hack);
- free_interface_address6_list(results1);
- free_interface_address6_list(results2);
+ interface_address6_list_free(results1);
+ interface_address6_list_free(results2);
return;
}
diff --git a/src/test/test_buffers.c b/src/test/test_buffers.c
index 9f4e19bc5f..057d9fa2dc 100644
--- a/src/test/test_buffers.c
+++ b/src/test/test_buffers.c
@@ -450,52 +450,54 @@ test_buffer_time_tracking(void *arg)
tt_assert(buf);
monotime_coarse_set_mock_time_nsec(START_NSEC);
- const uint32_t START_MSEC = (uint32_t)monotime_coarse_absolute_msec();
+ const uint32_t START_TS = monotime_coarse_get_stamp();
/* Empty buffer means the timestamp is 0. */
- tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC));
- tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+1000));
+ tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_TS));
+ tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_TS+1000));
buf_add(buf, "ABCDEFG", 7);
- tt_int_op(1000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+1000));
+ tt_int_op(1000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_TS+1000));
buf2 = buf_copy(buf);
tt_assert(buf2);
tt_int_op(1234, OP_EQ,
- buf_get_oldest_chunk_timestamp(buf2, START_MSEC+1234));
+ buf_get_oldest_chunk_timestamp(buf2, START_TS+1234));
/* Now add more bytes; enough to overflow the first chunk. */
monotime_coarse_set_mock_time_nsec(START_NSEC + 123 * (uint64_t)1000000);
+ const uint32_t TS2 = monotime_coarse_get_stamp();
for (i = 0; i < 600; ++i)
buf_add(buf, "ABCDEFG", 7);
tt_int_op(4207, OP_EQ, buf_datalen(buf));
/* The oldest bytes are still in the front. */
- tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2000));
+ tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_TS+2000));
/* Once those bytes are dropped, the chunk is still on the first
* timestamp. */
buf_get_bytes(buf, tmp, 100);
- tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2000));
+ tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_TS+2000));
/* But once we discard the whole first chunk, we get the data in the second
* chunk. */
buf_get_bytes(buf, tmp, 4000);
tt_int_op(107, OP_EQ, buf_datalen(buf));
- tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2123));
+ tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, TS2+2000));
/* This time we'll be grabbing a chunk from the freelist, and making sure
its time gets updated */
monotime_coarse_set_mock_time_nsec(START_NSEC + 5617 * (uint64_t)1000000);
+ const uint32_t TS3 = monotime_coarse_get_stamp();
for (i = 0; i < 600; ++i)
buf_add(buf, "ABCDEFG", 7);
tt_int_op(4307, OP_EQ, buf_datalen(buf));
- tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+2123));
+ tt_int_op(2000, OP_EQ, buf_get_oldest_chunk_timestamp(buf, TS2+2000));
buf_get_bytes(buf, tmp, 4000);
buf_get_bytes(buf, tmp, 306);
- tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+5617));
- tt_int_op(383, OP_EQ, buf_get_oldest_chunk_timestamp(buf, START_MSEC+6000));
+ tt_int_op(0, OP_EQ, buf_get_oldest_chunk_timestamp(buf, TS3));
+ tt_int_op(383, OP_EQ, buf_get_oldest_chunk_timestamp(buf, TS3+383));
done:
buf_free(buf);
diff --git a/src/test/test_cell_queue.c b/src/test/test_cell_queue.c
index 69e89b69b0..df987f82ce 100644
--- a/src/test/test_cell_queue.c
+++ b/src/test/test_cell_queue.c
@@ -130,8 +130,8 @@ test_circuit_n_cells(void *arg)
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));
+ circuit_free_(TO_CIRCUIT(or_c));
+ circuit_free_(TO_CIRCUIT(origin_c));
}
struct testcase_t cell_queue_tests[] = {
diff --git a/src/test/test_channel.c b/src/test/test_channel.c
index 023c2950c9..bdc9d32f78 100644
--- a/src/test/test_channel.c
+++ b/src/test/test_channel.c
@@ -6,8 +6,10 @@
#include "or.h"
#include "channel.h"
/* For channel_note_destroy_not_pending */
+#define CIRCUITLIST_PRIVATE
#include "circuitlist.h"
#include "circuitmux.h"
+#include "circuitmux_ewma.h"
/* For var_cell_free */
#include "connection_or.h"
/* For packed_cell stuff */
@@ -15,8 +17,10 @@
#include "relay.h"
/* For init/free stuff */
#include "scheduler.h"
+#include "networkstatus.h"
/* Test suite stuff */
+#include "log_test_helpers.h"
#include "test.h"
#include "fakechans.h"
@@ -26,62 +30,18 @@ static cell_t * test_chan_last_seen_fixed_cell_ptr = NULL;
static int test_chan_var_cells_recved = 0;
static var_cell_t * test_chan_last_seen_var_cell_ptr = NULL;
static int test_cells_written = 0;
-static int test_destroy_not_pending_calls = 0;
static int test_doesnt_want_writes_count = 0;
static int test_dumpstats_calls = 0;
static int test_has_waiting_cells_count = 0;
-static double test_overhead_estimate = 1.0;
static int test_releases_count = 0;
-static circuitmux_t *test_target_cmux = NULL;
-static unsigned int test_cmux_cells = 0;
static channel_t *dump_statistics_mock_target = NULL;
static int dump_statistics_mock_matches = 0;
-
-static void chan_test_channel_dump_statistics_mock(
- channel_t *chan, int severity);
-static int chan_test_channel_flush_from_first_active_circuit_mock(
- channel_t *chan, int max);
-static unsigned int chan_test_circuitmux_num_cells_mock(circuitmux_t *cmux);
-static void channel_note_destroy_not_pending_mock(channel_t *ch,
- circid_t circid);
-static void chan_test_cell_handler(channel_t *ch,
- cell_t *cell);
-static const char * chan_test_describe_transport(channel_t *ch);
-static void chan_test_dumpstats(channel_t *ch, int severity);
-static void chan_test_var_cell_handler(channel_t *ch,
- var_cell_t *var_cell);
-static void chan_test_close(channel_t *ch);
-static void chan_test_error(channel_t *ch);
-static void chan_test_finish_close(channel_t *ch);
-static const char * chan_test_get_remote_descr(channel_t *ch, int flags);
-static int chan_test_is_canonical(channel_t *ch, int req);
-static size_t chan_test_num_bytes_queued(channel_t *ch);
-static int chan_test_num_cells_writeable(channel_t *ch);
-static int chan_test_write_cell(channel_t *ch, cell_t *cell);
-static int chan_test_write_packed_cell(channel_t *ch,
- packed_cell_t *packed_cell);
-static int chan_test_write_var_cell(channel_t *ch, var_cell_t *var_cell);
-static void scheduler_channel_doesnt_want_writes_mock(channel_t *ch);
-
-static void test_channel_dumpstats(void *arg);
-static void test_channel_flush(void *arg);
-static void test_channel_flushmux(void *arg);
-static void test_channel_incoming(void *arg);
-static void test_channel_lifecycle(void *arg);
-static void test_channel_multi(void *arg);
-static void test_channel_queue_incoming(void *arg);
-static void test_channel_queue_size(void *arg);
-static void test_channel_write(void *arg);
-
-static void
-channel_note_destroy_not_pending_mock(channel_t *ch,
- circid_t circid)
-{
- (void)ch;
- (void)circid;
-
- ++test_destroy_not_pending_calls;
-}
+static int test_close_called = 0;
+static int test_chan_should_be_canonical = 0;
+static int test_chan_should_match_target = 0;
+static int test_chan_canonical_should_be_reliable = 0;
+static int test_chan_listener_close_fn_called = 0;
+static int test_chan_listener_fn_called = 0;
static const char *
chan_test_describe_transport(channel_t *ch)
@@ -112,71 +72,14 @@ chan_test_channel_dump_statistics_mock(channel_t *chan, int severity)
return;
}
-/**
- * If the target cmux is the cmux for chan, make fake cells up to the
- * target number of cells and write them to chan. Otherwise, invoke
- * the real channel_flush_from_first_active_circuit().
- */
-
-static int
-chan_test_channel_flush_from_first_active_circuit_mock(channel_t *chan,
- int max)
-{
- int result = 0, c = 0;
- packed_cell_t *cell = NULL;
-
- tt_ptr_op(chan, OP_NE, NULL);
- if (test_target_cmux != NULL &&
- test_target_cmux == chan->cmux) {
- while (c <= max && test_cmux_cells > 0) {
- cell = packed_cell_new();
- channel_write_packed_cell(chan, cell);
- ++c;
- --test_cmux_cells;
- }
- result = c;
- } else {
- result = channel_flush_from_first_active_circuit__real(chan, max);
- }
-
- done:
- return result;
-}
-
-/**
- * If we have a target cmux set and this matches it, lie about how
- * many cells we have according to the number indicated; otherwise
- * pass to the real circuitmux_num_cells().
- */
-
-static unsigned int
-chan_test_circuitmux_num_cells_mock(circuitmux_t *cmux)
-{
- unsigned int result = 0;
-
- tt_ptr_op(cmux, OP_NE, NULL);
- if (cmux != NULL) {
- if (cmux == test_target_cmux) {
- result = test_cmux_cells;
- } else {
- result = circuitmux_num_cells__real(cmux);
- }
- }
-
- done:
-
- return result;
-}
-
/*
* Handle an incoming fixed-size cell for unit tests
*/
static void
-chan_test_cell_handler(channel_t *ch,
- cell_t *cell)
+chan_test_cell_handler(channel_t *chan, cell_t *cell)
{
- tt_assert(ch);
+ tt_assert(chan);
tt_assert(cell);
test_chan_last_seen_fixed_cell_ptr = cell;
@@ -226,6 +129,8 @@ chan_test_close(channel_t *ch)
{
tt_assert(ch);
+ ++test_close_called;
+
done:
return;
}
@@ -274,35 +179,6 @@ chan_test_get_remote_descr(channel_t *ch, int flags)
return "Fake channel for unit tests; no real endpoint";
}
-static double
-chan_test_get_overhead_estimate(channel_t *ch)
-{
- tt_assert(ch);
-
- done:
- return test_overhead_estimate;
-}
-
-static int
-chan_test_is_canonical(channel_t *ch, int req)
-{
- tt_ptr_op(ch, OP_NE, NULL);
- tt_assert(req == 0 || req == 1);
-
- done:
- /* Fake channels are always canonical */
- return 1;
-}
-
-static size_t
-chan_test_num_bytes_queued(channel_t *ch)
-{
- tt_assert(ch);
-
- done:
- return 0;
-}
-
static int
chan_test_num_cells_writeable(channel_t *ch)
{
@@ -313,26 +189,6 @@ chan_test_num_cells_writeable(channel_t *ch)
}
static int
-chan_test_write_cell(channel_t *ch, cell_t *cell)
-{
- int rv = 0;
-
- tt_assert(ch);
- tt_assert(cell);
-
- if (test_chan_accept_cells) {
- /* Free the cell and bump the counter */
- tor_free(cell);
- ++test_cells_written;
- rv = 1;
- }
- /* else return 0, we didn't accept it */
-
- done:
- return rv;
-}
-
-static int
chan_test_write_packed_cell(channel_t *ch,
packed_cell_t *packed_cell)
{
@@ -343,7 +199,6 @@ chan_test_write_packed_cell(channel_t *ch,
if (test_chan_accept_cells) {
/* Free the cell and bump the counter */
- packed_cell_free(packed_cell);
++test_cells_written;
rv = 1;
}
@@ -419,36 +274,26 @@ new_fake_channel(void)
channel_init(chan);
chan->close = chan_test_close;
- chan->get_overhead_estimate = chan_test_get_overhead_estimate;
- chan->get_remote_descr = chan_test_get_remote_descr;
- chan->num_bytes_queued = chan_test_num_bytes_queued;
chan->num_cells_writeable = chan_test_num_cells_writeable;
- chan->write_cell = chan_test_write_cell;
+ chan->get_remote_descr = chan_test_get_remote_descr;
chan->write_packed_cell = chan_test_write_packed_cell;
chan->write_var_cell = chan_test_write_var_cell;
chan->state = CHANNEL_STATE_OPEN;
+ chan->cmux = circuitmux_alloc();
+
return chan;
}
void
free_fake_channel(channel_t *chan)
{
- cell_queue_entry_t *cell, *cell_tmp;
-
if (! chan)
return;
if (chan->cmux)
circuitmux_free(chan->cmux);
- TOR_SIMPLEQ_FOREACH_SAFE(cell, &chan->incoming_queue, next, cell_tmp) {
- cell_queue_entry_free(cell, 0);
- }
- TOR_SIMPLEQ_FOREACH_SAFE(cell, &chan->outgoing_queue, next, cell_tmp) {
- cell_queue_entry_free(cell, 0);
- }
-
tor_free(chan);
}
@@ -489,16 +334,6 @@ scheduler_channel_doesnt_want_writes_mock(channel_t *ch)
}
/**
- * Counter query for scheduler_release_channel_mock()
- */
-
-int
-get_mock_scheduler_release_channel_count(void)
-{
- return test_releases_count;
-}
-
-/**
* Mock for scheduler_release_channel()
*/
@@ -513,6 +348,58 @@ scheduler_release_channel_mock(channel_t *ch)
return;
}
+static int
+test_chan_is_canonical(channel_t *chan, int req)
+{
+ tor_assert(chan);
+
+ if (req && test_chan_canonical_should_be_reliable) {
+ return 1;
+ }
+
+ if (test_chan_should_be_canonical) {
+ return 1;
+ }
+ return 0;
+}
+
+static int
+test_chan_matches_target(channel_t *chan, const tor_addr_t *target)
+{
+ (void) chan;
+ (void) target;
+
+ if (test_chan_should_match_target) {
+ return 1;
+ }
+ return 0;
+}
+
+static void
+test_chan_listener_close(channel_listener_t *chan)
+{
+ (void) chan;
+ ++test_chan_listener_close_fn_called;
+ return;
+}
+
+static void
+test_chan_listener_fn(channel_listener_t *listener, channel_t *chan)
+{
+ (void) listener;
+ (void) chan;
+
+ ++test_chan_listener_fn_called;
+ return;
+}
+
+static const char *
+test_chan_listener_describe_transport(channel_listener_t *chan)
+{
+ (void) chan;
+ return "Fake listener channel.";
+}
+
/**
* Test for channel_dumpstats() and limited test for
* channel_dump_statistics()
@@ -523,6 +410,7 @@ test_channel_dumpstats(void *arg)
{
channel_t *ch = NULL;
cell_t *cell = NULL;
+ packed_cell_t *p_cell = NULL;
int old_count;
(void)arg;
@@ -536,7 +424,6 @@ test_channel_dumpstats(void *arg)
/* Set up a new fake channel */
ch = new_fake_channel();
tt_assert(ch);
- ch->cmux = circuitmux_alloc();
/* Try to register it */
channel_register(ch);
@@ -579,24 +466,21 @@ test_channel_dumpstats(void *arg)
/* Now make another channel */
ch = new_fake_channel();
tt_assert(ch);
- ch->cmux = circuitmux_alloc();
channel_register(ch);
- tt_assert(ch->registered);
+ 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_assert(ch->timestamp_created > 0);
- tt_assert(time(NULL) > ch->timestamp_created);
+ 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 */
- cell = tor_malloc_zero(sizeof(*cell));
- make_fake_cell(cell);
+ p_cell = packed_cell_new();
test_chan_accept_cells = 1;
old_count = test_cells_written;
- channel_write_cell(ch, cell);
- cell = NULL;
+ channel_write_packed_cell(ch, p_cell);
tt_int_op(test_cells_written, OP_EQ, old_count + 1);
- tt_assert(ch->n_bytes_xmitted > 0);
- tt_assert(ch->n_cells_xmitted > 0);
+ 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,
@@ -605,19 +489,18 @@ test_channel_dumpstats(void *arg)
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_t));
- make_fake_cell(cell);
+ cell = tor_malloc_zero(sizeof(*cell));
old_count = test_chan_fixed_cells_recved;
- channel_queue_cell(ch, cell);
- tor_free(cell);
+ channel_process_cell(ch, cell);
tt_int_op(test_chan_fixed_cells_recved, OP_EQ, old_count + 1);
- tt_assert(ch->n_bytes_recved > 0);
- tt_assert(ch->n_cells_recved > 0);
+ 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;
- ch->is_canonical = chan_test_is_canonical;
+ 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);
@@ -631,8 +514,8 @@ test_channel_dumpstats(void *arg)
ch = NULL;
done:
- tor_free(cell);
free_fake_channel(ch);
+ tor_free(cell);
UNMOCK(scheduler_channel_doesnt_want_writes);
UNMOCK(scheduler_release_channel);
@@ -640,215 +523,229 @@ test_channel_dumpstats(void *arg)
return;
}
+/* 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_flush(void *arg)
+test_channel_outbound_cell(void *arg)
{
- channel_t *ch = NULL;
- cell_t *cell = NULL;
- packed_cell_t *p_cell = NULL;
- var_cell_t *v_cell = NULL;
- int init_count;
-
- (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;
- ch = new_fake_channel();
- tt_assert(ch);
+ (void) arg;
- /* Cache the original count */
- init_count = test_cells_written;
+ /* 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);
- /* Stop accepting so we can queue some */
- test_chan_accept_cells = 0;
+ /* Accept cells to lower layer */
+ test_chan_accept_cells = 1;
- /* Queue a regular cell */
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
- channel_write_cell(ch, cell);
- /* It should be queued, so assert that we didn't write it */
- tt_int_op(test_cells_written, OP_EQ, init_count);
-
- /* Queue a var cell */
- v_cell = tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE);
- make_fake_var_cell(v_cell);
- channel_write_var_cell(ch, v_cell);
- /* It should be queued, so assert that we didn't write it */
- tt_int_op(test_cells_written, OP_EQ, init_count);
-
- /* Try a packed cell now */
+ /* 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);
- channel_write_packed_cell(ch, p_cell);
- /* It should be queued, so assert that we didn't write it */
- tt_int_op(test_cells_written, OP_EQ, init_count);
-
- /* Now allow writes through again */
- test_chan_accept_cells = 1;
-
- /* ...and flush */
- channel_flush_cells(ch);
-
- /* All three should have gone through */
- tt_int_op(test_cells_written, OP_EQ, init_count + 3);
-
- done:
- tor_free(ch);
-
- return;
-}
-
-/**
- * Channel flush tests that require cmux mocking
- */
-
-static void
-test_channel_flushmux(void *arg)
-{
- channel_t *ch = NULL;
- int old_count, q_len_before, q_len_after;
- ssize_t result;
-
- (void)arg;
-
- /* Install mocks we need for this test */
- MOCK(channel_flush_from_first_active_circuit,
- chan_test_channel_flush_from_first_active_circuit_mock);
- MOCK(circuitmux_num_cells,
- chan_test_circuitmux_num_cells_mock);
-
- ch = new_fake_channel();
- tt_assert(ch);
- ch->cmux = circuitmux_alloc();
-
+ 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. */
+ channel_set_cmux_policy_everywhere(&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);
+ tt_assert(!TO_CIRCUIT(circ)->next_active_on_n_chan);
+ tt_assert(!TO_CIRCUIT(circ)->prev_active_on_n_chan);
+ /* 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;
-
- test_target_cmux = ch->cmux;
- test_cmux_cells = 1;
-
- /* Enable cell acceptance */
- test_chan_accept_cells = 1;
-
- result = channel_flush_some_cells(ch, 1);
-
- tt_int_op(result, OP_EQ, 1);
+ 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(test_cmux_cells, OP_EQ, 0);
-
- /* Now try it without accepting to force them into the queue */
- test_chan_accept_cells = 0;
- test_cmux_cells = 1;
- q_len_before = chan_cell_queue_len(&(ch->outgoing_queue));
-
- result = channel_flush_some_cells(ch, 1);
-
- /* We should not have actually flushed any */
- tt_int_op(result, OP_EQ, 0);
+ 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);
- /* But we should have gotten to the fake cellgen loop */
- tt_int_op(test_cmux_cells, OP_EQ, 0);
- /* ...and we should have a queued cell */
- q_len_after = chan_cell_queue_len(&(ch->outgoing_queue));
- tt_int_op(q_len_after, OP_EQ, q_len_before + 1);
-
- /* Now accept cells again and drain the queue */
- test_chan_accept_cells = 1;
- channel_flush_cells(ch);
- tt_int_op(test_cells_written, OP_EQ, old_count + 2);
- tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), OP_EQ, 0);
-
- test_target_cmux = NULL;
- test_cmux_cells = 0;
+ 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 (ch)
- circuitmux_free(ch->cmux);
- tor_free(ch);
-
- UNMOCK(channel_flush_from_first_active_circuit);
- UNMOCK(circuitmux_num_cells);
-
- test_chan_accept_cells = 0;
-
- return;
+ if (circ) {
+ circuit_free_(TO_CIRCUIT(circ));
+ }
+ tor_free(p_cell);
+ channel_free_all();
+ UNMOCK(scheduler_release_channel);
}
+/* 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_incoming(void *arg)
+test_channel_inbound_cell(void *arg)
{
- channel_t *ch = NULL;
+ channel_t *chan = NULL;
cell_t *cell = NULL;
- var_cell_t *var_cell = NULL;
int old_count;
- (void)arg;
+ (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);
+ /* 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;
- /* Use default overhead factor */
- test_overhead_estimate = 1.0;
- ch = new_fake_channel();
- tt_assert(ch);
+ chan = new_fake_channel();
+ tt_assert(chan);
/* Start it off in OPENING */
- ch->state = CHANNEL_STATE_OPENING;
- /* We'll need a cmux */
- ch->cmux = circuitmux_alloc();
-
- /* Install incoming cell handlers */
- channel_set_cell_handlers(ch,
- chan_test_cell_handler,
- chan_test_var_cell_handler);
- /* Test cell handler getters */
- 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);
+ chan->state = CHANNEL_STATE_OPENING;
/* Try to register it */
- channel_register(ch);
- tt_assert(ch->registered);
+ channel_register(chan);
+ tt_int_op(chan->registered, OP_EQ, 1);
/* Open it */
- channel_change_state_open(ch);
- tt_int_op(ch->state, OP_EQ, CHANNEL_STATE_OPEN);
+ 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 fixed cell */
- cell = tor_malloc_zero(sizeof(cell_t));
+ /* Receive a cell now. */
+ cell = tor_malloc_zero(sizeof(*cell));
make_fake_cell(cell);
old_count = test_chan_fixed_cells_recved;
- channel_queue_cell(ch, cell);
- tor_free(cell);
+ 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);
-
- /* Receive a variable-size cell */
- var_cell = tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE);
- make_fake_var_cell(var_cell);
- old_count = test_chan_var_cells_recved;
- channel_queue_var_cell(ch, var_cell);
- tor_free(cell);
- tt_int_op(test_chan_var_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 */
- 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);
+ 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();
- ch = NULL;
+ chan = channel_find_by_global_id(chan_id);
+ tt_assert(chan == NULL);
done:
- free_fake_channel(ch);
tor_free(cell);
- tor_free(var_cell);
-
- UNMOCK(scheduler_channel_doesnt_want_writes);
UNMOCK(scheduler_release_channel);
-
- return;
}
/**
@@ -861,7 +758,7 @@ static void
test_channel_lifecycle(void *arg)
{
channel_t *ch1 = NULL, *ch2 = NULL;
- cell_t *cell = NULL;
+ packed_cell_t *p_cell = NULL;
int old_count, init_doesnt_want_writes_count;
int init_releases_count;
@@ -879,38 +776,29 @@ test_channel_lifecycle(void *arg)
/* Accept cells to lower layer */
test_chan_accept_cells = 1;
- /* Use default overhead factor */
- test_overhead_estimate = 1.0;
ch1 = new_fake_channel();
tt_assert(ch1);
/* Start it off in OPENING */
ch1->state = CHANNEL_STATE_OPENING;
- /* We'll need a cmux */
- ch1->cmux = circuitmux_alloc();
/* Try to register it */
channel_register(ch1);
tt_assert(ch1->registered);
/* Try to write a cell through (should queue) */
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
+ p_cell = packed_cell_new();
old_count = test_cells_written;
- channel_write_cell(ch1, cell);
+ channel_write_packed_cell(ch1, p_cell);
tt_int_op(old_count, OP_EQ, test_cells_written);
/* Move it to OPEN and flush */
channel_change_state_open(ch1);
- /* Queue should drain */
- tt_int_op(old_count + 1, OP_EQ, test_cells_written);
-
- /* Get another one */
+/* Get another one */
ch2 = new_fake_channel();
tt_assert(ch2);
ch2->state = CHANNEL_STATE_OPENING;
- ch2->cmux = circuitmux_alloc();
/* Register */
channel_register(ch2);
@@ -960,8 +848,6 @@ test_channel_lifecycle(void *arg)
UNMOCK(scheduler_channel_doesnt_want_writes);
UNMOCK(scheduler_release_channel);
-
- return;
}
/**
@@ -988,15 +874,11 @@ test_channel_lifecycle_2(void *arg)
/* Accept cells to lower layer */
test_chan_accept_cells = 1;
- /* Use default overhead factor */
- test_overhead_estimate = 1.0;
ch = new_fake_channel();
tt_assert(ch);
/* Start it off in OPENING */
ch->state = CHANNEL_STATE_OPENING;
- /* The full lifecycle test needs a cmux */
- ch->cmux = circuitmux_alloc();
/* Try to register it */
channel_register(ch);
@@ -1016,7 +898,6 @@ test_channel_lifecycle_2(void *arg)
ch = new_fake_channel();
tt_assert(ch);
ch->state = CHANNEL_STATE_OPENING;
- ch->cmux = circuitmux_alloc();
channel_register(ch);
tt_assert(ch->registered);
@@ -1035,7 +916,6 @@ test_channel_lifecycle_2(void *arg)
ch = new_fake_channel();
tt_assert(ch);
ch->state = CHANNEL_STATE_OPENING;
- ch->cmux = circuitmux_alloc();
channel_register(ch);
tt_assert(ch->registered);
@@ -1064,7 +944,6 @@ test_channel_lifecycle_2(void *arg)
ch = new_fake_channel();
tt_assert(ch);
ch->state = CHANNEL_STATE_OPENING;
- ch->cmux = circuitmux_alloc();
channel_register(ch);
tt_assert(ch->registered);
@@ -1090,7 +969,6 @@ test_channel_lifecycle_2(void *arg)
ch = new_fake_channel();
tt_assert(ch);
ch->state = CHANNEL_STATE_OPENING;
- ch->cmux = circuitmux_alloc();
channel_register(ch);
tt_assert(ch->registered);
@@ -1125,655 +1003,6 @@ test_channel_lifecycle_2(void *arg)
}
static void
-test_channel_multi(void *arg)
-{
- channel_t *ch1 = NULL, *ch2 = NULL;
- uint64_t global_queue_estimate;
- cell_t *cell = NULL;
-
- (void)arg;
-
- /* Accept cells to lower layer */
- test_chan_accept_cells = 1;
- /* Use default overhead factor */
- test_overhead_estimate = 1.0;
-
- ch1 = new_fake_channel();
- tt_assert(ch1);
- ch2 = new_fake_channel();
- tt_assert(ch2);
-
- /* Initial queue size update */
- channel_update_xmit_queue_size(ch1);
- tt_u64_op(ch1->bytes_queued_for_xmit, OP_EQ, 0);
- channel_update_xmit_queue_size(ch2);
- tt_u64_op(ch2->bytes_queued_for_xmit, OP_EQ, 0);
- global_queue_estimate = channel_get_global_queue_estimate();
- tt_u64_op(global_queue_estimate, OP_EQ, 0);
-
- /* Queue some cells, check queue estimates */
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
- channel_write_cell(ch1, cell);
-
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
- channel_write_cell(ch2, cell);
-
- channel_update_xmit_queue_size(ch1);
- channel_update_xmit_queue_size(ch2);
- tt_u64_op(ch1->bytes_queued_for_xmit, OP_EQ, 0);
- tt_u64_op(ch2->bytes_queued_for_xmit, OP_EQ, 0);
- global_queue_estimate = channel_get_global_queue_estimate();
- tt_u64_op(global_queue_estimate, OP_EQ, 0);
-
- /* Stop accepting cells at lower layer */
- test_chan_accept_cells = 0;
-
- /* Queue some cells and check queue estimates */
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
- channel_write_cell(ch1, cell);
-
- channel_update_xmit_queue_size(ch1);
- tt_u64_op(ch1->bytes_queued_for_xmit, OP_EQ, 512);
- global_queue_estimate = channel_get_global_queue_estimate();
- tt_u64_op(global_queue_estimate, OP_EQ, 512);
-
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
- channel_write_cell(ch2, cell);
-
- channel_update_xmit_queue_size(ch2);
- tt_u64_op(ch2->bytes_queued_for_xmit, OP_EQ, 512);
- global_queue_estimate = channel_get_global_queue_estimate();
- tt_u64_op(global_queue_estimate, OP_EQ, 1024);
-
- /* Allow cells through again */
- test_chan_accept_cells = 1;
-
- /* Flush chan 2 */
- channel_flush_cells(ch2);
-
- /* Update and check queue sizes */
- channel_update_xmit_queue_size(ch1);
- channel_update_xmit_queue_size(ch2);
- tt_u64_op(ch1->bytes_queued_for_xmit, OP_EQ, 512);
- tt_u64_op(ch2->bytes_queued_for_xmit, OP_EQ, 0);
- global_queue_estimate = channel_get_global_queue_estimate();
- tt_u64_op(global_queue_estimate, OP_EQ, 512);
-
- /* Flush chan 1 */
- channel_flush_cells(ch1);
-
- /* Update and check queue sizes */
- channel_update_xmit_queue_size(ch1);
- channel_update_xmit_queue_size(ch2);
- tt_u64_op(ch1->bytes_queued_for_xmit, OP_EQ, 0);
- tt_u64_op(ch2->bytes_queued_for_xmit, OP_EQ, 0);
- global_queue_estimate = channel_get_global_queue_estimate();
- tt_u64_op(global_queue_estimate, OP_EQ, 0);
-
- /* Now block again */
- test_chan_accept_cells = 0;
-
- /* Queue some cells */
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
- channel_write_cell(ch1, cell);
-
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
- channel_write_cell(ch2, cell);
- cell = NULL;
-
- /* Check the estimates */
- channel_update_xmit_queue_size(ch1);
- channel_update_xmit_queue_size(ch2);
- tt_u64_op(ch1->bytes_queued_for_xmit, OP_EQ, 512);
- tt_u64_op(ch2->bytes_queued_for_xmit, OP_EQ, 512);
- global_queue_estimate = channel_get_global_queue_estimate();
- tt_u64_op(global_queue_estimate, OP_EQ, 1024);
-
- /* Now close channel 2; it should be subtracted from the global queue */
- MOCK(scheduler_release_channel, scheduler_release_channel_mock);
- channel_mark_for_close(ch2);
- UNMOCK(scheduler_release_channel);
-
- global_queue_estimate = channel_get_global_queue_estimate();
- tt_u64_op(global_queue_estimate, OP_EQ, 512);
-
- /*
- * Since the fake channels aren't registered, channel_free_all() can't
- * see them properly.
- */
- MOCK(scheduler_release_channel, scheduler_release_channel_mock);
- channel_mark_for_close(ch1);
- UNMOCK(scheduler_release_channel);
-
- global_queue_estimate = channel_get_global_queue_estimate();
- tt_u64_op(global_queue_estimate, OP_EQ, 0);
-
- /* Now free everything */
- MOCK(scheduler_release_channel, scheduler_release_channel_mock);
- channel_free_all();
- UNMOCK(scheduler_release_channel);
-
- done:
- free_fake_channel(ch1);
- free_fake_channel(ch2);
-
- return;
-}
-
-/**
- * Check some hopefully-impossible edge cases in the channel queue we
- * can only trigger by doing evil things to the queue directly.
- */
-
-static void
-test_channel_queue_impossible(void *arg)
-{
- channel_t *ch = NULL;
- cell_t *cell = NULL;
- packed_cell_t *packed_cell = NULL;
- var_cell_t *var_cell = NULL;
- int old_count;
- cell_queue_entry_t *q = NULL;
- uint64_t global_queue_estimate;
- uintptr_t cellintptr;
-
- /* Cache the global queue size (see below) */
- global_queue_estimate = channel_get_global_queue_estimate();
-
- (void)arg;
-
- ch = new_fake_channel();
- tt_assert(ch);
-
- /* We test queueing here; tell it not to accept cells */
- test_chan_accept_cells = 0;
- /* ...and keep it from trying to flush the queue */
- ch->state = CHANNEL_STATE_MAINT;
-
- /* Cache the cell written count */
- old_count = test_cells_written;
-
- /* Assert that the queue is initially empty */
- tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), OP_EQ, 0);
-
- /* Get a fresh cell and write it to the channel*/
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
- cellintptr = (uintptr_t)(void*)cell;
- channel_write_cell(ch, cell);
-
- /* Now it should be queued */
- tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), OP_EQ, 1);
- q = TOR_SIMPLEQ_FIRST(&(ch->outgoing_queue));
- tt_assert(q);
- if (q) {
- tt_int_op(q->type, OP_EQ, CELL_QUEUE_FIXED);
- tt_assert((uintptr_t)q->u.fixed.cell == cellintptr);
- }
- /* Do perverse things to it */
- tor_free(q->u.fixed.cell);
- q->u.fixed.cell = NULL;
-
- /*
- * Now change back to open with channel_change_state() and assert that it
- * gets thrown away properly.
- */
- test_chan_accept_cells = 1;
- channel_change_state_open(ch);
- tt_assert(test_cells_written == old_count);
- tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), OP_EQ, 0);
-
- /* Same thing but for a var_cell */
-
- test_chan_accept_cells = 0;
- ch->state = CHANNEL_STATE_MAINT;
- var_cell = tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE);
- make_fake_var_cell(var_cell);
- cellintptr = (uintptr_t)(void*)var_cell;
- channel_write_var_cell(ch, var_cell);
-
- /* Check that it's queued */
- tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), OP_EQ, 1);
- q = TOR_SIMPLEQ_FIRST(&(ch->outgoing_queue));
- tt_assert(q);
- if (q) {
- tt_int_op(q->type, OP_EQ, CELL_QUEUE_VAR);
- tt_assert((uintptr_t)q->u.var.var_cell == cellintptr);
- }
-
- /* Remove the cell from the queue entry */
- tor_free(q->u.var.var_cell);
- q->u.var.var_cell = NULL;
-
- /* Let it drain and check that the bad entry is discarded */
- test_chan_accept_cells = 1;
- channel_change_state_open(ch);
- tt_assert(test_cells_written == old_count);
- tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), OP_EQ, 0);
-
- /* Same thing with a packed_cell */
-
- test_chan_accept_cells = 0;
- ch->state = CHANNEL_STATE_MAINT;
- packed_cell = packed_cell_new();
- tt_assert(packed_cell);
- cellintptr = (uintptr_t)(void*)packed_cell;
- channel_write_packed_cell(ch, packed_cell);
-
- /* Check that it's queued */
- tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), OP_EQ, 1);
- q = TOR_SIMPLEQ_FIRST(&(ch->outgoing_queue));
- tt_assert(q);
- if (q) {
- tt_int_op(q->type, OP_EQ, CELL_QUEUE_PACKED);
- tt_assert((uintptr_t)q->u.packed.packed_cell == cellintptr);
- }
-
- /* Remove the cell from the queue entry */
- packed_cell_free(q->u.packed.packed_cell);
- q->u.packed.packed_cell = NULL;
-
- /* Let it drain and check that the bad entry is discarded */
- test_chan_accept_cells = 1;
- channel_change_state_open(ch);
- tt_assert(test_cells_written == old_count);
- tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), OP_EQ, 0);
-
- /* Unknown cell type case */
- test_chan_accept_cells = 0;
- ch->state = CHANNEL_STATE_MAINT;
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
- cellintptr = (uintptr_t)(void*)cell;
- channel_write_cell(ch, cell);
-
- /* Check that it's queued */
- tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), OP_EQ, 1);
- q = TOR_SIMPLEQ_FIRST(&(ch->outgoing_queue));
- tt_assert(q);
- if (q) {
- tt_int_op(q->type, OP_EQ, CELL_QUEUE_FIXED);
- tt_assert((uintptr_t)q->u.fixed.cell == cellintptr);
- }
- /* Clobber it, including the queue entry type */
- tor_free(q->u.fixed.cell);
- q->u.fixed.cell = NULL;
- q->type = CELL_QUEUE_PACKED + 1;
-
- /* Let it drain and check that the bad entry is discarded */
- test_chan_accept_cells = 1;
- tor_capture_bugs_(1);
- channel_change_state_open(ch);
- tt_assert(test_cells_written == old_count);
- tt_int_op(chan_cell_queue_len(&(ch->outgoing_queue)), OP_EQ, 0);
-
- tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
- tor_end_capture_bugs_();
-
- done:
- free_fake_channel(ch);
-
- /*
- * Doing that meant that we couldn't correctly adjust the queue size
- * for the var cell, so manually reset the global queue size estimate
- * so the next test doesn't break if we run with --no-fork.
- */
- estimated_total_queue_size = global_queue_estimate;
-
- return;
-}
-
-static void
-test_channel_queue_incoming(void *arg)
-{
- channel_t *ch = NULL;
- cell_t *cell = NULL;
- var_cell_t *var_cell = NULL;
- int old_fixed_count, old_var_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);
-
- /* Accept cells to lower layer */
- test_chan_accept_cells = 1;
- /* Use default overhead factor */
- test_overhead_estimate = 1.0;
-
- ch = new_fake_channel();
- tt_assert(ch);
- /* Start it off in OPENING */
- ch->state = CHANNEL_STATE_OPENING;
- /* We'll need a cmux */
- ch->cmux = circuitmux_alloc();
-
- /* Test cell handler getters */
- tt_ptr_op(channel_get_cell_handler(ch), OP_EQ, NULL);
- tt_ptr_op(channel_get_var_cell_handler(ch), OP_EQ, NULL);
-
- /* Try to register it */
- channel_register(ch);
- tt_assert(ch->registered);
-
- /* Open it */
- channel_change_state_open(ch);
- tt_int_op(ch->state, OP_EQ, CHANNEL_STATE_OPEN);
-
- /* Assert that the incoming queue is empty */
- tt_assert(TOR_SIMPLEQ_EMPTY(&(ch->incoming_queue)));
-
- /* Queue an incoming fixed-length cell */
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
- channel_queue_cell(ch, cell);
-
- /* Assert that the incoming queue has one entry */
- tt_int_op(chan_cell_queue_len(&(ch->incoming_queue)), OP_EQ, 1);
-
- /* Queue an incoming var cell */
- var_cell = tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE);
- make_fake_var_cell(var_cell);
- channel_queue_var_cell(ch, var_cell);
-
- /* Assert that the incoming queue has two entries */
- tt_int_op(chan_cell_queue_len(&(ch->incoming_queue)), OP_EQ, 2);
-
- /*
- * Install cell handlers; this will drain the queue, so save the old
- * cell counters first
- */
- old_fixed_count = test_chan_fixed_cells_recved;
- old_var_count = test_chan_var_cells_recved;
- 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);
-
- /* Assert cells were received */
- tt_int_op(test_chan_fixed_cells_recved, OP_EQ, old_fixed_count + 1);
- tt_int_op(test_chan_var_cells_recved, OP_EQ, old_var_count + 1);
-
- /*
- * Assert that the pointers are different from the cells we allocated;
- * when queueing cells with no incoming cell handlers installed, the
- * channel layer should copy them to a new buffer, and free them after
- * delivery. These pointers will have already been freed by the time
- * we get here, so don't dereference them.
- */
- tt_ptr_op(test_chan_last_seen_fixed_cell_ptr, OP_NE, cell);
- tt_ptr_op(test_chan_last_seen_var_cell_ptr, OP_NE, var_cell);
-
- /* Assert queue is now empty */
- tt_assert(TOR_SIMPLEQ_EMPTY(&(ch->incoming_queue)));
-
- /* Close it; this contains an assertion that the incoming queue is empty */
- 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);
- tor_free(var_cell);
-
- UNMOCK(scheduler_channel_doesnt_want_writes);
- UNMOCK(scheduler_release_channel);
-
- return;
-}
-
-static void
-test_channel_queue_size(void *arg)
-{
- channel_t *ch = NULL;
- cell_t *cell = NULL;
- int n, old_count;
- uint64_t global_queue_estimate;
-
- (void)arg;
-
- ch = new_fake_channel();
- tt_assert(ch);
-
- /* Initial queue size update */
- channel_update_xmit_queue_size(ch);
- tt_u64_op(ch->bytes_queued_for_xmit, OP_EQ, 0);
- global_queue_estimate = channel_get_global_queue_estimate();
- tt_u64_op(global_queue_estimate, OP_EQ, 0);
-
- /* Test the call-through to our fake lower layer */
- n = channel_num_cells_writeable(ch);
- /* chan_test_num_cells_writeable() always returns 32 */
- tt_int_op(n, OP_EQ, 32);
-
- /*
- * Now we queue some cells and check that channel_num_cells_writeable()
- * adjusts properly
- */
-
- /* tell it not to accept cells */
- test_chan_accept_cells = 0;
- /* ...and keep it from trying to flush the queue */
- ch->state = CHANNEL_STATE_MAINT;
-
- /* Get a fresh cell */
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
-
- old_count = test_cells_written;
- channel_write_cell(ch, cell);
- /* Assert that it got queued, not written through, correctly */
- tt_int_op(test_cells_written, OP_EQ, old_count);
-
- /* Now check chan_test_num_cells_writeable() again */
- n = channel_num_cells_writeable(ch);
- /* Should return 0 since we're in CHANNEL_STATE_MAINT */
- tt_int_op(n, OP_EQ, 0);
-
- /* Update queue size estimates */
- channel_update_xmit_queue_size(ch);
- /* One cell, times an overhead factor of 1.0 */
- tt_u64_op(ch->bytes_queued_for_xmit, OP_EQ, 512);
- /* Try a different overhead factor */
- test_overhead_estimate = 0.5;
- /* This one should be ignored since it's below 1.0 */
- channel_update_xmit_queue_size(ch);
- tt_u64_op(ch->bytes_queued_for_xmit, OP_EQ, 512);
- /* Now try a larger one */
- test_overhead_estimate = 2.0;
- channel_update_xmit_queue_size(ch);
- tt_u64_op(ch->bytes_queued_for_xmit, OP_EQ, 1024);
- /* Go back to 1.0 */
- test_overhead_estimate = 1.0;
- channel_update_xmit_queue_size(ch);
- tt_u64_op(ch->bytes_queued_for_xmit, OP_EQ, 512);
- /* Check the global estimate too */
- global_queue_estimate = channel_get_global_queue_estimate();
- tt_u64_op(global_queue_estimate, OP_EQ, 512);
-
- /* Go to open */
- old_count = test_cells_written;
- channel_change_state_open(ch);
-
- /*
- * It should try to write, but we aren't accepting cells right now, so
- * it'll requeue
- */
- tt_int_op(test_cells_written, OP_EQ, old_count);
-
- /* Check the queue size again */
- channel_update_xmit_queue_size(ch);
- tt_u64_op(ch->bytes_queued_for_xmit, OP_EQ, 512);
- global_queue_estimate = channel_get_global_queue_estimate();
- tt_u64_op(global_queue_estimate, OP_EQ, 512);
-
- /*
- * Now the cell is in the queue, and we're open, so we should get 31
- * writeable cells.
- */
- n = channel_num_cells_writeable(ch);
- tt_int_op(n, OP_EQ, 31);
-
- /* Accept cells again */
- test_chan_accept_cells = 1;
- /* ...and re-process the queue */
- old_count = test_cells_written;
- channel_flush_cells(ch);
- tt_int_op(test_cells_written, OP_EQ, old_count + 1);
-
- /* Should have 32 writeable now */
- n = channel_num_cells_writeable(ch);
- tt_int_op(n, OP_EQ, 32);
-
- /* Should have queue size estimate of zero */
- channel_update_xmit_queue_size(ch);
- tt_u64_op(ch->bytes_queued_for_xmit, OP_EQ, 0);
- global_queue_estimate = channel_get_global_queue_estimate();
- tt_u64_op(global_queue_estimate, OP_EQ, 0);
-
- /* Okay, now we're done with this one */
- MOCK(scheduler_release_channel, scheduler_release_channel_mock);
- channel_mark_for_close(ch);
- UNMOCK(scheduler_release_channel);
-
- done:
- free_fake_channel(ch);
-
- return;
-}
-
-static void
-test_channel_write(void *arg)
-{
- channel_t *ch = NULL;
- cell_t *cell = tor_malloc_zero(sizeof(cell_t));
- packed_cell_t *packed_cell = NULL;
- var_cell_t *var_cell =
- tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE);
- int old_count;
-
- (void)arg;
-
- packed_cell = packed_cell_new();
- tt_assert(packed_cell);
-
- ch = new_fake_channel();
- tt_assert(ch);
- make_fake_cell(cell);
- make_fake_var_cell(var_cell);
-
- /* Tell it to accept cells */
- test_chan_accept_cells = 1;
-
- old_count = test_cells_written;
- channel_write_cell(ch, cell);
- cell = NULL;
- tt_assert(test_cells_written == old_count + 1);
-
- channel_write_var_cell(ch, var_cell);
- var_cell = NULL;
- tt_assert(test_cells_written == old_count + 2);
-
- channel_write_packed_cell(ch, packed_cell);
- packed_cell = NULL;
- tt_assert(test_cells_written == old_count + 3);
-
- /* Now we test queueing; tell it not to accept cells */
- test_chan_accept_cells = 0;
- /* ...and keep it from trying to flush the queue */
- ch->state = CHANNEL_STATE_MAINT;
-
- /* Get a fresh cell */
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
-
- old_count = test_cells_written;
- channel_write_cell(ch, cell);
- tt_assert(test_cells_written == old_count);
-
- /*
- * Now change back to open with channel_change_state() and assert that it
- * gets drained from the queue.
- */
- test_chan_accept_cells = 1;
- channel_change_state_open(ch);
- tt_assert(test_cells_written == old_count + 1);
-
- /*
- * Check the note destroy case
- */
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
- cell->command = CELL_DESTROY;
-
- /* Set up the mock */
- MOCK(channel_note_destroy_not_pending,
- channel_note_destroy_not_pending_mock);
-
- old_count = test_destroy_not_pending_calls;
- channel_write_cell(ch, cell);
- tt_assert(test_destroy_not_pending_calls == old_count + 1);
-
- /* Now send a non-destroy and check we don't call it */
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
- channel_write_cell(ch, cell);
- tt_assert(test_destroy_not_pending_calls == old_count + 1);
-
- UNMOCK(channel_note_destroy_not_pending);
-
- /*
- * Now switch it to CLOSING so we can test the discard-cells case
- * in the channel_write_*() functions.
- */
- MOCK(scheduler_release_channel, scheduler_release_channel_mock);
- channel_mark_for_close(ch);
- UNMOCK(scheduler_release_channel);
-
- /* Send cells that will drop in the closing state */
- old_count = test_cells_written;
-
- cell = tor_malloc_zero(sizeof(cell_t));
- make_fake_cell(cell);
- channel_write_cell(ch, cell);
- cell = NULL;
- tt_assert(test_cells_written == old_count);
-
- var_cell = tor_malloc_zero(sizeof(var_cell_t) + CELL_PAYLOAD_SIZE);
- make_fake_var_cell(var_cell);
- channel_write_var_cell(ch, var_cell);
- var_cell = NULL;
- tt_assert(test_cells_written == old_count);
-
- packed_cell = packed_cell_new();
- channel_write_packed_cell(ch, packed_cell);
- packed_cell = NULL;
- tt_assert(test_cells_written == old_count);
-
- done:
- free_fake_channel(ch);
- tor_free(var_cell);
- tor_free(cell);
- packed_cell_free(packed_cell);
- return;
-}
-
-static void
test_channel_id_map(void *arg)
{
(void)arg;
@@ -1879,19 +1108,449 @@ test_channel_id_map(void *arg)
#undef N_CHAN
}
+static void
+test_channel_state(void *arg)
+{
+ (void) arg;
+
+ /* Test state validity. */
+ tt_int_op(channel_state_is_valid(CHANNEL_STATE_CLOSED), OP_EQ, 1);
+ tt_int_op(channel_state_is_valid(CHANNEL_STATE_CLOSING), OP_EQ, 1);
+ tt_int_op(channel_state_is_valid(CHANNEL_STATE_ERROR), OP_EQ, 1);
+ tt_int_op(channel_state_is_valid(CHANNEL_STATE_OPEN), OP_EQ, 1);
+ tt_int_op(channel_state_is_valid(CHANNEL_STATE_OPENING), OP_EQ, 1);
+ tt_int_op(channel_state_is_valid(CHANNEL_STATE_MAINT), OP_EQ, 1);
+ tt_int_op(channel_state_is_valid(CHANNEL_STATE_LAST), OP_EQ, 0);
+ tt_int_op(channel_state_is_valid(INT_MAX), OP_EQ, 0);
+
+ /* Test listener state validity. */
+ tt_int_op(channel_listener_state_is_valid(CHANNEL_LISTENER_STATE_CLOSED),
+ OP_EQ, 1);
+ tt_int_op(channel_listener_state_is_valid(CHANNEL_LISTENER_STATE_LISTENING),
+ OP_EQ, 1);
+ tt_int_op(channel_listener_state_is_valid(CHANNEL_LISTENER_STATE_CLOSING),
+ OP_EQ, 1);
+ tt_int_op(channel_listener_state_is_valid(CHANNEL_LISTENER_STATE_ERROR),
+ OP_EQ, 1);
+ tt_int_op(channel_listener_state_is_valid(CHANNEL_LISTENER_STATE_LAST),
+ OP_EQ, 0);
+ tt_int_op(channel_listener_state_is_valid(INT_MAX), OP_EQ, 0);
+
+ /* Test state transition. */
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_CLOSED,
+ CHANNEL_STATE_OPENING), OP_EQ, 1);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_CLOSED,
+ CHANNEL_STATE_ERROR), OP_EQ, 0);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_CLOSING,
+ CHANNEL_STATE_ERROR), OP_EQ, 1);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_CLOSING,
+ CHANNEL_STATE_CLOSED), OP_EQ, 1);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_CLOSING,
+ CHANNEL_STATE_OPEN), OP_EQ, 0);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_MAINT,
+ CHANNEL_STATE_CLOSING), OP_EQ, 1);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_MAINT,
+ CHANNEL_STATE_ERROR), OP_EQ, 1);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_MAINT,
+ CHANNEL_STATE_OPEN), OP_EQ, 1);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_MAINT,
+ CHANNEL_STATE_OPENING), OP_EQ, 0);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_OPENING,
+ CHANNEL_STATE_OPEN), OP_EQ, 1);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_OPENING,
+ CHANNEL_STATE_CLOSING), OP_EQ, 1);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_OPENING,
+ CHANNEL_STATE_ERROR), OP_EQ, 1);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_OPEN,
+ CHANNEL_STATE_ERROR), OP_EQ, 1);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_OPEN,
+ CHANNEL_STATE_CLOSING), OP_EQ, 1);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_OPEN,
+ CHANNEL_STATE_ERROR), OP_EQ, 1);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_OPEN,
+ CHANNEL_STATE_MAINT), OP_EQ, 1);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_LAST,
+ CHANNEL_STATE_MAINT), OP_EQ, 0);
+ tt_int_op(channel_state_can_transition(CHANNEL_STATE_LAST, INT_MAX),
+ OP_EQ, 0);
+
+ /* Test listener state transition. */
+ tt_int_op(channel_listener_state_can_transition(
+ CHANNEL_LISTENER_STATE_CLOSED,
+ CHANNEL_LISTENER_STATE_LISTENING),
+ OP_EQ, 1);
+ tt_int_op(channel_listener_state_can_transition(
+ CHANNEL_LISTENER_STATE_CLOSED,
+ CHANNEL_LISTENER_STATE_ERROR),
+ OP_EQ, 0);
+
+ tt_int_op(channel_listener_state_can_transition(
+ CHANNEL_LISTENER_STATE_CLOSING,
+ CHANNEL_LISTENER_STATE_CLOSED),
+ OP_EQ, 1);
+
+ tt_int_op(channel_listener_state_can_transition(
+ CHANNEL_LISTENER_STATE_CLOSING,
+ CHANNEL_LISTENER_STATE_ERROR),
+ OP_EQ, 1);
+ tt_int_op(channel_listener_state_can_transition(
+ CHANNEL_LISTENER_STATE_ERROR,
+ CHANNEL_LISTENER_STATE_CLOSING),
+ OP_EQ, 0);
+
+ tt_int_op(channel_listener_state_can_transition(
+ CHANNEL_LISTENER_STATE_LISTENING,
+ CHANNEL_LISTENER_STATE_CLOSING),
+ OP_EQ, 1);
+ tt_int_op(channel_listener_state_can_transition(
+ CHANNEL_LISTENER_STATE_LISTENING,
+ CHANNEL_LISTENER_STATE_ERROR),
+ OP_EQ, 1);
+ tt_int_op(channel_listener_state_can_transition(
+ CHANNEL_LISTENER_STATE_LAST,
+ INT_MAX),
+ OP_EQ, 0);
+
+ /* Test state string. */
+ tt_str_op(channel_state_to_string(CHANNEL_STATE_CLOSING), OP_EQ,
+ "closing");
+ tt_str_op(channel_state_to_string(CHANNEL_STATE_ERROR), OP_EQ,
+ "channel error");
+ tt_str_op(channel_state_to_string(CHANNEL_STATE_CLOSED), OP_EQ,
+ "closed");
+ tt_str_op(channel_state_to_string(CHANNEL_STATE_OPEN), OP_EQ,
+ "open");
+ tt_str_op(channel_state_to_string(CHANNEL_STATE_OPENING), OP_EQ,
+ "opening");
+ tt_str_op(channel_state_to_string(CHANNEL_STATE_MAINT), OP_EQ,
+ "temporarily suspended for maintenance");
+ tt_str_op(channel_state_to_string(CHANNEL_STATE_LAST), OP_EQ,
+ "unknown or invalid channel state");
+ tt_str_op(channel_state_to_string(INT_MAX), OP_EQ,
+ "unknown or invalid channel state");
+
+ /* Test listener state string. */
+ tt_str_op(channel_listener_state_to_string(CHANNEL_LISTENER_STATE_CLOSING),
+ OP_EQ, "closing");
+ tt_str_op(channel_listener_state_to_string(CHANNEL_LISTENER_STATE_ERROR),
+ OP_EQ, "channel listener error");
+ tt_str_op(channel_listener_state_to_string(CHANNEL_LISTENER_STATE_LISTENING),
+ OP_EQ, "listening");
+ tt_str_op(channel_listener_state_to_string(CHANNEL_LISTENER_STATE_LAST),
+ OP_EQ, "unknown or invalid channel listener state");
+ tt_str_op(channel_listener_state_to_string(INT_MAX),
+ OP_EQ, "unknown or invalid channel listener state");
+
+ done:
+ ;
+}
+
+static networkstatus_t *mock_ns = NULL;
+
+static networkstatus_t *
+mock_networkstatus_get_latest_consensus(void)
+{
+ return mock_ns;
+}
+
+static void
+test_channel_duplicates(void *arg)
+{
+ channel_t *chan = NULL;
+ routerstatus_t rs;
+
+ (void) arg;
+
+ setup_full_capture_of_logs(LOG_INFO);
+ /* Try a flat call with channel nor connections. */
+ channel_check_for_duplicates();
+ expect_log_msg_containing(
+ "Found 0 connections to 0 relays. Found 0 current canonical "
+ "connections, in 0 of which we were a non-canonical peer. "
+ "0 relays had more than 1 connection, 0 had more than 2, and "
+ "0 had more than 4 connections.");
+
+ mock_ns = tor_malloc_zero(sizeof(*mock_ns));
+ mock_ns->routerstatus_list = smartlist_new();
+ MOCK(networkstatus_get_latest_consensus,
+ mock_networkstatus_get_latest_consensus);
+
+ chan = new_fake_channel();
+ tt_assert(chan);
+ chan->is_canonical = test_chan_is_canonical;
+ memset(chan->identity_digest, 'A', sizeof(chan->identity_digest));
+ channel_add_to_digest_map(chan);
+ tt_ptr_op(channel_find_by_remote_identity(chan->identity_digest, NULL),
+ OP_EQ, chan);
+
+ /* No relay has been associated with this channel. */
+ channel_check_for_duplicates();
+ expect_log_msg_containing(
+ "Found 0 connections to 0 relays. Found 0 current canonical "
+ "connections, in 0 of which we were a non-canonical peer. "
+ "0 relays had more than 1 connection, 0 had more than 2, and "
+ "0 had more than 4 connections.");
+
+ /* Associate relay to this connection in the consensus. */
+ memset(&rs, 0, sizeof(rs));
+ memset(rs.identity_digest, 'A', sizeof(rs.identity_digest));
+ smartlist_add(mock_ns->routerstatus_list, &rs);
+
+ /* Non opened channel. */
+ chan->state = CHANNEL_STATE_CLOSING;
+ channel_check_for_duplicates();
+ expect_log_msg_containing(
+ "Found 0 connections to 0 relays. Found 0 current canonical "
+ "connections, in 0 of which we were a non-canonical peer. "
+ "0 relays had more than 1 connection, 0 had more than 2, and "
+ "0 had more than 4 connections.");
+ chan->state = CHANNEL_STATE_OPEN;
+
+ channel_check_for_duplicates();
+ expect_log_msg_containing(
+ "Found 1 connections to 1 relays. Found 0 current canonical "
+ "connections, in 0 of which we were a non-canonical peer. "
+ "0 relays had more than 1 connection, 0 had more than 2, and "
+ "0 had more than 4 connections.");
+
+ test_chan_should_be_canonical = 1;
+ channel_check_for_duplicates();
+ expect_log_msg_containing(
+ "Found 1 connections to 1 relays. Found 1 current canonical "
+ "connections, in 1 of which we were a non-canonical peer. "
+ "0 relays had more than 1 connection, 0 had more than 2, and "
+ "0 had more than 4 connections.");
+ teardown_capture_of_logs();
+
+ done:
+ free_fake_channel(chan);
+ smartlist_clear(mock_ns->routerstatus_list);
+ networkstatus_vote_free(mock_ns);
+ UNMOCK(networkstatus_get_latest_consensus);
+}
+
+static void
+test_channel_for_extend(void *arg)
+{
+ channel_t *chan1 = NULL, *chan2 = NULL;
+ channel_t *ret_chan = NULL;
+ char digest[DIGEST_LEN];
+ ed25519_public_key_t ed_id;
+ tor_addr_t addr;
+ const char *msg;
+ int launch;
+ time_t now = time(NULL);
+
+ (void) arg;
+
+ memset(digest, 'A', sizeof(digest));
+ memset(&ed_id, 'B', sizeof(ed_id));
+
+ chan1 = new_fake_channel();
+ tt_assert(chan1);
+ /* Need to be registered to get added to the id map. */
+ channel_register(chan1);
+ tt_int_op(chan1->registered, OP_EQ, 1);
+ /* We need those for the test. */
+ chan1->is_canonical = test_chan_is_canonical;
+ chan1->matches_target = test_chan_matches_target;
+ chan1->timestamp_created = now - 9;
+
+ chan2 = new_fake_channel();
+ tt_assert(chan2);
+ /* Need to be registered to get added to the id map. */
+ channel_register(chan2);
+ tt_int_op(chan2->registered, OP_EQ, 1);
+ /* We need those for the test. */
+ chan2->is_canonical = test_chan_is_canonical;
+ chan2->matches_target = test_chan_matches_target;
+ /* Make it older than chan1. */
+ chan2->timestamp_created = chan1->timestamp_created - 1;
+
+ /* Set channel identities and add it to the channel map. The last one to be
+ * added is made the first one in the list so the lookup will always return
+ * that one first. */
+ channel_set_identity_digest(chan2, digest, &ed_id);
+ channel_set_identity_digest(chan1, digest, &ed_id);
+ tt_ptr_op(channel_find_by_remote_identity(digest, NULL), OP_EQ, chan1);
+ tt_ptr_op(channel_find_by_remote_identity(digest, &ed_id), OP_EQ, chan1);
+
+ /* The expected result is chan2 because it is older than chan1. */
+ ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
+ tt_assert(ret_chan);
+ tt_ptr_op(ret_chan, OP_EQ, chan2);
+ tt_int_op(launch, OP_EQ, 0);
+ tt_str_op(msg, OP_EQ, "Connection is fine; using it.");
+
+ /* Switch that around from previous test. */
+ chan2->timestamp_created = chan1->timestamp_created + 1;
+ ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
+ tt_assert(ret_chan);
+ tt_ptr_op(ret_chan, OP_EQ, chan1);
+ tt_int_op(launch, OP_EQ, 0);
+ tt_str_op(msg, OP_EQ, "Connection is fine; using it.");
+
+ /* Same creation time, num circuits will be used and they both have 0 so the
+ * channel 2 should be picked due to how channel_is_better() work. */
+ chan2->timestamp_created = chan1->timestamp_created;
+ ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
+ tt_assert(ret_chan);
+ tt_ptr_op(ret_chan, OP_EQ, chan1);
+ tt_int_op(launch, OP_EQ, 0);
+ tt_str_op(msg, OP_EQ, "Connection is fine; using it.");
+
+ /* For the rest of the tests, we need channel 1 to be the older. */
+ chan2->timestamp_created = chan1->timestamp_created + 1;
+
+ /* Condemned the older channel. */
+ chan1->state = CHANNEL_STATE_CLOSING;
+ ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
+ tt_assert(ret_chan);
+ tt_ptr_op(ret_chan, OP_EQ, chan2);
+ tt_int_op(launch, OP_EQ, 0);
+ tt_str_op(msg, OP_EQ, "Connection is fine; using it.");
+ chan1->state = CHANNEL_STATE_OPEN;
+
+ /* Make the older channel a client one. */
+ channel_mark_client(chan1);
+ ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
+ tt_assert(ret_chan);
+ tt_ptr_op(ret_chan, OP_EQ, chan2);
+ tt_int_op(launch, OP_EQ, 0);
+ tt_str_op(msg, OP_EQ, "Connection is fine; using it.");
+ channel_clear_client(chan1);
+
+ /* Non matching ed identity with valid digest. */
+ ed25519_public_key_t dumb_ed_id;
+ memset(&dumb_ed_id, 0, sizeof(dumb_ed_id));
+ ret_chan = channel_get_for_extend(digest, &dumb_ed_id, &addr, &msg,
+ &launch);
+ tt_assert(!ret_chan);
+ tt_str_op(msg, OP_EQ, "Not connected. Connecting.");
+ tt_int_op(launch, OP_EQ, 1);
+
+ /* Opening channel, we'll check if the target address matches. */
+ test_chan_should_match_target = 1;
+ chan1->state = CHANNEL_STATE_OPENING;
+ chan2->state = CHANNEL_STATE_OPENING;
+ ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
+ tt_assert(!ret_chan);
+ tt_str_op(msg, OP_EQ, "Connection in progress; waiting.");
+ tt_int_op(launch, OP_EQ, 0);
+ chan1->state = CHANNEL_STATE_OPEN;
+ chan2->state = CHANNEL_STATE_OPEN;
+
+ /* Mark channel 1 as bad for circuits. */
+ channel_mark_bad_for_new_circs(chan1);
+ ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
+ tt_assert(ret_chan);
+ tt_ptr_op(ret_chan, OP_EQ, chan2);
+ tt_int_op(launch, OP_EQ, 0);
+ tt_str_op(msg, OP_EQ, "Connection is fine; using it.");
+ chan1->is_bad_for_new_circs = 0;
+
+ /* Mark both channels as unusable. */
+ channel_mark_bad_for_new_circs(chan1);
+ channel_mark_bad_for_new_circs(chan2);
+ ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
+ tt_assert(!ret_chan);
+ tt_str_op(msg, OP_EQ, "Connections all too old, or too non-canonical. "
+ " Launching a new one.");
+ tt_int_op(launch, OP_EQ, 1);
+ chan1->is_bad_for_new_circs = 0;
+ chan2->is_bad_for_new_circs = 0;
+
+ /* Non canonical channels. */
+ test_chan_should_match_target = 0;
+ test_chan_canonical_should_be_reliable = 1;
+ ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
+ tt_assert(!ret_chan);
+ tt_str_op(msg, OP_EQ, "Connections all too old, or too non-canonical. "
+ " Launching a new one.");
+ tt_int_op(launch, OP_EQ, 1);
+
+ done:
+ free_fake_channel(chan1);
+ free_fake_channel(chan2);
+}
+
+static void
+test_channel_listener(void *arg)
+{
+ int old_count;
+ time_t now = time(NULL);
+ channel_listener_t *chan = NULL;
+
+ (void) arg;
+
+ chan = tor_malloc_zero(sizeof(*chan));
+ tt_assert(chan);
+ channel_init_listener(chan);
+ tt_u64_op(chan->global_identifier, OP_EQ, 1);
+ tt_int_op(chan->timestamp_created, OP_GE, now);
+ chan->close = test_chan_listener_close;
+
+ /* Register it. At this point, it is not open so it will be put in the
+ * finished list. */
+ channel_listener_register(chan);
+ tt_int_op(chan->registered, OP_EQ, 1);
+ channel_listener_unregister(chan);
+
+ /* Register it as listening now thus active. */
+ chan->state = CHANNEL_LISTENER_STATE_LISTENING;
+ channel_listener_register(chan);
+ tt_int_op(chan->registered, OP_EQ, 1);
+
+ /* Set the listener function. */
+ channel_listener_set_listener_fn(chan, test_chan_listener_fn);
+ tt_ptr_op(chan->listener, OP_EQ, test_chan_listener_fn);
+
+ /* Put a channel in the listener incoming list and queue it.
+ * function. By doing this, the listener() handler will be called. */
+ channel_t *in_chan = new_fake_channel();
+ old_count = test_chan_listener_fn_called;
+ channel_listener_queue_incoming(chan, in_chan);
+ free_fake_channel(in_chan);
+ tt_int_op(test_chan_listener_fn_called, OP_EQ, old_count + 1);
+
+ /* Put listener channel in CLOSING state. */
+ old_count = test_chan_listener_close_fn_called;
+ channel_listener_mark_for_close(chan);
+ tt_int_op(test_chan_listener_close_fn_called, OP_EQ, old_count + 1);
+ channel_listener_change_state(chan, CHANNEL_LISTENER_STATE_CLOSED);
+
+ /* Dump stats so we at least hit the code path. */
+ chan->describe_transport = test_chan_listener_describe_transport;
+ /* There is a check for "now > timestamp_created" when dumping the stats so
+ * make sure we go in. */
+ chan->timestamp_created = now - 10;
+ channel_listener_dump_statistics(chan, LOG_INFO);
+
+ done:
+ channel_free_all();
+}
+
struct testcase_t channel_tests[] = {
- { "dumpstats", test_channel_dumpstats, TT_FORK, NULL, NULL },
- { "flush", test_channel_flush, TT_FORK, NULL, NULL },
- { "flushmux", test_channel_flushmux, TT_FORK, NULL, NULL },
- { "incoming", test_channel_incoming, TT_FORK, NULL, NULL },
- { "lifecycle", test_channel_lifecycle, TT_FORK, NULL, NULL },
- { "lifecycle_2", test_channel_lifecycle_2, TT_FORK, NULL, NULL },
- { "multi", test_channel_multi, TT_FORK, NULL, NULL },
- { "queue_impossible", test_channel_queue_impossible, TT_FORK, NULL, NULL },
- { "queue_incoming", test_channel_queue_incoming, TT_FORK, NULL, NULL },
- { "queue_size", test_channel_queue_size, TT_FORK, NULL, NULL },
- { "write", test_channel_write, TT_FORK, NULL, NULL },
- { "id_map", test_channel_id_map, TT_FORK, NULL, NULL },
+ { "inbound_cell", test_channel_inbound_cell, TT_FORK,
+ NULL, NULL },
+ { "outbound_cell", test_channel_outbound_cell, TT_FORK,
+ NULL, NULL },
+ { "id_map", test_channel_id_map, TT_FORK,
+ NULL, NULL },
+ { "lifecycle", test_channel_lifecycle, TT_FORK,
+ NULL, NULL },
+ { "lifecycle_2", test_channel_lifecycle_2, TT_FORK,
+ NULL, NULL },
+ { "dumpstats", test_channel_dumpstats, TT_FORK,
+ NULL, NULL },
+ { "state", test_channel_state, TT_FORK,
+ NULL, NULL },
+ { "duplicates", test_channel_duplicates, TT_FORK,
+ NULL, NULL },
+ { "get_channel_for_extend", test_channel_for_extend, TT_FORK,
+ NULL, NULL },
+ { "listener", test_channel_listener, TT_FORK,
+ NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_channelpadding.c b/src/test/test_channelpadding.c
index d5713688a0..4cc33cbe70 100644
--- a/src/test/test_channelpadding.c
+++ b/src/test/test_channelpadding.c
@@ -1,3 +1,6 @@
+/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
#define TOR_CHANNEL_INTERNAL_
#define MAIN_PRIVATE
#define NETWORKSTATUS_PRIVATE
@@ -276,7 +279,6 @@ test_channelpadding_timers(void *arg)
{
channelpadding_decision_t decision;
channel_t *chans[CHANNELS_TO_TEST];
- int64_t new_time;
(void)arg;
tor_libevent_postfork();
@@ -286,8 +288,9 @@ test_channelpadding_timers(void *arg)
monotime_init();
monotime_enable_test_mocking();
- monotime_set_mock_time_nsec(1);
- monotime_coarse_set_mock_time_nsec(1);
+ uint64_t nsec_mock = 1;
+ monotime_set_mock_time_nsec(nsec_mock);
+ monotime_coarse_set_mock_time_nsec(nsec_mock);
timers_initialize();
channelpadding_new_consensus_params(NULL);
@@ -301,11 +304,14 @@ test_channelpadding_timers(void *arg)
tried_to_write_cell = 0;
int i = 0;
+ monotime_coarse_t now;
+ monotime_coarse_get(&now);
+
/* This loop fills our timerslot array with timers of increasing time
* until they fire */
for (; i < CHANNELPADDING_MAX_TIMERS; i++) {
- chans[i]->next_padding_time_ms = monotime_coarse_absolute_msec()
- + 10 + i*4;
+ monotime_coarse_add_msec(&chans[i]->next_padding_time,
+ &now, 10 + i*4);
decision = channelpadding_decide_to_pad_channel(chans[i]);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_assert(chans[i]->pending_padding_callback);
@@ -315,7 +321,8 @@ test_channelpadding_timers(void *arg)
/* This loop should add timers to the first position in the timerslot
* array, since its timeout is before all other timers. */
for (; i < CHANNELS_TO_TEST/3; i++) {
- chans[i]->next_padding_time_ms = monotime_coarse_absolute_msec() + 1;
+ monotime_coarse_add_msec(&chans[i]->next_padding_time,
+ &now, 1);
decision = channelpadding_decide_to_pad_channel(chans[i]);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_assert(chans[i]->pending_padding_callback);
@@ -326,8 +333,8 @@ test_channelpadding_timers(void *arg)
* pseudorandom pattern. It ensures that the lists can grow with multiple
* timers in them. */
for (; i < CHANNELS_TO_TEST/2; i++) {
- chans[i]->next_padding_time_ms = monotime_coarse_absolute_msec() + 10 +
- i*3 % CHANNELPADDING_MAX_TIMERS;
+ monotime_coarse_add_msec(&chans[i]->next_padding_time,
+ &now, 10 + i*3 % CHANNELPADDING_MAX_TIMERS);
decision = channelpadding_decide_to_pad_channel(chans[i]);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_assert(chans[i]->pending_padding_callback);
@@ -337,8 +344,8 @@ test_channelpadding_timers(void *arg)
/* This loop should add timers to the last position in the timerslot
* array, since its timeout is after all other timers. */
for (; i < CHANNELS_TO_TEST; i++) {
- chans[i]->next_padding_time_ms = monotime_coarse_absolute_msec() + 500 +
- i % CHANNELPADDING_MAX_TIMERS;
+ monotime_coarse_add_msec(&chans[i]->next_padding_time,
+ &now, 500 + i % CHANNELPADDING_MAX_TIMERS);
decision = channelpadding_decide_to_pad_channel(chans[i]);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_assert(chans[i]->pending_padding_callback);
@@ -346,9 +353,9 @@ test_channelpadding_timers(void *arg)
}
// Wait for the timers and then kill the event loop.
- new_time = (monotime_coarse_absolute_msec()+1001)*NSEC_PER_MSEC;
- monotime_coarse_set_mock_time_nsec(new_time);
- monotime_set_mock_time_nsec(new_time);
+ nsec_mock += 1001 * NSEC_PER_MSEC;
+ monotime_coarse_set_mock_time_nsec(nsec_mock);
+ monotime_set_mock_time_nsec(nsec_mock);
timers_run_pending();
tt_int_op(tried_to_write_cell, OP_EQ, CHANNELS_TO_TEST);
@@ -385,6 +392,7 @@ test_channelpadding_killonehop(void *arg)
monotime_enable_test_mocking();
monotime_set_mock_time_nsec(1);
monotime_coarse_set_mock_time_nsec(1);
+ new_time = 1;
timers_initialize();
setup_mock_consensus();
@@ -398,9 +406,12 @@ test_channelpadding_killonehop(void *arg)
smartlist_clear(current_md_consensus->net_params);
channelpadding_new_consensus_params(current_md_consensus);
+ monotime_coarse_t now;
+ monotime_coarse_get(&now);
+
tried_to_write_cell = 0;
get_options_mutable()->Tor2webMode = 1;
- client_relay3->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
+ monotime_coarse_add_msec(&client_relay3->next_padding_time, &now, 100);
decision = channelpadding_decide_to_pad_channel(client_relay3);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_assert(client_relay3->pending_padding_callback);
@@ -410,9 +421,10 @@ test_channelpadding_killonehop(void *arg)
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_ALREADY_SCHEDULED);
// Wait for the timer
- new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC;
+ new_time += 101*NSEC_PER_MSEC;
monotime_coarse_set_mock_time_nsec(new_time);
monotime_set_mock_time_nsec(new_time);
+ monotime_coarse_get(&now);
timers_run_pending();
tt_int_op(tried_to_write_cell, OP_EQ, 1);
tt_assert(!client_relay3->pending_padding_callback);
@@ -424,7 +436,7 @@ test_channelpadding_killonehop(void *arg)
// Before the client tries to pad, the relay will still pad:
tried_to_write_cell = 0;
- relay3_client->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
+ monotime_coarse_add_msec(&relay3_client->next_padding_time, &now, 100);
get_options_mutable()->ORPort_set = 1;
get_options_mutable()->Tor2webMode = 0;
decision = channelpadding_decide_to_pad_channel(relay3_client);
@@ -432,9 +444,10 @@ test_channelpadding_killonehop(void *arg)
tt_assert(relay3_client->pending_padding_callback);
// Wait for the timer
- new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC;
+ new_time += 101*NSEC_PER_MSEC;
monotime_coarse_set_mock_time_nsec(new_time);
monotime_set_mock_time_nsec(new_time);
+ monotime_coarse_get(&now);
timers_run_pending();
tt_int_op(tried_to_write_cell, OP_EQ, 1);
tt_assert(!client_relay3->pending_padding_callback);
@@ -471,7 +484,8 @@ test_channelpadding_killonehop(void *arg)
get_options_mutable()->ORPort_set = 0;
get_options_mutable()->HiddenServiceSingleHopMode = 1;
get_options_mutable()->HiddenServiceNonAnonymousMode = 1;
- client_relay3->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
+
+ monotime_coarse_add_msec(&client_relay3->next_padding_time, &now, 100);
decision = channelpadding_decide_to_pad_channel(client_relay3);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_assert(client_relay3->pending_padding_callback);
@@ -481,9 +495,10 @@ test_channelpadding_killonehop(void *arg)
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_ALREADY_SCHEDULED);
// Wait for the timer
- new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC;
+ new_time += 101 * NSEC_PER_MSEC;
monotime_coarse_set_mock_time_nsec(new_time);
monotime_set_mock_time_nsec(new_time);
+ monotime_coarse_get(&now);
timers_run_pending();
tt_int_op(tried_to_write_cell, OP_EQ, 1);
tt_assert(!client_relay3->pending_padding_callback);
@@ -495,7 +510,7 @@ test_channelpadding_killonehop(void *arg)
// Before the client tries to pad, the relay will still pad:
tried_to_write_cell = 0;
- relay3_client->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
+ monotime_coarse_add_msec(&relay3_client->next_padding_time, &now, 100);
get_options_mutable()->ORPort_set = 1;
get_options_mutable()->HiddenServiceSingleHopMode = 0;
get_options_mutable()->HiddenServiceNonAnonymousMode = 0;
@@ -504,9 +519,10 @@ test_channelpadding_killonehop(void *arg)
tt_assert(relay3_client->pending_padding_callback);
// Wait for the timer
- new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC;
+ new_time += 101 * NSEC_PER_MSEC;
monotime_coarse_set_mock_time_nsec(new_time);
monotime_set_mock_time_nsec(new_time);
+ monotime_coarse_get(&now);
timers_run_pending();
tt_int_op(tried_to_write_cell, OP_EQ, 1);
tt_assert(!client_relay3->pending_padding_callback);
@@ -570,6 +586,9 @@ test_channelpadding_consensus(void *arg)
monotime_enable_test_mocking();
monotime_set_mock_time_nsec(1);
monotime_coarse_set_mock_time_nsec(1);
+ new_time = 1;
+ monotime_coarse_t now;
+ monotime_coarse_get(&now);
timers_initialize();
if (!connection_array)
@@ -583,7 +602,7 @@ test_channelpadding_consensus(void *arg)
/* Test 1: Padding can be completely disabled via consensus */
tried_to_write_cell = 0;
- chan->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
+ monotime_coarse_add_msec(&chan->next_padding_time, &now, 100);
decision = channelpadding_decide_to_pad_channel(chan);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_assert(chan->pending_padding_callback);
@@ -593,9 +612,10 @@ test_channelpadding_consensus(void *arg)
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_ALREADY_SCHEDULED);
// Wait for the timer
- new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC;
+ new_time += 101*NSEC_PER_MSEC;
monotime_coarse_set_mock_time_nsec(new_time);
monotime_set_mock_time_nsec(new_time);
+ monotime_coarse_get(&now);
timers_run_pending();
tt_int_op(tried_to_write_cell, OP_EQ, 1);
tt_assert(!chan->pending_padding_callback);
@@ -625,7 +645,7 @@ test_channelpadding_consensus(void *arg)
tt_i64_op(val, OP_EQ, 0);
val = channelpadding_compute_time_until_pad_for_netflow(chan);
tt_i64_op(val, OP_EQ, -2);
- tt_assert(!chan->next_padding_time_ms);
+ tt_assert(monotime_coarse_is_zero(&chan->next_padding_time));
smartlist_clear(current_md_consensus->net_params);
@@ -638,7 +658,7 @@ test_channelpadding_consensus(void *arg)
channelpadding_new_consensus_params(current_md_consensus);
tried_to_write_cell = 0;
- chan->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
+ monotime_coarse_add_msec(&chan->next_padding_time, &now, 100);
decision = channelpadding_decide_to_pad_channel(chan);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_assert(chan->pending_padding_callback);
@@ -650,9 +670,10 @@ test_channelpadding_consensus(void *arg)
tt_i64_op(val, OP_LE, 200);
// Wait for the timer
- new_time = (monotime_coarse_absolute_msec()+201)*NSEC_PER_MSEC;
+ new_time += 201*NSEC_PER_MSEC;
monotime_set_mock_time_nsec(new_time);
monotime_coarse_set_mock_time_nsec(new_time);
+ monotime_coarse_get(&now);
timers_run_pending();
tt_int_op(tried_to_write_cell, OP_EQ, 1);
tt_assert(!chan->pending_padding_callback);
@@ -941,6 +962,9 @@ test_channelpadding_decide_to_pad_channel(void *arg)
monotime_enable_test_mocking();
monotime_set_mock_time_nsec(1);
monotime_coarse_set_mock_time_nsec(1);
+ new_time = 1;
+ monotime_coarse_t now;
+ monotime_coarse_get(&now);
timers_initialize();
setup_full_capture_of_logs(LOG_WARN);
channelpadding_new_consensus_params(NULL);
@@ -957,7 +981,7 @@ test_channelpadding_decide_to_pad_channel(void *arg)
/* Test case #2a: > 1.1s until timeout */
tried_to_write_cell = 0;
- chan->next_padding_time_ms = monotime_coarse_absolute_msec() + 1200;
+ monotime_coarse_add_msec(&chan->next_padding_time, &now, 1200);
decision = channelpadding_decide_to_pad_channel(chan);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADLATER);
tt_assert(!chan->pending_padding_callback);
@@ -965,23 +989,27 @@ test_channelpadding_decide_to_pad_channel(void *arg)
/* Test case #2b: >= 1.0s until timeout */
tried_to_write_cell = 0;
- chan->next_padding_time_ms = monotime_coarse_absolute_msec() + 1000;
+ monotime_coarse_add_msec(&chan->next_padding_time, &now, 1000);
decision = channelpadding_decide_to_pad_channel(chan);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_assert(chan->pending_padding_callback);
tt_int_op(tried_to_write_cell, OP_EQ, 0);
+ // Set up a timer for the <0 case below.
+ monotime_coarse_t now_minus_100s;
+ monotime_coarse_add_msec(&now_minus_100s, &now, 900);
// Wait for the timer from case #2b
- new_time = (monotime_coarse_absolute_msec() + 1000)*NSEC_PER_MSEC;
+ new_time += 1000*NSEC_PER_MSEC;
monotime_set_mock_time_nsec(new_time);
monotime_coarse_set_mock_time_nsec(new_time);
+ monotime_coarse_get(&now);
timers_run_pending();
tt_int_op(tried_to_write_cell, OP_EQ, 1);
tt_assert(!chan->pending_padding_callback);
/* Test case #2c: > 0.1s until timeout */
tried_to_write_cell = 0;
- chan->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
+ monotime_coarse_add_msec(&chan->next_padding_time, &now, 100);
decision = channelpadding_decide_to_pad_channel(chan);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_assert(chan->pending_padding_callback);
@@ -992,16 +1020,17 @@ test_channelpadding_decide_to_pad_channel(void *arg)
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_ALREADY_SCHEDULED);
// Wait for the timer
- new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC;
+ new_time += 101*NSEC_PER_MSEC;
monotime_coarse_set_mock_time_nsec(new_time);
monotime_set_mock_time_nsec(new_time);
+ monotime_coarse_get(&now);
timers_run_pending();
tt_int_op(tried_to_write_cell, OP_EQ, 1);
tt_assert(!chan->pending_padding_callback);
/* Test case #2e: 0s until timeout */
tried_to_write_cell = 0;
- chan->next_padding_time_ms = monotime_coarse_absolute_msec();
+ monotime_coarse_add_msec(&chan->next_padding_time, &now, 0);
decision = channelpadding_decide_to_pad_channel(chan);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SENT);
tt_int_op(tried_to_write_cell, OP_EQ, 1);
@@ -1009,7 +1038,7 @@ test_channelpadding_decide_to_pad_channel(void *arg)
/* Test case #2f: <0s until timeout */
tried_to_write_cell = 0;
- chan->next_padding_time_ms = monotime_coarse_absolute_msec() - 100;
+ monotime_coarse_add_msec(&chan->next_padding_time, &now_minus_100s, 0);
decision = channelpadding_decide_to_pad_channel(chan);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SENT);
tt_int_op(tried_to_write_cell, OP_EQ, 1);
@@ -1017,7 +1046,7 @@ test_channelpadding_decide_to_pad_channel(void *arg)
/* Test case #3: Channel that sends a packet while timeout is scheduled */
tried_to_write_cell = 0;
- chan->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
+ monotime_coarse_add_msec(&chan->next_padding_time, &now, 100);
decision = channelpadding_decide_to_pad_channel(chan);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_int_op(tried_to_write_cell, OP_EQ, 0);
@@ -1028,9 +1057,10 @@ test_channelpadding_decide_to_pad_channel(void *arg)
// We don't expect any timer callbacks here. Make a dummy one to be sure.
// Wait for the timer
- new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC;
+ new_time += 101*NSEC_PER_MSEC;
monotime_coarse_set_mock_time_nsec(new_time);
monotime_set_mock_time_nsec(new_time);
+ monotime_coarse_get(&now);
timers_run_pending();
tt_int_op(tried_to_write_cell, OP_EQ, 0);
@@ -1038,7 +1068,7 @@ test_channelpadding_decide_to_pad_channel(void *arg)
/* Test case #4: Channel that closes while a timeout is scheduled */
tried_to_write_cell = 0;
- chan->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
+ monotime_coarse_add_msec(&chan->next_padding_time, &now, 100);
decision = channelpadding_decide_to_pad_channel(chan);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_int_op(tried_to_write_cell, OP_EQ, 0);
@@ -1048,9 +1078,10 @@ test_channelpadding_decide_to_pad_channel(void *arg)
chan->state = CHANNEL_STATE_MAINT;
// We don't expect any timer callbacks here. Make a dummy one to be sure.
- new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC;
+ new_time += 101*NSEC_PER_MSEC;
monotime_coarse_set_mock_time_nsec(new_time);
monotime_set_mock_time_nsec(new_time);
+ monotime_coarse_get(&now);
timers_run_pending();
tt_int_op(tried_to_write_cell, OP_EQ, 0);
@@ -1059,16 +1090,17 @@ test_channelpadding_decide_to_pad_channel(void *arg)
/* Test case #5: Make sure previous test case didn't break everything */
tried_to_write_cell = 0;
- chan->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
+ monotime_coarse_add_msec(&chan->next_padding_time, &now, 100);
decision = channelpadding_decide_to_pad_channel(chan);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_assert(chan->pending_padding_callback);
tt_int_op(tried_to_write_cell, OP_EQ, 0);
// Wait for the timer
- new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC;
+ new_time += 101*NSEC_PER_MSEC;
monotime_coarse_set_mock_time_nsec(new_time);
monotime_set_mock_time_nsec(new_time);
+ monotime_coarse_get(&now);
timers_run_pending();
tt_int_op(tried_to_write_cell, OP_EQ, 1);
@@ -1087,7 +1119,7 @@ test_channelpadding_decide_to_pad_channel(void *arg)
* It must be last.
*/
tried_to_write_cell = 0;
- chan->next_padding_time_ms = monotime_coarse_absolute_msec() + 100;
+ monotime_coarse_add_msec(&chan->next_padding_time, &now, 100);
decision = channelpadding_decide_to_pad_channel(chan);
tt_int_op(decision, OP_EQ, CHANNELPADDING_PADDING_SCHEDULED);
tt_int_op(tried_to_write_cell, OP_EQ, 0);
@@ -1097,9 +1129,10 @@ test_channelpadding_decide_to_pad_channel(void *arg)
free_fake_channeltls((channel_tls_t*)chan);
// We don't expect any timer callbacks here. Make a dummy one to be sure.
- new_time = (monotime_coarse_absolute_msec()+101)*NSEC_PER_MSEC;
+ new_time = 101*NSEC_PER_MSEC;
monotime_coarse_set_mock_time_nsec(new_time);
monotime_set_mock_time_nsec(new_time);
+ monotime_coarse_get(&now);
timers_run_pending();
tt_int_op(tried_to_write_cell, OP_EQ, 0);
diff --git a/src/test/test_circuitlist.c b/src/test/test_circuitlist.c
index f622704ec5..d170009a9c 100644
--- a/src/test/test_circuitlist.c
+++ b/src/test/test_circuitlist.c
@@ -141,7 +141,7 @@ test_clist_maps(void *arg)
/* Okay, now free ch2 and make sure that the circuit ID is STILL not
* usable, because we haven't declared the destroy to be nonpending */
tt_int_op(cdm.ncalls, OP_EQ, 0);
- circuit_free(TO_CIRCUIT(or_c2));
+ circuit_free_(TO_CIRCUIT(or_c2));
or_c2 = NULL; /* prevent free */
tt_int_op(cdm.ncalls, OP_EQ, 2);
memset(&cdm, 0, sizeof(cdm));
@@ -160,9 +160,9 @@ test_clist_maps(void *arg)
done:
if (or_c1)
- circuit_free(TO_CIRCUIT(or_c1));
+ circuit_free_(TO_CIRCUIT(or_c1));
if (or_c2)
- circuit_free(TO_CIRCUIT(or_c2));
+ circuit_free_(TO_CIRCUIT(or_c2));
if (ch1)
tor_free(ch1->cmux);
if (ch2)
@@ -234,11 +234,11 @@ test_rend_token_maps(void *arg)
/* Marking a circuit makes it not get returned any more */
circuit_mark_for_close(TO_CIRCUIT(c1), END_CIRC_REASON_FINISHED);
tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_rend_circ_relay_side(tok1));
- circuit_free(TO_CIRCUIT(c1));
+ circuit_free_(TO_CIRCUIT(c1));
c1 = NULL;
/* Freeing a circuit makes it not get returned any more. */
- circuit_free(TO_CIRCUIT(c2));
+ circuit_free_(TO_CIRCUIT(c2));
c2 = NULL;
tt_ptr_op(NULL, OP_EQ, hs_circuitmap_get_intro_circ_v2_relay_side(tok2));
@@ -275,15 +275,15 @@ test_rend_token_maps(void *arg)
done:
if (c1)
- circuit_free(TO_CIRCUIT(c1));
+ circuit_free_(TO_CIRCUIT(c1));
if (c2)
- circuit_free(TO_CIRCUIT(c2));
+ circuit_free_(TO_CIRCUIT(c2));
if (c3)
- circuit_free(TO_CIRCUIT(c3));
+ circuit_free_(TO_CIRCUIT(c3));
if (c4)
- circuit_free(TO_CIRCUIT(c4));
+ circuit_free_(TO_CIRCUIT(c4));
if (c5)
- circuit_free(TO_CIRCUIT(c5));
+ circuit_free_(TO_CIRCUIT(c5));
}
static void
@@ -452,10 +452,10 @@ test_hs_circuitmap_isolation(void *arg)
}
done:
- circuit_free(TO_CIRCUIT(circ1));
- circuit_free(TO_CIRCUIT(circ2));
- circuit_free(TO_CIRCUIT(circ3));
- circuit_free(TO_CIRCUIT(circ4));
+ circuit_free_(TO_CIRCUIT(circ1));
+ circuit_free_(TO_CIRCUIT(circ2));
+ circuit_free_(TO_CIRCUIT(circ3));
+ circuit_free_(TO_CIRCUIT(circ4));
}
struct testcase_t circuitlist_tests[] = {
diff --git a/src/test/test_circuitstats.c b/src/test/test_circuitstats.c
new file mode 100644
index 0000000000..9d87c325b4
--- /dev/null
+++ b/src/test/test_circuitstats.c
@@ -0,0 +1,199 @@
+/* Copyright (c) 2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#define CIRCUITBUILD_PRIVATE
+#define CIRCUITSTATS_PRIVATE
+#define CIRCUITLIST_PRIVATE
+#define CHANNEL_PRIVATE_
+
+#include "or.h"
+#include "test.h"
+#include "test_helpers.h"
+#include "log_test_helpers.h"
+#include "config.h"
+#include "circuitlist.h"
+#include "circuitbuild.h"
+#include "circuitstats.h"
+#include "circuituse.h"
+#include "channel.h"
+
+void test_circuitstats_timeout(void *arg);
+void test_circuitstats_hoplen(void *arg);
+origin_circuit_t *subtest_fourhop_circuit(struct timeval, int);
+origin_circuit_t *add_opened_threehop(void);
+origin_circuit_t *build_unopened_fourhop(struct timeval);
+
+int onion_append_hop(crypt_path_t **head_ptr, extend_info_t *choice);
+
+static int marked_for_close;
+/* Mock function because we are not trying to test the close circuit that does
+ * an awful lot of checks on the circuit object. */
+static void
+mock_circuit_mark_for_close(circuit_t *circ, int reason, int line,
+ const char *file)
+{
+ (void) circ;
+ (void) reason;
+ (void) line;
+ (void) file;
+ marked_for_close = 1;
+ return;
+}
+
+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;
+}
+
+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);
+
+ return or_circ;
+}
+
+origin_circuit_t *
+subtest_fourhop_circuit(struct timeval circ_start_time, int should_timeout)
+{
+ origin_circuit_t *or_circ = build_unopened_fourhop(circ_start_time);
+
+ // Now make them open one at a time and call
+ // circuit_build_times_handle_completed_hop();
+ or_circ->cpath->state = CPATH_STATE_OPEN;
+ circuit_build_times_handle_completed_hop(or_circ);
+ tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ, 0);
+
+ or_circ->cpath->next->state = CPATH_STATE_OPEN;
+ circuit_build_times_handle_completed_hop(or_circ);
+ tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ, 0);
+
+ // Third hop: We should count it now.
+ or_circ->cpath->next->next->state = CPATH_STATE_OPEN;
+ circuit_build_times_handle_completed_hop(or_circ);
+ tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ,
+ !should_timeout); // 1 if counted, 0 otherwise
+
+ // Fourth hop: Don't double count
+ or_circ->cpath->next->next->next->state = CPATH_STATE_OPEN;
+ circuit_build_times_handle_completed_hop(or_circ);
+ tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ,
+ !should_timeout);
+
+ done:
+ return or_circ;
+}
+
+void
+test_circuitstats_hoplen(void *arg)
+{
+ /* Plan:
+ * 0. Test no other opened circs (relaxed timeout)
+ * 1. Check >3 hop circ building w/o timeout
+ * 2. Check >3 hop circs w/ timeouts..
+ */
+ struct timeval circ_start_time;
+ origin_circuit_t *threehop = NULL;
+ origin_circuit_t *fourhop = NULL;
+ (void)arg;
+ MOCK(circuit_mark_for_close_, mock_circuit_mark_for_close);
+
+ circuit_build_times_init(get_circuit_build_times_mutable());
+
+ // Let's set a close_ms to 2X the initial timeout, so we can
+ // test relaxed functionality (which uses the close_ms timeout)
+ get_circuit_build_times_mutable()->close_ms *= 2;
+
+ tor_gettimeofday(&circ_start_time);
+ circ_start_time.tv_sec -= 119; // make us hit "relaxed" cutoff
+
+ // Test 1: Build a fourhop circuit that should get marked
+ // as relaxed and eventually counted by circuit_expire_building
+ // (but not before)
+ fourhop = subtest_fourhop_circuit(circ_start_time, 0);
+ tt_int_op(fourhop->relaxed_timeout, OP_EQ, 0);
+ tt_int_op(marked_for_close, OP_EQ, 0);
+ circuit_expire_building();
+ tt_int_op(marked_for_close, OP_EQ, 0);
+ tt_int_op(fourhop->relaxed_timeout, OP_EQ, 1);
+ TO_CIRCUIT(fourhop)->timestamp_began.tv_sec -= 119;
+ circuit_expire_building();
+ tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ, 1);
+ tt_int_op(marked_for_close, OP_EQ, 1);
+
+ circuit_free_(TO_CIRCUIT(fourhop));
+ circuit_build_times_reset(get_circuit_build_times_mutable());
+
+ // Test 2: Add a threehop circuit for non-relaxed timeouts
+ threehop = add_opened_threehop();
+
+ /* This circuit should not timeout */
+ tor_gettimeofday(&circ_start_time);
+ circ_start_time.tv_sec -= 59;
+ fourhop = subtest_fourhop_circuit(circ_start_time, 0);
+ circuit_expire_building();
+ tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ, 1);
+ tt_int_op(TO_CIRCUIT(fourhop)->purpose, OP_NE,
+ CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT);
+
+ circuit_free_((circuit_t *)fourhop);
+ circuit_build_times_reset(get_circuit_build_times_mutable());
+
+ /* Test 3: This circuit should now time out and get marked as a
+ * measurement circuit, but still get counted (and counted only once)
+ */
+ circ_start_time.tv_sec -= 2;
+ fourhop = subtest_fourhop_circuit(circ_start_time, 0);
+ tt_int_op(TO_CIRCUIT(fourhop)->purpose, OP_EQ,
+ CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT);
+ tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ, 1);
+ circuit_expire_building();
+ tt_int_op(get_circuit_build_times()->total_build_times, OP_EQ, 1);
+
+ done:
+ UNMOCK(circuit_mark_for_close_);
+ circuit_free_(TO_CIRCUIT(threehop));
+ circuit_free_(TO_CIRCUIT(fourhop));
+ circuit_build_times_free_timeouts(get_circuit_build_times_mutable());
+}
+
+#define TEST_CIRCUITSTATS(name, flags) \
+ { #name, test_##name, (flags), NULL, NULL }
+
+struct testcase_t circuitstats_tests[] = {
+ TEST_CIRCUITSTATS(circuitstats_hoplen, TT_FORK),
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/test_config.c b/src/test/test_config.c
index e7380c1d14..4290d0dc6d 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -4833,7 +4833,7 @@ test_config_include_limit(void *data)
torrc_path);
tt_int_op(write_str_to_file(torrc_path, torrc_contents, 0), OP_EQ, 0);
- tt_int_op(config_get_lines_include(torrc_contents, &result, 0, NULL),
+ tt_int_op(config_get_lines_include(torrc_contents, &result, 0, NULL, NULL),
OP_EQ, -1);
done:
@@ -4863,7 +4863,7 @@ test_config_include_does_not_exist(void *data)
tor_snprintf(torrc_contents, sizeof(torrc_contents), "%%include %s",
missing_path);
- tt_int_op(config_get_lines_include(torrc_contents, &result, 0, NULL),
+ tt_int_op(config_get_lines_include(torrc_contents, &result, 0, NULL, NULL),
OP_EQ, -1);
done:
@@ -4895,7 +4895,7 @@ test_config_include_error_in_included_file(void *data)
tor_snprintf(torrc_contents, sizeof(torrc_contents), "%%include %s",
invalid_path);
- tt_int_op(config_get_lines_include(torrc_contents, &result, 0, NULL),
+ tt_int_op(config_get_lines_include(torrc_contents, &result, 0, NULL, NULL),
OP_EQ, -1);
done:
@@ -4937,8 +4937,8 @@ test_config_include_empty_file_folder(void *data)
folder_path, file_path);
int include_used;
- tt_int_op(config_get_lines_include(torrc_contents, &result, 0,&include_used),
- OP_EQ, 0);
+ tt_int_op(config_get_lines_include(torrc_contents, &result, 0,&include_used,
+ NULL), OP_EQ, 0);
tt_ptr_op(result, OP_EQ, NULL);
tt_int_op(include_used, OP_EQ, 1);
@@ -4975,7 +4975,8 @@ test_config_include_no_permission(void *data)
folder_path);
int include_used;
- tt_int_op(config_get_lines_include(torrc_contents, &result, 0,&include_used),
+ tt_int_op(config_get_lines_include(torrc_contents, &result, 0,
+ &include_used, NULL),
OP_EQ, -1);
tt_ptr_op(result, OP_EQ, NULL);
@@ -5031,8 +5032,8 @@ test_config_include_recursion_before_after(void *data)
}
int include_used;
- tt_int_op(config_get_lines_include(file_contents, &result, 0, &include_used),
- OP_EQ, 0);
+ tt_int_op(config_get_lines_include(file_contents, &result, 0, &include_used,
+ NULL), OP_EQ, 0);
tt_ptr_op(result, OP_NE, NULL);
tt_int_op(include_used, OP_EQ, 1);
@@ -5096,8 +5097,8 @@ test_config_include_recursion_after_only(void *data)
}
int include_used;
- tt_int_op(config_get_lines_include(file_contents, &result, 0, &include_used),
- OP_EQ, 0);
+ tt_int_op(config_get_lines_include(file_contents, &result, 0, &include_used,
+ NULL), OP_EQ, 0);
tt_ptr_op(result, OP_NE, NULL);
tt_int_op(include_used, OP_EQ, 1);
@@ -5185,8 +5186,8 @@ test_config_include_folder_order(void *data)
torrcd);
int include_used;
- tt_int_op(config_get_lines_include(torrc_contents, &result, 0,&include_used),
- OP_EQ, 0);
+ tt_int_op(config_get_lines_include(torrc_contents, &result, 0, &include_used,
+ NULL), OP_EQ, 0);
tt_ptr_op(result, OP_NE, NULL);
tt_int_op(include_used, OP_EQ, 1);
@@ -5239,8 +5240,8 @@ test_config_include_path_syntax(void *data)
esc_dir_with_pathsep);
int include_used;
- tt_int_op(config_get_lines_include(torrc_contents, &result, 0,&include_used),
- OP_EQ, 0);
+ tt_int_op(config_get_lines_include(torrc_contents, &result, 0,&include_used,
+ NULL), OP_EQ, 0);
tt_ptr_op(result, OP_EQ, NULL);
tt_int_op(include_used, OP_EQ, 1);
@@ -5294,14 +5295,14 @@ test_config_include_has_include(void *data)
char torrc_contents[1000] = "Test 1\n";
int include_used;
- tt_int_op(config_get_lines_include(torrc_contents, &result, 0,&include_used),
- OP_EQ, 0);
+ tt_int_op(config_get_lines_include(torrc_contents, &result, 0,&include_used,
+ NULL), OP_EQ, 0);
tt_int_op(include_used, OP_EQ, 0);
config_free_lines(result);
tor_snprintf(torrc_contents, sizeof(torrc_contents), "%%include %s\n", dir);
- tt_int_op(config_get_lines_include(torrc_contents, &result, 0,&include_used),
- OP_EQ, 0);
+ tt_int_op(config_get_lines_include(torrc_contents, &result, 0,&include_used,
+ NULL), OP_EQ, 0);
tt_int_op(include_used, OP_EQ, 1);
done:
@@ -5516,6 +5517,85 @@ test_config_check_bridge_distribution_setting_unrecognised(void *arg)
return;
}
+static void
+test_config_include_opened_file_list(void *data)
+{
+ (void)data;
+
+ config_line_t *result = NULL;
+ smartlist_t *opened_files = smartlist_new();
+ char *dir = tor_strdup(get_fname("test_include_opened_file_list"));
+ tt_ptr_op(dir, OP_NE, NULL);
+
+#ifdef _WIN32
+ tt_int_op(mkdir(dir), OP_EQ, 0);
+#else
+ tt_int_op(mkdir(dir, 0700), OP_EQ, 0);
+#endif
+
+ char torrcd[PATH_MAX+1];
+ tor_snprintf(torrcd, sizeof(torrcd), "%s"PATH_SEPARATOR"%s", dir, "torrc.d");
+
+#ifdef _WIN32
+ tt_int_op(mkdir(torrcd), OP_EQ, 0);
+#else
+ tt_int_op(mkdir(torrcd, 0700), OP_EQ, 0);
+#endif
+
+ char subfolder[PATH_MAX+1];
+ tor_snprintf(subfolder, sizeof(subfolder), "%s"PATH_SEPARATOR"%s", torrcd,
+ "subfolder");
+
+#ifdef _WIN32
+ tt_int_op(mkdir(subfolder), OP_EQ, 0);
+#else
+ tt_int_op(mkdir(subfolder, 0700), OP_EQ, 0);
+#endif
+
+ char path[PATH_MAX+1];
+ tor_snprintf(path, sizeof(path), "%s"PATH_SEPARATOR"%s", subfolder,
+ "01_file_in_subfolder");
+ tt_int_op(write_str_to_file(path, "Test 1\n", 0), OP_EQ, 0);
+
+ char empty[PATH_MAX+1];
+ tor_snprintf(empty, sizeof(empty), "%s"PATH_SEPARATOR"%s", torrcd, "empty");
+ tt_int_op(write_str_to_file(empty, "", 0), OP_EQ, 0);
+
+ char file[PATH_MAX+1];
+ tor_snprintf(file, sizeof(file), "%s"PATH_SEPARATOR"%s", torrcd, "file");
+ tt_int_op(write_str_to_file(file, "Test 2\n", 0), OP_EQ, 0);
+
+ char dot[PATH_MAX+1];
+ tor_snprintf(dot, sizeof(dot), "%s"PATH_SEPARATOR"%s", torrcd, ".dot");
+ tt_int_op(write_str_to_file(dot, "Test 3\n", 0), OP_EQ, 0);
+
+ char torrc_contents[1000];
+ tor_snprintf(torrc_contents, sizeof(torrc_contents),
+ "%%include %s\n",
+ torrcd);
+
+ int include_used;
+ tt_int_op(config_get_lines_include(torrc_contents, &result, 0, &include_used,
+ opened_files), OP_EQ, 0);
+ tt_ptr_op(result, OP_NE, NULL);
+ tt_int_op(include_used, OP_EQ, 1);
+
+ tt_int_op(smartlist_len(opened_files), OP_EQ, 4);
+ tt_int_op(smartlist_contains_string(opened_files, torrcd), OP_EQ, 1);
+ tt_int_op(smartlist_contains_string(opened_files, subfolder), OP_EQ, 1);
+ // files inside subfolders are not opended, only the subfolder is opened
+ tt_int_op(smartlist_contains_string(opened_files, empty), OP_EQ, 1);
+ tt_int_op(smartlist_contains_string(opened_files, file), OP_EQ, 1);
+ // dot files are not opened as we ignore them when we get their name from
+ // their parent folder
+
+ done:
+ SMARTLIST_FOREACH(opened_files, char *, f, tor_free(f));
+ smartlist_free(opened_files);
+ config_free_lines(result);
+ tor_free(dir);
+}
+
#define CONFIG_TEST(name, flags) \
{ #name, test_config_ ## name, flags, NULL, NULL }
@@ -5563,6 +5643,7 @@ struct testcase_t config_tests[] = {
CONFIG_TEST(check_bridge_distribution_setting_valid, 0),
CONFIG_TEST(check_bridge_distribution_setting_invalid, 0),
CONFIG_TEST(check_bridge_distribution_setting_unrecognised, 0),
+ CONFIG_TEST(include_opened_file_list, 0),
END_OF_TESTCASES
};
diff --git a/src/test/test_conscache.c b/src/test/test_conscache.c
index ddb1bc53c1..ffec3149b0 100644
--- a/src/test/test_conscache.c
+++ b/src/test/test_conscache.c
@@ -31,8 +31,8 @@ test_conscache_simple_usage(void *arg)
/* Make a temporary datadir for these tests */
char *ddir_fname = tor_strdup(get_fname_rnd("datadir_cache"));
- tor_free(get_options_mutable()->DataDirectory);
- get_options_mutable()->DataDirectory = tor_strdup(ddir_fname);
+ tor_free(get_options_mutable()->CacheDirectory);
+ get_options_mutable()->CacheDirectory = tor_strdup(ddir_fname);
check_private_dir(ddir_fname, CPD_CREATE, NULL);
consensus_cache_t *cache = consensus_cache_open("cons", 128);
@@ -124,8 +124,8 @@ test_conscache_cleanup(void *arg)
/* Make a temporary datadir for these tests */
char *ddir_fname = tor_strdup(get_fname_rnd("datadir_cache"));
- tor_free(get_options_mutable()->DataDirectory);
- get_options_mutable()->DataDirectory = tor_strdup(ddir_fname);
+ tor_free(get_options_mutable()->CacheDirectory);
+ get_options_mutable()->CacheDirectory = tor_strdup(ddir_fname);
check_private_dir(ddir_fname, CPD_CREATE, NULL);
consensus_cache_t *cache = consensus_cache_open("cons", 128);
@@ -267,8 +267,8 @@ test_conscache_filter(void *arg)
/* Make a temporary datadir for these tests */
char *ddir_fname = tor_strdup(get_fname_rnd("datadir_cache"));
- tor_free(get_options_mutable()->DataDirectory);
- get_options_mutable()->DataDirectory = tor_strdup(ddir_fname);
+ tor_free(get_options_mutable()->CacheDirectory);
+ get_options_mutable()->CacheDirectory = tor_strdup(ddir_fname);
check_private_dir(ddir_fname, CPD_CREATE, NULL);
consensus_cache_t *cache = consensus_cache_open("cons", 128);
diff --git a/src/test/test_consdiffmgr.c b/src/test/test_consdiffmgr.c
index 80d3f943ab..a9a4b6a98e 100644
--- a/src/test/test_consdiffmgr.c
+++ b/src/test/test_consdiffmgr.c
@@ -24,8 +24,8 @@ consdiffmgr_test_setup(const struct testcase_t *arg)
{
(void)arg;
char *ddir_fname = tor_strdup(get_fname_rnd("datadir_cdm"));
- tor_free(get_options_mutable()->DataDirectory);
- get_options_mutable()->DataDirectory = ddir_fname; // now owns the pointer.
+ tor_free(get_options_mutable()->CacheDirectory);
+ get_options_mutable()->CacheDirectory = ddir_fname; // now owns the pointer.
check_private_dir(ddir_fname, CPD_CREATE, NULL);
consdiff_cfg_t consdiff_cfg = { 300 };
@@ -215,8 +215,8 @@ test_consdiffmgr_init_failure(void *arg)
/* As in ...test_setup, but do not create the datadir. The missing directory
* will cause a failure. */
char *ddir_fname = tor_strdup(get_fname_rnd("datadir_cdm"));
- tor_free(get_options_mutable()->DataDirectory);
- get_options_mutable()->DataDirectory = ddir_fname; // now owns the pointer.
+ tor_free(get_options_mutable()->CacheDirectory);
+ get_options_mutable()->CacheDirectory = ddir_fname; // now owns the pointer.
consdiff_cfg_t consdiff_cfg = { 7200, 300 };
diff --git a/src/test/test_controller.c b/src/test/test_controller.c
index 472fcb8c53..af19f63f6c 100644
--- a/src/test/test_controller.c
+++ b/src/test/test_controller.c
@@ -6,6 +6,7 @@
#include "bridges.h"
#include "control.h"
#include "entrynodes.h"
+#include "hs_common.h"
#include "networkstatus.h"
#include "rendservice.h"
#include "routerlist.h"
@@ -13,10 +14,87 @@
#include "test_helpers.h"
static void
-test_add_onion_helper_keyarg(void *arg)
+test_add_onion_helper_keyarg_v3(void *arg)
{
- crypto_pk_t *pk = NULL;
- crypto_pk_t *pk2 = NULL;
+ int ret, hs_version;
+ add_onion_secret_key_t pk;
+ char *key_new_blob = NULL;
+ char *err_msg = NULL;
+ const char *key_new_alg = NULL;
+
+ (void) arg;
+
+ memset(&pk, 0, sizeof(pk));
+
+ /* Test explicit ED25519-V3 key generation. */
+ ret = add_onion_helper_keyarg("NEW:ED25519-V3", 0, &key_new_alg,
+ &key_new_blob, &pk, &hs_version,
+ &err_msg);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(hs_version, OP_EQ, HS_VERSION_THREE);
+ tt_assert(pk.v3);
+ tt_str_op(key_new_alg, OP_EQ, "ED25519-V3");
+ tt_assert(key_new_blob);
+ tt_ptr_op(err_msg, OP_EQ, NULL);
+ tor_free(pk.v3); pk.v3 = NULL;
+ tor_free(key_new_blob);
+
+ /* Test discarding the private key. */
+ ret = add_onion_helper_keyarg("NEW:ED25519-V3", 1, &key_new_alg,
+ &key_new_blob, &pk, &hs_version,
+ &err_msg);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(hs_version, OP_EQ, HS_VERSION_THREE);
+ tt_assert(pk.v3);
+ tt_ptr_op(key_new_alg, OP_EQ, NULL);
+ tt_ptr_op(key_new_blob, OP_EQ, NULL);
+ tt_ptr_op(err_msg, OP_EQ, NULL);
+ tor_free(pk.v3); pk.v3 = NULL;
+ tor_free(key_new_blob);
+
+ /* Test passing a key blob. */
+ {
+ /* The base64 key and hex key are the same. Hex key is 64 bytes long. The
+ * sk has been generated randomly using python3. */
+ const char *base64_sk =
+ "a9bT19PqGC9Y+BmOo1IQvCGjjwxMiaaxEXZ+FKMxpEQW"
+ "6AmSV5roThUGMRCaqQSCnR2jI1vL2QxHORzI4RxMmw==";
+ const char *hex_sk =
+ "\x6b\xd6\xd3\xd7\xd3\xea\x18\x2f\x58\xf8\x19\x8e\xa3\x52\x10\xbc"
+ "\x21\xa3\x8f\x0c\x4c\x89\xa6\xb1\x11\x76\x7e\x14\xa3\x31\xa4\x44"
+ "\x16\xe8\x09\x92\x57\x9a\xe8\x4e\x15\x06\x31\x10\x9a\xa9\x04\x82"
+ "\x9d\x1d\xa3\x23\x5b\xcb\xd9\x0c\x47\x39\x1c\xc8\xe1\x1c\x4c\x9b";
+ char *key_blob = NULL;
+
+ tor_asprintf(&key_blob, "ED25519-V3:%s", base64_sk);
+ tt_assert(key_blob);
+ ret = add_onion_helper_keyarg(key_blob, 1, &key_new_alg,
+ &key_new_blob, &pk, &hs_version,
+ &err_msg);
+ tor_free(key_blob);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(hs_version, OP_EQ, HS_VERSION_THREE);
+ tt_assert(pk.v3);
+ tt_mem_op(pk.v3, OP_EQ, hex_sk, 64);
+ tt_ptr_op(key_new_alg, OP_EQ, NULL);
+ tt_ptr_op(key_new_blob, OP_EQ, NULL);
+ tt_ptr_op(err_msg, OP_EQ, NULL);
+ tor_free(pk.v3); pk.v3 = NULL;
+ tor_free(key_new_blob);
+ }
+
+ done:
+ tor_free(pk.v3);
+ tor_free(key_new_blob);
+ tor_free(err_msg);
+}
+
+static void
+test_add_onion_helper_keyarg_v2(void *arg)
+{
+ int ret, hs_version;
+ add_onion_secret_key_t pk;
+ crypto_pk_t *pk1 = NULL;
const char *key_new_alg = NULL;
char *key_new_blob = NULL;
char *err_msg = NULL;
@@ -25,83 +103,100 @@ test_add_onion_helper_keyarg(void *arg)
(void) arg;
+ memset(&pk, 0, sizeof(pk));
+
/* Test explicit RSA1024 key generation. */
- pk = add_onion_helper_keyarg("NEW:RSA1024", 0, &key_new_alg, &key_new_blob,
- &err_msg);
- tt_assert(pk);
+ ret = add_onion_helper_keyarg("NEW:RSA1024", 0, &key_new_alg, &key_new_blob,
+ &pk, &hs_version, &err_msg);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(hs_version, OP_EQ, HS_VERSION_TWO);
+ tt_assert(pk.v2);
tt_str_op(key_new_alg, OP_EQ, "RSA1024");
tt_assert(key_new_blob);
tt_ptr_op(err_msg, OP_EQ, NULL);
/* Test "BEST" key generation (Assumes BEST = RSA1024). */
- crypto_pk_free(pk);
+ crypto_pk_free(pk.v2); pk.v2 = NULL;
tor_free(key_new_blob);
- pk = add_onion_helper_keyarg("NEW:BEST", 0, &key_new_alg, &key_new_blob,
- &err_msg);
- tt_assert(pk);
+ ret = add_onion_helper_keyarg("NEW:BEST", 0, &key_new_alg, &key_new_blob,
+ &pk, &hs_version, &err_msg);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(hs_version, OP_EQ, HS_VERSION_TWO);
+ tt_assert(pk.v2);
tt_str_op(key_new_alg, OP_EQ, "RSA1024");
tt_assert(key_new_blob);
tt_ptr_op(err_msg, OP_EQ, NULL);
/* Test discarding the private key. */
- crypto_pk_free(pk);
+ crypto_pk_free(pk.v2); pk.v2 = NULL;
tor_free(key_new_blob);
- pk = add_onion_helper_keyarg("NEW:BEST", 1, &key_new_alg, &key_new_blob,
- &err_msg);
- tt_assert(pk);
+ ret = add_onion_helper_keyarg("NEW:BEST", 1, &key_new_alg, &key_new_blob,
+ &pk, &hs_version, &err_msg);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(hs_version, OP_EQ, HS_VERSION_TWO);
+ tt_assert(pk.v2);
tt_ptr_op(key_new_alg, OP_EQ, NULL);
tt_ptr_op(key_new_blob, OP_EQ, NULL);
tt_ptr_op(err_msg, OP_EQ, NULL);
/* Test generating a invalid key type. */
- crypto_pk_free(pk);
- pk = add_onion_helper_keyarg("NEW:RSA512", 0, &key_new_alg, &key_new_blob,
- &err_msg);
- tt_ptr_op(pk, OP_EQ, NULL);
+ crypto_pk_free(pk.v2); pk.v2 = NULL;
+ ret = add_onion_helper_keyarg("NEW:RSA512", 0, &key_new_alg, &key_new_blob,
+ &pk, &hs_version, &err_msg);
+ tt_int_op(ret, OP_EQ, -1);
+ tt_int_op(hs_version, OP_EQ, HS_VERSION_TWO);
+ tt_assert(!pk.v2);
tt_ptr_op(key_new_alg, OP_EQ, NULL);
tt_ptr_op(key_new_blob, OP_EQ, NULL);
tt_assert(err_msg);
/* Test loading a RSA1024 key. */
tor_free(err_msg);
- pk = pk_generate(0);
- tt_int_op(0, OP_EQ, crypto_pk_base64_encode(pk, &encoded));
+ pk1 = pk_generate(0);
+ tt_int_op(0, OP_EQ, crypto_pk_base64_encode(pk1, &encoded));
tor_asprintf(&arg_str, "RSA1024:%s", encoded);
- pk2 = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob,
- &err_msg);
- tt_assert(pk2);
+ ret = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob,
+ &pk, &hs_version, &err_msg);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_int_op(hs_version, OP_EQ, HS_VERSION_TWO);
+ tt_assert(pk.v2);
tt_ptr_op(key_new_alg, OP_EQ, NULL);
tt_ptr_op(key_new_blob, OP_EQ, NULL);
tt_ptr_op(err_msg, OP_EQ, NULL);
- tt_int_op(crypto_pk_cmp_keys(pk, pk2), OP_EQ, 0);
+ tt_int_op(crypto_pk_cmp_keys(pk1, pk.v2), OP_EQ, 0);
/* Test loading a invalid key type. */
tor_free(arg_str);
- crypto_pk_free(pk); pk = NULL;
+ crypto_pk_free(pk1); pk1 = NULL;
+ crypto_pk_free(pk.v2); pk.v2 = NULL;
tor_asprintf(&arg_str, "RSA512:%s", encoded);
- pk = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob,
- &err_msg);
- tt_ptr_op(pk, OP_EQ, NULL);
+ ret = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob,
+ &pk, &hs_version, &err_msg);
+ tt_int_op(ret, OP_EQ, -1);
+ tt_int_op(hs_version, OP_EQ, HS_VERSION_TWO);
+ tt_assert(!pk.v2);
tt_ptr_op(key_new_alg, OP_EQ, NULL);
tt_ptr_op(key_new_blob, OP_EQ, NULL);
tt_assert(err_msg);
/* Test loading a invalid key. */
tor_free(arg_str);
- crypto_pk_free(pk); pk = NULL;
+ crypto_pk_free(pk.v2); pk.v2 = NULL;
tor_free(err_msg);
encoded[strlen(encoded)/2] = '\0';
tor_asprintf(&arg_str, "RSA1024:%s", encoded);
- pk = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob,
- &err_msg);
- tt_ptr_op(pk, OP_EQ, NULL);
+ ret = add_onion_helper_keyarg(arg_str, 0, &key_new_alg, &key_new_blob,
+ &pk, &hs_version, &err_msg);
+ tt_int_op(ret, OP_EQ, -1);
+ tt_int_op(hs_version, OP_EQ, HS_VERSION_TWO);
+ tt_assert(!pk.v2);
tt_ptr_op(key_new_alg, OP_EQ, NULL);
tt_ptr_op(key_new_blob, OP_EQ, NULL);
tt_assert(err_msg);
done:
- crypto_pk_free(pk);
- crypto_pk_free(pk2);
+ crypto_pk_free(pk1);
+ crypto_pk_free(pk.v2);
tor_free(key_new_blob);
tor_free(err_msg);
tor_free(encoded);
@@ -1370,7 +1465,10 @@ test_download_status_bridge(void *arg)
}
struct testcase_t controller_tests[] = {
- { "add_onion_helper_keyarg", test_add_onion_helper_keyarg, 0, NULL, NULL },
+ { "add_onion_helper_keyarg_v2", test_add_onion_helper_keyarg_v2, 0,
+ NULL, NULL },
+ { "add_onion_helper_keyarg_v3", test_add_onion_helper_keyarg_v3, 0,
+ NULL, NULL },
{ "getinfo_helper_onion", test_getinfo_helper_onion, 0, NULL, NULL },
{ "rend_service_parse_port_config", test_rend_service_parse_port_config, 0,
NULL, NULL },
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index 997b110d62..6092a5a4d0 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -567,7 +567,7 @@ test_dir_routerinfo_parsing(void *arg)
static void
routerinfo_free_wrapper_(void *arg)
{
- routerinfo_free(arg);
+ routerinfo_free_(arg);
}
static void
@@ -664,7 +664,7 @@ test_dir_extrainfo_parsing(void *arg)
escaped(NULL);
extrainfo_free(ei);
routerinfo_free(ri);
- digestmap_free((digestmap_t*)map, routerinfo_free_wrapper_);
+ digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
}
static void
@@ -760,7 +760,7 @@ test_dir_parse_router_list(void *arg)
smartlist_free(chunks);
routerinfo_free(ri);
if (map) {
- digestmap_free((digestmap_t*)map, routerinfo_free_wrapper_);
+ digestmap_free_((digestmap_t*)map, routerinfo_free_wrapper_);
router_get_routerlist()->identity_map =
(struct digest_ri_map_t*)digestmap_new();
}
@@ -4874,9 +4874,11 @@ mock_check_private_dir(const char *dirname, cpd_check_t check,
static char *
mock_get_datadir_fname(const or_options_t *options,
+ directory_root_t roottype,
const char *sub1, const char *sub2,
const char *suffix)
{
+ (void) roottype;
char *rv = NULL;
/*
@@ -5033,7 +5035,7 @@ test_dir_dump_unparseable_descriptors(void *data)
mock_options->MaxUnparseableDescSizeToLog = 1536;
MOCK(get_options, mock_get_options);
MOCK(check_private_dir, mock_check_private_dir);
- MOCK(options_get_datadir_fname2_suffix,
+ MOCK(options_get_dir_fname2_suffix,
mock_get_datadir_fname);
/*
@@ -5551,7 +5553,7 @@ test_dir_dump_unparseable_descriptors(void *data)
mock_unlink_reset();
UNMOCK(write_str_to_file);
mock_write_str_to_file_reset();
- UNMOCK(options_get_datadir_fname2_suffix);
+ UNMOCK(options_get_dir_fname2_suffix);
UNMOCK(check_private_dir);
UNMOCK(get_options);
tor_free(mock_options);
@@ -6174,6 +6176,106 @@ test_dir_platform_str(void *arg)
;
}
+static networkstatus_t *mock_networkstatus;
+
+static networkstatus_t *
+mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
+{
+ (void)f;
+ return mock_networkstatus;
+}
+
+static void
+test_dir_networkstatus_consensus_has_ipv6(void *arg)
+{
+ (void)arg;
+
+ int has_ipv6 = 0;
+
+ /* Init options and networkstatus */
+ or_options_t our_options;
+ mock_options = &our_options;
+ reset_options(mock_options, &mock_get_options_calls);
+ MOCK(get_options, mock_get_options);
+
+ networkstatus_t our_networkstatus;
+ mock_networkstatus = &our_networkstatus;
+ memset(mock_networkstatus, 0, sizeof(*mock_networkstatus));
+ MOCK(networkstatus_get_latest_consensus_by_flavor,
+ mock_networkstatus_get_latest_consensus_by_flavor);
+
+ /* A live consensus */
+ mock_networkstatus->valid_after = time(NULL) - 3600;
+ mock_networkstatus->valid_until = time(NULL) + 3600;
+
+ /* Test the bounds for A lines in the NS consensus */
+ mock_options->UseMicrodescriptors = 0;
+
+ mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES;
+ has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
+ tt_assert(has_ipv6);
+
+ mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES + 1;
+ has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
+ tt_assert(has_ipv6);
+
+ mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES + 20;
+ has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
+ tt_assert(has_ipv6);
+
+ mock_networkstatus->consensus_method = MIN_METHOD_FOR_A_LINES - 1;
+ has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
+ tt_assert(!has_ipv6);
+
+ /* Test the bounds for A lines in the microdesc consensus */
+ mock_options->UseMicrodescriptors = 1;
+
+ mock_networkstatus->consensus_method =
+ MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS;
+ has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
+ tt_assert(has_ipv6);
+
+ mock_networkstatus->consensus_method =
+ MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS + 1;
+ has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
+ tt_assert(has_ipv6);
+
+ mock_networkstatus->consensus_method =
+ MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS + 20;
+ has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
+ tt_assert(has_ipv6);
+
+ mock_networkstatus->consensus_method =
+ MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS - 1;
+ has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
+ tt_assert(!has_ipv6);
+
+ /* Test the edge cases */
+ mock_options->UseMicrodescriptors = 1;
+ mock_networkstatus->consensus_method =
+ MIN_METHOD_FOR_A_LINES_IN_MICRODESC_CONSENSUS;
+
+ /* Reasonably live */
+ mock_networkstatus->valid_until = time(NULL) - 60;
+ has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
+ tt_assert(has_ipv6);
+
+ /* Not reasonably live */
+ mock_networkstatus->valid_after = time(NULL) - 24*60*60 - 3600;
+ mock_networkstatus->valid_until = time(NULL) - 24*60*60 - 60;
+ has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
+ tt_assert(!has_ipv6);
+
+ /* NULL consensus */
+ mock_networkstatus = NULL;
+ has_ipv6 = networkstatus_consensus_has_ipv6(get_options());
+ tt_assert(!has_ipv6);
+
+ done:
+ UNMOCK(get_options);
+ UNMOCK(networkstatus_get_latest_consensus_by_flavor);
+}
+
#define DIR_LEGACY(name) \
{ #name, test_dir_ ## name , TT_FORK, NULL, NULL }
@@ -6241,6 +6343,7 @@ struct testcase_t dir_tests[] = {
DIR(assumed_flags, 0),
DIR(networkstatus_compute_bw_weights_v10, 0),
DIR(platform_str, 0),
+ DIR(networkstatus_consensus_has_ipv6, 0),
END_OF_TESTCASES
};
diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c
index fe26657ad8..ca64dce5fe 100644
--- a/src/test/test_dir_handle_get.c
+++ b/src/test/test_dir_handle_get.c
@@ -88,7 +88,7 @@ test_dir_handle_get_bad_request(void *data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -117,7 +117,7 @@ test_dir_handle_get_v1_command_not_found(void *data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -164,7 +164,7 @@ test_dir_handle_get_v1_command(void *data)
done:
UNMOCK(connection_write_to_buf_impl_);
UNMOCK(get_dirportfrontpage);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
}
@@ -190,7 +190,7 @@ test_dir_handle_get_not_found(void *data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -225,7 +225,7 @@ test_dir_handle_get_robots_txt(void *data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
}
@@ -254,7 +254,7 @@ test_dir_handle_get_rendezvous2_not_found_if_not_encrypted(void *data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -282,7 +282,7 @@ test_dir_handle_get_rendezvous2_on_encrypted_conn_with_invalid_desc_id(
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -315,7 +315,7 @@ test_dir_handle_get_rendezvous2_on_encrypted_conn_not_well_formed(void *data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -344,7 +344,7 @@ test_dir_handle_get_rendezvous2_not_found(void *data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
rend_cache_free_all();
}
@@ -424,7 +424,7 @@ test_dir_handle_get_rendezvous2_on_encrypted_conn_success(void *data)
UNMOCK(connection_write_to_buf_impl_);
NS_UNMOCK(router_get_my_routerinfo);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
rend_encoded_v2_service_descriptor_free(desc_holder);
@@ -457,7 +457,7 @@ test_dir_handle_get_micro_d_not_found(void *data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -469,6 +469,7 @@ init_mock_options(void)
memset(mock_options, 0, sizeof(or_options_t));
mock_options->TestingTorNetwork = 1;
mock_options->DataDirectory = tor_strdup(get_fname_rnd("datadir_tmp"));
+ mock_options->CacheDirectory = tor_strdup(mock_options->DataDirectory);
check_private_dir(mock_options->DataDirectory, CPD_CREATE, NULL);
}
@@ -541,7 +542,7 @@ test_dir_handle_get_micro_d(void *data)
UNMOCK(connection_write_to_buf_impl_);
or_options_free(mock_options); mock_options = NULL;
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
smartlist_free(list);
@@ -595,7 +596,7 @@ test_dir_handle_get_micro_d_server_busy(void *data)
UNMOCK(connection_write_to_buf_impl_);
or_options_free(mock_options); mock_options = NULL;
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
smartlist_free(list);
microdesc_free_all();
@@ -632,7 +633,7 @@ test_dir_handle_get_networkstatus_bridges_not_found_without_auth(void *data)
UNMOCK(get_options);
UNMOCK(connection_write_to_buf_impl_);
or_options_free(mock_options); mock_options = NULL;
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -672,7 +673,7 @@ test_dir_handle_get_networkstatus_bridges(void *data)
UNMOCK(get_options);
UNMOCK(connection_write_to_buf_impl_);
or_options_free(mock_options); mock_options = NULL;
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -709,7 +710,7 @@ test_dir_handle_get_networkstatus_bridges_not_found_wrong_auth(void *data)
UNMOCK(get_options);
UNMOCK(connection_write_to_buf_impl_);
or_options_free(mock_options); mock_options = NULL;
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -737,7 +738,7 @@ test_dir_handle_get_server_descriptors_not_found(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
or_options_free(mock_options); mock_options = NULL;
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -798,7 +799,7 @@ test_dir_handle_get_server_descriptors_all(void* data)
done:
NS_UNMOCK(router_get_my_routerinfo);
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
@@ -902,7 +903,7 @@ test_dir_handle_get_server_descriptors_authority(void* data)
UNMOCK(connection_write_to_buf_impl_);
tor_free(mock_routerinfo->cache_info.signed_descriptor_body);
tor_free(mock_routerinfo);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
crypto_pk_free(identity_pkey);
@@ -974,7 +975,7 @@ test_dir_handle_get_server_descriptors_fp(void* data)
UNMOCK(connection_write_to_buf_impl_);
tor_free(mock_routerinfo->cache_info.signed_descriptor_body);
tor_free(mock_routerinfo);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
crypto_pk_free(identity_pkey);
@@ -1038,7 +1039,7 @@ test_dir_handle_get_server_descriptors_d(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
tor_free(mock_routerinfo);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
crypto_pk_free(identity_pkey);
@@ -1094,7 +1095,7 @@ test_dir_handle_get_server_descriptors_busy(void* data)
UNMOCK(get_options);
UNMOCK(connection_write_to_buf_impl_);
tor_free(mock_routerinfo);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
crypto_pk_free(identity_pkey);
@@ -1125,7 +1126,7 @@ test_dir_handle_get_server_keys_bad_req(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -1151,7 +1152,7 @@ test_dir_handle_get_server_keys_all_not_found(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -1210,7 +1211,7 @@ test_dir_handle_get_server_keys_all(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
@@ -1240,7 +1241,7 @@ test_dir_handle_get_server_keys_authority_not_found(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -1288,7 +1289,7 @@ test_dir_handle_get_server_keys_authority(void* data)
done:
UNMOCK(get_my_v3_authority_cert);
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
authority_cert_free(mock_cert); mock_cert = NULL;
@@ -1316,7 +1317,7 @@ test_dir_handle_get_server_keys_fp_not_found(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -1370,7 +1371,7 @@ test_dir_handle_get_server_keys_fp(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
clear_dir_servers();
@@ -1399,7 +1400,7 @@ test_dir_handle_get_server_keys_sk_not_found(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -1444,7 +1445,7 @@ test_dir_handle_get_server_keys_sk(void* data)
done:
UNMOCK(get_my_v3_authority_cert);
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
authority_cert_free(mock_cert); mock_cert = NULL;
tor_free(header);
tor_free(body);
@@ -1472,7 +1473,7 @@ test_dir_handle_get_server_keys_fpsk_not_found(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -1529,7 +1530,7 @@ test_dir_handle_get_server_keys_fpsk(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
@@ -1583,7 +1584,7 @@ test_dir_handle_get_server_keys_busy(void* data)
done:
UNMOCK(get_options);
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
or_options_free(mock_options); mock_options = NULL;
@@ -1649,7 +1650,7 @@ test_dir_handle_get_status_vote_current_consensus_ns_not_enough_sigs(void* d)
UNMOCK(connection_write_to_buf_impl_);
UNMOCK(get_options);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(stats);
smartlist_free(mock_ns_val->voters);
@@ -1690,7 +1691,7 @@ test_dir_handle_get_status_vote_current_consensus_ns_not_found(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
UNMOCK(get_options);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(stats);
or_options_free(mock_options); mock_options = NULL;
@@ -1764,7 +1765,7 @@ test_dir_handle_get_status_vote_current_consensus_too_old(void *data)
UNMOCK(networkstatus_get_latest_consensus_by_flavor);
UNMOCK(connection_write_to_buf_impl_);
UNMOCK(get_options);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(mock_ns_val);
or_options_free(mock_options); mock_options = NULL;
@@ -1825,7 +1826,7 @@ status_vote_current_consensus_ns_test(char **header, char **body,
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
}
static void
@@ -1948,7 +1949,7 @@ test_dir_handle_get_status_vote_current_not_found(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -1971,7 +1972,7 @@ status_vote_current_d_test(char **header, char **body, size_t *body_l)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
}
static void
@@ -1991,7 +1992,7 @@ status_vote_next_d_test(char **header, char **body, size_t *body_l)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
}
static void
@@ -2116,7 +2117,7 @@ test_dir_handle_get_status_vote_next_not_found(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -2135,7 +2136,7 @@ status_vote_next_consensus_test(char **header, char **body, size_t *body_used)
body, body_used, 18, 0);
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
}
static void
@@ -2175,7 +2176,7 @@ test_dir_handle_get_status_vote_current_authority_not_found(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -2199,7 +2200,7 @@ test_dir_handle_get_status_vote_next_authority_not_found(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
}
@@ -2281,7 +2282,7 @@ status_vote_next_consensus_signatures_test(char **header, char **body,
body, body_used, 22, 0);
done:
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
UNMOCK(connection_write_to_buf_impl_);
}
@@ -2429,7 +2430,7 @@ test_dir_handle_get_status_vote_next_authority(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
UNMOCK(get_my_v3_authority_cert);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
authority_cert_free(mock_cert); mock_cert = NULL;
@@ -2511,7 +2512,7 @@ test_dir_handle_get_status_vote_current_authority(void* data)
done:
UNMOCK(connection_write_to_buf_impl_);
UNMOCK(get_my_v3_authority_cert);
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
tor_free(header);
tor_free(body);
authority_cert_free(mock_cert); mock_cert = NULL;
diff --git a/src/test/test_dns.c b/src/test/test_dns.c
index 19dcb02931..1fee01d2c0 100644
--- a/src/test/test_dns.c
+++ b/src/test/test_dns.c
@@ -1,3 +1,6 @@
+/* Copyright (c) 2015-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
#include "or.h"
#include "test.h"
@@ -121,7 +124,7 @@ static int n_connection_free = 0;
static connection_t *last_freed_conn = NULL;
static void
-NS(connection_free)(connection_t *conn)
+NS(connection_free_)(connection_t *conn)
{
n_connection_free++;
@@ -264,7 +267,7 @@ NS(test_main)(void *arg)
*/
NS_MOCK(dns_cancel_pending_resolve);
- NS_MOCK(connection_free);
+ NS_MOCK(connection_free_);
exitconn->on_circuit = &(on_circuit->base_);
exitconn->base_.purpose = EXIT_PURPOSE_RESOLVE;
@@ -291,7 +294,7 @@ NS(test_main)(void *arg)
NS_UNMOCK(send_resolved_cell);
NS_UNMOCK(send_resolved_hostname_cell);
NS_UNMOCK(dns_cancel_pending_resolve);
- NS_UNMOCK(connection_free);
+ NS_UNMOCK(connection_free_);
tor_free(on_circuit);
tor_free(exitconn);
tor_free(nextconn);
diff --git a/src/test/test_entryconn.c b/src/test/test_entryconn.c
index c29b1a7126..9d8a072c77 100644
--- a/src/test/test_entryconn.c
+++ b/src/test/test_entryconn.c
@@ -34,7 +34,7 @@ entryconn_rewrite_teardown(const struct testcase_t *tc, void *arg)
(void)tc;
entry_connection_t *ec = arg;
if (ec)
- connection_free_(ENTRY_TO_CONN(ec));
+ connection_free_minimal(ENTRY_TO_CONN(ec));
addressmap_free_all();
return 1;
}
@@ -156,8 +156,8 @@ test_entryconn_rewrite_automap_ipv4(void *arg)
ec->socks_request->address);
done:
- connection_free_(ENTRY_TO_CONN(ec2));
- connection_free_(ENTRY_TO_CONN(ec3));
+ connection_free_minimal(ENTRY_TO_CONN(ec2));
+ connection_free_minimal(ENTRY_TO_CONN(ec3));
}
/* Automap on resolve, connect to automapped address, resolve again and get
@@ -230,9 +230,9 @@ test_entryconn_rewrite_automap_ipv6(void *arg)
ec->socks_request->address);
done:
- connection_free_(ENTRY_TO_CONN(ec));
- connection_free_(ENTRY_TO_CONN(ec2));
- connection_free_(ENTRY_TO_CONN(ec3));
+ connection_free_minimal(ENTRY_TO_CONN(ec));
+ connection_free_minimal(ENTRY_TO_CONN(ec2));
+ connection_free_minimal(ENTRY_TO_CONN(ec3));
}
#if 0
@@ -283,7 +283,7 @@ test_entryconn_rewrite_automap_reverse(void *arg)
tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
done:
- connection_free_(ENTRY_TO_CONN(ec2));
+ connection_free_minimal(ENTRY_TO_CONN(ec2));
}
#endif /* 0 */
@@ -333,7 +333,7 @@ test_entryconn_rewrite_cached_dns_ipv4(void *arg)
tt_str_op(ec2->socks_request->address, OP_EQ, "240.240.241.241");
done:
- connection_free_(ENTRY_TO_CONN(ec2));
+ connection_free_minimal(ENTRY_TO_CONN(ec2));
}
/* Rewrite because of cached DNS entry. */
@@ -385,8 +385,8 @@ test_entryconn_rewrite_cached_dns_ipv6(void *arg)
tt_str_op(ec2->socks_request->address, OP_EQ, "[::f00f]");
done:
- connection_free_(ENTRY_TO_CONN(ec));
- connection_free_(ENTRY_TO_CONN(ec2));
+ connection_free_minimal(ENTRY_TO_CONN(ec));
+ connection_free_minimal(ENTRY_TO_CONN(ec2));
}
/* Fail to connect to unmapped address in virtual range. */
@@ -426,7 +426,7 @@ test_entryconn_rewrite_unmapped_virtual(void *arg)
tt_int_op(rr.exit_source, OP_EQ, ADDRMAPSRC_NONE);
done:
- connection_free_(ENTRY_TO_CONN(ec2));
+ connection_free_minimal(ENTRY_TO_CONN(ec2));
}
/* Rewrite because of mapaddress option */
@@ -507,7 +507,7 @@ test_entryconn_rewrite_automap_exit(void *arg)
tt_int_op(rr.end_reason, OP_EQ, END_STREAM_REASON_TORPROTOCOL);
done:
- connection_free_(ENTRY_TO_CONN(ec2));
+ connection_free_minimal(ENTRY_TO_CONN(ec2));
}
/* Rewrite into .exit because of mapaddress */
@@ -618,9 +618,9 @@ test_entryconn_rewrite_mapaddress_automap_onion(void *arg)
*/
done:
- connection_free_(ENTRY_TO_CONN(ec2));
- connection_free_(ENTRY_TO_CONN(ec3));
- connection_free_(ENTRY_TO_CONN(ec4));
+ connection_free_minimal(ENTRY_TO_CONN(ec2));
+ connection_free_minimal(ENTRY_TO_CONN(ec3));
+ connection_free_minimal(ENTRY_TO_CONN(ec4));
}
static void
@@ -678,8 +678,8 @@ test_entryconn_rewrite_mapaddress_automap_onion_common(entry_connection_t *ec,
"abcdefghijklmnop.onion"));
done:
- connection_free_(ENTRY_TO_CONN(ec2));
- connection_free_(ENTRY_TO_CONN(ec3));
+ connection_free_minimal(ENTRY_TO_CONN(ec2));
+ connection_free_minimal(ENTRY_TO_CONN(ec3));
}
/* This time is the same, but we start with a mapping from a non-onion
diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c
index 80ebebe3f8..1cff3828c4 100644
--- a/src/test/test_entrynodes.c
+++ b/src/test/test_entrynodes.c
@@ -2372,8 +2372,8 @@ upgrade_circuits_cleanup(const struct testcase_t *testcase, void *ptr)
// circuit_guard_state_free(data->guard2_state); // held in circ2
guard_selection_free(data->gs);
smartlist_free(data->all_origin_circuits);
- circuit_free(TO_CIRCUIT(data->circ1));
- circuit_free(TO_CIRCUIT(data->circ2));
+ circuit_free_(TO_CIRCUIT(data->circ1));
+ circuit_free_(TO_CIRCUIT(data->circ2));
tor_free(data);
return big_fake_network_cleanup(testcase, NULL);
}
diff --git a/src/test/test_extorport.c b/src/test/test_extorport.c
index e18deb2700..cadef257f1 100644
--- a/src/test/test_extorport.c
+++ b/src/test/test_extorport.c
@@ -58,11 +58,11 @@ test_ext_or_id_map(void *arg)
done:
if (c1)
- connection_free_(TO_CONN(c1));
+ connection_free_minimal(TO_CONN(c1));
if (c2)
- connection_free_(TO_CONN(c2));
+ connection_free_minimal(TO_CONN(c2));
if (c3)
- connection_free_(TO_CONN(c3));
+ connection_free_minimal(TO_CONN(c3));
tor_free(idp);
tor_free(idp2);
connection_or_clear_ext_or_id_map();
@@ -145,7 +145,7 @@ test_ext_or_write_command(void *arg)
done:
if (c1)
- connection_free_(TO_CONN(c1));
+ connection_free_minimal(TO_CONN(c1));
tor_free(cp);
tor_free(buf);
UNMOCK(connection_write_to_buf_impl_);
@@ -591,7 +591,7 @@ test_ext_or_handshake(void *arg)
UNMOCK(connection_write_to_buf_impl_);
UNMOCK(crypto_rand);
if (conn)
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
#undef CONTAINS
#undef WRITE
}
diff --git a/src/test/test_handles.c b/src/test/test_handles.c
index 7ddee6e376..eb1e1f1bbe 100644
--- a/src/test/test_handles.c
+++ b/src/test/test_handles.c
@@ -13,6 +13,8 @@ typedef struct demo_t {
} demo_t;
HANDLE_DECL(demo, demo_t, static)
+#define demo_handle_free(h) \
+ FREE_AND_NULL(demo_handle_t, demo_handle_free_, (h))
HANDLE_IMPL(demo, demo_t, static)
static demo_t *
diff --git a/src/test/test_hs.c b/src/test/test_hs.c
index 7737499f50..55c6218dd1 100644
--- a/src/test/test_hs.c
+++ b/src/test/test_hs.c
@@ -258,8 +258,9 @@ test_hs_desc_event(void *arg)
sizeof(desc_id_base32));
/* test request event */
- control_event_hs_descriptor_requested(&rend_query.base_, HSDIR_EXIST_ID,
- STR_DESC_ID_BASE32);
+ control_event_hs_descriptor_requested(rend_query.onion_address,
+ rend_query.auth_type, HSDIR_EXIST_ID,
+ STR_DESC_ID_BASE32, NULL);
expected_msg = "650 HS_DESC REQUESTED "STR_HS_ADDR" NO_AUTH "\
STR_HSDIR_EXIST_LONGNAME " " STR_DESC_ID_BASE32 "\r\n";
tt_assert(received_msg);
@@ -268,8 +269,8 @@ test_hs_desc_event(void *arg)
/* test received event */
rend_query.auth_type = REND_BASIC_AUTH;
- control_event_hs_descriptor_received(rend_query.onion_address,
- &rend_query.base_, HSDIR_EXIST_ID);
+ control_event_hsv2_descriptor_received(rend_query.onion_address,
+ &rend_query.base_, HSDIR_EXIST_ID);
expected_msg = "650 HS_DESC RECEIVED "STR_HS_ADDR" BASIC_AUTH "\
STR_HSDIR_EXIST_LONGNAME " " STR_DESC_ID_BASE32"\r\n";
tt_assert(received_msg);
@@ -278,7 +279,7 @@ test_hs_desc_event(void *arg)
/* test failed event */
rend_query.auth_type = REND_STEALTH_AUTH;
- control_event_hs_descriptor_failed(&rend_query.base_,
+ control_event_hsv2_descriptor_failed(&rend_query.base_,
HSDIR_NONE_EXIST_ID,
"QUERY_REJECTED");
expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" STEALTH_AUTH "\
@@ -289,7 +290,7 @@ test_hs_desc_event(void *arg)
/* test invalid auth type */
rend_query.auth_type = 999;
- control_event_hs_descriptor_failed(&rend_query.base_,
+ control_event_hsv2_descriptor_failed(&rend_query.base_,
HSDIR_EXIST_ID,
"QUERY_REJECTED");
expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" UNKNOWN "\
@@ -301,7 +302,7 @@ test_hs_desc_event(void *arg)
/* test no HSDir fingerprint type */
rend_query.auth_type = REND_NO_AUTH;
- control_event_hs_descriptor_failed(&rend_query.base_, NULL,
+ control_event_hsv2_descriptor_failed(&rend_query.base_, NULL,
"QUERY_NO_HSDIR");
expected_msg = "650 HS_DESC FAILED "STR_HS_ADDR" NO_AUTH " \
"UNKNOWN REASON=QUERY_NO_HSDIR\r\n";
diff --git a/src/test/test_hs_cache.c b/src/test/test_hs_cache.c
index 91b13be862..458ce1a92e 100644
--- a/src/test/test_hs_cache.c
+++ b/src/test/test_hs_cache.c
@@ -259,7 +259,7 @@ helper_fetch_desc_from_hsdir(const ed25519_public_key_t *blinded_key)
done:
tor_free(hsdir_query_str);
if (conn)
- connection_free_(TO_CONN(conn));
+ connection_free_minimal(TO_CONN(conn));
return received_desc;
}
diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c
index 750920fac0..7ee7210bc9 100644
--- a/src/test/test_hs_client.c
+++ b/src/test/test_hs_client.c
@@ -227,10 +227,10 @@ test_e2e_rend_circuit_setup_legacy(void *arg)
tt_ptr_op(TO_EDGE_CONN(conn)->on_circuit, OP_EQ, TO_CIRCUIT(or_circ));
done:
- connection_free_(conn);
+ connection_free_minimal(conn);
if (or_circ)
tor_free(TO_CIRCUIT(or_circ)->n_chan);
- circuit_free(TO_CIRCUIT(or_circ));
+ circuit_free_(TO_CIRCUIT(or_circ));
}
/* Test: Ensure that setting up v3 rendezvous circuits works correctly. */
@@ -297,10 +297,10 @@ test_e2e_rend_circuit_setup(void *arg)
tt_ptr_op(TO_EDGE_CONN(conn)->on_circuit, OP_EQ, TO_CIRCUIT(or_circ));
done:
- connection_free_(conn);
+ connection_free_minimal(conn);
if (or_circ)
tor_free(TO_CIRCUIT(or_circ)->n_chan);
- circuit_free(TO_CIRCUIT(or_circ));
+ circuit_free_(TO_CIRCUIT(or_circ));
}
/** Test client logic for picking intro points from a descriptor. Also test how
@@ -560,7 +560,7 @@ test_descriptor_fetch(void *arg)
smartlist_add(get_connection_array(), TO_CONN(dir_conn));
ret = hs_client_refetch_hsdesc(&service_pk);
smartlist_remove(get_connection_array(), TO_CONN(dir_conn));
- connection_free_(TO_CONN(dir_conn));
+ connection_free_minimal(TO_CONN(dir_conn));
tt_int_op(ret, OP_EQ, HS_CLIENT_FETCH_PENDING);
}
@@ -579,7 +579,7 @@ test_descriptor_fetch(void *arg)
tt_int_op(ec->edge_.end_reason, OP_EQ, END_STREAM_REASON_RESOLVEFAILED);
done:
- connection_free_(ENTRY_TO_CONN(ec));
+ connection_free_minimal(ENTRY_TO_CONN(ec));
UNMOCK(networkstatus_get_live_consensus);
UNMOCK(router_have_minimum_dir_info);
hs_free_all();
diff --git a/src/test/test_hs_control.c b/src/test/test_hs_control.c
new file mode 100644
index 0000000000..207a55de6d
--- /dev/null
+++ b/src/test/test_hs_control.c
@@ -0,0 +1,199 @@
+/* Copyright (c) 2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file test_hs_control.c
+ * \brief Unit tests for hidden service control port event and command.
+ **/
+
+#define CONTROL_PRIVATE
+#define CIRCUITBUILD_PRIVATE
+#define RENDCOMMON_PRIVATE
+#define RENDSERVICE_PRIVATE
+#define HS_SERVICE_PRIVATE
+
+#include "or.h"
+#include "test.h"
+#include "control.h"
+#include "config.h"
+#include "hs_common.h"
+#include "hs_control.h"
+#include "nodelist.h"
+//#include "rendcommon.h"
+//#include "rendservice.h"
+//#include "routerset.h"
+//#include "circuitbuild.h"
+#include "test_helpers.h"
+
+/* mock ID digest and longname for node that's in nodelist */
+#define HSDIR_EXIST_ID \
+ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" \
+ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+#define STR_HSDIR_EXIST_LONGNAME \
+ "$AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=TestDir"
+#define STR_HSDIR_NONE_EXIST_LONGNAME \
+ "$BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
+
+/* Helper global variable for hidden service descriptor event test.
+ * It's used as a pointer to dynamically created message buffer in
+ * send_control_event_string_replacement function, which mocks
+ * send_control_event_string function.
+ *
+ * Always free it after use! */
+static char *received_msg = NULL;
+
+/** Mock function for send_control_event_string
+ */
+static void
+queue_control_event_string_replacement(uint16_t event, char *msg)
+{
+ (void) event;
+ tor_free(received_msg);
+ received_msg = msg;
+}
+
+/** Mock function for node_describe_longname_by_id, it returns either
+ * STR_HSDIR_EXIST_LONGNAME or STR_HSDIR_NONE_EXIST_LONGNAME
+ */
+static const char *
+node_describe_longname_by_id_replacement(const char *id_digest)
+{
+ if (!strcmp(id_digest, HSDIR_EXIST_ID)) {
+ return STR_HSDIR_EXIST_LONGNAME;
+ } else {
+ return STR_HSDIR_NONE_EXIST_LONGNAME;
+ }
+}
+
+/* HSDir fetch index is a series of 'D' */
+#define HSDIR_INDEX_FETCH_HEX \
+ "4343434343434343434343434343434343434343434343434343434343434343"
+#define HSDIR_INDEX_STORE_HEX \
+ "4444444444444444444444444444444444444444444444444444444444444444"
+
+static const node_t *
+mock_node_get_by_id(const char *digest)
+{
+ static node_t node;
+ memcpy(node.identity, digest, DIGEST_LEN);
+ node.hsdir_index = tor_malloc_zero(sizeof(hsdir_index_t));
+ memset(node.hsdir_index->fetch, 'C', DIGEST256_LEN);
+ memset(node.hsdir_index->store_first, 'D', DIGEST256_LEN);
+ return &node;
+}
+
+static void
+test_hs_desc_event(void *arg)
+{
+ int ret;
+ char *expected_msg = NULL;
+ char onion_address[HS_SERVICE_ADDR_LEN_BASE32 + 1];
+ ed25519_keypair_t identity_kp;
+ ed25519_public_key_t blinded_pk;
+ char base64_blinded_pk[ED25519_BASE64_LEN + 1];
+ routerstatus_t hsdir_rs;
+ hs_ident_dir_conn_t ident;
+
+ (void) arg;
+ MOCK(queue_control_event_string,
+ queue_control_event_string_replacement);
+ MOCK(node_describe_longname_by_id,
+ node_describe_longname_by_id_replacement);
+ MOCK(node_get_by_id, mock_node_get_by_id);
+
+ /* Setup what we need for this test. */
+ ed25519_keypair_generate(&identity_kp, 0);
+ hs_build_address(&identity_kp.pubkey, HS_VERSION_THREE, onion_address);
+ ret = hs_address_is_valid(onion_address);
+ tt_int_op(ret, OP_EQ, 1);
+ memset(&blinded_pk, 'B', sizeof(blinded_pk));
+ memset(&hsdir_rs, 0, sizeof(hsdir_rs));
+ memcpy(hsdir_rs.identity_digest, HSDIR_EXIST_ID, DIGEST_LEN);
+ ret = ed25519_public_to_base64(base64_blinded_pk, &blinded_pk);
+ tt_int_op(ret, OP_EQ, 0);
+ memcpy(&ident.identity_pk, &identity_kp.pubkey,
+ sizeof(ed25519_public_key_t));
+ memcpy(&ident.blinded_pk, &blinded_pk, sizeof(blinded_pk));
+
+ /* HS_DESC REQUESTED ... */
+ hs_control_desc_event_requested(&identity_kp.pubkey, base64_blinded_pk,
+ &hsdir_rs);
+ tor_asprintf(&expected_msg, "650 HS_DESC REQUESTED %s NO_AUTH "
+ STR_HSDIR_EXIST_LONGNAME " %s HSDIR_INDEX="
+ HSDIR_INDEX_FETCH_HEX "\r\n",
+ onion_address, base64_blinded_pk);
+ tt_assert(received_msg);
+ tt_str_op(received_msg, OP_EQ, expected_msg);
+ tor_free(received_msg);
+ tor_free(expected_msg);
+
+ /* HS_DESC CREATED... */
+ hs_control_desc_event_created(onion_address, &blinded_pk);
+ tor_asprintf(&expected_msg, "650 HS_DESC CREATED %s UNKNOWN "
+ "UNKNOWN %s\r\n",
+ onion_address, base64_blinded_pk);
+ tt_assert(received_msg);
+ tt_str_op(received_msg, OP_EQ, expected_msg);
+ tor_free(received_msg);
+ tor_free(expected_msg);
+
+ /* HS_DESC UPLOAD... */
+ uint8_t hsdir_index_store[DIGEST256_LEN];
+ memset(hsdir_index_store, 'D', sizeof(hsdir_index_store));
+ hs_control_desc_event_upload(onion_address, HSDIR_EXIST_ID,
+ &blinded_pk, hsdir_index_store);
+ tor_asprintf(&expected_msg, "650 HS_DESC UPLOAD %s UNKNOWN "
+ STR_HSDIR_EXIST_LONGNAME " %s "
+ "HSDIR_INDEX=" HSDIR_INDEX_STORE_HEX "\r\n",
+ onion_address, base64_blinded_pk);
+ tt_assert(received_msg);
+ tt_str_op(received_msg, OP_EQ, expected_msg);
+ tor_free(received_msg);
+ tor_free(expected_msg);
+
+ /* HS_DESC FAILED... */
+ hs_control_desc_event_failed(&ident, HSDIR_EXIST_ID, "BAD_DESC");
+ tor_asprintf(&expected_msg, "650 HS_DESC FAILED %s NO_AUTH "
+ STR_HSDIR_EXIST_LONGNAME " %s "
+ "REASON=BAD_DESC\r\n",
+ onion_address, base64_blinded_pk);
+ tt_assert(received_msg);
+ tt_str_op(received_msg, OP_EQ, expected_msg);
+ tor_free(received_msg);
+ tor_free(expected_msg);
+
+ /* HS_DESC RECEIVED... */
+ hs_control_desc_event_received(&ident, HSDIR_EXIST_ID);
+ tor_asprintf(&expected_msg, "650 HS_DESC RECEIVED %s NO_AUTH "
+ STR_HSDIR_EXIST_LONGNAME " %s\r\n",
+ onion_address, base64_blinded_pk);
+ tt_assert(received_msg);
+ tt_str_op(received_msg, OP_EQ, expected_msg);
+ tor_free(received_msg);
+ tor_free(expected_msg);
+
+ /* HS_DESC UPLOADED... */
+ hs_control_desc_event_uploaded(&ident, HSDIR_EXIST_ID);
+ tor_asprintf(&expected_msg, "650 HS_DESC UPLOADED %s UNKNOWN "
+ STR_HSDIR_EXIST_LONGNAME "\r\n",
+ onion_address);
+ tt_assert(received_msg);
+ tt_str_op(received_msg, OP_EQ, expected_msg);
+ tor_free(received_msg);
+ tor_free(expected_msg);
+
+ done:
+ UNMOCK(queue_control_event_string);
+ UNMOCK(node_describe_longname_by_id);
+ UNMOCK(node_get_by_id);
+ tor_free(received_msg);
+ tor_free(expected_msg);
+}
+
+struct testcase_t hs_control_tests[] = {
+ { "hs_desc_event", test_hs_desc_event, TT_FORK,
+ NULL, NULL },
+
+ END_OF_TESTCASES
+};
+
diff --git a/src/test/test_hs_intropoint.c b/src/test/test_hs_intropoint.c
index 0cae2de7e1..6a7962b212 100644
--- a/src/test/test_hs_intropoint.c
+++ b/src/test/test_hs_intropoint.c
@@ -194,7 +194,7 @@ test_establish_intro_wrong_purpose(void *arg)
tt_int_op(retval, OP_EQ, -1);
done:
- circuit_free(TO_CIRCUIT(intro_circ));
+ circuit_free_(TO_CIRCUIT(intro_circ));
}
/* Prepare a circuit for accepting an ESTABLISH_INTRO cell */
@@ -228,7 +228,7 @@ test_establish_intro_wrong_keytype(void *arg)
tt_int_op(retval, OP_EQ, -1);
done:
- circuit_free(TO_CIRCUIT(intro_circ));
+ circuit_free_(TO_CIRCUIT(intro_circ));
}
/* Send an ESTABLISH_INTRO cell with an unknown auth key type. Should fail. */
@@ -263,7 +263,7 @@ test_establish_intro_wrong_keytype2(void *arg)
tt_int_op(retval, OP_EQ, -1);
done:
- circuit_free(TO_CIRCUIT(intro_circ));
+ circuit_free_(TO_CIRCUIT(intro_circ));
}
/* Send a legit ESTABLISH_INTRO cell but with a wrong MAC. Should fail. */
@@ -333,7 +333,7 @@ test_establish_intro_wrong_mac(void *arg)
done:
trn_cell_establish_intro_free(cell);
- circuit_free(TO_CIRCUIT(intro_circ));
+ circuit_free_(TO_CIRCUIT(intro_circ));
}
/* Send a legit ESTABLISH_INTRO cell but with a wrong auth key length. Should
@@ -378,7 +378,7 @@ test_establish_intro_wrong_auth_key_len(void *arg)
done:
trn_cell_establish_intro_free(cell);
- circuit_free(TO_CIRCUIT(intro_circ));
+ circuit_free_(TO_CIRCUIT(intro_circ));
}
/* Send a legit ESTABLISH_INTRO cell but with a wrong sig length. Should
@@ -423,7 +423,7 @@ test_establish_intro_wrong_sig_len(void *arg)
done:
trn_cell_establish_intro_free(cell);
- circuit_free(TO_CIRCUIT(intro_circ));
+ circuit_free_(TO_CIRCUIT(intro_circ));
}
/* Send a legit ESTABLISH_INTRO cell but slightly change the signature. Should
@@ -460,7 +460,7 @@ test_establish_intro_wrong_sig(void *arg)
tt_int_op(retval, OP_EQ, -1);
done:
- circuit_free(TO_CIRCUIT(intro_circ));
+ circuit_free_(TO_CIRCUIT(intro_circ));
}
/* Helper function: Send a well-formed v3 ESTABLISH_INTRO cell to
@@ -629,8 +629,8 @@ test_intro_point_registration(void *arg)
done:
crypto_pk_free(legacy_auth_key);
- circuit_free(TO_CIRCUIT(intro_circ));
- circuit_free(TO_CIRCUIT(legacy_intro_circ));
+ circuit_free_(TO_CIRCUIT(intro_circ));
+ circuit_free_(TO_CIRCUIT(legacy_intro_circ));
trn_cell_establish_intro_free(establish_intro_cell);
test_circuitmap_free_all();
@@ -650,7 +650,7 @@ test_introduce1_suitable_circuit(void *arg)
circ = or_circuit_new(0, NULL);
circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_OR);
ret = circuit_is_suitable_for_introduce1(circ);
- circuit_free(TO_CIRCUIT(circ));
+ circuit_free_(TO_CIRCUIT(circ));
tt_int_op(ret, OP_EQ, 1);
}
@@ -659,7 +659,7 @@ test_introduce1_suitable_circuit(void *arg)
circ = or_circuit_new(0, NULL);
circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_INTRO_POINT);
ret = circuit_is_suitable_for_introduce1(circ);
- circuit_free(TO_CIRCUIT(circ));
+ circuit_free_(TO_CIRCUIT(circ));
tt_int_op(ret, OP_EQ, 0);
}
@@ -670,7 +670,7 @@ test_introduce1_suitable_circuit(void *arg)
/* Bogus pointer, the check is against NULL on n_chan. */
circ->base_.n_chan = (channel_t *) circ;
ret = circuit_is_suitable_for_introduce1(circ);
- circuit_free(TO_CIRCUIT(circ));
+ circuit_free_(TO_CIRCUIT(circ));
tt_int_op(ret, OP_EQ, 0);
}
@@ -681,7 +681,7 @@ test_introduce1_suitable_circuit(void *arg)
circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_OR);
circ->already_received_introduce1 = 1;
ret = circuit_is_suitable_for_introduce1(circ);
- circuit_free(TO_CIRCUIT(circ));
+ circuit_free_(TO_CIRCUIT(circ));
tt_int_op(ret, OP_EQ, 0);
}
@@ -800,7 +800,7 @@ test_received_introduce1_handling(void *arg)
circ = helper_create_intro_circuit();
ret = hs_intro_received_introduce1(circ, buf, DIGEST_LEN - 1);
tt_int_op(ret, OP_EQ, -1);
- circuit_free(TO_CIRCUIT(circ));
+ circuit_free_(TO_CIRCUIT(circ));
}
/* We have a unit test only for the suitability of a circuit to receive an
@@ -813,7 +813,7 @@ test_received_introduce1_handling(void *arg)
memset(test, 0, sizeof(test));
ret = handle_introduce1(circ, test, sizeof(test));
tor_free(circ->p_chan);
- circuit_free(TO_CIRCUIT(circ));
+ circuit_free_(TO_CIRCUIT(circ));
tt_int_op(ret, OP_EQ, -1);
}
@@ -838,8 +838,8 @@ test_received_introduce1_handling(void *arg)
memcpy(auth_key.pubkey, cell_auth_key, ED25519_PUBKEY_LEN);
hs_circuitmap_register_intro_circ_v3_relay_side(service_circ, &auth_key);
ret = hs_intro_received_introduce1(circ, request, request_len);
- circuit_free(TO_CIRCUIT(circ));
- circuit_free(TO_CIRCUIT(service_circ));
+ circuit_free_(TO_CIRCUIT(circ));
+ circuit_free_(TO_CIRCUIT(service_circ));
tt_int_op(ret, OP_EQ, 0);
}
@@ -867,8 +867,8 @@ test_received_introduce1_handling(void *arg)
memcpy(token, legacy_key_id, sizeof(token));
hs_circuitmap_register_intro_circ_v2_relay_side(service_circ, token);
ret = hs_intro_received_introduce1(circ, request, request_len);
- circuit_free(TO_CIRCUIT(circ));
- circuit_free(TO_CIRCUIT(service_circ));
+ circuit_free_(TO_CIRCUIT(circ));
+ circuit_free_(TO_CIRCUIT(service_circ));
tt_int_op(ret, OP_EQ, 0);
}
diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c
index 8407eccfa8..3e3a7d8e0d 100644
--- a/src/test/test_hs_service.c
+++ b/src/test/test_hs_service.c
@@ -182,7 +182,7 @@ test_e2e_rend_circuit_setup(void *arg)
tt_int_op(or_circ->base_.purpose, OP_EQ, CIRCUIT_PURPOSE_S_REND_JOINED);
done:
- circuit_free(TO_CIRCUIT(or_circ));
+ circuit_free_(TO_CIRCUIT(or_circ));
}
/* Helper: Return a newly allocated and initialized origin circuit with
@@ -194,7 +194,7 @@ helper_create_origin_circuit(int purpose, int flags)
origin_circuit_t *circ = NULL;
circ = origin_circuit_init(purpose, flags);
- tt_assert(circ);
+ tor_assert(circ);
circ->cpath = tor_malloc_zero(sizeof(crypt_path_t));
circ->cpath->magic = CRYPT_PATH_MAGIC;
circ->cpath->state = CPATH_STATE_OPEN;
@@ -206,7 +206,6 @@ helper_create_origin_circuit(int purpose, int flags)
/* Create a default HS identifier. */
circ->hs_ident = tor_malloc_zero(sizeof(hs_ident_circuit_t));
- done:
return circ;
}
@@ -219,7 +218,7 @@ helper_create_service(void)
{
/* Set a service for this circuit. */
hs_service_t *service = hs_service_new(get_options());
- tt_assert(service);
+ tor_assert(service);
service->config.version = HS_VERSION_THREE;
ed25519_secret_key_generate(&service->keys.identity_sk, 0);
ed25519_public_key_generate(&service->keys.identity_pk,
@@ -241,7 +240,7 @@ helper_create_service_ip(void)
{
hs_desc_link_specifier_t *ls;
hs_service_intro_point_t *ip = service_intro_point_new(NULL, 0);
- tt_assert(ip);
+ tor_assert(ip);
/* Add a first unused link specifier. */
ls = tor_malloc_zero(sizeof(*ls));
ls->type = LS_IPV4;
@@ -252,7 +251,6 @@ helper_create_service_ip(void)
memset(ls->u.legacy_id, 'A', sizeof(ls->u.legacy_id));
smartlist_add(ip->base.link_specifiers, ls);
- done:
return ip;
}
@@ -655,7 +653,7 @@ test_intro_circuit_opened(void *arg)
teardown_capture_of_logs();
done:
- circuit_free(TO_CIRCUIT(circ));
+ circuit_free_(TO_CIRCUIT(circ));
hs_free_all();
UNMOCK(circuit_mark_for_close_);
UNMOCK(relay_send_command_from_edge_);
@@ -730,7 +728,7 @@ test_intro_established(void *arg)
done:
if (circ)
- circuit_free(TO_CIRCUIT(circ));
+ circuit_free_(TO_CIRCUIT(circ));
hs_free_all();
UNMOCK(circuit_mark_for_close_);
}
@@ -772,7 +770,7 @@ test_rdv_circuit_opened(void *arg)
tt_int_op(TO_CIRCUIT(circ)->purpose, OP_EQ, CIRCUIT_PURPOSE_S_REND_JOINED);
done:
- circuit_free(TO_CIRCUIT(circ));
+ circuit_free_(TO_CIRCUIT(circ));
hs_free_all();
UNMOCK(circuit_mark_for_close_);
UNMOCK(relay_send_command_from_edge_);
@@ -825,7 +823,7 @@ test_closing_intro_circs(void *arg)
/* Now pretend we are freeing this intro circuit. We want to see that our
* destructor is not gonna kill our intro point structure since that's the
* job of the cleanup routine. */
- circuit_free(TO_CIRCUIT(intro_circ));
+ circuit_free_(TO_CIRCUIT(intro_circ));
intro_circ = NULL;
entry = service_intro_point_find(service, &ip->auth_key_kp.pubkey);
tt_assert(entry);
@@ -857,7 +855,7 @@ test_closing_intro_circs(void *arg)
done:
if (intro_circ) {
- circuit_free(TO_CIRCUIT(intro_circ));
+ circuit_free_(TO_CIRCUIT(intro_circ));
}
/* Frees the service object. */
hs_free_all();
@@ -938,7 +936,7 @@ test_introduce2(void *arg)
or_state_free(dummy_state);
dummy_state = NULL;
if (circ)
- circuit_free(TO_CIRCUIT(circ));
+ circuit_free_(TO_CIRCUIT(circ));
hs_free_all();
UNMOCK(circuit_mark_for_close_);
}
@@ -1022,7 +1020,7 @@ test_service_event(void *arg)
done:
hs_circuitmap_remove_circuit(TO_CIRCUIT(circ));
- circuit_free(TO_CIRCUIT(circ));
+ circuit_free_(TO_CIRCUIT(circ));
hs_free_all();
UNMOCK(circuit_mark_for_close_);
}
@@ -1576,8 +1574,8 @@ test_rendezvous1_parsing(void *arg)
* would need an extra circuit and some more stuff but it's doable. */
done:
- circuit_free(TO_CIRCUIT(service_circ));
- circuit_free(TO_CIRCUIT(client_circ));
+ circuit_free_(TO_CIRCUIT(service_circ));
+ circuit_free_(TO_CIRCUIT(client_circ));
hs_service_free(service);
hs_free_all();
UNMOCK(relay_send_command_from_edge_);
diff --git a/src/test/test_keygen.sh b/src/test/test_keygen.sh
index 87012cd283..b3d4d8e39a 100755
--- a/src/test/test_keygen.sh
+++ b/src/test/test_keygen.sh
@@ -40,6 +40,12 @@ fi
CASE8=$dflt
CASE9=$dflt
CASE10=$dflt
+ CASE11A=$dflt
+ CASE11B=$dflt
+ CASE11C=$dflt
+ CASE11D=$dflt
+ CASE11E=$dflt
+ CASE11F=$dflt
if [ $# -ge 1 ]; then
eval "CASE${1}"=1
@@ -363,6 +369,109 @@ echo "==== Case 10 ok"
fi
+# Case 11a: -passphrase-fd without --keygen
+
+if [ "$CASE11A" = 1 ]; then
+
+ME="${DATA_DIR}/case11a"
+
+mkdir -p "${ME}/keys"
+
+${TOR} --DataDirectory "${ME}" --passphrase-fd 1 > "${ME}/stdout" && die "Successfully started with passphrase-fd but no keygen?" || true
+
+grep "passphrase-fd specified without --keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
+
+echo "==== Case 11A ok"
+
+fi
+
+# Case 11b: --no-passphrase without --keygen
+
+if [ "$CASE11B" = 1 ]; then
+
+ME="${DATA_DIR}/case11b"
+
+mkdir -p "${ME}/keys"
+
+${TOR} --DataDirectory "${ME}" --no-passphrase > "${ME}/stdout" && die "Successfully started with no-passphrase but no keygen?" || true
+
+grep "no-passphrase specified without --keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
+
+echo "==== Case 11B ok"
+
+fi
+
+# Case 11c: --newpass without --keygen
+
+if [ "$CASE11C" = 1 ]; then
+
+ME="${DATA_DIR}/case11C"
+
+mkdir -p "${ME}/keys"
+
+${TOR} --DataDirectory "${ME}" --newpass > "${ME}/stdout" && die "Successfully started with newpass but no keygen?" || true
+
+grep "newpass specified without --keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
+
+echo "==== Case 11C ok"
+
+fi
+
+######## --master-key does not work yet, but this will test the error case
+######## when it does.
+#
+# Case 11d: --master-key without --keygen
+#
+if [ "$CASE11D" = 1 ]; then
+#
+# ME="${DATA_DIR}/case11d"
+#
+# mkdir -p "${ME}/keys"
+#
+# ${TOR} --DataDirectory "${ME}" --master-key "${ME}/foobar" > "${ME}/stdout" && die "Successfully started with master-key but no keygen?" || true
+#
+# cat "${ME}/stdout"
+#
+# grep "master-key without --keygen" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
+
+ echo "==== Case 11D skipped"
+
+fi
+
+
+# Case 11E: Silly passphrase-fd
+
+if [ "$CASE11E" = 1 ]; then
+
+ME="${DATA_DIR}/case11E"
+
+mkdir -p "${ME}/keys"
+
+${TOR} --DataDirectory "${ME}" --keygen --passphrase-fd ewigeblumenkraft > "${ME}/stdout" && die "Successfully started with bogus passphrase-fd?" || true
+
+grep "Invalid --passphrase-fd value" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
+
+echo "==== Case 11E ok"
+
+fi
+
+
+# Case 11F: --no-passphrase with --passphrase-fd
+
+if [ "$CASE11F" = 1 ]; then
+
+ME="${DATA_DIR}/case11F"
+
+mkdir -p "${ME}/keys"
+
+${TOR} --DataDirectory "${ME}" --keygen --passphrase-fd 1 --no-passphrase > "${ME}/stdout" && die "Successfully started with bogus passphrase-fd combination?" || true
+
+grep "no-passphrase specified with --passphrase-fd" "${ME}/stdout" >/dev/null || die "Tor didn't declare that there was a problem with the arguments."
+
+echo "==== Case 11F ok"
+
+fi
+
# Check cert-only.
diff --git a/src/test/test_link_handshake.c b/src/test/test_link_handshake.c
index 422d419078..6840072d76 100644
--- a/src/test/test_link_handshake.c
+++ b/src/test/test_link_handshake.c
@@ -302,8 +302,8 @@ test_link_handshake_certs_ok(void *arg)
mock_own_cert = mock_peer_cert = NULL;
memset(c1->identity_digest, 0, sizeof(c1->identity_digest));
memset(c2->identity_digest, 0, sizeof(c2->identity_digest));
- connection_free_(TO_CONN(c1));
- connection_free_(TO_CONN(c2));
+ connection_free_minimal(TO_CONN(c1));
+ connection_free_minimal(TO_CONN(c2));
tor_free(cell1);
tor_free(cell2);
certs_cell_free(cc1);
@@ -343,7 +343,7 @@ recv_certs_cleanup(const struct testcase_t *test, void *obj)
tor_free(d->cell);
certs_cell_free(d->ccell);
connection_or_clear_identity(d->c);
- connection_free_(TO_CONN(d->c));
+ connection_free_minimal(TO_CONN(d->c));
circuitmux_free(d->chan->base_.cmux);
tor_free(d->chan);
crypto_pk_free(d->key1);
@@ -930,7 +930,7 @@ test_link_handshake_send_authchallenge(void *arg)
done:
UNMOCK(connection_or_write_var_cell_to_buf);
- connection_free_(TO_CONN(c1));
+ connection_free_minimal(TO_CONN(c1));
tor_free(cell1);
tor_free(cell2);
crypto_pk_free(rsa0);
@@ -955,7 +955,7 @@ recv_authchallenge_cleanup(const struct testcase_t *test, void *obj)
if (d) {
tor_free(d->cell);
- connection_free_(TO_CONN(d->c));
+ connection_free_minimal(TO_CONN(d->c));
circuitmux_free(d->chan->base_.cmux);
tor_free(d->chan);
tor_free(d);
@@ -1158,8 +1158,8 @@ authenticate_data_cleanup(const struct testcase_t *test, void *arg)
tor_free(d->cell);
connection_or_clear_identity(d->c1);
connection_or_clear_identity(d->c2);
- connection_free_(TO_CONN(d->c1));
- connection_free_(TO_CONN(d->c2));
+ connection_free_minimal(TO_CONN(d->c1));
+ connection_free_minimal(TO_CONN(d->c2));
circuitmux_free(d->chan2->base_.cmux);
tor_free(d->chan2);
crypto_pk_free(d->key1);
diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c
index 4f0ecd778b..59b28f7580 100644
--- a/src/test/test_microdesc.c
+++ b/src/test/test_microdesc.c
@@ -69,12 +69,12 @@ test_md_cache(void *data)
time3 = time(NULL) - 15*24*60*60;
/* Possibly, turn this into a test setup/cleanup pair */
- tor_free(options->DataDirectory);
- options->DataDirectory = tor_strdup(get_fname("md_datadir_test"));
+ tor_free(options->CacheDirectory);
+ options->CacheDirectory = tor_strdup(get_fname("md_datadir_test"));
#ifdef _WIN32
- tt_int_op(0, OP_EQ, mkdir(options->DataDirectory));
+ tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory));
#else
- tt_int_op(0, OP_EQ, mkdir(options->DataDirectory, 0700));
+ tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory, 0700));
#endif
tt_assert(!strcmpstart(test_md3_noannotation, "onion-key"));
@@ -152,7 +152,7 @@ test_md_cache(void *data)
strlen(test_md3_noannotation));
tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs.new",
- options->DataDirectory);
+ options->CacheDirectory);
s = read_file_to_str(fn, RFTS_BIN, NULL);
tt_assert(s);
tt_mem_op(md1->body, OP_EQ, s + md1->off, md1->bodylen);
@@ -180,7 +180,7 @@ test_md_cache(void *data)
/* read the cache. */
tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs",
- options->DataDirectory);
+ options->CacheDirectory);
s = read_file_to_str(fn, RFTS_BIN, NULL);
tt_mem_op(md1->body, OP_EQ, s + md1->off, strlen(test_md1));
tt_mem_op(md2->body, OP_EQ, s + md2->off, strlen(test_md2));
@@ -234,7 +234,7 @@ test_md_cache(void *data)
done:
if (options)
- tor_free(options->DataDirectory);
+ tor_free(options->CacheDirectory);
microdesc_free_all();
smartlist_free(added);
@@ -266,17 +266,17 @@ test_md_cache_broken(void *data)
options = get_options_mutable();
tt_assert(options);
- tor_free(options->DataDirectory);
- options->DataDirectory = tor_strdup(get_fname("md_datadir_test2"));
+ tor_free(options->CacheDirectory);
+ options->CacheDirectory = tor_strdup(get_fname("md_datadir_test2"));
#ifdef _WIN32
- tt_int_op(0, OP_EQ, mkdir(options->DataDirectory));
+ tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory));
#else
- tt_int_op(0, OP_EQ, mkdir(options->DataDirectory, 0700));
+ tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory, 0700));
#endif
tor_asprintf(&fn, "%s"PATH_SEPARATOR"cached-microdescs",
- options->DataDirectory);
+ options->CacheDirectory);
write_str_to_file(fn, truncated_md, 1);
@@ -285,7 +285,7 @@ test_md_cache_broken(void *data)
done:
if (options)
- tor_free(options->DataDirectory);
+ tor_free(options->CacheDirectory);
tor_free(fn);
microdesc_free_all();
}
@@ -754,8 +754,8 @@ test_md_reject_cache(void *arg)
or_options_t *options = get_options_mutable();
char buf[DIGEST256_LEN];
- tor_free(options->DataDirectory);
- options->DataDirectory = tor_strdup(get_fname("md_datadir_test_rej"));
+ tor_free(options->CacheDirectory);
+ options->CacheDirectory = tor_strdup(get_fname("md_datadir_test_rej"));
mock_rgsbd_val_a = tor_malloc_zero(sizeof(routerstatus_t));
mock_rgsbd_val_b = tor_malloc_zero(sizeof(routerstatus_t));
mock_ns_val = tor_malloc_zero(sizeof(networkstatus_t));
@@ -765,9 +765,9 @@ test_md_reject_cache(void *arg)
mock_ns_val->flavor = FLAV_MICRODESC;
#ifdef _WIN32
- tt_int_op(0, OP_EQ, mkdir(options->DataDirectory));
+ tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory));
#else
- tt_int_op(0, OP_EQ, mkdir(options->DataDirectory, 0700));
+ tt_int_op(0, OP_EQ, mkdir(options->CacheDirectory, 0700));
#endif
MOCK(router_get_mutable_consensus_status_by_descriptor_digest,
@@ -802,7 +802,7 @@ test_md_reject_cache(void *arg)
done:
UNMOCK(networkstatus_get_latest_consensus_by_flavor);
UNMOCK(router_get_mutable_consensus_status_by_descriptor_digest);
- tor_free(options->DataDirectory);
+ tor_free(options->CacheDirectory);
microdesc_free_all();
smartlist_free(added);
SMARTLIST_FOREACH(wanted, char *, cp, tor_free(cp));
diff --git a/src/test/test_oom.c b/src/test/test_oom.c
index cf28690a28..c172fe60c7 100644
--- a/src/test/test_oom.c
+++ b/src/test/test_oom.c
@@ -202,7 +202,7 @@ test_oom_streambuf(void *arg)
{
or_options_t *options = get_options_mutable();
circuit_t *c1 = NULL, *c2 = NULL, *c3 = NULL, *c4 = NULL, *c5 = NULL;
- uint32_t tvms;
+ uint32_t tvts;
int i;
smartlist_t *edgeconns = smartlist_new();
const uint64_t start_ns = 1389641159 * (uint64_t)1000000000;
@@ -270,22 +270,28 @@ test_oom_streambuf(void *arg)
now_ns -= now_ns % 1000000000;
now_ns += 1000000000;
monotime_coarse_set_mock_time_nsec(now_ns);
- tvms = (uint32_t) monotime_coarse_absolute_msec();
+ tvts = monotime_coarse_get_stamp();
- tt_int_op(circuit_max_queued_cell_age(c1, tvms), OP_EQ, 500);
- tt_int_op(circuit_max_queued_cell_age(c2, tvms), OP_EQ, 490);
- tt_int_op(circuit_max_queued_cell_age(c3, tvms), OP_EQ, 480);
- tt_int_op(circuit_max_queued_cell_age(c4, tvms), OP_EQ, 0);
+#define ts_is_approx(ts, val) do { \
+ uint32_t x_ = (uint32_t) monotime_coarse_stamp_units_to_approx_msec(ts); \
+ tt_int_op(x_, OP_GE, val - 5); \
+ tt_int_op(x_, OP_LE, val + 5); \
+ } while (0)
- tt_int_op(circuit_max_queued_data_age(c1, tvms), OP_EQ, 390);
- tt_int_op(circuit_max_queued_data_age(c2, tvms), OP_EQ, 380);
- tt_int_op(circuit_max_queued_data_age(c3, tvms), OP_EQ, 0);
- tt_int_op(circuit_max_queued_data_age(c4, tvms), OP_EQ, 370);
+ ts_is_approx(circuit_max_queued_cell_age(c1, tvts), 500);
+ ts_is_approx(circuit_max_queued_cell_age(c2, tvts), 490);
+ ts_is_approx(circuit_max_queued_cell_age(c3, tvts), 480);
+ ts_is_approx(circuit_max_queued_cell_age(c4, tvts), 0);
- tt_int_op(circuit_max_queued_item_age(c1, tvms), OP_EQ, 500);
- tt_int_op(circuit_max_queued_item_age(c2, tvms), OP_EQ, 490);
- tt_int_op(circuit_max_queued_item_age(c3, tvms), OP_EQ, 480);
- tt_int_op(circuit_max_queued_item_age(c4, tvms), OP_EQ, 370);
+ ts_is_approx(circuit_max_queued_data_age(c1, tvts), 390);
+ ts_is_approx(circuit_max_queued_data_age(c2, tvts), 380);
+ ts_is_approx(circuit_max_queued_data_age(c3, tvts), 0);
+ ts_is_approx(circuit_max_queued_data_age(c4, tvts), 370);
+
+ ts_is_approx(circuit_max_queued_item_age(c1, tvts), 500);
+ ts_is_approx(circuit_max_queued_item_age(c2, tvts), 490);
+ ts_is_approx(circuit_max_queued_item_age(c3, tvts), 480);
+ ts_is_approx(circuit_max_queued_item_age(c4, tvts), 370);
tt_int_op(cell_queues_get_total_allocation(), OP_EQ,
packed_cell_mem_cost() * 80);
@@ -301,7 +307,7 @@ test_oom_streambuf(void *arg)
smartlist_add(edgeconns, ec);
}
tt_int_op(buf_get_total_allocation(), OP_EQ, 4096*17*2);
- tt_int_op(circuit_max_queued_item_age(c4, tvms), OP_EQ, 1000);
+ ts_is_approx(circuit_max_queued_item_age(c4, tvts), 1000);
tt_int_op(cell_queues_check_size(), OP_EQ, 0);
@@ -335,7 +341,7 @@ test_oom_streambuf(void *arg)
circuit_free(c5);
SMARTLIST_FOREACH(edgeconns, edge_connection_t *, ec,
- connection_free_(TO_CONN(ec)));
+ connection_free_minimal(TO_CONN(ec)));
smartlist_free(edgeconns);
UNMOCK(circuit_mark_for_close_);
diff --git a/src/test/test_policy.c b/src/test/test_policy.c
index 83dca2d431..f8aa8ac40b 100644
--- a/src/test/test_policy.c
+++ b/src/test/test_policy.c
@@ -1318,7 +1318,7 @@ mock_get_interface_address6_list(int severity,
return clone_list;
done:
- free_interface_address6_list(clone_list);
+ interface_address6_list_free(clone_list);
return NULL;
}
@@ -1393,11 +1393,11 @@ test_policies_reject_interface_address(void *arg)
done:
addr_policy_list_free(policy);
- free_interface_address6_list(public_ipv4_addrs);
- free_interface_address6_list(public_ipv6_addrs);
+ interface_address6_list_free(public_ipv4_addrs);
+ interface_address6_list_free(public_ipv6_addrs);
UNMOCK(get_interface_address6_list);
- /* we don't use free_interface_address6_list on these lists because their
+ /* we don't use interface_address6_list_free on these lists because their
* address pointers are stack-based */
smartlist_free(mock_ipv4_addrs);
smartlist_free(mock_ipv6_addrs);
diff --git a/src/test/test_protover.c b/src/test/test_protover.c
index 6ce54890d6..6865362115 100644
--- a/src/test/test_protover.c
+++ b/src/test/test_protover.c
@@ -12,6 +12,13 @@ static void
test_protover_parse(void *arg)
{
(void) arg;
+#ifdef HAVE_RUST
+ /** This test is disabled on rust builds, because it only exists to test
+ * internal C functions. */
+ tt_skip();
+ done:
+ ;
+#else
char *re_encoded = NULL;
const char *orig = "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900";
@@ -78,12 +85,18 @@ test_protover_parse(void *arg)
SMARTLIST_FOREACH(elts, proto_entry_t *, ent, proto_entry_free(ent));
smartlist_free(elts);
tor_free(re_encoded);
+#endif
}
static void
test_protover_parse_fail(void *arg)
{
(void)arg;
+#ifdef HAVE_RUST
+ /** This test is disabled on rust builds, because it only exists to test
+ * internal C functions. */
+ tt_skip();
+#else
smartlist_t *elts;
/* random junk */
@@ -109,7 +122,7 @@ test_protover_parse_fail(void *arg)
/* Broken range */
elts = parse_protocol_list("Link=1,9-8,3");
tt_ptr_op(elts, OP_EQ, NULL);
-
+#endif
done:
;
}
@@ -182,6 +195,61 @@ test_protover_all_supported(void *arg)
tor_free(msg);
}
+static void
+test_protover_list_supports_protocol_returns_true(void *arg)
+{
+ (void)arg;
+
+ const char *protocols = "Link=1";
+ int is_supported = protocol_list_supports_protocol(protocols, PRT_LINK, 1);
+ tt_int_op(is_supported, OP_EQ, 1);
+
+ done:
+ ;
+}
+
+static void
+test_protover_list_supports_protocol_for_unsupported_returns_false(void *arg)
+{
+ (void)arg;
+
+ const char *protocols = "Link=1";
+ int is_supported = protocol_list_supports_protocol(protocols, PRT_LINK, 10);
+ tt_int_op(is_supported, OP_EQ, 0);
+
+ done:
+ ;
+}
+
+static void
+test_protover_supports_version(void *arg)
+{
+ (void)arg;
+
+ tt_assert(protocol_list_supports_protocol("Link=3-6", PRT_LINK, 3));
+ tt_assert(protocol_list_supports_protocol("Link=3-6", PRT_LINK, 6));
+ tt_assert(!protocol_list_supports_protocol("Link=3-6", PRT_LINK, 7));
+ tt_assert(!protocol_list_supports_protocol("Link=3-6", PRT_LINKAUTH, 3));
+
+ tt_assert(!protocol_list_supports_protocol("Link=4-6 LinkAuth=3",
+ PRT_LINKAUTH, 2));
+ tt_assert(protocol_list_supports_protocol("Link=4-6 LinkAuth=3",
+ PRT_LINKAUTH, 3));
+ tt_assert(!protocol_list_supports_protocol("Link=4-6 LinkAuth=3",
+ PRT_LINKAUTH, 4));
+ tt_assert(!protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3",
+ PRT_LINKAUTH, 4));
+ tt_assert(protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3",
+ PRT_LINKAUTH, 3));
+ tt_assert(protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3",
+ PRT_LINKAUTH, 2));
+
+ tt_assert(!protocol_list_supports_protocol_or_later("Link=4-6 LinkAuth=3",
+ PRT_DESC, 2));
+ done:
+ ;
+}
+
#define PV_TEST(name, flags) \
{ #name, test_protover_ ##name, (flags), NULL, NULL }
@@ -190,6 +258,9 @@ struct testcase_t protover_tests[] = {
PV_TEST(parse_fail, 0),
PV_TEST(vote, 0),
PV_TEST(all_supported, 0),
+ PV_TEST(list_supports_protocol_for_unsupported_returns_false, 0),
+ PV_TEST(list_supports_protocol_returns_true, 0),
+ PV_TEST(supports_version, 0),
END_OF_TESTCASES
};
diff --git a/src/test/test_relay.c b/src/test/test_relay.c
index e3489627a0..73c0ed5586 100644
--- a/src/test/test_relay.c
+++ b/src/test/test_relay.c
@@ -67,10 +67,6 @@ test_relay_append_cell_to_circuit_queue(void *arg)
pchan = new_fake_channel();
tt_assert(pchan);
- /* We'll need chans with working cmuxes */
- nchan->cmux = circuitmux_alloc();
- pchan->cmux = circuitmux_alloc();
-
/* Make a fake orcirc */
orcirc = new_fake_orcirc(nchan, pchan);
tt_assert(orcirc);
diff --git a/src/test/test_rendcache.c b/src/test/test_rendcache.c
index 9354dd0480..9f6cfc4a22 100644
--- a/src/test/test_rendcache.c
+++ b/src/test/test_rendcache.c
@@ -834,7 +834,7 @@ test_rend_cache_failure_entry_free(void *data)
(void)data;
// Test that it can deal with a NULL argument
- rend_cache_failure_entry_free(NULL);
+ rend_cache_failure_entry_free_(NULL);
/* done: */
/* (void)0; */
@@ -963,7 +963,7 @@ test_rend_cache_entry_free(void *data)
rend_cache_entry_t *e;
// Handles NULL correctly
- rend_cache_entry_free(NULL);
+ rend_cache_entry_free_(NULL);
// Handles NULL descriptor correctly
e = tor_malloc_zero(sizeof(rend_cache_entry_t));
@@ -1135,7 +1135,7 @@ test_rend_cache_failure_intro_entry_free(void *data)
rend_cache_failure_intro_t *entry;
// Handles a null argument
- rend_cache_failure_intro_entry_free(NULL);
+ rend_cache_failure_intro_entry_free_(NULL);
// Handles a non-null argument
entry = rend_cache_failure_intro_entry_new(INTRO_POINT_FAILURE_TIMEOUT);
@@ -1148,7 +1148,7 @@ test_rend_cache_failure_purge(void *data)
(void)data;
// Handles a null failure cache
- strmap_free(rend_cache_failure, rend_cache_failure_entry_free_);
+ strmap_free(rend_cache_failure, rend_cache_failure_entry_free_void);
rend_cache_failure = NULL;
rend_cache_failure_purge();
diff --git a/src/test/test_replay.c b/src/test/test_replay.c
index c379cafa7c..d8dcc7370c 100644
--- a/src/test/test_replay.c
+++ b/src/test/test_replay.c
@@ -74,7 +74,7 @@ static void
test_replaycache_free_null(void *arg)
{
(void)arg;
- replaycache_free(NULL);
+ replaycache_free_(NULL);
/* Assert that we're here without horrible death */
tt_assert(1);
diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c
index d8b72651a0..e4abcdb92d 100644
--- a/src/test/test_routerkeys.c
+++ b/src/test/test_routerkeys.c
@@ -421,6 +421,7 @@ test_routerkeys_ed_keys_init_all(void *arg)
{
(void)arg;
char *dir = tor_strdup(get_fname("test_ed_keys_init_all"));
+ char *keydir = tor_strdup(get_fname("test_ed_keys_init_all/KEYS"));
or_options_t *options = tor_malloc_zero(sizeof(or_options_t));
time_t now = time(NULL);
ed25519_public_key_t id;
@@ -445,13 +446,14 @@ test_routerkeys_ed_keys_init_all(void *arg)
#ifdef _WIN32
mkdir(dir);
- mkdir(get_fname("test_ed_keys_init_all/keys"));
+ mkdir(keydir);
#else
mkdir(dir, 0700);
- mkdir(get_fname("test_ed_keys_init_all/keys"), 0700);
+ mkdir(keydir, 0700);
#endif /* defined(_WIN32) */
options->DataDirectory = dir;
+ options->KeyDirectory = keydir;
tt_int_op(1, OP_EQ, load_ed_keys(options, now));
tt_int_op(0, OP_EQ, generate_ed_link_cert(options, now, 0));
@@ -521,7 +523,7 @@ test_routerkeys_ed_keys_init_all(void *arg)
/* Demonstrate that we can start up with no secret identity key */
routerkeys_free_all();
- unlink(get_fname("test_ed_keys_init_all/keys/"
+ unlink(get_fname("test_ed_keys_init_all/KEYS/"
"ed25519_master_id_secret_key"));
tt_int_op(1, OP_EQ, load_ed_keys(options, now));
tt_int_op(0, OP_EQ, generate_ed_link_cert(options, now, 0));
@@ -542,6 +544,7 @@ test_routerkeys_ed_keys_init_all(void *arg)
done:
tor_free(dir);
+ tor_free(keydir);
tor_free(options);
tor_cert_free(link_cert);
routerkeys_free_all();
diff --git a/src/test/test_routerlist.c b/src/test/test_routerlist.c
index 3b0e943ce5..c19d66ef9d 100644
--- a/src/test/test_routerlist.c
+++ b/src/test/test_routerlist.c
@@ -5,7 +5,11 @@
#include <math.h>
#include <time.h>
+#define CONNECTION_PRIVATE
+#define DIRECTORY_PRIVATE
#define DIRVOTE_PRIVATE
+#define ENTRYNODES_PRIVATE
+#define HIBERNATE_PRIVATE
#define NETWORKSTATUS_PRIVATE
#define ROUTERLIST_PRIVATE
#define TOR_UNIT_TESTING
@@ -13,19 +17,24 @@
#include "config.h"
#include "connection.h"
#include "container.h"
+#include "control.h"
#include "directory.h"
#include "dirvote.h"
#include "entrynodes.h"
+#include "hibernate.h"
#include "microdesc.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "policies.h"
#include "router.h"
#include "routerlist.h"
+#include "routerset.h"
#include "routerparse.h"
#include "shared_random.h"
+#include "statefile.h"
#include "test.h"
#include "test_dir_common.h"
+#include "log_test_helpers.h"
void construct_consensus(char **consensus_text_md);
@@ -411,6 +420,111 @@ test_router_pick_directory_server_impl(void *arg)
networkstatus_vote_free(con_md);
}
+static or_state_t *dummy_state = NULL;
+static or_state_t *
+get_or_state_replacement(void)
+{
+ return dummy_state;
+}
+
+static void
+mock_directory_initiate_request(directory_request_t *req)
+{
+ (void)req;
+ return;
+}
+
+static circuit_guard_state_t *
+mock_circuit_guard_state_new(entry_guard_t *guard, unsigned state,
+ entry_guard_restriction_t *rst)
+{
+ (void) guard;
+ (void) state;
+ (void) rst;
+ return NULL;
+}
+
+/** Test that we will use our directory guards to fetch mds even if we don't
+ * have any dirinfo (tests bug #23862). */
+static void
+test_directory_guard_fetch_with_no_dirinfo(void *arg)
+{
+ int retval;
+ char *consensus_text_md = NULL;
+ or_options_t *options = get_options_mutable();
+
+ (void) arg;
+
+ hibernate_set_state_for_testing_(HIBERNATE_STATE_LIVE);
+
+ /* Initialize the SRV subsystem */
+ MOCK(get_my_v3_authority_cert, get_my_v3_authority_cert_m);
+ mock_cert = authority_cert_parse_from_string(AUTHORITY_CERT_1, NULL);
+ sr_init(0);
+ UNMOCK(get_my_v3_authority_cert);
+
+ /* Initialize the entry node configuration from the ticket */
+ options->UseEntryGuards = 1;
+ options->StrictNodes = 1;
+ get_options_mutable()->EntryNodes = routerset_new();
+ routerset_parse(get_options_mutable()->EntryNodes,
+ "2121212121212121212121212121212121212121", "foo");
+
+ /* Mock some functions */
+ dummy_state = tor_malloc_zero(sizeof(or_state_t));
+ MOCK(get_or_state, get_or_state_replacement);
+ MOCK(directory_initiate_request, mock_directory_initiate_request);
+ /* we need to mock this one to avoid memleaks */
+ MOCK(circuit_guard_state_new, mock_circuit_guard_state_new);
+
+ /* Call guards_update_all() to simulate loading our state file (see
+ * entry_guards_load_guards_from_state() and ticket #23989). */
+ guards_update_all();
+
+ /* Test logic: Simulate the arrival of a new consensus when we have no
+ * dirinfo at all. Tor will need to fetch the mds from the consensus. Make
+ * sure that Tor will use the specified entry guard instead of relying on the
+ * fallback directories. */
+
+ /* Fixup the dirconn that will deliver the consensus */
+ dir_connection_t *conn = dir_connection_new(AF_INET);
+ tor_addr_from_ipv4h(&conn->base_.addr, 0x7f000001);
+ conn->base_.port = 8800;
+ TO_CONN(conn)->address = tor_strdup("127.0.0.1");
+ conn->base_.purpose = DIR_PURPOSE_FETCH_CONSENSUS;
+ conn->requested_resource = tor_strdup("ns");
+
+ /* Construct a consensus */
+ construct_consensus(&consensus_text_md);
+ tt_assert(consensus_text_md);
+
+ /* Place the consensus in the dirconn */
+ response_handler_args_t args;
+ memset(&args, 0, sizeof(response_handler_args_t));
+ args.status_code = 200;
+ args.body = consensus_text_md;
+ args.body_len = strlen(consensus_text_md);
+
+ /* Update approx time so that the consensus is considered live */
+ update_approx_time(time(NULL)+1010);
+
+ setup_capture_of_logs(LOG_DEBUG);
+
+ /* Now handle the consensus */
+ retval = handle_response_fetch_consensus(conn, &args);
+ tt_int_op(retval, OP_EQ, 0);
+
+ /* Make sure that our primary guard was chosen */
+ expect_log_msg_containing("Selected primary guard router3");
+
+ done:
+ tor_free(consensus_text_md);
+ tor_free(dummy_state);
+ connection_free_minimal(TO_CONN(conn));
+ entry_guards_free_all();
+ teardown_capture_of_logs();
+}
+
static connection_t *mocked_connection = NULL;
/* Mock connection_get_by_type_addr_port_purpose by returning
@@ -494,6 +608,8 @@ struct testcase_t routerlist_tests[] = {
NODE(launch_descriptor_downloads, 0),
NODE(router_is_already_dir_fetching, TT_FORK),
ROUTER(pick_directory_server_impl, TT_FORK),
+ { "directory_guard_fetch_with_no_dirinfo",
+ test_directory_guard_fetch_with_no_dirinfo, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_routerset.c b/src/test/test_routerset.c
index c9c69911da..c541324674 100644
--- a/src/test/test_routerset.c
+++ b/src/test/test_routerset.c
@@ -1,3 +1,6 @@
+/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
#define ROUTERSET_PRIVATE
#include "or.h"
@@ -696,7 +699,7 @@ NS(test_main)(void *arg)
static void
NS(test_main)(void *arg)
{
- const routerset_t *set;
+ routerset_t *set;
int needs_geoip;
(void)arg;
@@ -706,14 +709,14 @@ NS(test_main)(void *arg)
set = routerset_new();
needs_geoip = routerset_needs_geoip(set);
- routerset_free((routerset_t *)set);
+ routerset_free(set);
tt_int_op(needs_geoip, OP_EQ, 0);
set = NULL;
set = routerset_new();
smartlist_add(set->country_names, tor_strndup("xx", 2));
needs_geoip = routerset_needs_geoip(set);
- routerset_free((routerset_t *)set);
+ routerset_free(set);
set = NULL;
tt_int_op(needs_geoip, OP_NE, 0);
@@ -1944,7 +1947,7 @@ NS(test_main)(void *arg)
done:
tor_free(s);
- routerset_free((routerset_t *)set);
+ routerset_free(set);
}
#undef NS_SUBMODULE
@@ -2081,28 +2084,28 @@ NS(test_main)(void *arg)
* Structural test for routerset_free, where the routerset is NULL.
*/
-NS_DECL(void, smartlist_free, (smartlist_t *sl));
+NS_DECL(void, smartlist_free_, (smartlist_t *sl));
static void
NS(test_main)(void *arg)
{
(void)arg;
- NS_MOCK(smartlist_free);
+ NS_MOCK(smartlist_free_);
- routerset_free(NULL);
+ routerset_free_(NULL);
- tt_int_op(CALLED(smartlist_free), OP_EQ, 0);
+ tt_int_op(CALLED(smartlist_free_), OP_EQ, 0);
done:
;
}
void
-NS(smartlist_free)(smartlist_t *s)
+NS(smartlist_free_)(smartlist_t *s)
{
(void)s;
- CALLED(smartlist_free)++;
+ CALLED(smartlist_free_)++;
}
#undef NS_SUBMODULE
@@ -2112,9 +2115,9 @@ NS(smartlist_free)(smartlist_t *s)
* Structural test for routerset_free.
*/
-NS_DECL(void, smartlist_free, (smartlist_t *sl));
-NS_DECL(void, strmap_free,(strmap_t *map, void (*free_val)(void*)));
-NS_DECL(void, digestmap_free, (digestmap_t *map, void (*free_val)(void*)));
+NS_DECL(void, smartlist_free_, (smartlist_t *sl));
+NS_DECL(void, strmap_free_,(strmap_t *map, void (*free_val)(void*)));
+NS_DECL(void, digestmap_free_, (digestmap_t *map, void (*free_val)(void*)));
static void
NS(test_main)(void *arg)
@@ -2122,39 +2125,39 @@ NS(test_main)(void *arg)
routerset_t *routerset = routerset_new();
(void)arg;
- NS_MOCK(smartlist_free);
- NS_MOCK(strmap_free);
- NS_MOCK(digestmap_free);
+ NS_MOCK(smartlist_free_);
+ NS_MOCK(strmap_free_);
+ NS_MOCK(digestmap_free_);
routerset_free(routerset);
- tt_int_op(CALLED(smartlist_free), OP_NE, 0);
- tt_int_op(CALLED(strmap_free), OP_NE, 0);
- tt_int_op(CALLED(digestmap_free), OP_NE, 0);
+ tt_int_op(CALLED(smartlist_free_), OP_NE, 0);
+ tt_int_op(CALLED(strmap_free_), OP_NE, 0);
+ tt_int_op(CALLED(digestmap_free_), OP_NE, 0);
done:
;
}
void
-NS(smartlist_free)(smartlist_t *s)
+NS(smartlist_free_)(smartlist_t *s)
{
- CALLED(smartlist_free)++;
- smartlist_free__real(s);
+ CALLED(smartlist_free_)++;
+ smartlist_free___real(s);
}
void
-NS(strmap_free)(strmap_t *map, void (*free_val)(void*))
+NS(strmap_free_)(strmap_t *map, void (*free_val)(void*))
{
- CALLED(strmap_free)++;
- strmap_free__real(map, free_val);
+ CALLED(strmap_free_)++;
+ strmap_free___real(map, free_val);
}
void
-NS(digestmap_free)(digestmap_t *map, void (*free_val)(void*))
+NS(digestmap_free_)(digestmap_t *map, void (*free_val)(void*))
{
- CALLED(digestmap_free)++;
- digestmap_free__real(map, free_val);
+ CALLED(digestmap_free_)++;
+ digestmap_free___real(map, free_val);
}
#undef NS_SUBMODULE
diff --git a/src/test/test_rust.c b/src/test/test_rust.c
deleted file mode 100644
index 6ad57d6fcb..0000000000
--- a/src/test/test_rust.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Copyright (c) 2017, The Tor Project, Inc. */
-/* See LICENSE for licensing information */
-
-#include "orconfig.h"
-#include "compat_rust.h"
-#include "test.h"
-#include "util.h"
-
-static void
-test_welcome_string(void *arg)
-{
- (void)arg;
- rust_str_t s = rust_welcome_string();
- const char *c_str = rust_str_get(s);
- tt_assert(c_str);
- size_t len = strlen(c_str);
-#ifdef HAVE_RUST
- tt_assert(len > 0);
-#else
- tt_assert(len == 0);
-#endif
-
- done:
- rust_str_free(s);
-}
-
-struct testcase_t rust_tests[] = {
- { "welcome_string", test_welcome_string, 0, NULL, NULL },
- END_OF_TESTCASES
-};
-
diff --git a/src/test/test_rust.sh b/src/test/test_rust.sh
index d559f94ce0..133f2bb940 100755
--- a/src/test/test_rust.sh
+++ b/src/test/test_rust.sh
@@ -1,13 +1,20 @@
#!/bin/sh
-# Test all the Rust crates we're using
+# Test all Rust crates
-crates=tor_util
+crates="protover tor_util smartlist tor_allocate"
exitcode=0
+set -e
+
for crate in $crates; do
- cd "${abs_top_srcdir:-.}/src/rust/${crate}"
- CARGO_TARGET_DIR="${abs_top_builddir}/src/rust/target" CARGO_HOME="${abs_top_builddir}/src/rust" "${CARGO:-cargo}" test ${CARGO_ONLINE-"--frozen"} || exitcode=1
+ cd "${abs_top_builddir:-../../..}/src/rust"
+ CARGO_TARGET_DIR="${abs_top_builddir:-../../..}/src/rust/target" \
+ CARGO_HOME="${abs_top_builddir:-../../..}/src/rust" \
+ "${CARGO:-cargo}" test ${CARGO_ONLINE-"--frozen"} \
+ --manifest-path "${abs_top_srcdir:-.}/src/rust/${crate}/Cargo.toml" \
+ || exitcode=1
+ cd -
done
exit $exitcode
diff --git a/src/test/test_scheduler.c b/src/test/test_scheduler.c
index 63add2f382..0d8a9eaa1f 100644
--- a/src/test/test_scheduler.c
+++ b/src/test/test_scheduler.c
@@ -299,10 +299,6 @@ channel_more_to_flush_mock(channel_t *chan)
flush_mock_channel_t *found_mock_ch = NULL;
- /* Check if we have any queued */
- if (! TOR_SIMPLEQ_EMPTY(&chan->incoming_queue))
- return 1;
-
SMARTLIST_FOREACH_BEGIN(chans_for_flush_mock,
flush_mock_channel_t *,
flush_mock_ch) {
@@ -444,8 +440,6 @@ perform_channel_state_tests(int KISTSchedRunInterval, int sched_type)
/* Start it off in OPENING */
ch1->state = CHANNEL_STATE_OPENING;
- /* We'll need a cmux */
- ch1->cmux = circuitmux_alloc();
/* Try to register it */
channel_register(ch1);
tt_assert(ch1->registered);
@@ -457,7 +451,6 @@ perform_channel_state_tests(int KISTSchedRunInterval, int sched_type)
ch2 = new_fake_channel();
tt_assert(ch2);
ch2->state = CHANNEL_STATE_OPENING;
- ch2->cmux = circuitmux_alloc();
channel_register(ch2);
tt_assert(ch2->registered);
@@ -656,8 +649,6 @@ test_scheduler_loop_vanilla(void *arg)
/* Start it off in OPENING */
ch1->state = CHANNEL_STATE_OPENING;
- /* We'll need a cmux */
- ch1->cmux = circuitmux_alloc();
/* Try to register it */
channel_register(ch1);
tt_assert(ch1->registered);
@@ -672,7 +663,6 @@ test_scheduler_loop_vanilla(void *arg)
ch2->magic = TLS_CHAN_MAGIC;
tt_assert(ch2);
ch2->state = CHANNEL_STATE_OPENING;
- ch2->cmux = circuitmux_alloc();
channel_register(ch2);
tt_assert(ch2->registered);
/*
@@ -824,7 +814,6 @@ test_scheduler_loop_kist(void *arg)
tt_assert(ch1);
ch1->magic = TLS_CHAN_MAGIC;
ch1->state = CHANNEL_STATE_OPENING;
- ch1->cmux = circuitmux_alloc();
channel_register(ch1);
tt_assert(ch1->registered);
channel_change_state_open(ch1);
@@ -835,7 +824,6 @@ test_scheduler_loop_kist(void *arg)
tt_assert(ch2);
ch2->magic = TLS_CHAN_MAGIC;
ch2->state = CHANNEL_STATE_OPENING;
- ch2->cmux = circuitmux_alloc();
channel_register(ch2);
tt_assert(ch2->registered);
channel_change_state_open(ch2);
diff --git a/src/test/test_shared_random.c b/src/test/test_shared_random.c
index cac78baecf..96494904e3 100644
--- a/src/test/test_shared_random.c
+++ b/src/test/test_shared_random.c
@@ -1,3 +1,6 @@
+/* Copyright (c) 2016-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
#define SHARED_RANDOM_PRIVATE
#define SHARED_RANDOM_STATE_PRIVATE
#define CONFIG_PRIVATE
@@ -1348,7 +1351,7 @@ test_state_update(void *arg)
tt_assert(state->current_srv);
done:
- sr_state_free();
+ sr_state_free_all();
UNMOCK(get_my_v3_authority_cert);
}
diff --git a/src/test/test_status.c b/src/test/test_status.c
index f86f8e3b9e..50ea203e4d 100644
--- a/src/test/test_status.c
+++ b/src/test/test_status.c
@@ -1,3 +1,6 @@
+/* Copyright (c) 2014-2017, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
#define STATUS_PRIVATE
#define HIBERNATE_PRIVATE
#define LOG_PRIVATE
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 0519a4758f..1fd41a348a 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -5801,6 +5801,7 @@ test_util_monotonic_time(void *arg)
monotime_coarse_t mtc1, mtc2;
uint64_t nsec1, nsec2, usec1, msec1;
uint64_t nsecc1, nsecc2, usecc1, msecc1;
+ uint32_t stamp1, stamp2;
monotime_init();
@@ -5812,6 +5813,7 @@ test_util_monotonic_time(void *arg)
nsecc1 = monotime_coarse_absolute_nsec();
usecc1 = monotime_coarse_absolute_usec();
msecc1 = monotime_coarse_absolute_msec();
+ stamp1 = monotime_coarse_to_stamp(&mtc1);
tor_sleep_msec(200);
@@ -5819,6 +5821,7 @@ test_util_monotonic_time(void *arg)
monotime_coarse_get(&mtc2);
nsec2 = monotime_absolute_nsec();
nsecc2 = monotime_coarse_absolute_nsec();
+ stamp2 = monotime_coarse_to_stamp(&mtc2);
/* We need to be a little careful here since we don't know the system load.
*/
@@ -5840,6 +5843,11 @@ test_util_monotonic_time(void *arg)
tt_u64_op(msecc1, OP_LE, nsecc1 / 1000000 + 1);
tt_u64_op(usecc1, OP_LE, nsecc1 / 1000 + 1000);
+ uint64_t coarse_stamp_diff =
+ monotime_coarse_stamp_units_to_approx_msec(stamp2-stamp1);
+ tt_u64_op(coarse_stamp_diff, OP_GE, 120);
+ tt_u64_op(coarse_stamp_diff, OP_LE, 1200);
+
done:
;
}
@@ -5918,6 +5926,64 @@ test_util_monotonic_time_ratchet(void *arg)
}
static void
+test_util_monotonic_time_zero(void *arg)
+{
+ (void) arg;
+ monotime_t t1;
+ monotime_coarse_t ct1;
+ monotime_init();
+ /* Check 1: The current time is not zero. */
+ monotime_get(&t1);
+ monotime_coarse_get(&ct1);
+ tt_assert(!monotime_is_zero(&t1));
+ tt_assert(!monotime_coarse_is_zero(&ct1));
+
+ /* Check 2: The _zero() makes the time zero. */
+ monotime_zero(&t1);
+ monotime_coarse_zero(&ct1);
+ tt_assert(monotime_is_zero(&t1));
+ tt_assert(monotime_coarse_is_zero(&ct1));
+ done:
+ ;
+}
+
+static void
+test_util_monotonic_time_add_msec(void *arg)
+{
+ (void) arg;
+ monotime_t t1, t2;
+ monotime_coarse_t ct1, ct2;
+ monotime_init();
+
+ monotime_get(&t1);
+ monotime_coarse_get(&ct1);
+
+ /* adding zero does nothing */
+ monotime_add_msec(&t2, &t1, 0);
+ monotime_coarse_add_msec(&ct2, &ct1, 0);
+ tt_i64_op(monotime_diff_msec(&t1, &t2), OP_EQ, 0);
+ tt_i64_op(monotime_coarse_diff_msec(&ct1, &ct2), OP_EQ, 0);
+
+ /* Add 1337 msec; see if the diff function agree */
+ monotime_add_msec(&t2, &t1, 1337);
+ monotime_coarse_add_msec(&ct2, &ct1, 1337);
+ tt_i64_op(monotime_diff_msec(&t1, &t2), OP_EQ, 1337);
+ tt_i64_op(monotime_coarse_diff_msec(&ct1, &ct2), OP_EQ, 1337);
+
+ /* Add 1337 msec twice more; make sure that any second rollover issues
+ * worked. */
+ monotime_add_msec(&t2, &t2, 1337);
+ monotime_coarse_add_msec(&ct2, &ct2, 1337);
+ monotime_add_msec(&t2, &t2, 1337);
+ monotime_coarse_add_msec(&ct2, &ct2, 1337);
+ tt_i64_op(monotime_diff_msec(&t1, &t2), OP_EQ, 1337*3);
+ tt_i64_op(monotime_coarse_diff_msec(&ct1, &ct2), OP_EQ, 1337*3);
+
+ done:
+ ;
+}
+
+static void
test_util_htonll(void *arg)
{
(void)arg;
@@ -6150,6 +6216,8 @@ struct testcase_t util_tests[] = {
UTIL_TEST(calloc_check, 0),
UTIL_TEST(monotonic_time, 0),
UTIL_TEST(monotonic_time_ratchet, TT_FORK),
+ UTIL_TEST(monotonic_time_zero, 0),
+ UTIL_TEST(monotonic_time_add_msec, 0),
UTIL_TEST(htonll, 0),
UTIL_TEST(get_unquoted_path, 0),
END_OF_TESTCASES
diff --git a/src/test/testing_common.c b/src/test/testing_common.c
index 7e9c47b48d..142c681079 100644
--- a/src/test/testing_common.c
+++ b/src/test/testing_common.c
@@ -3,12 +3,6 @@
* Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-extern const char tor_git_revision[];
-
-/* Ordinarily defined in tor_main.c; this bit is just here to provide one
- * since we're not linking to tor_main.c */
-const char tor_git_revision[] = "";
-
/**
* \file test_common.c
* \brief Common pieces to implement unit tests.
@@ -299,6 +293,9 @@ main(int c, const char **v)
setup_directory();
options_init(options);
options->DataDirectory = tor_strdup(temp_dir);
+ tor_asprintf(&options->KeyDirectory, "%s"PATH_SEPARATOR"keys",
+ options->DataDirectory);
+ options->CacheDirectory = tor_strdup(temp_dir);
options->EntryStatistics = 1;
if (set_options(options, &errmsg) < 0) {
printf("Failed to set initial options: %s\n", errmsg);