aboutsummaryrefslogtreecommitdiff
path: root/src/test/test_entrynodes.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-05-08 14:12:29 -0400
committerNick Mathewson <nickm@torproject.org>2018-05-08 14:12:29 -0400
commit5edc72a45b7479f5fe791054aa19f6b3b478c725 (patch)
tree9d950f8c59ca8a57884be821f4eab4775125f087 /src/test/test_entrynodes.c
parent2a4439adf37ed75c8f7d2db3134d0263f70de796 (diff)
parente716c92127f0da2fc5758c091a9e33857cd5e5d5 (diff)
downloadtor-5edc72a45b7479f5fe791054aa19f6b3b478c725.tar.gz
tor-5edc72a45b7479f5fe791054aa19f6b3b478c725.zip
Merge remote-tracking branch 'mikeperry/bug25870_rebase'
Diffstat (limited to 'src/test/test_entrynodes.c')
-rw-r--r--src/test/test_entrynodes.c201
1 files changed, 190 insertions, 11 deletions
diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c
index 6af18f8f4f..cfcb88a66e 100644
--- a/src/test/test_entrynodes.c
+++ b/src/test/test_entrynodes.c
@@ -4,6 +4,7 @@
#include "orconfig.h"
#define CIRCUITLIST_PRIVATE
+#define CIRCUITBUILD_PRIVATE
#define STATEFILE_PRIVATE
#define ENTRYNODES_PRIVATE
#define ROUTERLIST_PRIVATE
@@ -14,6 +15,7 @@
#include "bridges.h"
#include "circuitlist.h"
+#include "circuitbuild.h"
#include "config.h"
#include "confparse.h"
#include "crypto_rand.h"
@@ -75,6 +77,17 @@ bfn_mock_node_get_by_id(const char *id)
return NULL;
}
+/* Helper function to free a test node. */
+static void
+test_node_free(node_t *n)
+{
+ tor_free(n->rs);
+ tor_free(n->md->onion_curve25519_pkey);
+ short_policy_free(n->md->exit_policy);
+ tor_free(n->md);
+ tor_free(n);
+}
+
/* Unittest cleanup function: Cleanup the fake network. */
static int
big_fake_network_cleanup(const struct testcase_t *testcase, void *ptr)
@@ -84,9 +97,7 @@ big_fake_network_cleanup(const struct testcase_t *testcase, void *ptr)
if (big_fake_net_nodes) {
SMARTLIST_FOREACH(big_fake_net_nodes, node_t *, n, {
- tor_free(n->rs);
- tor_free(n->md);
- tor_free(n);
+ test_node_free(n);
});
smartlist_free(big_fake_net_nodes);
}
@@ -114,9 +125,18 @@ big_fake_network_setup(const struct testcase_t *testcase)
big_fake_net_nodes = smartlist_new();
for (i = 0; i < N_NODES; ++i) {
+ curve25519_secret_key_t curve25519_secret_key;
+
node_t *n = tor_malloc_zero(sizeof(node_t));
n->md = tor_malloc_zero(sizeof(microdesc_t));
+ /* Generate curve25519 key for this node */
+ n->md->onion_curve25519_pkey =
+ tor_malloc_zero(sizeof(curve25519_public_key_t));
+ curve25519_secret_key_generate(&curve25519_secret_key, 0);
+ curve25519_public_key_generate(n->md->onion_curve25519_pkey,
+ &curve25519_secret_key);
+
crypto_rand(n->identity, sizeof(n->identity));
n->rs = tor_malloc_zero(sizeof(routerstatus_t));
@@ -136,8 +156,8 @@ big_fake_network_setup(const struct testcase_t *testcase)
{
char nickname_binary[8];
crypto_rand(nickname_binary, sizeof(nickname_binary));
- base64_encode(n->rs->nickname, sizeof(n->rs->nickname),
- nickname_binary, sizeof(nickname_binary), 0);
+ base32_encode(n->rs->nickname, sizeof(n->rs->nickname),
+ nickname_binary, sizeof(nickname_binary));
}
/* Call half of the nodes a possible guard. */
@@ -145,6 +165,12 @@ big_fake_network_setup(const struct testcase_t *testcase)
n->is_possible_guard = 1;
n->rs->guardfraction_percentage = 100;
n->rs->has_guardfraction = 1;
+ n->rs->is_possible_guard = 1;
+ }
+
+ /* Make some of these nodes a possible exit */
+ if (i % 7 == 0) {
+ n->md->exit_policy = parse_short_policy("accept 443");
}
smartlist_add(big_fake_net_nodes, n);
@@ -1076,9 +1102,7 @@ test_entry_guard_expand_sample_small_net(void *arg)
/* Fun corner case: not enough guards to make up our whole sample size. */
SMARTLIST_FOREACH(big_fake_net_nodes, node_t *, n, {
if (n_sl_idx >= 15) {
- tor_free(n->rs);
- tor_free(n->md);
- tor_free(n);
+ test_node_free(n);
SMARTLIST_DEL_CURRENT(big_fake_net_nodes, n);
} else {
n->rs->addr = 0; // make the filter reject this.
@@ -1172,9 +1196,7 @@ test_entry_guard_update_from_consensus_status(void *arg)
entry_guard_t *g = smartlist_get(gs->sampled_entry_guards, 5);
node_t *n = (node_t*) bfn_mock_node_get_by_id(g->identity);
smartlist_remove(big_fake_net_nodes, n);
- tor_free(n->rs);
- tor_free(n->md);
- tor_free(n);
+ test_node_free(n);
}
update_approx_time(start + 300);
sampled_guards_update_from_consensus(gs);
@@ -2805,6 +2827,161 @@ test_entry_guard_outdated_dirserver_exclusion(void *arg)
}
}
+/** Test helper to extend the <b>oc</b> circuit path <b>n</b> times and then
+ * ensure that the circuit is now complete. */
+static void
+helper_extend_circuit_path_n_times(origin_circuit_t *oc, int n)
+{
+ int retval;
+ int i;
+
+ /* Extend path n times */
+ for (i = 0 ; i < n ; i++) {
+ retval = onion_extend_cpath(oc);
+ tt_int_op(retval, OP_EQ, 0);
+ tt_int_op(circuit_get_cpath_len(oc), OP_EQ, i+1);
+ }
+
+ /* Now do it one last time and see that circ is complete */
+ retval = onion_extend_cpath(oc);
+ tt_int_op(retval, OP_EQ, 1);
+
+ done:
+ ;
+}
+
+/** Test for basic Tor path selection. Makes sure we build 3-hop circuits. */
+static void
+test_entry_guard_basic_path_selection(void *arg)
+{
+ (void) arg;
+
+ int retval;
+
+ /* Enable entry guards */
+ or_options_t *options = get_options_mutable();
+ options->UseEntryGuards = 1;
+
+ /* disables /16 check since all nodes have the same addr... */
+ options->EnforceDistinctSubnets = 0;
+
+ /* Create our circuit */
+ circuit_t *circ = dummy_origin_circuit_new(30);
+ origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(circ);
+ oc->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
+
+ /* First pick the exit and pin it on the build_state */
+ retval = onion_pick_cpath_exit(oc, NULL, 0);
+ tt_int_op(retval, OP_EQ, 0);
+
+ /* Extend path 3 times. First we pick guard, then middle, then exit. */
+ helper_extend_circuit_path_n_times(oc, 3);
+
+ done:
+ circuit_free_(circ);
+}
+
+/** Test helper to build an L2 and L3 vanguard list. The vanguard lists
+ * produced should be completely disjoint. */
+static void
+helper_setup_vanguard_list(or_options_t *options)
+{
+ int i = 0;
+
+ /* Add some nodes to the vanguard L2 list */
+ options->HSLayer2Nodes = routerset_new();
+ for (i = 0; i < 10 ; i += 2) {
+ node_t *vanguard_node = smartlist_get(big_fake_net_nodes, i);
+ tt_assert(vanguard_node->is_possible_guard);
+ routerset_parse(options->HSLayer2Nodes, vanguard_node->rs->nickname, "l2");
+ }
+ /* also add some nodes to vanguard L3 list
+ * (L2 list and L3 list should be disjoint for this test to work) */
+ options->HSLayer3Nodes = routerset_new();
+ for (i = 10; i < 20 ; i += 2) {
+ node_t *vanguard_node = smartlist_get(big_fake_net_nodes, i);
+ tt_assert(vanguard_node->is_possible_guard);
+ routerset_parse(options->HSLayer3Nodes, vanguard_node->rs->nickname, "l3");
+ }
+
+ done:
+ ;
+}
+
+/** Test to ensure that vanguard path selection works properly. Ensures that
+ * default vanguard circuits are 4 hops, and that path selection works
+ * correctly given the vanguard settings. */
+static void
+test_entry_guard_vanguard_path_selection(void *arg)
+{
+ (void) arg;
+
+ int retval;
+
+ /* Enable entry guards */
+ or_options_t *options = get_options_mutable();
+ options->UseEntryGuards = 1;
+
+ /* XXX disables /16 check */
+ options->EnforceDistinctSubnets = 0;
+
+ /* Setup our vanguard list */
+ helper_setup_vanguard_list(options);
+
+ /* Create our circuit */
+ circuit_t *circ = dummy_origin_circuit_new(30);
+ origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(circ);
+ oc->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
+ oc->build_state->is_internal = 1;
+
+ /* Switch circuit purpose to vanguards */
+ circ->purpose = CIRCUIT_PURPOSE_HS_VANGUARDS;
+
+ /* First pick the exit and pin it on the build_state */
+ tt_int_op(oc->build_state->desired_path_len, OP_EQ, 0);
+ retval = onion_pick_cpath_exit(oc, NULL, 0);
+ tt_int_op(retval, OP_EQ, 0);
+
+ /* Ensure that vanguards make 4-hop circuits by default */
+ tt_int_op(oc->build_state->desired_path_len, OP_EQ, 4);
+
+ /* Extend path as many times as needed to have complete circ. */
+ helper_extend_circuit_path_n_times(oc, oc->build_state->desired_path_len);
+
+ /* Test that the cpath linked list is set correctly. */
+ crypt_path_t *l1_node = oc->cpath;
+ crypt_path_t *l2_node = l1_node->next;
+ crypt_path_t *l3_node = l2_node->next;
+ crypt_path_t *l4_node = l3_node->next;
+ crypt_path_t *l1_node_again = l4_node->next;
+ tt_ptr_op(l1_node, OP_EQ, l1_node_again);
+
+ /* Test that L2 is indeed HSLayer2Node */
+ retval = routerset_contains_extendinfo(options->HSLayer2Nodes,
+ l2_node->extend_info);
+ tt_int_op(retval, OP_EQ, 4);
+ /* test that L3 node is _not_ contained in HSLayer2Node */
+ retval = routerset_contains_extendinfo(options->HSLayer2Nodes,
+ l3_node->extend_info);
+ tt_int_op(retval, OP_LT, 4);
+
+ /* Test that L3 is indeed HSLayer3Node */
+ retval = routerset_contains_extendinfo(options->HSLayer3Nodes,
+ l3_node->extend_info);
+ tt_int_op(retval, OP_EQ, 4);
+ /* test that L2 node is _not_ contained in HSLayer3Node */
+ retval = routerset_contains_extendinfo(options->HSLayer3Nodes,
+ l2_node->extend_info);
+ tt_int_op(retval, OP_LT, 4);
+
+ /* TODO: Test that L1 can be the same as exit. To test this we need start
+ enforcing EnforceDistinctSubnets again, which means that we need to give
+ each test node a different address which currently breaks some tests. */
+
+ done:
+ circuit_free_(circ);
+}
+
static const struct testcase_setup_t big_fake_network = {
big_fake_network_setup, big_fake_network_cleanup
};
@@ -2868,6 +3045,8 @@ struct testcase_t entrynodes_tests[] = {
BFN_TEST(select_and_cancel),
BFN_TEST(drop_guards),
BFN_TEST(outdated_dirserver_exclusion),
+ BFN_TEST(basic_path_selection),
+ BFN_TEST(vanguard_path_selection),
UPGRADE_TEST(upgrade_a_circuit, "c1-done c2-done"),
UPGRADE_TEST(upgrade_blocked_by_live_primary_guards, "c1-done c2-done"),