summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/fuzz/fuzz_consensus.c6
-rw-r--r--src/test/fuzz/fuzz_descriptor.c10
-rw-r--r--src/test/fuzz/fuzz_extrainfo.c6
-rw-r--r--src/test/fuzz/fuzz_hsdescv2.c4
-rw-r--r--src/test/fuzz/fuzz_hsdescv3.c3
-rw-r--r--src/test/fuzz/fuzz_http.c5
-rw-r--r--src/test/fuzz/fuzz_iptsv2.c5
-rw-r--r--src/test/fuzz/fuzz_microdesc.c5
-rw-r--r--src/test/fuzz/fuzz_vrs.c5
-rw-r--r--src/test/hs_test_helpers.c6
-rw-r--r--src/test/include.am7
-rw-r--r--src/test/test.c29
-rw-r--r--src/test/test.h33
-rw-r--r--src/test/test_addr.c56
-rw-r--r--src/test/test_bridges.c93
-rw-r--r--src/test/test_cell_formats.c2
-rw-r--r--src/test/test_channelpadding.c4
-rw-r--r--src/test/test_circuitmux.c13
-rw-r--r--src/test/test_config.c6
-rw-r--r--src/test/test_connection.c6
-rw-r--r--src/test/test_consdiffmgr.c2
-rw-r--r--src/test/test_controller.c2
-rw-r--r--src/test/test_controller_events.c68
-rw-r--r--src/test/test_dir.c72
-rw-r--r--src/test/test_dir_common.c2
-rw-r--r--src/test/test_dir_common.h1
-rw-r--r--src/test/test_dir_handle_get.c11
-rw-r--r--src/test/test_dns.c66
-rw-r--r--src/test/test_dos.c3
-rw-r--r--src/test/test_entrynodes.c6
-rw-r--r--src/test/test_extorport.c23
-rw-r--r--src/test/test_geoip.c17
-rw-r--r--src/test/test_guardfraction.c9
-rw-r--r--src/test/test_helpers.c25
-rw-r--r--src/test/test_helpers.h3
-rw-r--r--src/test/test_hs_cache.c6
-rw-r--r--src/test/test_hs_client.c226
-rw-r--r--src/test/test_hs_common.c2
-rw-r--r--src/test/test_hs_config.c16
-rw-r--r--src/test/test_hs_descriptor.c6
-rw-r--r--src/test/test_hs_service.c140
-rw-r--r--src/test/test_link_handshake.c14
-rw-r--r--src/test/test_mainloop.c2
-rw-r--r--src/test/test_microdesc.c5
-rw-r--r--src/test/test_nodelist.c36
-rw-r--r--src/test/test_oos.c4
-rw-r--r--src/test/test_options.c4
-rw-r--r--src/test/test_parsecommon.c594
-rw-r--r--src/test/test_periodic_event.c12
-rw-r--r--src/test/test_policy.c11
-rw-r--r--src/test/test_protover.c39
-rw-r--r--src/test/test_rebind.py93
-rwxr-xr-xsrc/test/test_rebind.sh19
-rw-r--r--src/test/test_relay.c115
-rw-r--r--src/test/test_relaycell.c642
-rw-r--r--src/test/test_router.c2
-rw-r--r--src/test/test_routerkeys.c1
-rw-r--r--src/test/test_routerlist.c11
-rw-r--r--src/test/test_routerset.c9
-rwxr-xr-xsrc/test/test_rust.sh9
-rw-r--r--src/test/test_shared_random.c5
-rw-r--r--src/test/test_status.c3
-rw-r--r--src/test/test_storagedir.c2
-rw-r--r--src/test/test_threads.c30
-rw-r--r--src/test/test_tortls.c1
-rw-r--r--src/test/test_tortls_openssl.c45
-rw-r--r--src/test/test_util.c61
-rw-r--r--src/test/test_workqueue.c2
-rw-r--r--src/test/testing_common.c5
69 files changed, 2502 insertions, 284 deletions
diff --git a/src/test/fuzz/fuzz_consensus.c b/src/test/fuzz/fuzz_consensus.c
index 5a04683a11..1a4195b418 100644
--- a/src/test/fuzz/fuzz_consensus.c
+++ b/src/test/fuzz/fuzz_consensus.c
@@ -1,8 +1,10 @@
/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
+#define SIGCOMMON_PRIVATE
#include "core/or/or.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/dirparse/ns_parse.h"
+#include "feature/dirparse/sigcommon.h"
+#include "feature/dirparse/unparseable.h"
#include "feature/nodelist/networkstatus.h"
#include "lib/crypt_ops/crypto_ed25519.h"
#include "feature/nodelist/networkstatus_st.h"
diff --git a/src/test/fuzz/fuzz_descriptor.c b/src/test/fuzz/fuzz_descriptor.c
index 5a56f4081a..3420113717 100644
--- a/src/test/fuzz/fuzz_descriptor.c
+++ b/src/test/fuzz/fuzz_descriptor.c
@@ -1,10 +1,13 @@
/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
+#define SIGCOMMON_PRIVATE
#include "core/or/or.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/dirparse/routerparse.h"
+#include "feature/dirparse/sigcommon.h"
+#include "feature/dirparse/unparseable.h"
#include "feature/nodelist/routerlist.h"
-#include "feature/relay/routerkeys.h"
+#include "feature/nodelist/torcert.h"
+#include "feature/keymgt/loadkey.h"
#include "test/fuzz/fuzzing.h"
static int
@@ -76,4 +79,3 @@ fuzz_main(const uint8_t *data, size_t sz)
}
return 0;
}
-
diff --git a/src/test/fuzz/fuzz_extrainfo.c b/src/test/fuzz/fuzz_extrainfo.c
index 6c88f80122..da0fe80838 100644
--- a/src/test/fuzz/fuzz_extrainfo.c
+++ b/src/test/fuzz/fuzz_extrainfo.c
@@ -1,8 +1,10 @@
/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
+#define SIGCOMMON_PRIVATE
#include "core/or/or.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/dirparse/routerparse.h"
+#include "feature/dirparse/sigcommon.h"
+#include "feature/dirparse/unparseable.h"
#include "feature/nodelist/routerlist.h"
#include "feature/relay/routerkeys.h"
#include "test/fuzz/fuzzing.h"
diff --git a/src/test/fuzz/fuzz_hsdescv2.c b/src/test/fuzz/fuzz_hsdescv2.c
index fd5da41635..667b58b3aa 100644
--- a/src/test/fuzz/fuzz_hsdescv2.c
+++ b/src/test/fuzz/fuzz_hsdescv2.c
@@ -1,9 +1,9 @@
/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
#include "core/or/or.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/dirparse/unparseable.h"
#include "feature/rend/rendcommon.h"
+#include "feature/rend/rendparse.h"
#include "lib/crypt_ops/crypto_ed25519.h"
#include "test/fuzz/fuzzing.h"
diff --git a/src/test/fuzz/fuzz_hsdescv3.c b/src/test/fuzz/fuzz_hsdescv3.c
index b332973b39..d5ddcc2e27 100644
--- a/src/test/fuzz/fuzz_hsdescv3.c
+++ b/src/test/fuzz/fuzz_hsdescv3.c
@@ -1,14 +1,13 @@
/* Copyright (c) 2017-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
#define HS_DESCRIPTOR_PRIVATE
#include "core/or/or.h"
#include "trunnel/ed25519_cert.h" /* Trunnel interface. */
#include "lib/crypt_ops/crypto_ed25519.h"
#include "feature/hs/hs_descriptor.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/dirparse/unparseable.h"
#include "test/fuzz/fuzzing.h"
diff --git a/src/test/fuzz/fuzz_http.c b/src/test/fuzz/fuzz_http.c
index 2fbb275614..06483282bc 100644
--- a/src/test/fuzz/fuzz_http.c
+++ b/src/test/fuzz/fuzz_http.c
@@ -4,14 +4,14 @@
#include "orconfig.h"
#define BUFFERS_PRIVATE
-#define DIRECTORY_PRIVATE
+#define DIRCACHE_PRIVATE
#include "core/or/or.h"
#include "lib/err/backtrace.h"
#include "lib/container/buffers.h"
#include "app/config/config.h"
#include "core/mainloop/connection.h"
-#include "feature/dircache/directory.h"
+#include "feature/dircache/dircache.h"
#include "lib/log/log.h"
#include "feature/dircommon/dir_connection_st.h"
@@ -132,4 +132,3 @@ fuzz_main(const uint8_t *stdin_buf, size_t data_size)
return 0;
}
-
diff --git a/src/test/fuzz/fuzz_iptsv2.c b/src/test/fuzz/fuzz_iptsv2.c
index a3082f4d0e..265677eebe 100644
--- a/src/test/fuzz/fuzz_iptsv2.c
+++ b/src/test/fuzz/fuzz_iptsv2.c
@@ -1,9 +1,10 @@
/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
+
#include "core/or/or.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/dirparse/unparseable.h"
#include "feature/rend/rendcommon.h"
+#include "feature/rend/rendparse.h"
#include "lib/crypt_ops/crypto_ed25519.h"
#include "feature/rend/rend_service_descriptor_st.h"
diff --git a/src/test/fuzz/fuzz_microdesc.c b/src/test/fuzz/fuzz_microdesc.c
index fa9676372d..ab54cf2a34 100644
--- a/src/test/fuzz/fuzz_microdesc.c
+++ b/src/test/fuzz/fuzz_microdesc.c
@@ -1,8 +1,9 @@
/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
+
#include "core/or/or.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/dirparse/microdesc_parse.h"
+#include "feature/dirparse/unparseable.h"
#include "feature/nodelist/microdesc.h"
#include "lib/crypt_ops/crypto_ed25519.h"
diff --git a/src/test/fuzz/fuzz_vrs.c b/src/test/fuzz/fuzz_vrs.c
index 5665ffeaca..3c6d205a3f 100644
--- a/src/test/fuzz/fuzz_vrs.c
+++ b/src/test/fuzz/fuzz_vrs.c
@@ -1,9 +1,10 @@
/* Copyright (c) 2016-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define ROUTERPARSE_PRIVATE
+#define NS_PARSE_PRIVATE
#define NETWORKSTATUS_PRIVATE
#include "core/or/or.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/dirparse/ns_parse.h"
+#include "feature/dirparse/unparseable.h"
#include "lib/memarea/memarea.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
diff --git a/src/test/hs_test_helpers.c b/src/test/hs_test_helpers.c
index 4e13ba43a7..dcec1b9d48 100644
--- a/src/test/hs_test_helpers.c
+++ b/src/test/hs_test_helpers.c
@@ -241,11 +241,11 @@ hs_helper_desc_equal(const hs_descriptor_t *desc1,
hs_desc_authorized_client_t
*client1 = smartlist_get(desc1->superencrypted_data.clients, i),
*client2 = smartlist_get(desc2->superencrypted_data.clients, i);
- tor_memeq(client1->client_id, client2->client_id,
+ tt_mem_op(client1->client_id, OP_EQ, client2->client_id,
sizeof(client1->client_id));
- tor_memeq(client1->iv, client2->iv,
+ tt_mem_op(client1->iv, OP_EQ, client2->iv,
sizeof(client1->iv));
- tor_memeq(client1->encrypted_cookie, client2->encrypted_cookie,
+ tt_mem_op(client1->encrypted_cookie, OP_EQ, client2->encrypted_cookie,
sizeof(client1->encrypted_cookie));
}
}
diff --git a/src/test/include.am b/src/test/include.am
index c54605383c..e5eae56e25 100644
--- a/src/test/include.am
+++ b/src/test/include.am
@@ -12,8 +12,7 @@ TESTS_ENVIRONMENT = \
export EXTRA_CARGO_OPTIONS="$(EXTRA_CARGO_OPTIONS)"; \
export CARGO_ONLINE="$(CARGO_ONLINE)"; \
export CCLD="$(CCLD)"; \
- chmod +x "$(abs_top_builddir)/link_rust.sh"; \
- export RUSTFLAGS="-C linker=$(abs_top_builddir)/link_rust.sh";
+ export RUSTFLAGS="-C linker=`echo '$(CC)' | cut -d' ' -f 1` $(RUST_LINKER_OPTIONS)";
TESTSCRIPTS = \
src/test/fuzz_static_testcases.sh \
@@ -33,6 +32,7 @@ endif
if USEPYTHON
TESTSCRIPTS += src/test/test_ntor.sh src/test/test_hs_ntor.sh src/test/test_bt.sh
+TESTSCRIPTS += src/test/test_rebind.sh
endif
TESTS += src/test/test src/test/test-slow src/test/test-memwipe \
@@ -181,6 +181,7 @@ src_test_test_SOURCES += \
src/test/test_x509.c \
src/test/test_helpers.c \
src/test/test_dns.c \
+ src/test/test_parsecommon.c \
src/test/testing_common.c \
src/test/testing_rsakeys.c \
src/ext/tinytest.c
@@ -353,6 +354,8 @@ EXTRA_DIST += \
src/test/hs_indexes.py \
src/test/fuzz_static_testcases.sh \
src/test/slownacl_curve25519.py \
+ src/test/test_rebind.sh \
+ src/test/test_rebind.py \
src/test/zero_length_keys.sh \
src/test/rust_supp.txt \
src/test/test_keygen.sh \
diff --git a/src/test/test.c b/src/test/test.c
index dc8e3bede3..17b736d305 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -11,7 +11,6 @@
#include "orconfig.h"
#include "lib/crypt_ops/crypto_dh.h"
#include "lib/crypt_ops/crypto_rand.h"
-
#include "app/config/or_state_st.h"
#include <stdio.h>
@@ -33,7 +32,7 @@
#define ROUTER_PRIVATE
#define CIRCUITSTATS_PRIVATE
#define CIRCUITLIST_PRIVATE
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#define STATEFILE_PRIVATE
#include "core/or/or.h"
@@ -46,16 +45,16 @@
#include "core/or/connection_edge.h"
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendcache.h"
+#include "feature/rend/rendparse.h"
#include "test/test.h"
-#include "core/mainloop/main.h"
+#include "core/mainloop/mainloop.h"
#include "lib/memarea/memarea.h"
-#include "core/crypto/onion.h"
+#include "core/or/onion.h"
#include "core/crypto/onion_ntor.h"
#include "core/crypto/onion_fast.h"
#include "core/crypto/onion_tap.h"
#include "core/or/policies.h"
#include "feature/stats/rephist.h"
-#include "feature/nodelist/routerparse.h"
#include "app/config/statefile.h"
#include "lib/crypt_ops/crypto_curve25519.h"
@@ -64,6 +63,7 @@
#include "feature/rend/rend_encoded_v2_service_descriptor_st.h"
#include "feature/rend/rend_intro_point_st.h"
#include "feature/rend/rend_service_descriptor_st.h"
+#include "feature/relay/onion_queue.h"
/** Run unit tests for the onion handshake code. */
static void
@@ -847,8 +847,8 @@ struct testgroup_t testgroups[] = {
{ "circuitbuild/", circuitbuild_tests },
{ "circuitlist/", circuitlist_tests },
{ "circuitmux/", circuitmux_tests },
- { "circuituse/", circuituse_tests },
{ "circuitstats/", circuitstats_tests },
+ { "circuituse/", circuituse_tests },
{ "compat/libevent/", compat_libevent_tests },
{ "config/", config_tests },
{ "connection/", connection_tests },
@@ -865,34 +865,36 @@ struct testgroup_t testgroups[] = {
#endif
{ "crypto/pem/", pem_tests },
{ "dir/", dir_tests },
- { "dir_handle_get/", dir_handle_get_tests },
{ "dir/md/", microdesc_tests },
{ "dir/voting-schedule/", voting_schedule_tests },
+ { "dir_handle_get/", dir_handle_get_tests },
+ { "dns/", dns_tests },
{ "dos/", dos_tests },
{ "entryconn/", entryconn_tests },
{ "entrynodes/", entrynodes_tests },
- { "guardfraction/", guardfraction_tests },
{ "extorport/", extorport_tests },
{ "geoip/", geoip_tests },
- { "legacy_hs/", hs_tests },
+ { "guardfraction/", guardfraction_tests },
{ "hs_cache/", hs_cache },
{ "hs_cell/", hs_cell_tests },
+ { "hs_client/", hs_client_tests },
{ "hs_common/", hs_common_tests },
{ "hs_config/", hs_config_tests },
{ "hs_control/", hs_control_tests },
{ "hs_descriptor/", hs_descriptor },
+ { "hs_intropoint/", hs_intropoint_tests },
{ "hs_ntor/", hs_ntor_tests },
{ "hs_service/", hs_service_tests },
- { "hs_client/", hs_client_tests },
- { "hs_intropoint/", hs_intropoint_tests },
{ "introduce/", introduce_tests },
{ "keypin/", keypin_tests },
+ { "legacy_hs/", hs_tests },
{ "link-handshake/", link_handshake_tests },
{ "mainloop/", mainloop_tests },
{ "nodelist/", nodelist_tests },
{ "oom/", oom_tests },
{ "oos/", oos_tests },
{ "options/", options_tests },
+ { "parsecommon/", parsecommon_tests },
{ "periodic-event/" , periodic_event_tests },
{ "policy/" , policy_tests },
{ "procmon/", procmon_tests },
@@ -910,8 +912,8 @@ struct testgroup_t testgroups[] = {
{ "routerlist/", routerlist_tests },
{ "routerset/" , routerset_tests },
{ "scheduler/", scheduler_tests },
- { "socks/", socks_tests },
{ "shared-random/", sr_tests },
+ { "socks/", socks_tests },
{ "status/" , status_tests },
{ "storagedir/", storagedir_tests },
{ "tortls/", tortls_tests },
@@ -921,10 +923,9 @@ struct testgroup_t testgroups[] = {
{ "tortls/x509/", x509_tests },
{ "util/", util_tests },
{ "util/format/", util_format_tests },
+ { "util/handle/", handle_tests },
{ "util/logging/", logging_tests },
{ "util/process/", util_process_tests },
{ "util/thread/", thread_tests },
- { "util/handle/", handle_tests },
- { "dns/", dns_tests },
END_OF_GROUPS
};
diff --git a/src/test/test.h b/src/test/test.h
index a46fedf3e0..092356f0fb 100644
--- a/src/test/test.h
+++ b/src/test/test.h
@@ -177,11 +177,11 @@ extern const struct testcase_setup_t ed25519_test_setup;
extern struct testcase_t accounting_tests[];
extern struct testcase_t addr_tests[];
-extern struct testcase_t address_tests[];
extern struct testcase_t address_set_tests[];
+extern struct testcase_t address_tests[];
extern struct testcase_t bridges_tests[];
-extern struct testcase_t bwmgt_tests[];
extern struct testcase_t buffer_tests[];
+extern struct testcase_t bwmgt_tests[];
extern struct testcase_t cell_format_tests[];
extern struct testcase_t cell_queue_tests[];
extern struct testcase_t channel_tests[];
@@ -191,8 +191,8 @@ extern struct testcase_t checkdir_tests[];
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 circuituse_tests[];
extern struct testcase_t compat_libevent_tests[];
extern struct testcase_t config_tests[];
extern struct testcase_t connection_tests[];
@@ -200,30 +200,32 @@ extern struct testcase_t conscache_tests[];
extern struct testcase_t consdiff_tests[];
extern struct testcase_t consdiffmgr_tests[];
extern struct testcase_t container_tests[];
-extern struct testcase_t controller_tests[];
extern struct testcase_t controller_event_tests[];
-extern struct testcase_t crypto_tests[];
+extern struct testcase_t controller_tests[];
extern struct testcase_t crypto_ope_tests[];
extern struct testcase_t crypto_openssl_tests[];
-extern struct testcase_t dir_tests[];
+extern struct testcase_t crypto_tests[];
extern struct testcase_t dir_handle_get_tests[];
+extern struct testcase_t dir_tests[];
+extern struct testcase_t dns_tests[];
extern struct testcase_t dos_tests[];
extern struct testcase_t entryconn_tests[];
extern struct testcase_t entrynodes_tests[];
-extern struct testcase_t guardfraction_tests[];
extern struct testcase_t extorport_tests[];
extern struct testcase_t geoip_tests[];
-extern struct testcase_t hs_tests[];
+extern struct testcase_t guardfraction_tests[];
+extern struct testcase_t handle_tests[];
extern struct testcase_t hs_cache[];
extern struct testcase_t hs_cell_tests[];
+extern struct testcase_t hs_client_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_intropoint_tests[];
extern struct testcase_t hs_ntor_tests[];
extern struct testcase_t hs_service_tests[];
-extern struct testcase_t hs_client_tests[];
-extern struct testcase_t hs_intropoint_tests[];
+extern struct testcase_t hs_tests[];
extern struct testcase_t introduce_tests[];
extern struct testcase_t keypin_tests[];
extern struct testcase_t link_handshake_tests[];
@@ -234,6 +236,7 @@ extern struct testcase_t nodelist_tests[];
extern struct testcase_t oom_tests[];
extern struct testcase_t oos_tests[];
extern struct testcase_t options_tests[];
+extern struct testcase_t parsecommon_tests[];
extern struct testcase_t pem_tests[];
extern struct testcase_t periodic_event_tests[];
extern struct testcase_t policy_tests[];
@@ -252,19 +255,17 @@ extern struct testcase_t routerkeys_tests[];
extern struct testcase_t routerlist_tests[];
extern struct testcase_t routerset_tests[];
extern struct testcase_t scheduler_tests[];
-extern struct testcase_t storagedir_tests[];
extern struct testcase_t socks_tests[];
+extern struct testcase_t sr_tests[];
extern struct testcase_t status_tests[];
+extern struct testcase_t storagedir_tests[];
extern struct testcase_t thread_tests[];
-extern struct testcase_t tortls_tests[];
extern struct testcase_t tortls_openssl_tests[];
-extern struct testcase_t util_tests[];
+extern struct testcase_t tortls_tests[];
extern struct testcase_t util_format_tests[];
extern struct testcase_t util_process_tests[];
+extern struct testcase_t util_tests[];
extern struct testcase_t voting_schedule_tests[];
-extern struct testcase_t dns_tests[];
-extern struct testcase_t handle_tests[];
-extern struct testcase_t sr_tests[];
extern struct testcase_t x509_tests[];
extern struct testcase_t slow_crypto_tests[];
diff --git a/src/test/test_addr.c b/src/test/test_addr.c
index a9004048a5..1d97db52a6 100644
--- a/src/test/test_addr.c
+++ b/src/test/test_addr.c
@@ -723,7 +723,7 @@ test_addr_ip6_helpers(void *arg)
;
}
-/** Test tor_addr_port_parse(). */
+/** Test tor_addr_parse() and tor_addr_port_parse(). */
static void
test_addr_parse(void *arg)
{
@@ -734,6 +734,60 @@ test_addr_parse(void *arg)
/* Correct call. */
(void)arg;
+ r= tor_addr_parse(&addr, "192.0.2.1");
+ tt_int_op(r,OP_EQ, AF_INET);
+ tor_addr_to_str(buf, &addr, sizeof(buf), 0);
+ tt_str_op(buf,OP_EQ, "192.0.2.1");
+
+ r= tor_addr_parse(&addr, "11:22::33:44");
+ tt_int_op(r,OP_EQ, AF_INET6);
+ tor_addr_to_str(buf, &addr, sizeof(buf), 0);
+ tt_str_op(buf,OP_EQ, "11:22::33:44");
+
+ r= tor_addr_parse(&addr, "[11:22::33:44]");
+ tt_int_op(r,OP_EQ, AF_INET6);
+ tor_addr_to_str(buf, &addr, sizeof(buf), 0);
+ tt_str_op(buf,OP_EQ, "11:22::33:44");
+
+ r= tor_addr_parse(&addr, "11:22:33:44:55:66:1.2.3.4");
+ tt_int_op(r,OP_EQ, AF_INET6);
+ tor_addr_to_str(buf, &addr, sizeof(buf), 0);
+ tt_str_op(buf,OP_EQ, "11:22:33:44:55:66:102:304");
+
+ r= tor_addr_parse(&addr, "11:22::33:44:1.2.3.4");
+ tt_int_op(r,OP_EQ, AF_INET6);
+ tor_addr_to_str(buf, &addr, sizeof(buf), 0);
+ tt_str_op(buf,OP_EQ, "11:22::33:44:102:304");
+
+ /* Empty string. */
+ r= tor_addr_parse(&addr, "");
+ tt_int_op(r,OP_EQ, -1);
+
+ /* Square brackets around IPv4 address. */
+ r= tor_addr_parse(&addr, "[192.0.2.1]");
+ tt_int_op(r,OP_EQ, -1);
+
+ /* Only left square bracket. */
+ r= tor_addr_parse(&addr, "[11:22::33:44");
+ tt_int_op(r,OP_EQ, -1);
+
+ /* Only right square bracket. */
+ r= tor_addr_parse(&addr, "11:22::33:44]");
+ tt_int_op(r,OP_EQ, -1);
+
+ /* Leading colon. */
+ r= tor_addr_parse(&addr, ":11:22::33:44");
+ tt_int_op(r,OP_EQ, -1);
+
+ /* Trailing colon. */
+ r= tor_addr_parse(&addr, "11:22::33:44:");
+ tt_int_op(r,OP_EQ, -1);
+
+ /* Too many hex words in IPv4-mapped IPv6 address. */
+ r= tor_addr_parse(&addr, "11:22:33:44:55:66:77:88:1.2.3.4");
+ tt_int_op(r,OP_EQ, -1);
+
+ /* Correct call. */
r= tor_addr_port_parse(LOG_DEBUG,
"192.0.2.1:1234",
&addr, &port, -1);
diff --git a/src/test/test_bridges.c b/src/test/test_bridges.c
index 07d6b88ed9..1cad5445f4 100644
--- a/src/test/test_bridges.c
+++ b/src/test/test_bridges.c
@@ -16,6 +16,10 @@
#include "feature/client/bridges.h"
#include "app/config/config.h"
#include "feature/client/transports.h"
+#include "feature/nodelist/node_st.h"
+#include "feature/nodelist/routerinfo_st.h"
+#include "feature/nodelist/routerstatus_st.h"
+#include "feature/nodelist/microdesc_st.h"
/* Test suite stuff */
#include "test/test.h"
@@ -75,6 +79,7 @@ helper_add_bridges_to_bridgelist(void *arg)
char *bridge5 = tor_strdup("apple 4.4.4.4:4444 "
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "
"foo=abcdefghijklmnopqrstuvwxyz");
+ char *bridge6 = tor_strdup("[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:6666");
mark_bridge_list();
@@ -93,6 +98,7 @@ helper_add_bridges_to_bridgelist(void *arg)
ADD_BRIDGE(bridge3);
ADD_BRIDGE(bridge4);
ADD_BRIDGE(bridge5);
+ ADD_BRIDGE(bridge6);
#undef ADD_BRIDGES
sweep_bridge_list();
@@ -585,6 +591,92 @@ test_bridges_get_transport_by_bridge_addrport(void *arg)
sweep_bridge_list();
}
+static void
+test_bridges_node_is_a_configured_bridge(void *arg)
+{
+ routerinfo_t ri_ipv4 = { .addr = 0x06060606, .or_port = 6666 };
+ routerstatus_t rs_ipv4 = { .addr = 0x06060606, .or_port = 6666 };
+
+ routerinfo_t ri_ipv6 = { .ipv6_orport = 6666 };
+ tor_addr_parse(&(ri_ipv6.ipv6_addr),
+ "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
+
+ routerstatus_t rs_ipv6 = { .ipv6_orport = 6666 };
+ tor_addr_parse(&(rs_ipv6.ipv6_addr),
+ "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
+
+ microdesc_t md_ipv6 = { .ipv6_orport = 6666 };
+ tor_addr_parse(&(md_ipv6.ipv6_addr),
+ "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
+
+ helper_add_bridges_to_bridgelist(arg);
+
+ node_t node_with_digest;
+ memset(&node_with_digest, 0, sizeof(node_with_digest));
+
+ const char fingerprint[HEX_DIGEST_LEN] =
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+
+ const char fingerprint2[HEX_DIGEST_LEN] =
+ "ffffffffffffffffffffffffffffffffffffffff";
+
+ base16_decode(node_with_digest.identity, DIGEST_LEN,
+ fingerprint, HEX_DIGEST_LEN);
+
+ node_t node_ri_ipv4 = { .ri = &ri_ipv4 };
+ base16_decode(node_ri_ipv4.identity, DIGEST_LEN,
+ fingerprint2, HEX_DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_ri_ipv4));
+
+ /* This will still match bridge0, since bridge0 has no digest set. */
+ memset(node_ri_ipv4.identity, 0x3f, DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_ri_ipv4));
+
+ /* It won't match bridge1, though, since bridge1 has a digest, and this
+ isn't it! */
+ node_ri_ipv4.ri->addr = 0x06060607;
+ node_ri_ipv4.ri->or_port = 6667;
+ tt_assert(! node_is_a_configured_bridge(&node_ri_ipv4));
+ /* If we set the fingerprint right, though, it will match. */
+ base16_decode(node_ri_ipv4.identity, DIGEST_LEN,
+ "A10C4F666D27364036B562823E5830BC448E046A", HEX_DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_ri_ipv4));
+
+ node_t node_rs_ipv4 = { .rs = &rs_ipv4 };
+ base16_decode(node_rs_ipv4.identity, DIGEST_LEN,
+ fingerprint2, HEX_DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_rs_ipv4));
+
+ node_t node_ri_ipv6 = { .ri = &ri_ipv6 };
+ base16_decode(node_ri_ipv6.identity, DIGEST_LEN,
+ fingerprint2, HEX_DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_ri_ipv6));
+
+ node_t node_rs_ipv6 = { .rs = &rs_ipv6 };
+ base16_decode(node_rs_ipv6.identity, DIGEST_LEN,
+ fingerprint2, HEX_DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_rs_ipv6));
+
+ node_t node_md_ipv6 = { .md = &md_ipv6 };
+ base16_decode(node_md_ipv6.identity, DIGEST_LEN,
+ fingerprint2, HEX_DIGEST_LEN);
+ tt_assert(node_is_a_configured_bridge(&node_md_ipv6));
+
+ mark_bridge_list();
+ sweep_bridge_list();
+
+ tt_assert(!node_is_a_configured_bridge(&node_with_digest));
+ tt_assert(!node_is_a_configured_bridge(&node_ri_ipv4));
+ tt_assert(!node_is_a_configured_bridge(&node_ri_ipv6));
+ tt_assert(!node_is_a_configured_bridge(&node_rs_ipv4));
+ tt_assert(!node_is_a_configured_bridge(&node_rs_ipv6));
+ tt_assert(!node_is_a_configured_bridge(&node_md_ipv6));
+
+ done:
+ mark_bridge_list();
+ sweep_bridge_list();
+}
+
#undef PT_PRIVATE /* defined(PT_PRIVATE) */
#define B_TEST(name, flags) \
@@ -607,5 +699,6 @@ struct testcase_t bridges_tests[] = {
B_TEST(get_transport_by_bridge_addrport_no_ptlist, 0),
B_TEST(get_transport_by_bridge_addrport, 0),
B_TEST(transport_is_needed, 0),
+ B_TEST(node_is_a_configured_bridge, 0),
END_OF_TESTCASES
};
diff --git a/src/test/test_cell_formats.c b/src/test/test_cell_formats.c
index 2753c42191..daf0296e2a 100644
--- a/src/test/test_cell_formats.c
+++ b/src/test/test_cell_formats.c
@@ -13,7 +13,7 @@
#include "core/or/connection_or.h"
#include "app/config/config.h"
#include "lib/crypt_ops/crypto_rand.h"
-#include "core/crypto/onion.h"
+#include "core/or/onion.h"
#include "core/crypto/onion_tap.h"
#include "core/crypto/onion_fast.h"
#include "core/crypto/onion_ntor.h"
diff --git a/src/test/test_channelpadding.c b/src/test/test_channelpadding.c
index de673de543..0fd60d0a92 100644
--- a/src/test/test_channelpadding.c
+++ b/src/test/test_channelpadding.c
@@ -2,7 +2,7 @@
/* See LICENSE for licensing information */
#define TOR_CHANNEL_INTERNAL_
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#define NETWORKSTATUS_PRIVATE
#define TOR_TIMERS_PRIVATE
#include "core/or/or.h"
@@ -16,7 +16,7 @@
#include "lib/evloop/compat_libevent.h"
#include "app/config/config.h"
#include "lib/time/compat_time.h"
-#include "core/mainloop/main.h"
+#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "test/log_test_helpers.h"
#include "lib/tls/tortls.h"
diff --git a/src/test/test_circuitmux.c b/src/test/test_circuitmux.c
index 1d46f8de0d..1be2ff5281 100644
--- a/src/test/test_circuitmux.c
+++ b/src/test/test_circuitmux.c
@@ -15,6 +15,8 @@
#include "core/or/destroy_cell_queue_st.h"
+#include <math.h>
+
/* XXXX duplicated function from test_circuitlist.c */
static channel_t *
new_fake_channel(void)
@@ -105,16 +107,19 @@ test_cmux_compute_ticks(void *arg)
monotime_coarse_set_mock_time_nsec(now);
tick = cell_ewma_get_current_tick_and_fraction(&rem);
tt_uint_op(tick, OP_EQ, tick_zero);
- tt_double_op(rem, OP_GT, .149999999);
- tt_double_op(rem, OP_LT, .150000001);
+#ifdef USING_32BIT_MSEC_HACK
+ const double tolerance = .0005;
+#else
+ const double tolerance = .00000001;
+#endif
+ tt_double_op(fabs(rem - .15), OP_LT, tolerance);
/* 25 second later and we should be in another tick. */
now = START_NS + NS_PER_S * 25;
monotime_coarse_set_mock_time_nsec(now);
tick = cell_ewma_get_current_tick_and_fraction(&rem);
tt_uint_op(tick, OP_EQ, tick_zero + 2);
- tt_double_op(rem, OP_GT, .499999999);
- tt_double_op(rem, OP_LT, .500000001);
+ tt_double_op(fabs(rem - .5), OP_LT, tolerance);
done:
;
diff --git a/src/test/test_config.c b/src/test/test_config.c
index bf21a8d512..dae4d83766 100644
--- a/src/test/test_config.c
+++ b/src/test/test_config.c
@@ -29,15 +29,17 @@
#include "feature/client/entrynodes.h"
#include "feature/client/transports.h"
#include "feature/relay/ext_orport.h"
-#include "feature/stats/geoip.h"
+#include "lib/geoip/geoip.h"
#include "feature/hibernate/hibernate.h"
-#include "core/mainloop/main.h"
+#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/policies.h"
#include "feature/rend/rendclient.h"
#include "feature/rend/rendservice.h"
#include "feature/relay/router.h"
+#include "feature/relay/routermode.h"
+#include "feature/nodelist/dirlist.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerset.h"
#include "app/config/statefile.h"
diff --git a/src/test/test_connection.c b/src/test/test_connection.c
index e716c83fe1..0013f47fbc 100644
--- a/src/test/test_connection.c
+++ b/src/test/test_connection.c
@@ -4,7 +4,7 @@
#include "orconfig.h"
#define CONNECTION_PRIVATE
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#define CONNECTION_OR_PRIVATE
#include "core/or/or.h"
@@ -13,12 +13,12 @@
#include "core/mainloop/connection.h"
#include "core/or/connection_edge.h"
#include "feature/hs/hs_common.h"
-#include "core/mainloop/main.h"
+#include "core/mainloop/mainloop.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/rend/rendcache.h"
-#include "feature/dircache/directory.h"
+#include "feature/dircommon/directory.h"
#include "core/or/connection_or.h"
#include "lib/net/resolve.h"
diff --git a/src/test/test_consdiffmgr.c b/src/test/test_consdiffmgr.c
index 966314be13..b84753ff83 100644
--- a/src/test/test_consdiffmgr.c
+++ b/src/test/test_consdiffmgr.c
@@ -11,7 +11,7 @@
#include "core/mainloop/cpuworker.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "feature/nodelist/networkstatus.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/dirparse/ns_parse.h"
#include "lib/evloop/workqueue.h"
#include "lib/compress/compress.h"
#include "lib/encoding/confline.h"
diff --git a/src/test/test_controller.c b/src/test/test_controller.c
index 0428ac6fce..4f5a9f58d5 100644
--- a/src/test/test_controller.c
+++ b/src/test/test_controller.c
@@ -10,7 +10,7 @@
#include "feature/hs/hs_common.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/rend/rendservice.h"
-#include "feature/nodelist/routerlist.h"
+#include "feature/nodelist/authcert.h"
#include "feature/nodelist/nodelist.h"
#include "test/test.h"
#include "test/test_helpers.h"
diff --git a/src/test/test_controller_events.c b/src/test/test_controller_events.c
index e935b70428..4c404876b0 100644
--- a/src/test/test_controller_events.c
+++ b/src/test/test_controller_events.c
@@ -322,6 +322,72 @@ test_cntev_event_mask(void *arg)
;
}
+static char *saved_event_str = NULL;
+
+static void
+mock_queue_control_event_string(uint16_t event, char *msg)
+{
+ (void)event;
+
+ tor_free(saved_event_str);
+ saved_event_str = msg;
+}
+
+/* Helper macro for checking bootstrap control event strings */
+#define assert_bootmsg(s) \
+ tt_ptr_op(strstr(saved_event_str, "650 STATUS_CLIENT NOTICE " \
+ "BOOTSTRAP PROGRESS=" s), OP_EQ, saved_event_str)
+
+/* Test deferral of directory bootstrap messages (requesting_descriptors) */
+static void
+test_cntev_dirboot_defer_desc(void *arg)
+{
+ (void)arg;
+
+ MOCK(queue_control_event_string, mock_queue_control_event_string);
+ control_testing_set_global_event_mask(EVENT_MASK_(EVENT_STATUS_CLIENT));
+ control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0);
+ assert_bootmsg("0 TAG=starting");
+ /* This event should get deferred */
+ control_event_boot_dir(BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, 0);
+ assert_bootmsg("0 TAG=starting");
+ control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DIR, 0);
+ assert_bootmsg("5 TAG=conn_dir");
+ control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0);
+ assert_bootmsg("10 TAG=handshake_dir");
+ /* The deferred event should appear */
+ control_event_boot_first_orconn();
+ assert_bootmsg("45 TAG=requesting_descriptors");
+ done:
+ tor_free(saved_event_str);
+ UNMOCK(queue_control_event_string);
+}
+
+/* Test deferral of directory bootstrap messages (conn_or) */
+static void
+test_cntev_dirboot_defer_orconn(void *arg)
+{
+ (void)arg;
+
+ MOCK(queue_control_event_string, mock_queue_control_event_string);
+ control_testing_set_global_event_mask(EVENT_MASK_(EVENT_STATUS_CLIENT));
+ control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0);
+ assert_bootmsg("0 TAG=starting");
+ /* This event should get deferred */
+ control_event_boot_dir(BOOTSTRAP_STATUS_CONN_OR, 0);
+ assert_bootmsg("0 TAG=starting");
+ control_event_bootstrap(BOOTSTRAP_STATUS_CONN_DIR, 0);
+ assert_bootmsg("5 TAG=conn_dir");
+ control_event_bootstrap(BOOTSTRAP_STATUS_HANDSHAKE, 0);
+ assert_bootmsg("10 TAG=handshake_dir");
+ /* The deferred event should appear */
+ control_event_boot_first_orconn();
+ assert_bootmsg("80 TAG=conn_or");
+ done:
+ tor_free(saved_event_str);
+ UNMOCK(queue_control_event_string);
+}
+
#define TEST(name, flags) \
{ #name, test_cntev_ ## name, flags, 0, NULL }
@@ -330,5 +396,7 @@ struct testcase_t controller_event_tests[] = {
TEST(append_cell_stats, TT_FORK),
TEST(format_cell_stats, TT_FORK),
TEST(event_mask, TT_FORK),
+ TEST(dirboot_defer_desc, TT_FORK),
+ TEST(dirboot_defer_orconn, TT_FORK),
END_OF_TESTCASES
};
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index 078a383dd8..26ba269abd 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -6,49 +6,73 @@
#include "orconfig.h"
#include <math.h>
+#define BWAUTH_PRIVATE
#define CONFIG_PRIVATE
#define CONTROL_PRIVATE
+#define DIRCACHE_PRIVATE
+#define DIRCLIENT_PRIVATE
#define DIRSERV_PRIVATE
#define DIRVOTE_PRIVATE
-#define ROUTER_PRIVATE
-#define ROUTERLIST_PRIVATE
-#define ROUTERPARSE_PRIVATE
+#define DLSTATUS_PRIVATE
#define HIBERNATE_PRIVATE
#define NETWORKSTATUS_PRIVATE
+#define NS_PARSE_PRIVATE
+#define NODE_SELECT_PRIVATE
#define RELAY_PRIVATE
+#define ROUTERLIST_PRIVATE
+#define ROUTER_PRIVATE
+#define UNPARSEABLE_PRIVATE
+#define VOTEFLAGS_PRIVATE
#include "core/or/or.h"
-#include "feature/client/bridges.h"
-#include "core/mainloop/connection.h"
-#include "app/config/confparse.h"
#include "app/config/config.h"
+#include "app/config/confparse.h"
+#include "core/mainloop/connection.h"
+#include "core/or/relay.h"
+#include "core/or/versions.h"
+#include "feature/client/bridges.h"
+#include "feature/client/entrynodes.h"
#include "feature/control/control.h"
-#include "lib/encoding/confline.h"
-#include "lib/crypt_ops/crypto_ed25519.h"
-#include "lib/crypt_ops/crypto_format.h"
-#include "lib/crypt_ops/crypto_rand.h"
-#include "feature/dircache/directory.h"
-#include "feature/dircache/dirserv.h"
+#include "feature/dirauth/bwauth.h"
#include "feature/dirauth/dirvote.h"
-#include "feature/client/entrynodes.h"
+#include "feature/dirauth/dsigs_parse.h"
+#include "feature/dirauth/process_descs.h"
+#include "feature/dirauth/recommend_pkg.h"
+#include "feature/dirauth/shared_random_state.h"
+#include "feature/dirauth/voteflags.h"
+#include "feature/dircache/dircache.h"
+#include "feature/dircache/dirserv.h"
+#include "feature/dirclient/dirclient.h"
+#include "feature/dirclient/dlstatus.h"
+#include "feature/dircommon/directory.h"
#include "feature/dircommon/fp_pair.h"
+#include "feature/dircommon/voting_schedule.h"
#include "feature/hibernate/hibernate.h"
-#include "lib/memarea/memarea.h"
-#include "lib/osinfo/uname.h"
+#include "feature/nodelist/authcert.h"
+#include "feature/nodelist/dirlist.h"
#include "feature/nodelist/networkstatus.h"
-#include "feature/relay/router.h"
-#include "feature/relay/routerkeys.h"
+#include "feature/nodelist/nickname.h"
+#include "feature/nodelist/node_select.h"
#include "feature/nodelist/routerlist.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/dirparse/authcert_parse.h"
+#include "feature/dirparse/ns_parse.h"
+#include "feature/dirparse/routerparse.h"
+#include "feature/dirparse/unparseable.h"
#include "feature/nodelist/routerset.h"
-#include "feature/dirauth/shared_random_state.h"
-#include "test/test.h"
-#include "test/test_dir_common.h"
#include "feature/nodelist/torcert.h"
-#include "core/or/relay.h"
-#include "test/log_test_helpers.h"
-#include "feature/dircommon/voting_schedule.h"
+#include "feature/relay/router.h"
+#include "feature/relay/routerkeys.h"
+#include "feature/relay/routermode.h"
#include "lib/compress/compress.h"
+#include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/crypt_ops/crypto_format.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "lib/encoding/confline.h"
+#include "lib/memarea/memarea.h"
+#include "lib/osinfo/uname.h"
+#include "test/log_test_helpers.h"
+#include "test/test.h"
+#include "test/test_dir_common.h"
#include "core/or/addr_policy_st.h"
#include "feature/nodelist/authority_cert_st.h"
diff --git a/src/test/test_dir_common.c b/src/test/test_dir_common.c
index 63bd082eea..eadeb11921 100644
--- a/src/test/test_dir_common.c
+++ b/src/test/test_dir_common.c
@@ -10,6 +10,8 @@
#include "feature/dirauth/dirvote.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerlist.h"
+#include "feature/dirparse/authcert_parse.h"
+#include "feature/dirparse/ns_parse.h"
#include "test/test_dir_common.h"
#include "feature/dircommon/voting_schedule.h"
diff --git a/src/test/test_dir_common.h b/src/test/test_dir_common.h
index 1e90228edb..1e958a21ff 100644
--- a/src/test/test_dir_common.h
+++ b/src/test/test_dir_common.h
@@ -5,7 +5,6 @@
#include "core/or/or.h"
#include "feature/nodelist/networkstatus.h"
-#include "feature/nodelist/routerparse.h"
#define TEST_DIR_ROUTER_ID_1 3
#define TEST_DIR_ROUTER_ID_2 5
diff --git a/src/test/test_dir_handle_get.c b/src/test/test_dir_handle_get.c
index b591396913..2ce98769af 100644
--- a/src/test/test_dir_handle_get.c
+++ b/src/test/test_dir_handle_get.c
@@ -8,27 +8,32 @@
#define CONNECTION_PRIVATE
#define CONFIG_PRIVATE
#define RENDCACHE_PRIVATE
+#define DIRCACHE_PRIVATE
#include "core/or/or.h"
#include "app/config/config.h"
#include "core/mainloop/connection.h"
#include "feature/dircache/consdiffmgr.h"
-#include "feature/dircache/directory.h"
+#include "feature/dircommon/directory.h"
+#include "feature/dircache/dircache.h"
#include "test/test.h"
#include "lib/compress/compress.h"
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendcache.h"
#include "feature/relay/router.h"
+#include "feature/nodelist/authcert.h"
+#include "feature/nodelist/dirlist.h"
#include "feature/nodelist/routerlist.h"
#include "test/rend_test_helpers.h"
#include "feature/nodelist/microdesc.h"
#include "test/test_helpers.h"
#include "feature/nodelist/nodelist.h"
#include "feature/client/entrynodes.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/dirparse/authcert_parse.h"
#include "feature/nodelist/networkstatus.h"
#include "core/proto/proto_http.h"
-#include "feature/stats/geoip.h"
+#include "lib/geoip/geoip.h"
+#include "feature/stats/geoip_stats.h"
#include "feature/dircache/dirserv.h"
#include "feature/dirauth/dirvote.h"
#include "test/log_test_helpers.h"
diff --git a/src/test/test_dns.c b/src/test/test_dns.c
index 8369f844f6..ea0fcf8c5e 100644
--- a/src/test/test_dns.c
+++ b/src/test/test_dns.c
@@ -1,6 +1,7 @@
/* Copyright (c) 2015-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
+#include "orconfig.h"
#include "core/or/or.h"
#include "test/test.h"
@@ -13,9 +14,71 @@
#include "core/or/edge_connection_st.h"
#include "core/or/or_circuit_st.h"
+#include "app/config/or_options_st.h"
+#include "app/config/config.h"
+
+#include <event2/event.h>
+#include <event2/dns.h>
#define NS_MODULE dns
+#ifdef HAVE_EVDNS_BASE_GET_NAMESERVER_ADDR
+#define NS_SUBMODULE configure_nameservers_fallback
+
+static or_options_t options = {
+ .ORPort_set = 1,
+};
+
+static const or_options_t *
+mock_get_options(void)
+{
+ return &options;
+}
+
+static void
+NS(test_main)(void *arg)
+{
+ (void)arg;
+ tor_addr_t *nameserver_addr = NULL;
+
+ MOCK(get_options, mock_get_options);
+
+ options.ServerDNSResolvConfFile = (char *)"no_such_file!!!";
+
+ dns_init(); // calls configure_nameservers()
+
+ tt_int_op(number_of_configured_nameservers(), OP_EQ, 1);
+
+ nameserver_addr = configured_nameserver_address(0);
+
+ tt_assert(tor_addr_family(nameserver_addr) == AF_INET);
+ tt_assert(tor_addr_eq_ipv4h(nameserver_addr, 0x7f000001));
+
+#ifndef _WIN32
+ tor_free(nameserver_addr);
+
+ options.ServerDNSResolvConfFile = (char *)"/dev/null";
+
+ dns_init();
+
+ tt_int_op(number_of_configured_nameservers(), OP_EQ, 1);
+
+ nameserver_addr = configured_nameserver_address(0);
+
+ tt_assert(tor_addr_family(nameserver_addr) == AF_INET);
+ tt_assert(tor_addr_eq_ipv4h(nameserver_addr, 0x7f000001));
+#endif
+
+ UNMOCK(get_options);
+
+ done:
+ tor_free(nameserver_addr);
+ return;
+}
+
+#undef NS_SUBMODULE
+#endif
+
#define NS_SUBMODULE clip_ttl
static void
@@ -736,6 +799,9 @@ NS(test_main)(void *arg)
#undef NS_SUBMODULE
struct testcase_t dns_tests[] = {
+#ifdef HAVE_EVDNS_BASE_GET_NAMESERVER_ADDR
+ TEST_CASE(configure_nameservers_fallback),
+#endif
TEST_CASE(clip_ttl),
TEST_CASE(resolve),
TEST_CASE_ASPECT(resolve_impl, addr_is_ip_no_need_to_resolve),
diff --git a/src/test/test_dos.c b/src/test/test_dos.c
index b411e7b38a..40a4c6ba29 100644
--- a/src/test/test_dos.c
+++ b/src/test/test_dos.c
@@ -9,7 +9,7 @@
#include "core/or/dos.h"
#include "core/or/circuitlist.h"
#include "lib/crypt_ops/crypto_rand.h"
-#include "feature/stats/geoip.h"
+#include "feature/stats/geoip_stats.h"
#include "core/or/channel.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
@@ -500,4 +500,3 @@ struct testcase_t dos_tests[] = {
NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c
index cb694106c4..b67c9fae53 100644
--- a/src/test/test_entrynodes.c
+++ b/src/test/test_entrynodes.c
@@ -8,7 +8,7 @@
#define STATEFILE_PRIVATE
#define ENTRYNODES_PRIVATE
#define ROUTERLIST_PRIVATE
-#define DIRECTORY_PRIVATE
+#define DIRCLIENT_PRIVATE
#include "core/or/or.h"
#include "test/test.h"
@@ -19,13 +19,13 @@
#include "app/config/config.h"
#include "app/config/confparse.h"
#include "lib/crypt_ops/crypto_rand.h"
-#include "feature/dircache/directory.h"
+#include "feature/dircommon/directory.h"
+#include "feature/dirclient/dirclient.h"
#include "feature/client/entrynodes.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/networkstatus.h"
#include "core/or/policies.h"
#include "feature/nodelist/routerlist.h"
-#include "feature/nodelist/routerparse.h"
#include "feature/nodelist/routerset.h"
#include "app/config/statefile.h"
diff --git a/src/test/test_extorport.c b/src/test/test_extorport.c
index ff987563c6..71be9131c7 100644
--- a/src/test/test_extorport.c
+++ b/src/test/test_extorport.c
@@ -3,7 +3,7 @@
#define CONNECTION_PRIVATE
#define EXT_ORPORT_PRIVATE
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#include "core/or/or.h"
#include "lib/container/buffers.h"
#include "core/mainloop/connection.h"
@@ -12,11 +12,12 @@
#include "feature/control/control.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "feature/relay/ext_orport.h"
-#include "core/mainloop/main.h"
+#include "core/mainloop/mainloop.h"
#include "core/or/or_connection_st.h"
#include "test/test.h"
+#include "test/test_helpers.h"
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
@@ -89,22 +90,6 @@ connection_write_to_buf_impl_replacement(const char *string, size_t len,
buf_add(conn->outbuf, string, len);
}
-static char *
-buf_get_contents(buf_t *buf, size_t *sz_out)
-{
- char *out;
- *sz_out = buf_datalen(buf);
- if (*sz_out >= ULONG_MAX)
- return NULL; /* C'mon, really? */
- out = tor_malloc(*sz_out + 1);
- if (buf_get_bytes(buf, out, (unsigned long)*sz_out) != 0) {
- tor_free(out);
- return NULL;
- }
- out[*sz_out] = '\0'; /* Hopefully gratuitous. */
- return out;
-}
-
static void
test_ext_or_write_command(void *arg)
{
@@ -463,7 +448,7 @@ test_ext_or_handshake(void *arg)
memcpy(ext_or_auth_cookie, "Gliding wrapt in a brown mantle," , 32);
ext_or_auth_cookie_is_set = 1;
- init_connection_lists();
+ tor_init_connection_lists();
conn = or_connection_new(CONN_TYPE_EXT_OR, AF_INET);
tt_int_op(0, OP_EQ, connection_ext_or_start_auth(conn));
diff --git a/src/test/test_geoip.c b/src/test/test_geoip.c
index 9df8ea7988..6f9c39063b 100644
--- a/src/test/test_geoip.c
+++ b/src/test/test_geoip.c
@@ -10,7 +10,8 @@
#define GEOIP_PRIVATE
#include "core/or/or.h"
#include "app/config/config.h"
-#include "feature/stats/geoip.h"
+#include "lib/geoip/geoip.h"
+#include "feature/stats/geoip_stats.h"
#include "test/test.h"
/* Record odd numbered fake-IPs using ipv6, even numbered fake-IPs
@@ -403,7 +404,8 @@ test_geoip_load_file(void *arg)
/* A nonexistant filename should fail. */
tt_int_op(-1, OP_EQ,
- geoip_load_file(AF_INET, "/you/did/not/put/a/file/here/I/hope"));
+ geoip_load_file(AF_INET, "/you/did/not/put/a/file/here/I/hope",
+ LOG_INFO));
/* We start out with only "Ningunpartia" in the database. */
tt_int_op(1, OP_EQ, geoip_get_n_countries());
@@ -417,7 +419,7 @@ test_geoip_load_file(void *arg)
const char *fname = get_fname("geoip");
tt_int_op(0, OP_EQ, write_str_to_file(fname, GEOIP_CONTENT, 1));
- int rv = geoip_load_file(AF_INET, fname);
+ int rv = geoip_load_file(AF_INET, fname, LOG_WARN);
if (rv != 0) {
TT_GRIPE(("Unable to load geoip from %s", escaped(fname)));
}
@@ -467,7 +469,8 @@ test_geoip6_load_file(void *arg)
/* A nonexistant filename should fail. */
tt_int_op(-1, OP_EQ,
- geoip_load_file(AF_INET6, "/you/did/not/put/a/file/here/I/hope"));
+ geoip_load_file(AF_INET6, "/you/did/not/put/a/file/here/I/hope",
+ LOG_INFO));
/* Any lookup attempt should say "-1" because we have no info */
tor_inet_pton(AF_INET6, "2001:4860:4860::8888", &iaddr6);
@@ -493,7 +496,7 @@ test_geoip6_load_file(void *arg)
"2001:4878:205::,2001:4878:214:ffff:ffff:ffff:ffff:ffff,US\n";
tt_int_op(0, OP_EQ, write_str_to_file(fname6, CONTENT, 1));
- tt_int_op(0, OP_EQ, geoip_load_file(AF_INET6, fname6));
+ tt_int_op(0, OP_EQ, geoip_load_file(AF_INET6, fname6, LOG_WARN));
/* Check that we loaded some countries; this will fail if there are ever
* fewer than 5 countries in our test data above. */
@@ -545,11 +548,11 @@ test_geoip_load_2nd_file(void *arg)
tt_int_op(0, OP_EQ, write_str_to_file(fname_empty, "\n", 1));
/* Load 1st geoip file */
- tt_int_op(0, OP_EQ, geoip_load_file(AF_INET, fname_geoip));
+ tt_int_op(0, OP_EQ, geoip_load_file(AF_INET, fname_geoip, LOG_WARN));
/* Load 2nd geoip (empty) file */
/* It has to be the same IP address family */
- tt_int_op(0, OP_EQ, geoip_load_file(AF_INET, fname_empty));
+ tt_int_op(0, OP_EQ, geoip_load_file(AF_INET, fname_empty, LOG_WARN));
/* Check that there is no geoip information for 8.8.8.8, */
/* since loading the empty 2nd file should have delete it. */
diff --git a/src/test/test_guardfraction.c b/src/test/test_guardfraction.c
index f45a723295..d6f4cd63f2 100644
--- a/src/test/test_guardfraction.c
+++ b/src/test/test_guardfraction.c
@@ -1,16 +1,16 @@
/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#define DIRSERV_PRIVATE
-#define ROUTERPARSE_PRIVATE
+#define GUARDFRACTION_PRIVATE
#define NETWORKSTATUS_PRIVATE
+#define NS_PARSE_PRIVATE
#include "orconfig.h"
#include "core/or/or.h"
#include "app/config/config.h"
-#include "feature/dircache/dirserv.h"
+#include "feature/dirauth/guardfraction.h"
#include "feature/client/entrynodes.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/dirparse/ns_parse.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/networkstatus_st.h"
@@ -422,4 +422,3 @@ struct testcase_t guardfraction_tests[] = {
END_OF_TESTCASES
};
-
diff --git a/src/test/test_helpers.c b/src/test/test_helpers.c
index c9138611d8..6ac73bff5c 100644
--- a/src/test/test_helpers.c
+++ b/src/test/test_helpers.c
@@ -9,7 +9,7 @@
#define ROUTERLIST_PRIVATE
#define CONFIG_PRIVATE
#define CONNECTION_PRIVATE
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#include "orconfig.h"
#include "core/or/or.h"
@@ -19,7 +19,7 @@
#include "app/config/confparse.h"
#include "core/mainloop/connection.h"
#include "lib/crypt_ops/crypto_rand.h"
-#include "core/mainloop/main.h"
+#include "core/mainloop/mainloop.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/relay.h"
#include "feature/nodelist/routerlist.h"
@@ -125,6 +125,25 @@ connection_write_to_buf_mock(const char *string, size_t len,
buf_add(conn->outbuf, string, len);
}
+char *
+buf_get_contents(buf_t *buf, size_t *sz_out)
+{
+ tor_assert(buf);
+ tor_assert(sz_out);
+
+ char *out;
+ *sz_out = buf_datalen(buf);
+ if (*sz_out >= ULONG_MAX)
+ return NULL; /* C'mon, really? */
+ out = tor_malloc(*sz_out + 1);
+ if (buf_get_bytes(buf, out, (unsigned long)*sz_out) != 0) {
+ tor_free(out);
+ return NULL;
+ }
+ out[*sz_out] = '\0'; /* Hopefully gratuitous. */
+ return out;
+}
+
/* Set up a fake origin circuit with the specified number of cells,
* Return a pointer to the newly-created dummy circuit */
circuit_t *
@@ -217,7 +236,7 @@ test_conn_get_connection(uint8_t state, uint8_t type, uint8_t purpose)
mock_connection_connect_sockaddr);
MOCK(tor_close_socket, fake_close_socket);
- init_connection_lists();
+ tor_init_connection_lists();
conn = connection_new(type, TEST_CONN_FAMILY);
tt_assert(conn);
diff --git a/src/test/test_helpers.h b/src/test/test_helpers.h
index 3196c93e6b..72bf7f2f71 100644
--- a/src/test/test_helpers.h
+++ b/src/test/test_helpers.h
@@ -4,6 +4,8 @@
#ifndef TOR_TEST_HELPERS_H
#define TOR_TEST_HELPERS_H
+#define BUFFERS_PRIVATE
+
#include "core/or/or.h"
const char *get_yesterday_date_str(void);
@@ -18,6 +20,7 @@ void helper_setup_fake_routerlist(void);
#define GET(path) "GET " path " HTTP/1.0\r\n\r\n"
void connection_write_to_buf_mock(const char *string, size_t len,
connection_t *conn, int compressed);
+char *buf_get_contents(buf_t *buf, size_t *sz_out);
int mock_tor_addr_lookup__fail_on_bad_addrs(const char *name,
uint16_t family, tor_addr_t *out);
diff --git a/src/test/test_hs_cache.c b/src/test/test_hs_cache.c
index 728bb4a2f5..203a1d7039 100644
--- a/src/test/test_hs_cache.c
+++ b/src/test/test_hs_cache.c
@@ -7,13 +7,15 @@
*/
#define CONNECTION_PRIVATE
-#define DIRECTORY_PRIVATE
+#define DIRCACHE_PRIVATE
+#define DIRCLIENT_PRIVATE
#define HS_CACHE_PRIVATE
#include "trunnel/ed25519_cert.h"
#include "feature/hs/hs_cache.h"
#include "feature/rend/rendcache.h"
-#include "feature/dircache/directory.h"
+#include "feature/dircache/dircache.h"
+#include "feature/dirclient/dirclient.h"
#include "feature/nodelist/networkstatus.h"
#include "core/mainloop/connection.h"
#include "core/proto/proto_http.h"
diff --git a/src/test/test_hs_client.c b/src/test/test_hs_client.c
index c91e82ed4a..91b3ed1ec4 100644
--- a/src/test/test_hs_client.c
+++ b/src/test/test_hs_client.c
@@ -8,7 +8,7 @@
#define CONFIG_PRIVATE
#define CRYPTO_PRIVATE
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#define HS_CLIENT_PRIVATE
#define TOR_CHANNEL_INTERNAL_
#define CIRCUITBUILD_PRIVATE
@@ -25,8 +25,8 @@
#include "lib/crypt_ops/crypto_cipher.h"
#include "lib/crypt_ops/crypto_dh.h"
#include "core/or/channeltls.h"
-#include "feature/dircache/directory.h"
-#include "core/mainloop/main.h"
+#include "feature/dircommon/directory.h"
+#include "core/mainloop/mainloop.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerset.h"
@@ -523,6 +523,9 @@ mock_connection_mark_unattached_ap_(entry_connection_t *conn, int endreason,
(void) line;
(void) file;
conn->edge_.end_reason = endreason;
+ /* This function ultimately will flag this so make sure we do also in the
+ * MOCK one so we can assess closed connections vs open ones. */
+ conn->edge_.base_.marked_for_close = 1;
}
static void
@@ -771,6 +774,218 @@ test_config_client_authorization(void *arg)
UNMOCK(check_private_dir);
}
+static entry_connection_t *
+helper_build_socks_connection(const ed25519_public_key_t *service_pk,
+ int conn_state)
+{
+ entry_connection_t *socks = entry_connection_new(CONN_TYPE_AP, AF_INET);
+ ENTRY_TO_EDGE_CONN(socks)->hs_ident = hs_ident_edge_conn_new(service_pk);
+ TO_CONN(ENTRY_TO_EDGE_CONN(socks))->state = conn_state;
+ smartlist_add(get_connection_array(), &socks->edge_.base_);
+ return socks;
+}
+
+static void
+test_desc_has_arrived_cleanup(void *arg)
+{
+ /* The goal of this test is to make sure we clean up everything in between
+ * two descriptors from the same .onion. Because intro points can change
+ * from one descriptor to another, once we received a new descriptor, we
+ * need to cleanup the remaining circuits so they aren't used or selected
+ * when establishing a connection with the newly stored descriptor.
+ *
+ * This test was created because of #27410. */
+
+ int ret;
+ char *desc_str = NULL;
+ hs_descriptor_t *desc = NULL;
+ const hs_descriptor_t *cached_desc;
+ ed25519_keypair_t signing_kp;
+ entry_connection_t *socks1 = NULL, *socks2 = NULL;
+ hs_ident_dir_conn_t hs_dir_ident;
+
+ (void) arg;
+
+ hs_init();
+
+ MOCK(networkstatus_get_live_consensus,
+ mock_networkstatus_get_live_consensus);
+ MOCK(connection_mark_unattached_ap_,
+ mock_connection_mark_unattached_ap_);
+ MOCK(router_have_minimum_dir_info,
+ mock_router_have_minimum_dir_info_true);
+
+ /* Set consensus time before our time so the cache lookup can always
+ * validate that the entry is not expired. */
+ parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC", &mock_ns.valid_after);
+ parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC", &mock_ns.fresh_until);
+ parse_rfc1123_time("Sat, 26 Oct 1985 16:00:00 UTC", &mock_ns.valid_until);
+
+ /* Build a descriptor for a specific .onion. */
+ ret = ed25519_keypair_generate(&signing_kp, 0);
+ tt_int_op(ret, OP_EQ, 0);
+ desc = hs_helper_build_hs_desc_with_ip(&signing_kp);
+ tt_assert(desc);
+ ret = hs_desc_encode_descriptor(desc, &signing_kp, NULL, &desc_str);
+ tt_int_op(ret, OP_EQ, 0);
+
+ /* Store in the client cache. */
+ ret = hs_cache_store_as_client(desc_str, &signing_kp.pubkey);
+ tt_int_op(ret, OP_EQ, 0);
+ cached_desc = hs_cache_lookup_as_client(&signing_kp.pubkey);
+ tt_assert(cached_desc);
+ hs_helper_desc_equal(desc, cached_desc);
+
+ /* Create two SOCKS connection for the same .onion both in the waiting for a
+ * descriptor state. */
+ socks1 = helper_build_socks_connection(&signing_kp.pubkey,
+ AP_CONN_STATE_RENDDESC_WAIT);
+ tt_assert(socks1);
+ socks2 = helper_build_socks_connection(&signing_kp.pubkey,
+ AP_CONN_STATE_RENDDESC_WAIT);
+ tt_assert(socks2);
+
+ /* Now, we'll make the intro points in the current descriptor unusable so
+ * the hs_client_desc_has_arrived() will take the right code path that we
+ * want to test that is the fetched descriptor has bad intro points. */
+ SMARTLIST_FOREACH_BEGIN(desc->encrypted_data.intro_points,
+ hs_desc_intro_point_t *, ip) {
+ hs_cache_client_intro_state_note(&signing_kp.pubkey,
+ &ip->auth_key_cert->signed_key,
+ INTRO_POINT_FAILURE_GENERIC);
+ } SMARTLIST_FOREACH_END(ip);
+
+ /* Simulate that a new descriptor just arrived. We should have both of our
+ * SOCKS connection to be ended with a resolved failed. */
+ hs_ident_dir_conn_init(&signing_kp.pubkey,
+ &desc->plaintext_data.blinded_pubkey, &hs_dir_ident);
+ hs_client_desc_has_arrived(&hs_dir_ident);
+ tt_int_op(socks1->edge_.end_reason, OP_EQ, END_STREAM_REASON_RESOLVEFAILED);
+ /* XXX: MUST work with OP_EQ. */
+ tt_int_op(socks2->edge_.end_reason, OP_EQ, END_STREAM_REASON_RESOLVEFAILED);
+
+ /* Now let say tor cleans up the intro state cache which resets all intro
+ * point failure count. */
+ hs_cache_client_intro_state_purge();
+
+ /* Retrying all SOCKS which should basically do nothing since we don't have
+ * any pending SOCKS connection in AP_CONN_STATE_RENDDESC_WAIT state. */
+ /* XXX: BUG() is triggered here, shouldn't if socks2 wasn't alive. */
+ retry_all_socks_conn_waiting_for_desc();
+
+ done:
+ connection_free_minimal(ENTRY_TO_CONN(socks1));
+ connection_free_minimal(ENTRY_TO_CONN(socks2));
+ hs_descriptor_free(desc);
+ tor_free(desc_str);
+ hs_free_all();
+
+ UNMOCK(networkstatus_get_live_consensus);
+ UNMOCK(connection_mark_unattached_ap_);
+ UNMOCK(router_have_minimum_dir_info);
+}
+
+static void
+test_close_intro_circuits_new_desc(void *arg)
+{
+ int ret;
+ ed25519_keypair_t service_kp;
+ circuit_t *circ = NULL;
+ origin_circuit_t *ocirc = NULL;
+ hs_descriptor_t *desc1 = NULL, *desc2 = NULL;
+
+ (void) arg;
+
+ hs_init();
+
+ /* This is needed because of the client cache expiration timestamp is based
+ * on having a consensus. See cached_client_descriptor_has_expired(). */
+ MOCK(networkstatus_get_live_consensus,
+ mock_networkstatus_get_live_consensus);
+
+ /* Set consensus time */
+ parse_rfc1123_time("Sat, 26 Oct 1985 13:00:00 UTC",
+ &mock_ns.valid_after);
+ parse_rfc1123_time("Sat, 26 Oct 1985 14:00:00 UTC",
+ &mock_ns.fresh_until);
+ parse_rfc1123_time("Sat, 26 Oct 1985 16:00:00 UTC",
+ &mock_ns.valid_until);
+
+ /* Generate service keypair */
+ tt_int_op(0, OP_EQ, ed25519_keypair_generate(&service_kp, 0));
+
+ /* Create and add to the global list a dummy client introduction circuits.
+ * We'll then make sure the hs_ident is attached to a dummy descriptor. */
+ circ = dummy_origin_circuit_new(0);
+ tt_assert(circ);
+ circ->purpose = CIRCUIT_PURPOSE_C_INTRODUCING;
+ ocirc = TO_ORIGIN_CIRCUIT(circ);
+
+ /* Build the first descriptor and cache it. */
+ {
+ char *encoded;
+ desc1 = hs_helper_build_hs_desc_with_ip(&service_kp);
+ tt_assert(desc1);
+ ret = hs_desc_encode_descriptor(desc1, &service_kp, NULL, &encoded);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_assert(encoded);
+
+ /* Store it */
+ ret = hs_cache_store_as_client(encoded, &service_kp.pubkey);
+ tt_int_op(ret, OP_EQ, 0);
+ tor_free(encoded);
+ tt_assert(hs_cache_lookup_as_client(&service_kp.pubkey));
+ }
+
+ /* We'll pick one introduction point and associate it with the circuit. */
+ {
+ const hs_desc_intro_point_t *ip =
+ smartlist_get(desc1->encrypted_data.intro_points, 0);
+ tt_assert(ip);
+ ocirc->hs_ident = hs_ident_circuit_new(&service_kp.pubkey,
+ HS_IDENT_CIRCUIT_INTRO);
+ ed25519_pubkey_copy(&ocirc->hs_ident->intro_auth_pk,
+ &ip->auth_key_cert->signed_key);
+ }
+
+ /* Before we are about to clean up the intro circuits, make sure it is
+ * actually there. */
+ tt_assert(circuit_get_next_intro_circ(NULL, true));
+
+ /* Build the second descriptor for the same service and cache it. */
+ {
+ char *encoded;
+ desc2 = hs_helper_build_hs_desc_with_ip(&service_kp);
+ tt_assert(desc2);
+ tt_mem_op(&desc1->plaintext_data.signing_pubkey, OP_EQ,
+ &desc2->plaintext_data.signing_pubkey, ED25519_PUBKEY_LEN);
+ /* To replace the existing descriptor, the revision counter needs to be
+ * bigger. */
+ desc2->plaintext_data.revision_counter =
+ desc1->plaintext_data.revision_counter + 1;
+
+ ret = hs_desc_encode_descriptor(desc2, &service_kp, NULL, &encoded);
+ tt_int_op(ret, OP_EQ, 0);
+ tt_assert(encoded);
+
+ hs_cache_store_as_client(encoded, &service_kp.pubkey);
+ tt_int_op(ret, OP_EQ, 0);
+ tor_free(encoded);
+ tt_assert(hs_cache_lookup_as_client(&service_kp.pubkey));
+ }
+
+ /* Once stored, our intro circuit should be closed because it is related to
+ * an old introduction point that doesn't exists anymore. */
+ tt_assert(!circuit_get_next_intro_circ(NULL, true));
+
+ done:
+ circuit_free(circ);
+ hs_descriptor_free(desc1);
+ hs_descriptor_free(desc2);
+ hs_free_all();
+ UNMOCK(networkstatus_get_live_consensus);
+}
+
struct testcase_t hs_client_tests[] = {
{ "e2e_rend_circuit_setup_legacy", test_e2e_rend_circuit_setup_legacy,
TT_FORK, NULL, NULL },
@@ -786,5 +1001,10 @@ struct testcase_t hs_client_tests[] = {
NULL, NULL },
{ "config_client_authorization", test_config_client_authorization,
TT_FORK, NULL, NULL },
+ { "desc_has_arrived_cleanup", test_desc_has_arrived_cleanup,
+ TT_FORK, NULL, NULL },
+ { "close_intro_circuits_new_desc", test_close_intro_circuits_new_desc,
+ TT_FORK, NULL, NULL },
+
END_OF_TESTCASES
};
diff --git a/src/test/test_hs_common.c b/src/test/test_hs_common.c
index c60d6e2640..95f7ed14ba 100644
--- a/src/test/test_hs_common.c
+++ b/src/test/test_hs_common.c
@@ -24,7 +24,7 @@
#include "feature/hs/hs_service.h"
#include "app/config/config.h"
#include "feature/nodelist/networkstatus.h"
-#include "feature/dircache/directory.h"
+#include "feature/dirclient/dirclient.h"
#include "feature/dirauth/dirvote.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerlist.h"
diff --git a/src/test/test_hs_config.c b/src/test/test_hs_config.c
index 553b96758a..b6ab0c21f9 100644
--- a/src/test/test_hs_config.c
+++ b/src/test/test_hs_config.c
@@ -366,6 +366,22 @@ test_invalid_service_v3(void *arg)
teardown_capture_of_logs();
}
+ /* v2-specific HiddenServiceAuthorizeClient set. */
+ {
+ const char *conf =
+ "HiddenServiceDir /tmp/tor-test-hs-RANDOM/hs1\n"
+ "HiddenServiceVersion 3\n"
+ "HiddenServiceAuthorizeClient stealth client1\n";
+ setup_full_capture_of_logs(LOG_WARN);
+ ret = helper_config_service(conf, validate_only);
+ tt_int_op(ret, OP_EQ, -1);
+ expect_log_msg_containing("Hidden service option "
+ "HiddenServiceAuthorizeClient is incompatible "
+ "with version 3 of service in "
+ "/tmp/tor-test-hs-RANDOM/hs1");
+ teardown_capture_of_logs();
+ }
+
done:
;
}
diff --git a/src/test/test_hs_descriptor.c b/src/test/test_hs_descriptor.c
index 4889281cb1..428ca1024b 100644
--- a/src/test/test_hs_descriptor.c
+++ b/src/test/test_hs_descriptor.c
@@ -675,6 +675,8 @@ test_decode_bad_signature(void *arg)
(void) arg;
+ memset(&desc_plaintext, 0, sizeof(desc_plaintext));
+
/* Update approx time to dodge cert expiration */
update_approx_time(1502661599);
@@ -907,7 +909,7 @@ test_build_authorized_client(void *arg)
client_pubkey_b16,
strlen(client_pubkey_b16));
- MOCK(crypto_strongest_rand, mock_crypto_strongest_rand);
+ MOCK(crypto_strongest_rand_, mock_crypto_strongest_rand);
hs_desc_build_authorized_client(subcredential,
&client_auth_pk, &auth_ephemeral_sk,
@@ -923,7 +925,7 @@ test_build_authorized_client(void *arg)
done:
tor_free(desc_client);
tor_free(mem_op_hex_tmp);
- UNMOCK(crypto_strongest_rand);
+ UNMOCK(crypto_strongest_rand_);
}
struct testcase_t hs_descriptor[] = {
diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c
index 6a061eaea4..ee2d71aa75 100644
--- a/src/test/test_hs_service.c
+++ b/src/test/test_hs_service.c
@@ -10,17 +10,17 @@
#define CIRCUITLIST_PRIVATE
#define CONFIG_PRIVATE
#define CONNECTION_PRIVATE
+#define CONNECTION_EDGE_PRIVATE
#define CRYPTO_PRIVATE
#define HS_COMMON_PRIVATE
#define HS_SERVICE_PRIVATE
#define HS_INTROPOINT_PRIVATE
#define HS_CIRCUIT_PRIVATE
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#define NETWORKSTATUS_PRIVATE
#define STATEFILE_PRIVATE
#define TOR_CHANNEL_INTERNAL_
#define HS_CLIENT_PRIVATE
-#define ROUTERPARSE_PRIVATE
#include "test/test.h"
#include "test/test_helpers.h"
@@ -30,30 +30,33 @@
#include "core/or/or.h"
#include "app/config/config.h"
+#include "app/config/statefile.h"
+#include "core/crypto/hs_ntor.h"
+#include "core/mainloop/connection.h"
+#include "core/mainloop/mainloop.h"
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
-#include "lib/crypt_ops/crypto_rand.h"
-#include "lib/fs/dir.h"
-#include "feature/dirauth/dirvote.h"
-#include "feature/nodelist/networkstatus.h"
-#include "feature/nodelist/nodelist.h"
+#include "core/or/connection_edge.h"
+#include "core/or/edge_connection_st.h"
#include "core/or/relay.h"
-#include "feature/nodelist/routerparse.h"
+#include "core/or/versions.h"
+#include "feature/dirauth/dirvote.h"
+#include "feature/dirauth/shared_random_state.h"
+#include "feature/dircommon/voting_schedule.h"
+#include "feature/hs/hs_circuit.h"
+#include "feature/hs/hs_circuitmap.h"
+#include "feature/hs/hs_client.h"
#include "feature/hs/hs_common.h"
#include "feature/hs/hs_config.h"
#include "feature/hs/hs_ident.h"
#include "feature/hs/hs_intropoint.h"
-#include "core/crypto/hs_ntor.h"
-#include "feature/hs/hs_circuit.h"
-#include "feature/hs/hs_circuitmap.h"
#include "feature/hs/hs_service.h"
-#include "feature/hs/hs_client.h"
-#include "core/mainloop/main.h"
+#include "feature/nodelist/networkstatus.h"
+#include "feature/nodelist/nodelist.h"
#include "feature/rend/rendservice.h"
-#include "app/config/statefile.h"
-#include "feature/dirauth/shared_random_state.h"
-#include "feature/dircommon/voting_schedule.h"
+#include "lib/crypt_ops/crypto_rand.h"
+#include "lib/fs/dir.h"
#include "core/or/cpath_build_state_st.h"
#include "core/or/crypt_path_st.h"
@@ -534,6 +537,7 @@ test_load_keys_with_client_auth(void *arg)
tt_int_op(get_hs_service_map_size(), OP_EQ, 1);
service = get_first_service();
+ tt_assert(service);
tt_assert(service->config.clients);
tt_int_op(smartlist_len(service->config.clients), OP_EQ,
smartlist_len(pubkey_b32_list));
@@ -563,9 +567,7 @@ test_load_keys_with_client_auth(void *arg)
} SMARTLIST_FOREACH_END(pubkey_b32);
done:
- if (pubkey_b32_list) {
- SMARTLIST_FOREACH(pubkey_b32_list, char *, s, tor_free(s));
- }
+ SMARTLIST_FOREACH(pubkey_b32_list, char *, s, tor_free(s));
smartlist_free(pubkey_b32_list);
tor_free(hsdir_v3);
hs_free_all();
@@ -746,6 +748,8 @@ test_helper_functions(void *arg)
MOCK(node_get_by_id, mock_node_get_by_id);
hs_service_init();
+ time_t now = time(NULL);
+ update_approx_time(now);
service = helper_create_service();
@@ -805,7 +809,6 @@ test_helper_functions(void *arg)
/* Testing can_service_launch_intro_circuit() */
{
- time_t now = time(NULL);
/* Put the start of the retry period back in time, we should be allowed.
* to launch intro circuit. */
service->state.num_intro_circ_launched = 2;
@@ -829,7 +832,6 @@ test_helper_functions(void *arg)
/* Testing intro_point_should_expire(). */
{
- time_t now = time(NULL);
/* Just some basic test of the current state. */
tt_u64_op(ip->introduce2_max, OP_GE,
INTRO_POINT_MIN_LIFETIME_INTRODUCTIONS);
@@ -1455,7 +1457,7 @@ test_build_update_descriptors(void *arg)
/* Time to test the update of those descriptors. At first, we have no node
* in the routerlist so this will find NO suitable node for the IPs. */
setup_full_capture_of_logs(LOG_INFO);
- update_all_descriptors(now);
+ update_all_descriptors_intro_points(now);
expect_log_msg_containing("Unable to find a suitable node to be an "
"introduction point for service");
teardown_capture_of_logs();
@@ -1506,7 +1508,7 @@ test_build_update_descriptors(void *arg)
/* We expect to pick only one intro point from the node above. */
setup_full_capture_of_logs(LOG_INFO);
- update_all_descriptors(now);
+ update_all_descriptors_intro_points(now);
tor_free(node->ri->onion_curve25519_pkey); /* Avoid memleak. */
tor_free(node->ri->cache_info.signing_key_cert);
tor_free(node->ri->onion_pkey);
@@ -2005,6 +2007,96 @@ test_authorized_client_config_equal(void *arg)
tor_free(config2);
}
+/** Test that client circuit ID gets correctly exported */
+static void
+test_export_client_circuit_id(void *arg)
+{
+ origin_circuit_t *or_circ = NULL;
+ size_t sz;
+ char *cp1=NULL, *cp2=NULL;
+ connection_t *conn = NULL;
+
+ (void) arg;
+
+ MOCK(connection_write_to_buf_impl_, connection_write_to_buf_mock);
+
+ hs_service_init();
+
+ /* Create service */
+ hs_service_t *service = helper_create_service();
+ /* Check that export circuit ID detection works */
+ service->config.circuit_id_protocol = HS_CIRCUIT_ID_PROTOCOL_NONE;
+ tt_int_op(0, OP_EQ,
+ hs_service_exports_circuit_id(&service->keys.identity_pk));
+ service->config.circuit_id_protocol = HS_CIRCUIT_ID_PROTOCOL_HAPROXY;
+ tt_int_op(1, OP_EQ,
+ hs_service_exports_circuit_id(&service->keys.identity_pk));
+
+ /* Create client connection */
+ conn = test_conn_get_connection(AP_CONN_STATE_CIRCUIT_WAIT, CONN_TYPE_AP, 0);
+
+ /* Create client edge conn hs_ident */
+ edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
+ edge_conn->hs_ident = hs_ident_edge_conn_new(&service->keys.identity_pk);
+ edge_conn->hs_ident->orig_virtual_port = 42;
+
+ /* Create rend circuit */
+ or_circ = origin_circuit_new();
+ or_circ->base_.purpose = CIRCUIT_PURPOSE_C_REND_JOINED;
+ edge_conn->on_circuit = TO_CIRCUIT(or_circ);
+ or_circ->global_identifier = 666;
+
+ /* Export circuit ID */
+ export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
+
+ /* Check contents */
+ cp1 = buf_get_contents(conn->outbuf, &sz);
+ tt_str_op(cp1, OP_EQ,
+ "PROXY TCP6 fc00:dead:beef:4dad::0:29a ::1 666 42\r\n");
+
+ /* Change circ GID and see that the reported circuit ID also changes */
+ or_circ->global_identifier = 22;
+
+ /* check changes */
+ export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
+ cp2 = buf_get_contents(conn->outbuf, &sz);
+ tt_str_op(cp1, OP_NE, cp2);
+ tor_free(cp1);
+
+ /* Check that GID with UINT32_MAX works. */
+ or_circ->global_identifier = UINT32_MAX;
+
+ export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
+ cp1 = buf_get_contents(conn->outbuf, &sz);
+ tt_str_op(cp1, OP_EQ,
+ "PROXY TCP6 fc00:dead:beef:4dad::ffff:ffff ::1 65535 42\r\n");
+ tor_free(cp1);
+
+ /* Check that GID with UINT16_MAX works. */
+ or_circ->global_identifier = UINT16_MAX;
+
+ export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
+ cp1 = buf_get_contents(conn->outbuf, &sz);
+ tt_str_op(cp1, OP_EQ,
+ "PROXY TCP6 fc00:dead:beef:4dad::0:ffff ::1 65535 42\r\n");
+ tor_free(cp1);
+
+ /* Check that GID with UINT16_MAX + 7 works. */
+ or_circ->global_identifier = UINT16_MAX + 7;
+
+ export_hs_client_circuit_id(edge_conn, service->config.circuit_id_protocol);
+ cp1 = buf_get_contents(conn->outbuf, &sz);
+ tt_str_op(cp1, OP_EQ, "PROXY TCP6 fc00:dead:beef:4dad::1:6 ::1 6 42\r\n");
+
+ done:
+ UNMOCK(connection_write_to_buf_impl_);
+ circuit_free_(TO_CIRCUIT(or_circ));
+ connection_free_minimal(conn);
+ hs_service_free(service);
+ tor_free(cp1);
+ tor_free(cp2);
+}
+
struct testcase_t hs_service_tests[] = {
{ "e2e_rend_circuit_setup", test_e2e_rend_circuit_setup, TT_FORK,
NULL, NULL },
@@ -2046,6 +2138,8 @@ struct testcase_t hs_service_tests[] = {
NULL, NULL },
{ "authorized_client_config_equal", test_authorized_client_config_equal,
TT_FORK, NULL, NULL },
+ { "export_client_circuit_id", test_export_client_circuit_id, TT_FORK,
+ NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_link_handshake.c b/src/test/test_link_handshake.c
index df3fa67eb1..82a91a9ae2 100644
--- a/src/test/test_link_handshake.c
+++ b/src/test/test_link_handshake.c
@@ -942,15 +942,25 @@ test_link_handshake_send_authchallenge(void *arg)
cell1 = mock_got_var_cell;
tt_int_op(0, OP_EQ, connection_or_send_auth_challenge_cell(c1));
cell2 = mock_got_var_cell;
+#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
tt_int_op(38, OP_EQ, cell1->payload_len);
tt_int_op(38, OP_EQ, cell2->payload_len);
+#else
+ tt_int_op(36, OP_EQ, cell1->payload_len);
+ tt_int_op(36, OP_EQ, cell2->payload_len);
+#endif
tt_int_op(0, OP_EQ, cell1->circ_id);
tt_int_op(0, OP_EQ, cell2->circ_id);
tt_int_op(CELL_AUTH_CHALLENGE, OP_EQ, cell1->command);
tt_int_op(CELL_AUTH_CHALLENGE, OP_EQ, cell2->command);
+#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
tt_mem_op("\x00\x02\x00\x01\x00\x03", OP_EQ, cell1->payload + 32, 6);
tt_mem_op("\x00\x02\x00\x01\x00\x03", OP_EQ, cell2->payload + 32, 6);
+#else
+ tt_mem_op("\x00\x01\x00\x03", OP_EQ, cell1->payload + 32, 4);
+ tt_mem_op("\x00\x01\x00\x03", OP_EQ, cell2->payload + 32, 4);
+#endif
tt_mem_op(cell1->payload, OP_NE, cell2->payload, 32);
done:
@@ -992,6 +1002,8 @@ static void *
recv_authchallenge_setup(const struct testcase_t *test)
{
(void)test;
+
+ testing__connection_or_pretend_TLSSECRET_is_supported = 1;
authchallenge_data_t *d = tor_malloc_zero(sizeof(*d));
d->c = or_connection_new(CONN_TYPE_OR, AF_INET);
d->chan = tor_malloc_zero(sizeof(*d->chan));
@@ -1205,6 +1217,8 @@ authenticate_data_setup(const struct testcase_t *test)
authenticate_data_t *d = tor_malloc_zero(sizeof(*d));
int is_ed = d->is_ed = (test->setup_data == (void*)3);
+ testing__connection_or_pretend_TLSSECRET_is_supported = 1;
+
scheduler_init();
MOCK(connection_or_write_var_cell_to_buf, mock_write_var_cell);
diff --git a/src/test/test_mainloop.c b/src/test/test_mainloop.c
index f85c224ae9..92ce2e9918 100644
--- a/src/test/test_mainloop.c
+++ b/src/test/test_mainloop.c
@@ -10,7 +10,7 @@
#include "test/log_test_helpers.h"
#include "core/or/or.h"
-#include "core/mainloop/main.h"
+#include "core/mainloop/mainloop.h"
static const uint64_t BILLION = 1000000000;
diff --git a/src/test/test_microdesc.c b/src/test/test_microdesc.c
index ec4779ead1..8ede2690ec 100644
--- a/src/test/test_microdesc.c
+++ b/src/test/test_microdesc.c
@@ -4,13 +4,14 @@
#include "orconfig.h"
#include "core/or/or.h"
-#include "app/config/config.h"
#define DIRVOTE_PRIVATE
+#include "app/config/config.h"
#include "feature/dirauth/dirvote.h"
+#include "feature/dirparse/microdesc_parse.h"
+#include "feature/dirparse/routerparse.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/routerlist.h"
-#include "feature/nodelist/routerparse.h"
#include "feature/nodelist/torcert.h"
#include "feature/nodelist/microdesc_st.h"
diff --git a/src/test/test_nodelist.c b/src/test/test_nodelist.c
index cdd5e95cf0..1af6db68ec 100644
--- a/src/test/test_nodelist.c
+++ b/src/test/test_nodelist.c
@@ -19,6 +19,7 @@
#include "feature/nodelist/routerstatus_st.h"
#include "test/test.h"
+#include "test/log_test_helpers.h"
/** Test the case when node_get_by_id() returns NULL,
* node_get_verbose_nickname_by_id should return the base 16 encoding
@@ -126,9 +127,10 @@ mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
static void
test_nodelist_ed_id(void *arg)
{
- routerstatus_t *rs[4];
- microdesc_t *md[4];
- routerinfo_t *ri[4];
+#define N_NODES 5
+ routerstatus_t *rs[N_NODES];
+ microdesc_t *md[N_NODES];
+ routerinfo_t *ri[N_NODES];
networkstatus_t *ns;
int i;
(void)arg;
@@ -145,7 +147,7 @@ test_nodelist_ed_id(void *arg)
/* Make a bunch of dummy objects that we can play around with. Only set the
necessary fields */
- for (i = 0; i < 4; ++i) {
+ for (i = 0; i < N_NODES; ++i) {
rs[i] = tor_malloc_zero(sizeof(*rs[i]));
md[i] = tor_malloc_zero(sizeof(*md[i]));
ri[i] = tor_malloc_zero(sizeof(*ri[i]));
@@ -162,7 +164,7 @@ test_nodelist_ed_id(void *arg)
memcpy(&ri[i]->cache_info.signing_key_cert->signing_key,
md[i]->ed25519_identity_pkey, sizeof(ed25519_public_key_t));
- if (i != 3)
+ if (i < 3)
smartlist_add(ns->routerstatus_list, rs[i]);
}
@@ -192,13 +194,30 @@ test_nodelist_ed_id(void *arg)
/* Register the 4th by ri only -- we never put it into the networkstatus,
* so it has to be independent */
- n = nodelist_set_routerinfo(ri[3], &ri_old);
- tt_ptr_op(n, OP_EQ, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
+ node_t *n3 = nodelist_set_routerinfo(ri[3], &ri_old);
+ tt_ptr_op(n3, OP_EQ, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
tt_ptr_op(ri_old, OP_EQ, NULL);
tt_int_op(4, OP_EQ, smartlist_len(nodelist_get_list()));
+ /* Register the 5th by ri only, and rewrite its ed25519 pubkey to be
+ * the same as the 4th, to test the duplicate ed25519 key logging in
+ * nodelist.c */
+ memcpy(md[4]->ed25519_identity_pkey, md[3]->ed25519_identity_pkey,
+ sizeof(ed25519_public_key_t));
+ memcpy(&ri[4]->cache_info.signing_key_cert->signing_key,
+ md[3]->ed25519_identity_pkey, sizeof(ed25519_public_key_t));
+
+ setup_capture_of_logs(LOG_NOTICE);
+ node_t *n4 = nodelist_set_routerinfo(ri[4], &ri_old);
+ tt_ptr_op(ri_old, OP_EQ, NULL);
+ tt_int_op(5, OP_EQ, smartlist_len(nodelist_get_list()));
+ tt_ptr_op(n4, OP_NE, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
+ tt_ptr_op(n3, OP_EQ, node_get_by_ed25519_id(md[3]->ed25519_identity_pkey));
+ expect_log_msg_containing("Reused ed25519_id");
+
done:
- for (i = 0; i < 4; ++i) {
+ teardown_capture_of_logs();
+ for (i = 0; i < N_NODES; ++i) {
tor_free(rs[i]);
tor_free(md[i]->ed25519_identity_pkey);
tor_free(md[i]);
@@ -209,6 +228,7 @@ test_nodelist_ed_id(void *arg)
networkstatus_vote_free(ns);
UNMOCK(networkstatus_get_latest_consensus);
UNMOCK(networkstatus_get_latest_consensus_by_flavor);
+#undef N_NODES
}
#define NODE(name, flags) \
diff --git a/src/test/test_oos.c b/src/test/test_oos.c
index 5f9942d8ae..fb0daa7a8d 100644
--- a/src/test/test_oos.c
+++ b/src/test/test_oos.c
@@ -9,8 +9,8 @@
#include "app/config/config.h"
#include "core/mainloop/connection.h"
#include "core/or/connection_or.h"
-#include "feature/dircache/directory.h"
-#include "core/mainloop/main.h"
+#include "feature/dircommon/directory.h"
+#include "core/mainloop/mainloop.h"
#include "test/test.h"
#include "feature/dircommon/dir_connection_st.h"
diff --git a/src/test/test_options.c b/src/test/test_options.c
index 56b7f3cf0f..f14e620eeb 100644
--- a/src/test/test_options.c
+++ b/src/test/test_options.c
@@ -8,11 +8,11 @@
#include "app/config/confparse.h"
#include "app/config/config.h"
#include "test/test.h"
-#include "feature/stats/geoip.h"
+#include "lib/geoip/geoip.h"
#define ROUTERSET_PRIVATE
#include "feature/nodelist/routerset.h"
-#include "core/mainloop/main.h"
+#include "core/mainloop/mainloop.h"
#include "test/log_test_helpers.h"
#include "lib/sandbox/sandbox.h"
diff --git a/src/test/test_parsecommon.c b/src/test/test_parsecommon.c
new file mode 100644
index 0000000000..6da125dd0a
--- /dev/null
+++ b/src/test/test_parsecommon.c
@@ -0,0 +1,594 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "core/or/or.h"
+#include "test/test.h"
+#include "lib/memarea/memarea.h"
+#include "lib/encoding/binascii.h"
+#include "feature/dirparse/parsecommon.h"
+#include "test/log_test_helpers.h"
+
+static void
+test_parsecommon_tokenize_string_null(void *arg)
+{
+
+ memarea_t *area = memarea_new();
+ smartlist_t *tokens = smartlist_new();
+
+ (void)arg;
+
+ const char *str_with_null = "a\0bccccccccc";
+
+ int retval =
+ tokenize_string(area, str_with_null,
+ str_with_null + 3,
+ tokens, NULL, 0);
+
+ tt_int_op(retval, OP_EQ, -1);
+
+ done:
+ memarea_drop_all(area);
+ smartlist_free(tokens);
+ return;
+}
+
+static void
+test_parsecommon_tokenize_string_multiple_lines(void *arg)
+{
+ memarea_t *area = memarea_new();
+ smartlist_t *tokens = smartlist_new();
+
+ (void)arg;
+
+ token_rule_t table[] = {
+ T01("uptime", K_UPTIME, GE(1), NO_OBJ),
+ T01("hibernating", K_HIBERNATING, GE(1), NO_OBJ),
+ T1( "published", K_PUBLISHED, CONCAT_ARGS, NO_OBJ),
+ END_OF_TABLE,
+ };
+
+ char *str = tor_strdup(
+ "hibernating 0\nuptime 1024\n"
+ "published 2018-10-15 10:00:00\n");
+
+ int retval =
+ tokenize_string(area, str, NULL,
+ tokens, table, 0);
+
+ tt_int_op(smartlist_len(tokens), OP_EQ, 3);
+ directory_token_t *token = smartlist_get(tokens, 0);
+
+ tt_int_op(token->tp, OP_EQ, K_HIBERNATING);
+
+ token = smartlist_get(tokens, 1);
+
+ tt_int_op(token->tp, OP_EQ, K_UPTIME);
+
+ token = smartlist_get(tokens, 2);
+
+ tt_int_op(token->tp, OP_EQ, K_PUBLISHED);
+
+ tt_int_op(retval, OP_EQ, 0);
+
+ done:
+ tor_free(str);
+ memarea_drop_all(area);
+ smartlist_free(tokens);
+ return;
+}
+
+static void
+test_parsecommon_tokenize_string_min_cnt(void *arg)
+{
+ memarea_t *area = memarea_new();
+ smartlist_t *tokens = smartlist_new();
+
+ (void)arg;
+
+ token_rule_t table[] = {
+ T01("uptime", K_UPTIME, EQ(2), NO_OBJ),
+ T01("hibernating", K_HIBERNATING, GE(1), NO_OBJ),
+ END_OF_TABLE,
+ };
+
+ // Missing "uptime"
+ char *str = tor_strdup("uptime 1024\nhibernating 0\n");
+
+ int retval =
+ tokenize_string(area, str, NULL,
+ tokens, table, 0);
+
+ tt_int_op(retval, OP_EQ, -1);
+
+ done:
+ tor_free(str);
+ memarea_drop_all(area);
+ smartlist_free(tokens);
+ return;
+}
+
+static void
+test_parsecommon_tokenize_string_max_cnt(void *arg)
+{
+ memarea_t *area = memarea_new();
+ smartlist_t *tokens = smartlist_new();
+
+ (void)arg;
+
+ token_rule_t table[] = {
+ T01("uptime", K_UPTIME, EQ(1), NO_OBJ),
+ T01("hibernating", K_HIBERNATING, GE(1), NO_OBJ),
+ END_OF_TABLE,
+ };
+
+ // "uptime" expected once, but occurs twice in input.
+ char *str = tor_strdup(
+ "uptime 1024\nuptime 2048\nhibernating 0\n");
+
+ int retval =
+ tokenize_string(area, str, NULL,
+ tokens, table, 0);
+
+ tt_int_op(retval, OP_EQ, -1);
+
+ done:
+ tor_free(str);
+ memarea_drop_all(area);
+ smartlist_free(tokens);
+ return;
+}
+
+static void
+test_parsecommon_tokenize_string_at_start(void *arg)
+{
+ memarea_t *area = memarea_new();
+ smartlist_t *tokens = smartlist_new();
+
+ (void)arg;
+
+ token_rule_t table[] = {
+ T1_START("client-name", C_CLIENT_NAME, CONCAT_ARGS, NO_OBJ),
+ T01("uptime", K_UPTIME, EQ(1), NO_OBJ),
+ END_OF_TABLE,
+ };
+
+ // "client-name" is not the first line.
+ char *str = tor_strdup(
+ "uptime 1024\nclient-name Alice\n");
+
+ int retval =
+ tokenize_string(area, str, NULL, tokens, table, 0);
+
+ tt_int_op(retval, OP_EQ, -1);
+
+ done:
+ tor_free(str);
+ memarea_drop_all(area);
+ smartlist_free(tokens);
+ return;
+}
+
+static void
+test_parsecommon_tokenize_string_at_end(void *arg)
+{
+ memarea_t *area = memarea_new();
+ smartlist_t *tokens = smartlist_new();
+
+ (void)arg;
+
+ token_rule_t table[] = {
+ T1_END("client-name", C_CLIENT_NAME, CONCAT_ARGS, NO_OBJ),
+ T01("uptime", K_UPTIME, EQ(1), NO_OBJ),
+ END_OF_TABLE,
+ };
+
+ // "client-name" is not the last line.
+ char *str = tor_strdup(
+ "client-name Alice\nuptime 1024\n");
+
+ int retval =
+ tokenize_string(area, str, NULL, tokens, table, 0);
+
+ tt_int_op(retval, OP_EQ, -1);
+
+ done:
+ tor_free(str);
+ memarea_drop_all(area);
+ smartlist_free(tokens);
+ return;
+}
+
+static void
+test_parsecommon_tokenize_string_no_annotations(void *arg)
+{
+ memarea_t *area = memarea_new();
+ smartlist_t *tokens = smartlist_new();
+
+ (void)arg;
+
+ token_rule_t table[] = {
+ A01("@last-listed", A_LAST_LISTED, CONCAT_ARGS, NO_OBJ),
+ END_OF_TABLE,
+ };
+
+ char *str = tor_strdup("@last-listed 2018-09-21 15:30:03\n");
+
+ int retval =
+ tokenize_string(area, str, NULL, tokens, table, 0);
+
+ tt_int_op(retval, OP_EQ, -1);
+
+ done:
+ tor_free(str);
+ memarea_drop_all(area);
+ smartlist_free(tokens);
+ return;
+}
+
+static void
+test_parsecommon_get_next_token_success(void *arg)
+{
+ memarea_t *area = memarea_new();
+ const char *str = "uptime 1024";
+ const char *end = str + strlen(str);
+ const char **s = &str;
+ token_rule_t table = T01("uptime", K_UPTIME, GE(1), NO_OBJ);
+ (void)arg;
+
+ directory_token_t *token = get_next_token(area, s, end, &table);
+
+ tt_int_op(token->tp, OP_EQ, K_UPTIME);
+ tt_int_op(token->n_args, OP_EQ, 1);
+ tt_str_op(*(token->args), OP_EQ, "1024");
+ tt_assert(!token->object_type);
+ tt_int_op(token->object_size, OP_EQ, 0);
+ tt_assert(!token->object_body);
+
+ tt_ptr_op(*s, OP_EQ, end);
+
+ done:
+ memarea_drop_all(area);
+ return;
+}
+
+static void
+test_parsecommon_get_next_token_concat_args(void *arg)
+{
+ memarea_t *area = memarea_new();
+ const char *str = "proto A=1 B=2";
+ const char *end = str + strlen(str);
+ const char **s = &str;
+ token_rule_t rule = T01("proto", K_PROTO, CONCAT_ARGS, NO_OBJ);
+ (void)arg;
+
+ directory_token_t *token = get_next_token(area, s, end, &rule);
+
+ tt_int_op(token->tp, OP_EQ, K_PROTO);
+ tt_int_op(token->n_args, OP_EQ, 1);
+ tt_str_op(*(token->args), OP_EQ, "A=1 B=2");
+
+ done:
+ memarea_drop_all(area);
+}
+
+static void
+test_parsecommon_get_next_token_parse_keys(void *arg)
+{
+ (void)arg;
+
+ memarea_t *area = memarea_new();
+ const char *str =
+ "onion-key\n"
+ "-----BEGIN RSA PUBLIC KEY-----\n"
+ "MIGJAoGBAMDdIya33BfNlHOkzoTKSTT8EjD64waMfUr372syVHiFjHhObwKwGA5u\n"
+ "sHaMIe9r+Ij/4C1dKyuXkcz3DOl6gWNhTD7dZ89I+Okoh1jWe30jxCiAcywC22p5\n"
+ "XLhrDkX1A63Z7XCH9ltwU2WMqWsVM98N2GR6MTujP7wtqdLExYN1AgMBAAE=\n"
+ "-----END RSA PUBLIC KEY-----\n";
+
+ const char *end = str + strlen(str);
+ const char **s = (const char **)&str;
+ directory_token_t *token = NULL;
+ directory_token_t *token2 = NULL;
+
+ token_rule_t rule = T1("onion-key", R_IPO_ONION_KEY, NO_ARGS, NEED_KEY_1024);
+
+ token = get_next_token(area, s, end, &rule);
+ tt_assert(token);
+
+ tt_int_op(token->tp, OP_EQ, R_IPO_ONION_KEY);
+ tt_int_op(token->n_args, OP_EQ, 0);
+ tt_str_op(token->object_type, OP_EQ, "RSA PUBLIC KEY");
+ tt_int_op(token->object_size, OP_EQ, 0);
+ tt_assert(!token->object_body);
+ tt_assert(token->key);
+ tt_assert(!token->error);
+
+ const char *str2 =
+ "client-key\n"
+ "-----BEGIN RSA PRIVATE KEY-----\n"
+ "MIICXAIBAAKBgQCwS810a2auH2PQchOBz9smNgjlDu31aq0IYlUohSYbhcv5AJ+d\n"
+ "DY0nfZWzS+mZPwzL3UiEnTt6PVv7AgoZ5V9ZJWJTKIURjJpkK0mstfJKHKIZhf84\n"
+ "pmFfRej9GQViB6NLtp1obOXJgJixSlMfw9doDI4NoAnEISCyH/tD77Qs2wIDAQAB\n"
+ "AoGAbDg8CKkdQOnX9c7xFpCnsE8fKqz9eddgHHNwXw1NFTwOt+2gDWKSMZmv2X5S\n"
+ "CVZg3owZxf5W0nT0D6Ny2+6nliak7foYAvkD0BsCiBhgftwC0zAo6k5rIbUKB3PJ\n"
+ "QLFXgpJhqWuXkODyt/hS/GTernR437WVSEGp1bnALqiFabECQQDaqHOxzoWY/nvH\n"
+ "KrfUi8EhqCnqERlRHwrW0MQZ1RPvF16OPPma+xa+ht/amfh3vYN5tZY82Zm43gGl\n"
+ "XWL5cZhNAkEAzmdSootYVnqLLLRMfHKXnO1XbaEcA/08MDNKGlSclBJixFenE8jX\n"
+ "iQsUbHwMJuGONvzWpRGPBP2f8xBd28ZtxwJARY+LZshtpfNniz/ixYJESaHG28je\n"
+ "xfjbKOW3TQSFV+2WTifFvHEeljQwKMoMyoMGvYRwLCGJjs9JtMLVxsdFjQJBAKwD\n"
+ "3BBvBQ39TuPQ1zWX4tb7zjMlY83HTFP3Sriq71tP/1QWoL2SUl56B2lp8E6vB/C3\n"
+ "wsMK4SCNprHRYAd7VZ0CQDKn6Zhd11P94PLs0msybFEh1VXr6CEW/BrxBgbL4ls6\n"
+ "dbX5XO0z4Ra8gYXgObgimhyMDYO98Idt5+Z3HIdyrSc=\n"
+ "-----END RSA PRIVATE KEY-----\n";
+
+ const char *end2 = str2 + strlen(str2);
+ const char **s2 = (const char **)&str2;
+
+ token_rule_t rule2 = T01("client-key", C_CLIENT_KEY, NO_ARGS,
+ NEED_SKEY_1024);
+
+ token2 = get_next_token(area, s2, end2, &rule2);
+ tt_assert(token2);
+
+ tt_int_op(token2->tp, OP_EQ, C_CLIENT_KEY);
+ tt_int_op(token2->n_args, OP_EQ, 0);
+ tt_str_op(token2->object_type, OP_EQ, "RSA PRIVATE KEY");
+ tt_int_op(token2->object_size, OP_EQ, 0);
+ tt_assert(!token2->object_body);
+ tt_assert(token2->key);
+ tt_assert(!token->error);
+
+ done:
+ if (token) token_clear(token);
+ if (token2) token_clear(token2);
+ memarea_drop_all(area);
+}
+
+static void
+test_parsecommon_get_next_token_object(void *arg)
+{
+ memarea_t *area = memarea_new();
+
+ const char *str =
+ "directory-signature 0232AF901C31A04EE9848595AF9BB7620D4C5B2E "
+ "CD1FD971855430880D3C31E0331C5C55800C2F79\n"
+ "-----BEGIN SIGNATURE-----\n"
+ "dLTbc1Lad/OWKBJhA/dERzDHumswTAzBFAWAz2vnQhLsebs1SOm0W/vceEsiEkiF\n"
+ "A+JJSzIyfywJc6Mnk7aKMEIFjOO/MaxuAp4zv+q+JonJkF0ExjMqvKR0D6pSFmfN\n"
+ "cnemnxGHxNuPDnKl0imbWKmWDsHtwgi4zWeTq3MekfMOXKi6gIh+bDFzCs9/Vquh\n"
+ "uNKJI1jW/A2DEKeaSAODEv9VoCsYSvbVVEuHCBWjeNAurd5aL26BrAolW6m7pkD6\n"
+ "I+cQ8dQG6Wa/Zt6gLXtBbOP2o/iDI7ahDP9diNkBI/rm4nfp9j4piTwsqpi7xz9J\n"
+ "Ua9DEZB9KbJHVX1rGShrLA==\n"
+ "-----END SIGNATURE-----\n";
+
+ const char *end = str + strlen(str);
+ const char **s = &str;
+ token_rule_t rule = T("directory-signature", K_DIRECTORY_SIGNATURE,
+ GE(2), NEED_OBJ);
+ (void)arg;
+
+ directory_token_t *token = get_next_token(area, s, end, &rule);
+
+ tt_int_op(token->tp, OP_EQ, K_DIRECTORY_SIGNATURE);
+ tt_int_op(token->n_args, OP_EQ, 2);
+ tt_str_op(token->args[0], OP_EQ,
+ "0232AF901C31A04EE9848595AF9BB7620D4C5B2E");
+ tt_str_op(token->args[1], OP_EQ,
+ "CD1FD971855430880D3C31E0331C5C55800C2F79");
+
+ tt_assert(!token->error);
+
+ char decoded[256];
+ const char *signature =
+ "dLTbc1Lad/OWKBJhA/dERzDHumswTAzBFAWAz2vnQhLsebs1SOm0W/vceEsiEkiF\n"
+ "A+JJSzIyfywJc6Mnk7aKMEIFjOO/MaxuAp4zv+q+JonJkF0ExjMqvKR0D6pSFmfN\n"
+ "cnemnxGHxNuPDnKl0imbWKmWDsHtwgi4zWeTq3MekfMOXKi6gIh+bDFzCs9/Vquh\n"
+ "uNKJI1jW/A2DEKeaSAODEv9VoCsYSvbVVEuHCBWjeNAurd5aL26BrAolW6m7pkD6\n"
+ "I+cQ8dQG6Wa/Zt6gLXtBbOP2o/iDI7ahDP9diNkBI/rm4nfp9j4piTwsqpi7xz9J\n"
+ "Ua9DEZB9KbJHVX1rGShrLA==\n";
+ tt_assert(signature);
+ size_t signature_len = strlen(signature);
+ base64_decode(decoded, sizeof(decoded), signature, signature_len);
+
+ tt_str_op(token->object_type, OP_EQ, "SIGNATURE");
+ tt_int_op(token->object_size, OP_EQ, 256);
+ tt_mem_op(token->object_body, OP_EQ, decoded, 256);
+
+ tt_assert(!token->key);
+
+ done:
+ memarea_drop_all(area);
+}
+
+static void
+test_parsecommon_get_next_token_err_too_many_args(void *arg)
+{
+ memarea_t *area = memarea_new();
+ const char *str = "uptime 1024 1024 1024";
+ const char *end = str + strlen(str);
+ const char **s = &str;
+ token_rule_t table = T01("uptime", K_UPTIME, EQ(1), NO_OBJ);
+ (void)arg;
+
+ directory_token_t *token = get_next_token(area, s, end, &table);
+
+ tt_int_op(token->tp, OP_EQ, ERR_);
+ tt_str_op(token->error, OP_EQ, "Too many arguments to uptime");
+
+ done:
+ memarea_drop_all(area);
+ return;
+}
+
+static void
+test_parsecommon_get_next_token_err_too_few_args(void *arg)
+{
+ memarea_t *area = memarea_new();
+ const char *str = "uptime";
+ const char *end = str + strlen(str);
+ const char **s = &str;
+ token_rule_t table = T01("uptime", K_UPTIME, EQ(1), NO_OBJ);
+ (void)arg;
+
+ directory_token_t *token = get_next_token(area, s, end, &table);
+
+ tt_int_op(token->tp, OP_EQ, ERR_);
+ tt_str_op(token->error, OP_EQ, "Too few arguments to uptime");
+
+ done:
+ memarea_drop_all(area);
+ return;
+}
+
+static void
+test_parsecommon_get_next_token_err_obj_missing_endline(void *arg)
+{
+ memarea_t *area = memarea_new();
+
+ const char *str =
+ "directory-signature 0232AF901C31A04EE9848595AF9BB7620D4C5B2E "
+ "CD1FD971855430880D3C31E0331C5C55800C2F79\n"
+ "-----BEGIN SIGNATURE-----\n"
+ "dLTbc1Lad/OWKBJhA/dERzDHumswTAzBFAWAz2vnQhLsebs1SOm0W/vceEsiEkiF\n"
+ "A+JJSzIyfywJc6Mnk7aKMEIFjOO/MaxuAp4zv+q+JonJkF0ExjMqvKR0D6pSFmfN\n"
+ "cnemnxGHxNuPDnKl0imbWKmWDsHtwgi4zWeTq3MekfMOXKi6gIh+bDFzCs9/Vquh\n"
+ "uNKJI1jW/A2DEKeaSAODEv9VoCsYSvbVVEuHCBWjeNAurd5aL26BrAolW6m7pkD6\n"
+ "I+cQ8dQG6Wa/Zt6gLXtBbOP2o/iDI7ahDP9diNkBI/rm4nfp9j4piTwsqpi7xz9J\n"
+ "Ua9DEZB9KbJHVX1rGShrLA==\n";
+
+ const char *end = str + strlen(str);
+ const char **s = &str;
+ token_rule_t rule = T("directory-signature", K_DIRECTORY_SIGNATURE,
+ GE(2), NEED_OBJ);
+ (void)arg;
+
+ directory_token_t *token = get_next_token(area, s, end, &rule);
+
+ tt_int_op(token->tp, OP_EQ, ERR_);
+ tt_str_op(token->error, OP_EQ, "Malformed object: missing object end line");
+
+ done:
+ memarea_drop_all(area);
+ return;
+}
+
+static void
+test_parsecommon_get_next_token_err_bad_beginline(void *arg)
+{
+ memarea_t *area = memarea_new();
+
+ const char *str =
+ "directory-signature 0232AF901C31A04EE9848595AF9BB7620D4C5B2E "
+ "CD1FD971855430880D3C31E0331C5C55800C2F79\n"
+ "-----BEGIN SIGNATURE-Z---\n"
+ "dLTbc1Lad/OWKBJhA/dERzDHumswTAzBFAWAz2vnQhLsebs1SOm0W/vceEsiEkiF\n"
+ "A+JJSzIyfywJc6Mnk7aKMEIFjOO/MaxuAp4zv+q+JonJkF0ExjMqvKR0D6pSFmfN\n"
+ "cnemnxGHxNuPDnKl0imbWKmWDsHtwgi4zWeTq3MekfMOXKi6gIh+bDFzCs9/Vquh\n"
+ "uNKJI1jW/A2DEKeaSAODEv9VoCsYSvbVVEuHCBWjeNAurd5aL26BrAolW6m7pkD6\n"
+ "I+cQ8dQG6Wa/Zt6gLXtBbOP2o/iDI7ahDP9diNkBI/rm4nfp9j4piTwsqpi7xz9J\n"
+ "Ua9DEZB9KbJHVX1rGShrLA==\n"
+ "-----END SIGNATURE-----\n";
+
+ const char *end = str + strlen(str);
+ const char **s = &str;
+ token_rule_t rule = T("directory-signature", K_DIRECTORY_SIGNATURE,
+ GE(2), NEED_OBJ);
+ (void)arg;
+
+ directory_token_t *token = get_next_token(area, s, end, &rule);
+
+ tt_int_op(token->tp, OP_EQ, ERR_);
+ tt_str_op(token->error, OP_EQ, "Malformed object: bad begin line");
+
+ done:
+ memarea_drop_all(area);
+ return;
+}
+
+static void
+test_parsecommon_get_next_token_err_tag_mismatch(void *arg)
+{
+ memarea_t *area = memarea_new();
+
+ const char *str =
+ "directory-signature 0232AF901C31A04EE9848595AF9BB7620D4C5B2E "
+ "CD1FD971855430880D3C31E0331C5C55800C2F79\n"
+ "-----BEGIN SIGNATURE-----\n"
+ "dLTbc1Lad/OWKBJhA/dERzDHumswTAzBFAWAz2vnQhLsebs1SOm0W/vceEsiEkiF\n"
+ "A+JJSzIyfywJc6Mnk7aKMEIFjOO/MaxuAp4zv+q+JonJkF0ExjMqvKR0D6pSFmfN\n"
+ "cnemnxGHxNuPDnKl0imbWKmWDsHtwgi4zWeTq3MekfMOXKi6gIh+bDFzCs9/Vquh\n"
+ "uNKJI1jW/A2DEKeaSAODEv9VoCsYSvbVVEuHCBWjeNAurd5aL26BrAolW6m7pkD6\n"
+ "I+cQ8dQG6Wa/Zt6gLXtBbOP2o/iDI7ahDP9diNkBI/rm4nfp9j4piTwsqpi7xz9J\n"
+ "Ua9DEZB9KbJHVX1rGShrLA==\n"
+ "-----END SOMETHINGELSE-----\n";
+
+ const char *end = str + strlen(str);
+ const char **s = &str;
+ token_rule_t rule = T("directory-signature", K_DIRECTORY_SIGNATURE,
+ GE(2), NEED_OBJ);
+ (void)arg;
+
+ directory_token_t *token = get_next_token(area, s, end, &rule);
+
+ tt_int_op(token->tp, OP_EQ, ERR_);
+ tt_str_op(token->error, OP_EQ,
+ "Malformed object: mismatched end tag SIGNATURE");
+
+ done:
+ memarea_drop_all(area);
+ return;
+}
+
+static void
+test_parsecommon_get_next_token_err_bad_base64(void *arg)
+{
+ memarea_t *area = memarea_new();
+
+ const char *str =
+ "directory-signature 0232AF901C31A04EE9848595AF9BB7620D4C5B2E "
+ "CD1FD971855430880D3C31E0331C5C55800C2F79\n"
+ "-----BEGIN SIGNATURE-----\n"
+ "%%@%%%%%%%!!!'\n"
+ "-----END SIGNATURE-----\n";
+
+ const char *end = str + strlen(str);
+ const char **s = &str;
+ token_rule_t rule = T("directory-signature", K_DIRECTORY_SIGNATURE,
+ GE(2), NEED_OBJ);
+ (void)arg;
+
+ directory_token_t *token = get_next_token(area, s, end, &rule);
+
+ tt_int_op(token->tp, OP_EQ, ERR_);
+ tt_str_op(token->error, OP_EQ, "Malformed object: bad base64-encoded data");
+
+ done:
+ memarea_drop_all(area);
+ return;
+}
+
+#define PARSECOMMON_TEST(name) \
+ { #name, test_parsecommon_ ## name, 0, NULL, NULL }
+
+struct testcase_t parsecommon_tests[] = {
+ PARSECOMMON_TEST(tokenize_string_null),
+ PARSECOMMON_TEST(tokenize_string_multiple_lines),
+ PARSECOMMON_TEST(tokenize_string_min_cnt),
+ PARSECOMMON_TEST(tokenize_string_max_cnt),
+ PARSECOMMON_TEST(tokenize_string_at_start),
+ PARSECOMMON_TEST(tokenize_string_at_end),
+ PARSECOMMON_TEST(tokenize_string_no_annotations),
+ PARSECOMMON_TEST(get_next_token_success),
+ PARSECOMMON_TEST(get_next_token_concat_args),
+ PARSECOMMON_TEST(get_next_token_parse_keys),
+ PARSECOMMON_TEST(get_next_token_object),
+ PARSECOMMON_TEST(get_next_token_err_too_many_args),
+ PARSECOMMON_TEST(get_next_token_err_too_few_args),
+ PARSECOMMON_TEST(get_next_token_err_obj_missing_endline),
+ PARSECOMMON_TEST(get_next_token_err_bad_beginline),
+ PARSECOMMON_TEST(get_next_token_err_tag_mismatch),
+ PARSECOMMON_TEST(get_next_token_err_bad_base64),
+ END_OF_TESTCASES
+};
diff --git a/src/test/test_periodic_event.c b/src/test/test_periodic_event.c
index b447ae8888..86dedd85d8 100644
--- a/src/test/test_periodic_event.c
+++ b/src/test/test_periodic_event.c
@@ -9,7 +9,7 @@
#define CONFIG_PRIVATE
#define HS_SERVICE_PRIVATE
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#include "test/test.h"
#include "test/test_helpers.h"
@@ -18,7 +18,7 @@
#include "app/config/config.h"
#include "feature/hibernate/hibernate.h"
#include "feature/hs/hs_service.h"
-#include "core/mainloop/main.h"
+#include "core/mainloop/mainloop.h"
#include "core/mainloop/periodic.h"
/** Helper function: This is replaced in some tests for the event callbacks so
@@ -87,15 +87,19 @@ test_pe_launch(void *arg)
item->fn = dumb_event_fn;
}
- /* Lets make sure that before intialization, we can't scan the periodic
- * events list and launch them. Lets try by being a Client. */
options = get_options_mutable();
options->SocksPort_set = 1;
periodic_events_on_new_options(options);
+#if 0
+ /* Lets make sure that before intialization, we can't scan the periodic
+ * events list and launch them. Lets try by being a Client. */
+ /* XXXX We make sure these events are initialized now way earlier than we
+ * did before. */
for (int i = 0; periodic_events[i].name; ++i) {
periodic_event_item_t *item = &periodic_events[i];
tt_int_op(periodic_event_is_enabled(item), OP_EQ, 0);
}
+#endif
initialize_periodic_events();
diff --git a/src/test/test_policy.c b/src/test/test_policy.c
index 6a07e5b1f8..afe608f5f7 100644
--- a/src/test/test_policy.c
+++ b/src/test/test_policy.c
@@ -1,19 +1,20 @@
/* Copyright (c) 2013-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "core/or/or.h"
#define CONFIG_PRIVATE
-#include "app/config/config.h"
-#include "feature/relay/router.h"
-#include "feature/nodelist/routerparse.h"
#define POLICIES_PRIVATE
+
+#include "core/or/or.h"
+#include "app/config/config.h"
#include "core/or/policies.h"
+#include "feature/dirparse/policy_parse.h"
+#include "feature/relay/router.h"
#include "lib/encoding/confline.h"
#include "test/test.h"
#include "core/or/addr_policy_st.h"
-#include "feature/nodelist/node_st.h"
#include "core/or/port_cfg_st.h"
+#include "feature/nodelist/node_st.h"
#include "feature/nodelist/routerinfo_st.h"
#include "feature/nodelist/routerstatus_st.h"
diff --git a/src/test/test_protover.c b/src/test/test_protover.c
index ac8e98250e..5f9a8b7937 100644
--- a/src/test/test_protover.c
+++ b/src/test/test_protover.c
@@ -10,6 +10,7 @@
#include "core/or/or.h"
#include "core/or/connection_or.h"
+#include "lib/tls/tortls.h"
static void
test_protover_parse(void *arg)
@@ -167,6 +168,14 @@ test_protover_vote(void *arg)
tt_str_op(result, OP_EQ, "");
tor_free(result);
+ /* Don't count double-voting. */
+ smartlist_clear(lst);
+ smartlist_add(lst, (void*) "Foo=1 Foo=1");
+ smartlist_add(lst, (void*) "Bar=1-2,2-3");
+ result = protover_compute_vote(lst, 2);
+ tt_str_op(result, OP_EQ, "");
+ tor_free(result);
+
/* Bad votes: the result must be empty */
smartlist_clear(lst);
smartlist_add(lst, (void*) "Faux=10-5");
@@ -259,6 +268,7 @@ test_protover_all_supported(void *arg)
tt_ptr_op(msg, OP_EQ, NULL);
// Some things we don't support
+ tt_assert(! protover_all_supported("Wombat=9", NULL));
tt_assert(! protover_all_supported("Wombat=9", &msg));
tt_str_op(msg, OP_EQ, "Wombat=9");
tor_free(msg);
@@ -290,13 +300,13 @@ test_protover_all_supported(void *arg)
tor_free(msg);
/* We shouldn't be able to DoS ourselves parsing a large range. */
- tt_assert(! protover_all_supported("Sleen=0-2147483648", &msg));
- tt_str_op(msg, OP_EQ, "Sleen=0-2147483648");
+ tt_assert(! protover_all_supported("Sleen=1-2147483648", &msg));
+ tt_str_op(msg, OP_EQ, "Sleen=1-2147483648");
tor_free(msg);
/* This case is allowed. */
- tt_assert(! protover_all_supported("Sleen=0-4294967294", &msg));
- tt_str_op(msg, OP_EQ, "Sleen=0-4294967294");
+ tt_assert(! protover_all_supported("Sleen=1-4294967294", &msg));
+ tt_str_op(msg, OP_EQ, "Sleen=1-4294967294");
tor_free(msg);
/* If we get a (barely) valid (but unsupported list, we say "yes, that's
@@ -313,7 +323,7 @@ test_protover_all_supported(void *arg)
/* If we get a completely unparseable list, protover_all_supported should
* hit a fatal assertion for BUG(entries == NULL). */
tor_capture_bugs_(1);
- tt_assert(protover_all_supported("Sleen=0-4294967295", &msg));
+ tt_assert(protover_all_supported("Sleen=1-4294967295", &msg));
tor_end_capture_bugs_();
/* Protocol name too long */
@@ -444,10 +454,12 @@ test_protover_supported_protocols(void *arg)
}
}
+#ifdef HAVE_WORKING_TOR_TLS_GET_TLSSECRETS
/* Legacy LinkAuth does not appear anywhere in the code. */
tt_assert(protocol_list_supports_protocol(supported_protocols,
PRT_LINKAUTH,
PROTOVER_LINKAUTH_V1));
+#endif
/* Latest LinkAuth is not exposed in the headers. */
tt_assert(protocol_list_supports_protocol(supported_protocols,
PRT_LINKAUTH,
@@ -543,16 +555,20 @@ test_protover_vote_roundtrip(void *args)
const char *input;
const char *expected_output;
} examples[] = {
+ { "Risqu\u00e9=1", NULL },
+ { ",,,=1", NULL },
+ { "\xc1=1", NULL },
+ { "Foo_Bar=1", NULL },
{ "Fkrkljdsf", NULL },
{ "Zn=4294967295", NULL },
{ "Zn=4294967295-1", NULL },
{ "Zn=4294967293-4294967295", NULL },
/* Will fail because of 4294967295. */
- { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=0,4294967295",
+ { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=1,4294967295",
NULL },
- { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=0,4294967294",
- "Bar=3 Foo=1,3 Quux=9-12,14-16,900 Zn=0,4294967294" },
- { "Zu16=0,65536", "Zu16=0,65536" },
+ { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=1,4294967294",
+ "Bar=3 Foo=1,3 Quux=9-12,14-16,900 Zn=1,4294967294" },
+ { "Zu16=1,65536", "Zu16=1,65536" },
{ "N-1=1,2", "N-1=1-2" },
{ "-1=4294967295", NULL },
{ "-1=3", "-1=3" },
@@ -589,9 +605,9 @@ test_protover_vote_roundtrip(void *args)
{ "Sleen=1-501", "Sleen=1-501" },
{ "Sleen=1-65537", NULL },
/* Both C/Rust implementations should be able to handle this mild DoS. */
- { "Sleen=0-2147483648", NULL },
+ { "Sleen=1-2147483648", NULL },
/* Rust tests are built in debug mode, so ints are bounds-checked. */
- { "Sleen=0-4294967295", NULL },
+ { "Sleen=1-4294967295", NULL },
};
unsigned u;
smartlist_t *votes = smartlist_new();
@@ -633,4 +649,3 @@ struct testcase_t protover_tests[] = {
PV_TEST(vote_roundtrip, 0),
END_OF_TESTCASES
};
-
diff --git a/src/test/test_rebind.py b/src/test/test_rebind.py
new file mode 100644
index 0000000000..7ba3a5796d
--- /dev/null
+++ b/src/test/test_rebind.py
@@ -0,0 +1,93 @@
+from __future__ import print_function
+
+import sys
+import subprocess
+import socket
+import os
+import time
+import random
+
+def try_connecting_to_socksport():
+ socks_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ if socks_socket.connect_ex(('127.0.0.1', socks_port)):
+ tor_process.terminate()
+ print('FAIL')
+ sys.exit('Cannot connect to SOCKSPort')
+ socks_socket.close()
+
+def wait_for_log(s):
+ while True:
+ l = tor_process.stdout.readline()
+ if s in l.decode('utf8'):
+ return
+
+def pick_random_port():
+ port = 0
+ random.seed()
+
+ for i in range(8):
+ port = random.randint(10000, 60000)
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ if s.connect_ex(('127.0.0.1', port)) == 0:
+ s.close()
+ else:
+ break
+
+ return port
+
+if sys.hexversion < 0x02070000:
+ sys.exit("ERROR: unsupported Python version (should be >= 2.7)")
+
+if sys.hexversion > 0x03000000 and sys.hexversion < 0x03010000:
+ sys.exit("ERROR: unsupported Python3 version (should be >= 3.1)")
+
+control_port = pick_random_port()
+socks_port = pick_random_port()
+
+assert control_port != 0
+assert socks_port != 0
+
+if not os.path.exists(sys.argv[1]):
+ sys.exit('ERROR: cannot find tor at %s' % sys.argv[1])
+
+tor_path = sys.argv[1]
+
+tor_process = subprocess.Popen([tor_path,
+ '-ControlPort', '127.0.0.1:{}'.format(control_port),
+ '-SOCKSPort', '127.0.0.1:{}'.format(socks_port),
+ '-FetchServerDescriptors', '0'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+
+if tor_process == None:
+ sys.exit('ERROR: running tor failed')
+
+if len(sys.argv) < 2:
+ sys.exit('Usage: %s <path-to-tor>' % sys.argv[0])
+
+wait_for_log('Opened Control listener on')
+
+try_connecting_to_socksport()
+
+control_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+if control_socket.connect_ex(('127.0.0.1', control_port)):
+ tor_process.terminate()
+ print('FAIL')
+ sys.exit('Cannot connect to ControlPort')
+
+control_socket.sendall('AUTHENTICATE \r\n'.encode('utf8'))
+control_socket.sendall('SETCONF SOCKSPort=0.0.0.0:{}\r\n'.format(socks_port).encode('utf8'))
+wait_for_log('Opened Socks listener')
+
+try_connecting_to_socksport()
+
+control_socket.sendall('SETCONF SOCKSPort=127.0.0.1:{}\r\n'.format(socks_port).encode('utf8'))
+wait_for_log('Opened Socks listener')
+
+try_connecting_to_socksport()
+
+control_socket.sendall('SIGNAL HALT\r\n'.encode('utf8'))
+
+time.sleep(0.1)
+print('OK')
+tor_process.terminate()
diff --git a/src/test/test_rebind.sh b/src/test/test_rebind.sh
new file mode 100755
index 0000000000..76eb9f2e4d
--- /dev/null
+++ b/src/test/test_rebind.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+set -x
+
+UNAME_OS=$(uname -s | cut -d_ -f1)
+if test "$UNAME_OS" = 'CYGWIN' || \
+ test "$UNAME_OS" = 'MSYS' || \
+ test "$UNAME_OS" = 'MINGW'; then
+ if test "$APPVEYOR" = 'True'; then
+ echo "This test is disabled on Windows CI, as it requires firewall examptions. Skipping." >&2
+ exit 77
+ fi
+fi
+
+exitcode=0
+
+"${PYTHON:-python}" "${abs_top_srcdir:-.}/src/test/test_rebind.py" "${TESTING_TOR_BINARY}" || exitcode=1
+
+exit ${exitcode}
diff --git a/src/test/test_relay.c b/src/test/test_relay.c
index 25084fab37..4311392be8 100644
--- a/src/test/test_relay.c
+++ b/src/test/test_relay.c
@@ -1,12 +1,17 @@
/* Copyright (c) 2014-2018, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "core/or/or.h"
#define CIRCUITBUILD_PRIVATE
+#define RELAY_PRIVATE
+#define REPHIST_PRIVATE
+#include "core/or/or.h"
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
-#define RELAY_PRIVATE
+#include "core/or/channeltls.h"
+#include "feature/stats/rephist.h"
#include "core/or/relay.h"
+#include "feature/stats/rephist.h"
+#include "lib/container/order.h"
/* For init/free stuff */
#include "core/or/scheduler.h"
@@ -31,10 +36,9 @@ new_fake_orcirc(channel_t *nchan, channel_t *pchan)
circ = &(orcirc->base_);
circ->magic = OR_CIRCUIT_MAGIC;
- circ->n_chan = nchan;
- circ->n_circ_id = get_unique_circ_id_by_chan(nchan);
- circ->n_mux = NULL; /* ?? */
+ circuit_set_n_circid_chan(circ, get_unique_circ_id_by_chan(nchan), nchan);
cell_queue_init(&(circ->n_chan_cells));
+
circ->n_hop = NULL;
circ->streams_blocked_on_n_chan = 0;
circ->streams_blocked_on_p_chan = 0;
@@ -47,14 +51,109 @@ new_fake_orcirc(channel_t *nchan, channel_t *pchan)
circ->deliver_window = CIRCWINDOW_START_MAX;
circ->n_chan_create_cell = NULL;
- orcirc->p_chan = pchan;
- orcirc->p_circ_id = get_unique_circ_id_by_chan(pchan);
+ circuit_set_p_circid_chan(orcirc, get_unique_circ_id_by_chan(pchan), pchan);
cell_queue_init(&(orcirc->p_chan_cells));
return orcirc;
}
static void
+assert_circuit_ok_mock(const circuit_t *c)
+{
+ (void) c;
+ return;
+}
+
+static void
+test_relay_close_circuit(void *arg)
+{
+ channel_t *nchan = NULL, *pchan = NULL;
+ or_circuit_t *orcirc = NULL;
+ cell_t *cell = NULL;
+ int old_count, new_count;
+
+ (void)arg;
+
+ /* Make fake channels to be nchan and pchan for the circuit */
+ nchan = new_fake_channel();
+ tt_assert(nchan);
+
+ pchan = new_fake_channel();
+ tt_assert(pchan);
+
+ /* Make a fake orcirc */
+ orcirc = new_fake_orcirc(nchan, pchan);
+ tt_assert(orcirc);
+ circuitmux_attach_circuit(nchan->cmux, TO_CIRCUIT(orcirc),
+ CELL_DIRECTION_OUT);
+ circuitmux_attach_circuit(pchan->cmux, TO_CIRCUIT(orcirc),
+ CELL_DIRECTION_IN);
+
+ /* Make a cell */
+ cell = tor_malloc_zero(sizeof(cell_t));
+ make_fake_cell(cell);
+
+ MOCK(scheduler_channel_has_waiting_cells,
+ scheduler_channel_has_waiting_cells_mock);
+ MOCK(assert_circuit_ok,
+ assert_circuit_ok_mock);
+
+ /* Append it */
+ old_count = get_mock_scheduler_has_waiting_cells_count();
+ append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell,
+ CELL_DIRECTION_OUT, 0);
+ new_count = get_mock_scheduler_has_waiting_cells_count();
+ tt_int_op(new_count, OP_EQ, old_count + 1);
+
+ /* Now try the reverse direction */
+ old_count = get_mock_scheduler_has_waiting_cells_count();
+ append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell,
+ CELL_DIRECTION_IN, 0);
+ new_count = get_mock_scheduler_has_waiting_cells_count();
+ tt_int_op(new_count, OP_EQ, old_count + 1);
+
+ /* Ensure our write totals are 0 */
+ tt_u64_op(find_largest_max(write_array), OP_EQ, 0);
+
+ /* Mark the circuit for close */
+ circuit_mark_for_close(TO_CIRCUIT(orcirc), 0);
+
+ /* Check our write totals. */
+ advance_obs(write_array);
+ commit_max(write_array);
+ /* Check for two cells plus overhead */
+ tt_u64_op(find_largest_max(write_array), OP_EQ,
+ 2*(get_cell_network_size(nchan->wide_circ_ids)
+ +TLS_PER_CELL_OVERHEAD));
+
+ UNMOCK(scheduler_channel_has_waiting_cells);
+
+ /* Get rid of the fake channels */
+ MOCK(scheduler_release_channel, scheduler_release_channel_mock);
+ channel_mark_for_close(nchan);
+ channel_mark_for_close(pchan);
+ UNMOCK(scheduler_release_channel);
+
+ /* Shut down channels */
+ channel_free_all();
+
+ done:
+ tor_free(cell);
+ if (orcirc) {
+ circuitmux_detach_circuit(nchan->cmux, TO_CIRCUIT(orcirc));
+ circuitmux_detach_circuit(pchan->cmux, TO_CIRCUIT(orcirc));
+ cell_queue_clear(&orcirc->base_.n_chan_cells);
+ cell_queue_clear(&orcirc->p_chan_cells);
+ }
+ tor_free(orcirc);
+ free_fake_channel(nchan);
+ free_fake_channel(pchan);
+ UNMOCK(assert_circuit_ok);
+
+ return;
+}
+
+static void
test_relay_append_cell_to_circuit_queue(void *arg)
{
channel_t *nchan = NULL, *pchan = NULL;
@@ -129,5 +228,7 @@ test_relay_append_cell_to_circuit_queue(void *arg)
struct testcase_t relay_tests[] = {
{ "append_cell_to_circuit_queue", test_relay_append_cell_to_circuit_queue,
TT_FORK, NULL, NULL },
+ { "close_circ_rephist", test_relay_close_circuit,
+ TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c
index a6c152f738..3d3addfb9e 100644
--- a/src/test/test_relaycell.c
+++ b/src/test/test_relaycell.c
@@ -5,22 +5,31 @@
#define RELAY_PRIVATE
#define CIRCUITLIST_PRIVATE
+#define CONNECTION_EDGE_PRIVATE
+#define CONNECTION_PRIVATE
+
#include "core/or/or.h"
-#include "core/mainloop/main.h"
+#include "core/mainloop/mainloop.h"
#include "app/config/config.h"
#include "core/mainloop/connection.h"
#include "lib/crypt_ops/crypto_cipher.h"
+#include "lib/crypt_ops/crypto_rand.h"
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/connection_edge.h"
#include "core/or/relay.h"
#include "test/test.h"
+#include "test/log_test_helpers.h"
#include "core/or/cell_st.h"
#include "core/or/crypt_path_st.h"
#include "core/or/entry_connection_st.h"
#include "core/or/origin_circuit_st.h"
#include "core/or/socks_request_st.h"
+#include "core/or/half_edge_st.h"
+
+#include "feature/client/circpathbias.h"
+#include "core/or/connection_edge.h"
static int srm_ncalls;
static entry_connection_t *srm_conn;
@@ -31,11 +40,6 @@ static uint8_t srm_answer[512];
static int srm_ttl;
static time_t srm_expires;
-void connection_free_minimal(connection_t*);
-int connected_cell_format_payload(uint8_t *payload_out,
- const tor_addr_t *addr,
- uint32_t ttl);
-
/* Mock replacement for connection_ap_hannshake_socks_resolved() */
static void
socks_resolved_mock(entry_connection_t *conn,
@@ -108,6 +112,16 @@ mock_connection_mark_unattached_ap_(entry_connection_t *conn, int endreason,
}
static void
+mock_mark_circ_for_close(circuit_t *circ, int reason, int line,
+ const char *file)
+{
+ (void)reason; (void)line; (void)file;
+
+ circ->marked_for_close = 1;
+ return;
+}
+
+static void
mock_mark_for_close(connection_t *conn,
int line, const char *file)
{
@@ -125,19 +139,38 @@ mock_start_reading(connection_t *conn)
return;
}
-static void
-test_circbw_relay(void *arg)
+static int
+mock_send_command(streamid_t stream_id, circuit_t *circ,
+ uint8_t relay_command, const char *payload,
+ size_t payload_len, crypt_path_t *cpath_layer,
+ const char *filename, int lineno)
+{
+ (void)stream_id; (void)circ;
+ (void)relay_command; (void)payload;
+ (void)payload_len; (void)cpath_layer;
+ (void)filename; (void)lineno;
+
+ return 0;
+}
+
+static entry_connection_t *
+fake_entry_conn(origin_circuit_t *oncirc, streamid_t id)
{
- cell_t cell;
- relay_header_t rh;
- tor_addr_t addr;
edge_connection_t *edgeconn;
entry_connection_t *entryconn;
- origin_circuit_t *circ;
- int delivered = 0;
- int overhead = 0;
- (void)arg;
+ entryconn = entry_connection_new(CONN_TYPE_AP, AF_INET);
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
+ edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
+ edgeconn->deliver_window = STREAMWINDOW_START;
+ edgeconn->package_window = STREAMWINDOW_START;
+
+ edgeconn->stream_id = id;
+ edgeconn->on_circuit = TO_CIRCUIT(oncirc);
+ edgeconn->cpath_layer = oncirc->cpath;
+
+ return entryconn;
+}
#define PACK_CELL(id, cmd, body_s) do { \
memset(&cell, 0, sizeof(cell)); \
@@ -160,18 +193,521 @@ test_circbw_relay(void *arg)
tt_int_op(circ->n_overhead_read_circ_bw, OP_EQ, overhead); \
} while (0)
+static int
+subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
+{
+ cell_t cell;
+ relay_header_t rh;
+ edge_connection_t *edgeconn;
+ entry_connection_t *entryconn2=NULL;
+ entry_connection_t *entryconn3=NULL;
+ entry_connection_t *entryconn4=NULL;
+ int delivered = circ->n_delivered_read_circ_bw;
+ int overhead = circ->n_overhead_read_circ_bw;
+
+ /* Make new entryconns */
+ entryconn2 = fake_entry_conn(circ, init_id);
+ entryconn2->socks_request->has_finished = 1;
+ entryconn3 = fake_entry_conn(circ, init_id+1);
+ entryconn3->socks_request->has_finished = 1;
+ entryconn4 = fake_entry_conn(circ, init_id+2);
+ entryconn4->socks_request->has_finished = 1;
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn2);
+ edgeconn->package_window = 23;
+ edgeconn->base_.state = AP_CONN_STATE_OPEN;
+
+ int data_cells = edgeconn->deliver_window;
+ int sendme_cells = (STREAMWINDOW_START-edgeconn->package_window)
+ /STREAMWINDOW_INCREMENT;
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ connection_edge_reached_eof(edgeconn);
+
+ /* Data cell not in the half-opened list */
+ PACK_CELL(4000, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Sendme cell not in the half-opened list */
+ PACK_CELL(4000, RELAY_COMMAND_SENDME, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Connected cell not in the half-opened list */
+ PACK_CELL(4000, RELAY_COMMAND_CONNECTED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Resolved cell not in the half-opened list */
+ PACK_CELL(4000, RELAY_COMMAND_RESOLVED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Connected cell: not counted -- we were open */
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn2);
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* DATA cells up to limit */
+ while (data_cells > 0) {
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+ data_cells--;
+ }
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* SENDME cells up to limit */
+ while (sendme_cells > 0) {
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+ sendme_cells--;
+ }
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Only one END cell */
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn3);
+ edgeconn->base_.state = AP_CONN_STATE_OPEN;
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ /* sendme cell on open entryconn with full window */
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
+ int ret =
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ tt_int_op(ret, OP_EQ, -END_CIRC_REASON_TORPROTOCOL);
+ ASSERT_UNCOUNTED_BW();
+
+ /* connected cell on a after EOF */
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
+ connection_edge_reached_eof(edgeconn);
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* DATA and SENDME after END cell */
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
+ ret =
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ tt_int_op(ret, OP_NE, -END_CIRC_REASON_TORPROTOCOL);
+ ASSERT_UNCOUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Resolved: 1 counted, more not */
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn4);
+ entryconn4->socks_request->command = SOCKS_COMMAND_RESOLVE;
+ edgeconn->base_.state = AP_CONN_STATE_RESOLVE_WAIT;
+ edgeconn->on_circuit = TO_CIRCUIT(circ);
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ connection_edge_reached_eof(edgeconn);
+
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
+ "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
+ "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Data not counted after resolved */
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* End not counted after resolved */
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ connection_free_minimal(ENTRY_TO_CONN(entryconn2));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn3));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn4));
+ return 1;
+ done:
+ connection_free_minimal(ENTRY_TO_CONN(entryconn2));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn3));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn4));
+ return 0;
+}
+
+static int
+halfstream_insert(origin_circuit_t *circ, edge_connection_t *edgeconn,
+ streamid_t *streams, int num, int random)
+{
+ int inserted = 0;
+
+ /* Insert num random elements */
+ while (inserted < num) {
+ streamid_t id;
+
+ if (random)
+ id = (streamid_t)crypto_rand_int(65535)+1;
+ else
+ id = get_unique_stream_id_by_circ(circ);
+
+ edgeconn->stream_id = id;
+
+ /* Ensure it isn't there */
+ if (connection_half_edge_find_stream_id(circ->half_streams, id)) {
+ continue;
+ }
+
+ connection_half_edge_add(edgeconn, circ);
+ if (streams)
+ streams[inserted] = id;
+ inserted++;
+ }
+
+ return inserted;
+}
+
+static void
+subtest_halfstream_insertremove(int num)
+{
+ origin_circuit_t *circ =
+ helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
+ edge_connection_t *edgeconn;
+ entry_connection_t *entryconn;
+ streamid_t *streams = tor_malloc_zero(num*sizeof(streamid_t));
+ int i = 0;
+
+ circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
+ circ->cpath->deliver_window = CIRCWINDOW_START;
+
+ entryconn = fake_entry_conn(circ, 23);
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
+
+ /* Explicity test all operations on an absent stream list */
+ tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 23), OP_EQ, 0);
+
+ /* Insert a duplicate element; verify that other elements absent;
+ * ensure removing it once works */
+ edgeconn->stream_id = 23;
+ connection_half_edge_add(edgeconn, circ);
+ connection_half_edge_add(edgeconn, circ);
+ connection_half_edge_add(edgeconn, circ);
+
+ /* Verify that other elements absent */
+ tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
+ 22), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
+ 22), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
+ 22), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
+ 22), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 22), OP_EQ, 0);
+
+ tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
+ 24), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
+ 24), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
+ 24), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
+ 24), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 24), OP_EQ, 0);
+
+ /* Verify we only remove it once */
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 23), OP_EQ, 1);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 23), OP_EQ, 0);
+
+ halfstream_insert(circ, edgeconn, streams, num, 1);
+
+ /* Remove half of them */
+ for (i = 0; i < num/2; i++) {
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ streams[i]),
+ OP_EQ, 1);
+ }
+
+ /* Verify first half of list is gone */
+ for (i = 0; i < num/2; i++) {
+ tt_ptr_op(connection_half_edge_find_stream_id(circ->half_streams,
+ streams[i]),
+ OP_EQ, NULL);
+ }
+
+ /* Verify second half of list is present */
+ for (; i < num; i++) {
+ tt_ptr_op(connection_half_edge_find_stream_id(circ->half_streams,
+ streams[i]),
+ OP_NE, NULL);
+ }
+
+ /* Remove other half. Verify list is empty. */
+ for (i = num/2; i < num; i++) {
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ streams[i]),
+ OP_EQ, 1);
+ }
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 0);
+
+ /* Explicity test all operations on an empty stream list */
+ tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 23), OP_EQ, 0);
+
+ /* For valgrind, leave some around then free the circ */
+ halfstream_insert(circ, edgeconn, NULL, 10, 0);
+
+ done:
+ tor_free(streams);
+ circuit_free_(TO_CIRCUIT(circ));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn));
+}
+
+static void
+test_halfstream_insertremove(void *arg)
+{
+ (void)arg;
+
+ /* Suppress the WARN message we generate in this test */
+ setup_full_capture_of_logs(LOG_WARN);
+
+ /* Test insertion and removal with a few different sizes */
+ subtest_halfstream_insertremove(10);
+ subtest_halfstream_insertremove(100);
+ subtest_halfstream_insertremove(1000);
+}
+
+static void
+test_halfstream_wrap(void *arg)
+{
+ origin_circuit_t *circ =
+ helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
+ edge_connection_t *edgeconn;
+ entry_connection_t *entryconn;
+
+ circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
+ circ->cpath->deliver_window = CIRCWINDOW_START;
+
+ entryconn = fake_entry_conn(circ, 23);
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
+
+ (void)arg;
+
+ /* Suppress the WARN message we generate in this test */
+ setup_full_capture_of_logs(LOG_WARN);
+ MOCK(connection_mark_for_close_internal_, mock_mark_for_close);
+
+ /* Verify that get_unique_stream_id_by_circ() can wrap uint16_t */
+ circ->next_stream_id = 65530;
+ halfstream_insert(circ, edgeconn, NULL, 7, 0);
+ tt_int_op(circ->next_stream_id, OP_EQ, 2);
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 7);
+
+ /* Insert full-1 */
+ halfstream_insert(circ, edgeconn, NULL,
+ 65534-smartlist_len(circ->half_streams), 0);
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65534);
+
+ /* Verify that we can get_unique_stream_id_by_circ() successfully */
+ edgeconn->stream_id = get_unique_stream_id_by_circ(circ);
+ tt_int_op(edgeconn->stream_id, OP_NE, 0); /* 0 is failure */
+
+ /* Insert an opened stream on the circ with that id */
+ ENTRY_TO_CONN(entryconn)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
+ edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
+ circ->p_streams = edgeconn;
+
+ /* Verify that get_unique_stream_id_by_circ() fails */
+ tt_int_op(get_unique_stream_id_by_circ(circ), OP_EQ, 0); /* 0 is failure */
+
+ /* eof the one opened stream. Verify it is now in half-closed */
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65534);
+ connection_edge_reached_eof(edgeconn);
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65535);
+
+ /* Verify get_unique_stream_id_by_circ() fails due to full half-closed */
+ circ->p_streams = NULL;
+ tt_int_op(get_unique_stream_id_by_circ(circ), OP_EQ, 0); /* 0 is failure */
+
+ done:
+ circuit_free_(TO_CIRCUIT(circ));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn));
+ UNMOCK(connection_mark_for_close_internal_);
+}
+
+static void
+test_circbw_relay(void *arg)
+{
+ cell_t cell;
+ relay_header_t rh;
+ tor_addr_t addr;
+ edge_connection_t *edgeconn;
+ entry_connection_t *entryconn1=NULL;
+ origin_circuit_t *circ;
+ int delivered = 0;
+ int overhead = 0;
+
+ (void)arg;
+
MOCK(connection_mark_unattached_ap_, mock_connection_mark_unattached_ap_);
MOCK(connection_start_reading, mock_start_reading);
MOCK(connection_mark_for_close_internal_, mock_mark_for_close);
+ MOCK(relay_send_command_from_edge_, mock_send_command);
+ MOCK(circuit_mark_for_close_, mock_mark_circ_for_close);
- entryconn = entry_connection_new(CONN_TYPE_AP, AF_INET);
- edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
- edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
- edgeconn->deliver_window = 1000;
circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
- edgeconn->cpath_layer = circ->cpath;
circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
- circ->cpath->deliver_window = 1000;
+ circ->cpath->deliver_window = CIRCWINDOW_START;
+
+ entryconn1 = fake_entry_conn(circ, 1);
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn1);
/* Stream id 0: Not counted */
PACK_CELL(0, RELAY_COMMAND_END, "Data1234");
@@ -197,7 +733,7 @@ test_circbw_relay(void *arg)
/* Properly formatted resolved cell in correct state: counted */
edgeconn->base_.state = AP_CONN_STATE_RESOLVE_WAIT;
- entryconn->socks_request->command = SOCKS_COMMAND_RESOLVE;
+ entryconn1->socks_request->command = SOCKS_COMMAND_RESOLVE;
edgeconn->on_circuit = TO_CIRCUIT(circ);
PACK_CELL(1, RELAY_COMMAND_RESOLVED,
"\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
@@ -206,7 +742,7 @@ test_circbw_relay(void *arg)
ASSERT_COUNTED_BW();
edgeconn->base_.state = AP_CONN_STATE_OPEN;
- entryconn->socks_request->has_finished = 1;
+ entryconn1->socks_request->has_finished = 1;
/* Connected cell after open: not counted */
PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234");
@@ -227,42 +763,43 @@ test_circbw_relay(void *arg)
ASSERT_UNCOUNTED_BW();
/* Data cell on stream 0: not counted */
- PACK_CELL(1, RELAY_COMMAND_DATA, "Data1234");
+ PACK_CELL(0, RELAY_COMMAND_DATA, "Data1234");
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Data cell on open connection: counted */
- ENTRY_TO_CONN(entryconn)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
PACK_CELL(1, RELAY_COMMAND_DATA, "Data1234");
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_COUNTED_BW();
/* Empty Data cell on open connection: not counted */
- ENTRY_TO_CONN(entryconn)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
PACK_CELL(1, RELAY_COMMAND_DATA, "");
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Sendme on valid stream: counted */
- ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
+ edgeconn->package_window -= STREAMWINDOW_INCREMENT;
+ ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_COUNTED_BW();
/* Sendme on valid stream with full window: not counted */
- ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
+ ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
- edgeconn->package_window = 500;
+ edgeconn->package_window = STREAMWINDOW_START;
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Sendme on unknown stream: not counted */
- ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
+ ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -281,18 +818,6 @@ test_circbw_relay(void *arg)
circ->cpath);
ASSERT_COUNTED_BW();
- /* End cell on non-closed connection: counted */
- PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
- circ->cpath);
- ASSERT_COUNTED_BW();
-
- /* End cell on connection that already got one: not counted */
- PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
- circ->cpath);
- ASSERT_UNCOUNTED_BW();
-
/* Invalid extended cell: not counted */
PACK_CELL(1, RELAY_COMMAND_EXTENDED2, "Data1234");
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
@@ -318,12 +843,40 @@ test_circbw_relay(void *arg)
circ->cpath);
ASSERT_COUNTED_BW();
+ /* End cell on non-closed connection: counted */
+ PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ /* End cell on connection that already got one: not counted */
+ PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Simulate closed stream on entryconn, then test: */
+ if (!subtest_circbw_halfclosed(circ, 2))
+ goto done;
+
+ circ->base_.purpose = CIRCUIT_PURPOSE_PATH_BIAS_TESTING;
+ if (!subtest_circbw_halfclosed(circ, 6))
+ goto done;
+
+ /* Path bias: truncated */
+ tt_int_op(circ->base_.marked_for_close, OP_EQ, 0);
+ PACK_CELL(0, RELAY_COMMAND_TRUNCATED, "Data1234");
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
+ tt_int_op(circ->base_.marked_for_close, OP_EQ, 1);
+
done:
UNMOCK(connection_start_reading);
UNMOCK(connection_mark_unattached_ap_);
UNMOCK(connection_mark_for_close_internal_);
+ UNMOCK(relay_send_command_from_edge_);
+ UNMOCK(circuit_mark_for_close_);
circuit_free_(TO_CIRCUIT(circ));
- connection_free_minimal(ENTRY_TO_CONN(entryconn));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn1));
}
/* Tests for connection_edge_process_resolved_cell().
@@ -511,6 +1064,7 @@ test_relaycell_resolved(void *arg)
struct testcase_t relaycell_tests[] = {
{ "resolved", test_relaycell_resolved, TT_FORK, NULL, NULL },
{ "circbw", test_circbw_relay, TT_FORK, NULL, NULL },
+ { "halfstream", test_halfstream_insertremove, TT_FORK, NULL, NULL },
+ { "streamwrap", test_halfstream_wrap, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_router.c b/src/test/test_router.c
index 533135669f..921ec42904 100644
--- a/src/test/test_router.c
+++ b/src/test/test_router.c
@@ -9,7 +9,7 @@
#include "core/or/or.h"
#include "app/config/config.h"
-#include "core/mainloop/main.h"
+#include "core/mainloop/mainloop.h"
#include "feature/hibernate/hibernate.h"
#include "feature/nodelist/routerinfo_st.h"
#include "feature/nodelist/routerlist.h"
diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c
index b62aea113e..f05401ba0d 100644
--- a/src/test/test_routerkeys.c
+++ b/src/test/test_routerkeys.c
@@ -11,6 +11,7 @@
#include "feature/relay/routerkeys.h"
#include "lib/crypt_ops/crypto_cipher.h"
#include "lib/crypt_ops/crypto_format.h"
+#include "feature/keymgt/loadkey.h"
#include "feature/nodelist/torcert.h"
#include "test/test.h"
diff --git a/src/test/test_routerlist.c b/src/test/test_routerlist.c
index e7c577cf66..1071a095fe 100644
--- a/src/test/test_routerlist.c
+++ b/src/test/test_routerlist.c
@@ -6,19 +6,21 @@
#include <time.h>
#define CONNECTION_PRIVATE
-#define DIRECTORY_PRIVATE
+#define DIRCLIENT_PRIVATE
#define DIRVOTE_PRIVATE
#define ENTRYNODES_PRIVATE
#define HIBERNATE_PRIVATE
#define NETWORKSTATUS_PRIVATE
#define ROUTERLIST_PRIVATE
+#define NODE_SELECT_PRIVATE
#define TOR_UNIT_TESTING
#include "core/or/or.h"
#include "app/config/config.h"
#include "core/mainloop/connection.h"
#include "feature/control/control.h"
#include "lib/crypt_ops/crypto_rand.h"
-#include "feature/dircache/directory.h"
+#include "feature/dircommon/directory.h"
+#include "feature/dirclient/dirclient.h"
#include "feature/dirauth/dirvote.h"
#include "feature/client/entrynodes.h"
#include "feature/hibernate/hibernate.h"
@@ -27,9 +29,12 @@
#include "feature/nodelist/nodelist.h"
#include "core/or/policies.h"
#include "feature/relay/router.h"
+#include "feature/nodelist/authcert.h"
+#include "feature/nodelist/node_select.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerset.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/dirparse/authcert_parse.h"
+#include "feature/dirparse/ns_parse.h"
#include "feature/dirauth/shared_random.h"
#include "app/config/statefile.h"
diff --git a/src/test/test_routerset.c b/src/test/test_routerset.c
index 2017ef0050..86f9c0fa82 100644
--- a/src/test/test_routerset.c
+++ b/src/test/test_routerset.c
@@ -4,11 +4,11 @@
#define ROUTERSET_PRIVATE
#include "core/or/or.h"
-#include "feature/stats/geoip.h"
-#include "feature/nodelist/routerset.h"
-#include "feature/nodelist/routerparse.h"
#include "core/or/policies.h"
+#include "feature/dirparse/policy_parse.h"
#include "feature/nodelist/nodelist.h"
+#include "feature/nodelist/routerset.h"
+#include "lib/geoip/geoip.h"
#include "core/or/addr_policy_st.h"
#include "core/or/extend_info_st.h"
@@ -1496,6 +1496,7 @@ NS(test_main)(void *arg)
int r;
(void)arg;
+ memset(&NS(mock_node), 0, sizeof(NS(mock_node)));
NS(mock_node).ri = NULL;
NS(mock_node).rs = NULL;
@@ -1529,6 +1530,7 @@ NS(test_main)(void *arg)
strncpy(rs.nickname, nickname, sizeof(rs.nickname) - 1);
rs.nickname[sizeof(rs.nickname) - 1] = '\0';
+ memset(&NS(mock_node), 0, sizeof(NS(mock_node)));
NS(mock_node).ri = NULL;
NS(mock_node).rs = &rs;
@@ -1560,6 +1562,7 @@ NS(test_main)(void *arg)
strmap_set_lc(set->names, nickname, (void *)1);
ri.nickname = (char *)nickname;
+ memset(&mock_node, 0, sizeof(mock_node));
mock_node.ri = &ri;
mock_node.rs = NULL;
diff --git a/src/test/test_rust.sh b/src/test/test_rust.sh
index 4afc84285f..00b3e88d37 100755
--- a/src/test/test_rust.sh
+++ b/src/test/test_rust.sh
@@ -5,11 +5,20 @@ set -e
export LSAN_OPTIONS=suppressions=${abs_top_srcdir:-../../..}/src/test/rust_supp.txt
+# When testing Cargo we pass a number of very specific linker flags down
+# through Cargo. We do not, however, want these flags to affect things like
+# build scripts, only the tests that we're compiling. To ensure this happens
+# we unconditionally pass `--target` into Cargo, ensuring that `RUSTFLAGS` in
+# the environment won't make their way into build scripts.
+rustc_host=$(rustc -vV | grep host | sed 's/host: //')
+
for cargo_toml_dir in "${abs_top_srcdir:-../../..}"/src/rust/*; do
if [ -e "${cargo_toml_dir}/Cargo.toml" ]; then
cd "${abs_top_builddir:-../../..}/src/rust" && \
CARGO_TARGET_DIR="${abs_top_builddir:-../../..}/src/rust/target" \
"${CARGO:-cargo}" test ${CARGO_ONLINE-"--frozen"} \
+ --features "test_linking_hack" \
+ --target $rustc_host \
${EXTRA_CARGO_OPTIONS} \
--manifest-path "${cargo_toml_dir}/Cargo.toml" || exitcode=1
fi
diff --git a/src/test/test_shared_random.c b/src/test/test_shared_random.c
index 2043613641..433661f128 100644
--- a/src/test/test_shared_random.c
+++ b/src/test/test_shared_random.c
@@ -17,8 +17,9 @@
#include "feature/nodelist/networkstatus.h"
#include "feature/relay/router.h"
#include "feature/relay/routerkeys.h"
-#include "feature/nodelist/routerlist.h"
-#include "feature/nodelist/routerparse.h"
+#include "feature/nodelist/authcert.h"
+#include "feature/nodelist/dirlist.h"
+#include "feature/dirparse/authcert_parse.h"
#include "feature/hs_common/shared_random_client.h"
#include "feature/dircommon/voting_schedule.h"
diff --git a/src/test/test_status.c b/src/test/test_status.c
index 15c406d2ff..3ceba77a84 100644
--- a/src/test/test_status.c
+++ b/src/test/test_status.c
@@ -21,7 +21,8 @@
#include "feature/stats/rephist.h"
#include "core/or/relay.h"
#include "feature/relay/router.h"
-#include "core/mainloop/main.h"
+#include "feature/relay/routermode.h"
+#include "core/mainloop/mainloop.h"
#include "feature/nodelist/nodelist.h"
#include "app/config/statefile.h"
#include "lib/tls/tortls.h"
diff --git a/src/test/test_storagedir.c b/src/test/test_storagedir.c
index 68cee418ad..76aae7e033 100644
--- a/src/test/test_storagedir.c
+++ b/src/test/test_storagedir.c
@@ -283,7 +283,7 @@ test_storagedir_save_labeled(void *arg)
int r = storage_dir_save_labeled_to_file(d, labels, inp, 8192, &fname);
tt_int_op(r, OP_EQ, 0);
- size_t n;
+ size_t n = 0;
saved = storage_dir_read(d, fname, 1, &n);
tt_assert(memchr(saved, '\0', n));
tt_str_op((char*)saved, OP_EQ, expected); /* NUL guarantees strcmp works */
diff --git a/src/test/test_threads.c b/src/test/test_threads.c
index f0a4dd2057..2bf5026061 100644
--- a/src/test/test_threads.c
+++ b/src/test/test_threads.c
@@ -234,25 +234,33 @@ test_threads_conditionvar(void *arg)
if (timeout) {
ti->tv = &msec100;
}
+
+#define SPIN_UNTIL(condition,sleep_msec) \
+ while (1) { \
+ tor_mutex_acquire(ti->mutex); \
+ if (condition) { \
+ break; \
+ } \
+ tor_mutex_release(ti->mutex); \
+ tor_sleep_msec(sleep_msec); \
+ }
+
spawn_func(cv_test_thr_fn_, ti);
spawn_func(cv_test_thr_fn_, ti);
spawn_func(cv_test_thr_fn_, ti);
spawn_func(cv_test_thr_fn_, ti);
- tor_mutex_acquire(ti->mutex);
+ SPIN_UNTIL(ti->n_threads == 4, 10);
+
+ time_t started_at = time(NULL);
+
ti->addend = 7;
ti->shutdown = 1;
tor_cond_signal_one(ti->cond);
tor_mutex_release(ti->mutex);
#define SPIN() \
- while (1) { \
- tor_mutex_acquire(ti->mutex); \
- if (ti->addend == 0) { \
- break; \
- } \
- tor_mutex_release(ti->mutex); \
- }
+ SPIN_UNTIL(ti->addend == 0, 0)
SPIN();
@@ -279,8 +287,9 @@ test_threads_conditionvar(void *arg)
if (!timeout) {
tt_int_op(ti->n_shutdown, OP_EQ, 4);
} else {
- tor_sleep_msec(200);
- tor_mutex_acquire(ti->mutex);
+ const int GIVE_UP_AFTER_SEC = 30;
+ SPIN_UNTIL((ti->n_timeouts == 2 ||
+ time(NULL) >= started_at + GIVE_UP_AFTER_SEC), 10);
tt_int_op(ti->n_shutdown, OP_EQ, 2);
tt_int_op(ti->n_timeouts, OP_EQ, 2);
tor_mutex_release(ti->mutex);
@@ -301,4 +310,3 @@ struct testcase_t thread_tests[] = {
&passthrough_setup, (void*)"tv" },
END_OF_TESTCASES
};
-
diff --git a/src/test/test_tortls.c b/src/test/test_tortls.c
index f4315364a2..79b52437f8 100644
--- a/src/test/test_tortls.c
+++ b/src/test/test_tortls.c
@@ -238,6 +238,7 @@ test_tortls_x509_cert_get_id_digests(void *ignored)
cert->pkey_digests_set = 1;
cert->pkey_digests = *d;
res = tor_x509_cert_get_id_digests(cert);
+ tt_assert(res);
tt_int_op(res->d[0][0], OP_EQ, 42);
done:
diff --git a/src/test/test_tortls_openssl.c b/src/test/test_tortls_openssl.c
index 6086252882..abe1fb7889 100644
--- a/src/test/test_tortls_openssl.c
+++ b/src/test/test_tortls_openssl.c
@@ -1007,6 +1007,7 @@ test_tortls_try_to_extract_certs_from_tls(void *ignored)
tt_assert(cert == c1);
tt_assert(id_cert);
X509_free(cert); /* decrease refcnt */
+ X509_free(id_cert); /* decrease refcnt */
done:
sk_X509_free(sess->cert_chain);
@@ -1848,16 +1849,44 @@ fixed_tor_tls_create_certificate(crypto_pk_t *rsa,
(void)cname;
(void)cname_sign;
(void)cert_lifetime;
- return fixed_tor_tls_create_certificate_result[
+ X509 *result = fixed_tor_tls_create_certificate_result[
fixed_tor_tls_create_certificate_result_index++];
+ if (result)
+ return X509_dup(result);
+ else
+ return NULL;
+}
+
+static void
+fixed_tor_tls_create_certificate_results_free(void)
+{
+ unsigned i;
+ for (i = 0; i < ARRAY_LENGTH(fixed_tor_tls_create_certificate_result); ++i) {
+ X509 *cert = fixed_tor_tls_create_certificate_result[i];
+ if (cert)
+ X509_free(cert);
+ fixed_tor_tls_create_certificate_result[i] = NULL;
+ }
+}
+
+static void
+fixed_tor_x509_cert_new_results_free(void)
+{
+ unsigned i;
+ for (i = 0; i < ARRAY_LENGTH(fixed_tor_x509_cert_new_result); ++i) {
+ tor_x509_cert_free(fixed_tor_x509_cert_new_result[i]);
+ }
}
static tor_x509_cert_t *
fixed_tor_x509_cert_new(tor_x509_cert_impl_t *x509_cert)
{
(void) x509_cert;
- return fixed_tor_x509_cert_new_result[
- fixed_tor_x509_cert_new_result_index++];
+ tor_x509_cert_t **certp =
+ &fixed_tor_x509_cert_new_result[fixed_tor_x509_cert_new_result_index++];
+ tor_x509_cert_t *cert = *certp;
+ *certp = NULL;
+ return cert;
}
static void
@@ -1937,6 +1966,7 @@ test_tortls_context_new(void *ignored)
fixed_tor_tls_create_certificate_result[2] = X509_new();
ret = tor_tls_context_new(NULL, 0, 0, 0);
tt_assert(!ret);
+ fixed_tor_tls_create_certificate_results_free();
fixed_crypto_pk_new_result_index = 0;
fixed_crypto_pk_new_result[0] = pk7;
@@ -1949,6 +1979,7 @@ test_tortls_context_new(void *ignored)
fixed_tor_tls_create_certificate_result[2] = X509_new();
ret = tor_tls_context_new(NULL, 0, 0, 0);
tt_assert(!ret);
+ fixed_tor_tls_create_certificate_results_free();
fixed_crypto_pk_new_result_index = 0;
fixed_crypto_pk_new_result[0] = pk9;
@@ -1961,6 +1992,7 @@ test_tortls_context_new(void *ignored)
fixed_tor_tls_create_certificate_result[2] = NULL;
ret = tor_tls_context_new(NULL, 0, 0, 0);
tt_assert(!ret);
+ fixed_tor_tls_create_certificate_results_free();
MOCK(tor_x509_cert_new, fixed_tor_x509_cert_new);
fixed_crypto_pk_new_result_index = 0;
@@ -1978,6 +2010,7 @@ test_tortls_context_new(void *ignored)
fixed_tor_x509_cert_new_result[2] = NULL;
ret = tor_tls_context_new(NULL, 0, 0, 0);
tt_assert(!ret);
+ fixed_tor_tls_create_certificate_results_free();
fixed_crypto_pk_new_result_index = 0;
fixed_crypto_pk_new_result[0] = pk13;
@@ -1994,6 +2027,8 @@ test_tortls_context_new(void *ignored)
fixed_tor_x509_cert_new_result[2] = NULL;
ret = tor_tls_context_new(NULL, 0, 0, 0);
tt_assert(!ret);
+ fixed_tor_tls_create_certificate_results_free();
+ fixed_tor_x509_cert_new_results_free();
fixed_crypto_pk_new_result_index = 0;
fixed_crypto_pk_new_result[0] = pk15;
@@ -2010,6 +2045,8 @@ test_tortls_context_new(void *ignored)
fixed_tor_x509_cert_new_result[2] = NULL;
ret = tor_tls_context_new(NULL, 0, 0, 0);
tt_assert(!ret);
+ fixed_tor_tls_create_certificate_results_free();
+ fixed_tor_x509_cert_new_results_free();
fixed_crypto_pk_new_result_index = 0;
fixed_crypto_pk_new_result[0] = pk17;
@@ -2028,6 +2065,8 @@ test_tortls_context_new(void *ignored)
tt_assert(!ret);
done:
+ fixed_tor_tls_create_certificate_results_free();
+ fixed_tor_x509_cert_new_results_free();
UNMOCK(tor_x509_cert_new);
UNMOCK(tor_tls_create_certificate);
UNMOCK(crypto_pk_generate_key_with_bits);
diff --git a/src/test/test_util.c b/src/test/test_util.c
index b5a231dac6..1a71da2794 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -4013,6 +4013,53 @@ test_util_string_is_C_identifier(void *ptr)
}
static void
+test_util_string_is_utf8(void *ptr)
+{
+ (void)ptr;
+
+ tt_int_op(1, OP_EQ, string_is_utf8(NULL, 0));
+ tt_int_op(1, OP_EQ, string_is_utf8("", 1));
+ tt_int_op(1, OP_EQ, string_is_utf8("\uFEFF", 3));
+ tt_int_op(1, OP_EQ, string_is_utf8("\uFFFE", 3));
+ tt_int_op(1, OP_EQ, string_is_utf8("ascii\x7f\n", 7));
+ tt_int_op(1, OP_EQ, string_is_utf8("Risqu\u00e9=1", 9));
+
+ // Validate exactly 'len' bytes.
+ tt_int_op(0, OP_EQ, string_is_utf8("\0\x80", 2));
+ tt_int_op(0, OP_EQ, string_is_utf8("Risqu\u00e9=1", 6));
+
+ // Reject sequences with missing bytes.
+ tt_int_op(0, OP_EQ, string_is_utf8("\x80", 1));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xc2", 1));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xc2 ", 2));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xe1\x80", 2));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xe1\x80 ", 3));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xf1\x80\x80", 3));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xf1\x80\x80 ", 4));
+
+ // Reject encodings that are overly long.
+ tt_int_op(0, OP_EQ, string_is_utf8("\xc1\xbf", 2));
+ tt_int_op(1, OP_EQ, string_is_utf8("\xc2\x80", 2));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xe0\x9f\xbf", 3));
+ tt_int_op(1, OP_EQ, string_is_utf8("\xe0\xa0\x80", 3));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xf0\x8f\xbf\xbf", 4));
+ tt_int_op(1, OP_EQ, string_is_utf8("\xf0\x90\x80\x80", 4));
+
+ // Reject UTF-16 surrogate halves.
+ tt_int_op(1, OP_EQ, string_is_utf8("\xed\x9f\xbf", 3));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xed\xa0\x80", 3));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xed\xbf\xbf", 3));
+ tt_int_op(1, OP_EQ, string_is_utf8("\xee\x80\x80", 3));
+
+ // The maximum legal codepoint, 10FFFF.
+ tt_int_op(1, OP_EQ, string_is_utf8("\xf4\x8f\xbf\xbf", 4));
+ tt_int_op(0, OP_EQ, string_is_utf8("\xf4\x90\x80\x80", 4));
+
+ done:
+ ;
+}
+
+static void
test_util_asprintf(void *ptr)
{
#define LOREMIPSUM \
@@ -5761,6 +5808,18 @@ test_util_ipv4_validation(void *arg)
}
static void
+test_util_ipv6_validation(void *arg)
+{
+ (void)arg;
+
+ tt_assert(string_is_valid_ipv6_address("2a00:1450:401b:800::200e"));
+ tt_assert(!string_is_valid_ipv6_address("11:22::33:44:"));
+
+ done:
+ return;
+}
+
+static void
test_util_writepid(void *arg)
{
(void) arg;
@@ -6409,6 +6468,7 @@ struct testcase_t util_tests[] = {
UTIL_TEST(clamp_double_to_int64, 0),
UTIL_TEST(find_str_at_start_of_line, 0),
UTIL_TEST(string_is_C_identifier, 0),
+ UTIL_TEST(string_is_utf8, 0),
UTIL_TEST(asprintf, 0),
UTIL_TEST(listdir, 0),
UTIL_TEST(parent_dir, 0),
@@ -6450,6 +6510,7 @@ struct testcase_t util_tests[] = {
UTIL_TEST(hostname_validation, 0),
UTIL_TEST(dest_validation_edgecase, 0),
UTIL_TEST(ipv4_validation, 0),
+ UTIL_TEST(ipv6_validation, 0),
UTIL_TEST(writepid, 0),
UTIL_TEST(get_avail_disk_space, 0),
UTIL_TEST(touch_file, 0),
diff --git a/src/test/test_workqueue.c b/src/test/test_workqueue.c
index 9d48d92773..28fbd6fb9f 100644
--- a/src/test/test_workqueue.c
+++ b/src/test/test_workqueue.c
@@ -5,7 +5,7 @@
#include "core/or/or.h"
#include "lib/thread/threads.h"
-#include "core/crypto/onion.h"
+#include "core/or/onion.h"
#include "lib/evloop/workqueue.h"
#include "lib/crypt_ops/crypto_curve25519.h"
#include "lib/crypt_ops/crypto_rand.h"
diff --git a/src/test/testing_common.c b/src/test/testing_common.c
index 5d4c2f15af..c52683afca 100644
--- a/src/test/testing_common.c
+++ b/src/test/testing_common.c
@@ -8,7 +8,7 @@
* \brief Common pieces to implement unit tests.
**/
-#define MAIN_PRIVATE
+#define MAINLOOP_PRIVATE
#include "orconfig.h"
#include "core/or/or.h"
#include "feature/control/control.h"
@@ -16,11 +16,12 @@
#include "lib/crypt_ops/crypto_dh.h"
#include "lib/crypt_ops/crypto_ed25519.h"
#include "lib/crypt_ops/crypto_rand.h"
+#include "feature/stats/predict_ports.h"
#include "feature/stats/rephist.h"
#include "lib/err/backtrace.h"
#include "test/test.h"
#include "core/or/channelpadding.h"
-#include "core/mainloop/main.h"
+#include "core/mainloop/mainloop.h"
#include "lib/compress/compress.h"
#include "lib/evloop/compat_libevent.h"
#include "lib/crypt_ops/crypto_init.h"