mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Merge branch 'bug12844'
Conflicts: src/or/circuituse.c src/test/include.am src/test/test_entrynodes.c
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
o Minor features:
|
||||
- Introduce the config option Tor2webRendezvousPoints, which
|
||||
allows clients in Tor2webMode to select a specific Rendezvous
|
||||
Point to be used in HS circuits. This might allow better
|
||||
performance for Tor2Web nodes. Implements ticket #12844.
|
||||
@@ -1335,6 +1335,22 @@ The following options are useful only for clients (that is, if
|
||||
To enable this option the compile time flag --enable-tor2webmode must be
|
||||
specified. (Default: 0)
|
||||
|
||||
[[Tor2webRendezvousPoints]] **Tor2webRendezvousPoints** __node__,__node__,__...__::
|
||||
A list of identity fingerprints, nicknames, country codes and
|
||||
address patterns of nodes that are allowed to be used as RPs
|
||||
in HS circuits; any other nodes will not be used as RPs.
|
||||
(Example:
|
||||
Tor2webRendezvousPoints Fastyfasty, ABCD1234CDEF5678ABCD1234CDEF5678ABCD1234, \{cc}, 255.254.0.0/8) +
|
||||
+
|
||||
This feature can only be used if Tor2webMode is also enabled.
|
||||
+
|
||||
ExcludeNodes have higher priority than Tor2webRendezvousPoints,
|
||||
which means that nodes specified in ExcludeNodes will not be
|
||||
picked as RPs.
|
||||
+
|
||||
If no nodes in Tor2webRendezvousPoints are currently available for
|
||||
use, Tor will choose a random node when building HS circuits.
|
||||
|
||||
[[UseMicrodescriptors]] **UseMicrodescriptors** **0**|**1**|**auto**::
|
||||
Microdescriptors are a smaller version of the information that Tor needs
|
||||
in order to build its circuits. Using microdescriptors makes Tor clients
|
||||
|
||||
+84
-3
@@ -1737,6 +1737,83 @@ choose_good_exit_server_general(int need_uptime, int need_capacity)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(ENABLE_TOR2WEB_MODE) || defined(TOR_UNIT_TESTS)
|
||||
/* The config option Tor2webRendezvousPoints has been set and we need
|
||||
* to pick an RP out of that set. Make sure that the RP we choose is
|
||||
* alive, and return it. Return NULL if no usable RP could be found in
|
||||
* Tor2webRendezvousPoints. */
|
||||
STATIC const node_t *
|
||||
pick_tor2web_rendezvous_node(router_crn_flags_t flags,
|
||||
const or_options_t *options)
|
||||
{
|
||||
const node_t *rp_node = NULL;
|
||||
const int allow_invalid = (flags & CRN_ALLOW_INVALID) != 0;
|
||||
const int need_desc = (flags & CRN_NEED_DESC) != 0;
|
||||
|
||||
smartlist_t *whitelisted_live_rps = smartlist_new();
|
||||
smartlist_t *all_live_nodes = smartlist_new();
|
||||
|
||||
tor_assert(options->Tor2webRendezvousPoints);
|
||||
|
||||
/* Add all running nodes to all_live_nodes */
|
||||
router_add_running_nodes_to_smartlist(all_live_nodes,
|
||||
allow_invalid,
|
||||
0, 0, 0,
|
||||
need_desc);
|
||||
|
||||
/* Filter all_live_nodes to only add live *and* whitelisted RPs to
|
||||
* the list whitelisted_live_rps. */
|
||||
SMARTLIST_FOREACH_BEGIN(all_live_nodes, node_t *, live_node) {
|
||||
if (routerset_contains_node(options->Tor2webRendezvousPoints, live_node)) {
|
||||
smartlist_add(whitelisted_live_rps, live_node);
|
||||
}
|
||||
} SMARTLIST_FOREACH_END(live_node);
|
||||
|
||||
/* Honor ExcludeNodes */
|
||||
if (options->ExcludeNodes) {
|
||||
routerset_subtract_nodes(whitelisted_live_rps, options->ExcludeNodes);
|
||||
}
|
||||
|
||||
/* Now pick randomly amongst the whitelisted RPs. No need to waste time
|
||||
doing bandwidth load balancing, for most use cases
|
||||
'whitelisted_live_rps' contains a single OR anyway. */
|
||||
rp_node = smartlist_choose(whitelisted_live_rps);
|
||||
|
||||
if (!rp_node) {
|
||||
log_warn(LD_REND, "Could not find a Rendezvous Point that suits "
|
||||
"the purposes of Tor2webRendezvousPoints. Choosing random one.");
|
||||
}
|
||||
|
||||
smartlist_free(whitelisted_live_rps);
|
||||
smartlist_free(all_live_nodes);
|
||||
|
||||
return rp_node;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Pick a Rendezvous Point for our HS circuits according to <b>flags</b>. */
|
||||
static const node_t *
|
||||
pick_rendezvous_node(router_crn_flags_t flags)
|
||||
{
|
||||
const or_options_t *options = get_options();
|
||||
|
||||
if (options->AllowInvalid_ & ALLOW_INVALID_RENDEZVOUS)
|
||||
flags |= CRN_ALLOW_INVALID;
|
||||
|
||||
#ifdef ENABLE_TOR2WEB_MODE
|
||||
/* The user wants us to pick specific RPs. */
|
||||
if (options->Tor2webRendezvousPoints) {
|
||||
const node_t *tor2web_rp = pick_tor2web_rendezvous_node(flags, options);
|
||||
if (tor2web_rp) {
|
||||
return tor2web_rp;
|
||||
}
|
||||
/* Else, if no tor2web RP was found, fall back to choosing a random node */
|
||||
}
|
||||
#endif
|
||||
|
||||
return router_choose_random_node(NULL, options->ExcludeNodes, flags);
|
||||
}
|
||||
|
||||
/** Return a pointer to a suitable router to be the exit node for the
|
||||
* circuit of purpose <b>purpose</b> that we're about to build (or NULL
|
||||
* if no router is suitable).
|
||||
@@ -1767,9 +1844,13 @@ choose_good_exit_server(uint8_t purpose,
|
||||
else
|
||||
return choose_good_exit_server_general(need_uptime,need_capacity);
|
||||
case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
|
||||
if (options->AllowInvalid_ & ALLOW_INVALID_RENDEZVOUS)
|
||||
flags |= CRN_ALLOW_INVALID;
|
||||
return router_choose_random_node(NULL, options->ExcludeNodes, flags);
|
||||
{
|
||||
/* Pick a new RP */
|
||||
const node_t *rendezvous_node = pick_rendezvous_node(flags);
|
||||
log_info(LD_REND, "Picked new RP: %s",
|
||||
safe_str_client(node_describe(rendezvous_node)));
|
||||
return rendezvous_node;
|
||||
}
|
||||
}
|
||||
log_warn(LD_BUG,"Unhandled purpose %d", purpose);
|
||||
tor_fragile_assert();
|
||||
|
||||
@@ -61,6 +61,9 @@ const node_t *choose_good_entry_server(uint8_t purpose,
|
||||
|
||||
#ifdef CIRCUITBUILD_PRIVATE
|
||||
STATIC circid_t get_unique_circ_id_by_chan(channel_t *chan);
|
||||
STATIC const node_t *pick_tor2web_rendezvous_node(router_crn_flags_t flags,
|
||||
const or_options_t *options);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+11
-1
@@ -1677,6 +1677,7 @@ circuit_launch_by_extend_info(uint8_t purpose,
|
||||
origin_circuit_t *circ;
|
||||
int onehop_tunnel = (flags & CIRCLAUNCH_ONEHOP_TUNNEL) != 0;
|
||||
int have_path = have_enough_path_info(! (flags & CIRCLAUNCH_IS_INTERNAL) );
|
||||
int need_specific_rp = 0;
|
||||
|
||||
if (!onehop_tunnel && (!router_have_minimum_dir_info() || !have_path)) {
|
||||
log_debug(LD_CIRC,"Haven't %s yet; canceling "
|
||||
@@ -1687,8 +1688,17 @@ circuit_launch_by_extend_info(uint8_t purpose,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If Tor2webRendezvousPoints is enabled and we are dealing with an
|
||||
RP circuit, we want a specific RP node so we shouldn't canibalize
|
||||
an already existing circuit. */
|
||||
if (get_options()->Tor2webRendezvousPoints &&
|
||||
purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND) {
|
||||
need_specific_rp = 1;
|
||||
}
|
||||
|
||||
if ((extend_info || purpose != CIRCUIT_PURPOSE_C_GENERAL) &&
|
||||
purpose != CIRCUIT_PURPOSE_TESTING && !onehop_tunnel) {
|
||||
purpose != CIRCUIT_PURPOSE_TESTING &&
|
||||
!onehop_tunnel && !need_specific_rp) {
|
||||
/* see if there are appropriate circs available to cannibalize. */
|
||||
/* XXX if we're planning to add a hop, perhaps we want to look for
|
||||
* internal circs rather than exit circs? -RD */
|
||||
|
||||
+11
-2
@@ -80,6 +80,7 @@ static config_abbrev_t option_abbrevs_[] = {
|
||||
PLURAL(AuthDirRejectCC),
|
||||
PLURAL(EntryNode),
|
||||
PLURAL(ExcludeNode),
|
||||
PLURAL(Tor2webRendezvousPoint),
|
||||
PLURAL(FirewallPort),
|
||||
PLURAL(LongLivedPort),
|
||||
PLURAL(HiddenServiceNode),
|
||||
@@ -404,6 +405,7 @@ static config_var_t option_vars_[] = {
|
||||
V(TestSocks, BOOL, "0"),
|
||||
V(TokenBucketRefillInterval, MSEC_INTERVAL, "100 msec"),
|
||||
V(Tor2webMode, BOOL, "0"),
|
||||
V(Tor2webRendezvousPoints, ROUTERSET, NULL),
|
||||
V(TLSECGroup, STRING, NULL),
|
||||
V(TrackHostExits, CSV, NULL),
|
||||
V(TrackHostExitsExpire, INTERVAL, "30 minutes"),
|
||||
@@ -1262,7 +1264,8 @@ options_need_geoip_info(const or_options_t *options, const char **reason_out)
|
||||
routerset_needs_geoip(options->EntryNodes) ||
|
||||
routerset_needs_geoip(options->ExitNodes) ||
|
||||
routerset_needs_geoip(options->ExcludeExitNodes) ||
|
||||
routerset_needs_geoip(options->ExcludeNodes);
|
||||
routerset_needs_geoip(options->ExcludeNodes) ||
|
||||
routerset_needs_geoip(options->Tor2webRendezvousPoints);
|
||||
|
||||
if (routerset_usage && reason_out) {
|
||||
*reason_out = "We've been configured to use (or avoid) nodes in certain "
|
||||
@@ -1395,7 +1398,7 @@ options_act(const or_options_t *old_options)
|
||||
log_err(LD_CONFIG, "This copy of Tor was not compiled to run in "
|
||||
"'tor2web mode'. It cannot be run with the Tor2webMode torrc "
|
||||
"option enabled. To enable Tor2webMode recompile with the "
|
||||
"--enable-tor2webmode option.");
|
||||
"--enable-tor2web-mode option.");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
@@ -1651,6 +1654,8 @@ options_act(const or_options_t *old_options)
|
||||
options->ExcludeExitNodes) ||
|
||||
!routerset_equal(old_options->EntryNodes, options->EntryNodes) ||
|
||||
!routerset_equal(old_options->ExitNodes, options->ExitNodes) ||
|
||||
!routerset_equal(old_options->Tor2webRendezvousPoints,
|
||||
options->Tor2webRendezvousPoints) ||
|
||||
options->StrictNodes != old_options->StrictNodes) {
|
||||
log_info(LD_CIRC,
|
||||
"Changed to using entry guards or bridges, or changed "
|
||||
@@ -3057,6 +3062,10 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||
options->UseEntryGuards = 0;
|
||||
}
|
||||
|
||||
if (options->Tor2webRendezvousPoints && !options->Tor2webMode) {
|
||||
REJECT("Tor2webRendezvousPoints cannot be set without Tor2webMode.");
|
||||
}
|
||||
|
||||
if (!(options->UseEntryGuards) &&
|
||||
(options->RendConfigLines != NULL)) {
|
||||
log_warn(LD_CONFIG,
|
||||
|
||||
@@ -3567,6 +3567,9 @@ typedef struct {
|
||||
* circuits.) */
|
||||
int Tor2webMode;
|
||||
|
||||
/** A routerset that should be used when picking RPs for HS circuits. */
|
||||
routerset_t *Tor2webRendezvousPoints;
|
||||
|
||||
/** Close hidden service client circuits immediately when they reach
|
||||
* the normal circuit-build timeout, even if they have already sent
|
||||
* an INTRODUCE1 cell on its way to the service. */
|
||||
|
||||
+1
-1
@@ -1775,7 +1775,7 @@ routerlist_add_node_and_family(smartlist_t *sl, const routerinfo_t *router)
|
||||
/** Add every suitable node from our nodelist to <b>sl</b>, so that
|
||||
* we can pick a node for a circuit.
|
||||
*/
|
||||
static void
|
||||
void
|
||||
router_add_running_nodes_to_smartlist(smartlist_t *sl, int allow_invalid,
|
||||
int need_uptime, int need_capacity,
|
||||
int need_guard, int need_desc)
|
||||
|
||||
@@ -58,6 +58,10 @@ const routerstatus_t *router_pick_fallback_dirserver(dirinfo_type_t type,
|
||||
int router_get_my_share_of_directory_requests(double *v3_share_out);
|
||||
void router_reset_status_download_failures(void);
|
||||
int routers_have_same_or_addrs(const routerinfo_t *r1, const routerinfo_t *r2);
|
||||
void router_add_running_nodes_to_smartlist(smartlist_t *sl, int allow_invalid,
|
||||
int need_uptime, int need_capacity,
|
||||
int need_guard, int need_desc);
|
||||
|
||||
const routerinfo_t *routerlist_find_my_routerinfo(void);
|
||||
uint32_t router_get_advertised_bandwidth(const routerinfo_t *router);
|
||||
uint32_t router_get_advertised_bandwidth_capped(const routerinfo_t *router);
|
||||
|
||||
+4
-1
@@ -62,6 +62,7 @@ src_test_test_SOURCES = \
|
||||
src/test/test_threads.c \
|
||||
src/test/test_util.c \
|
||||
src/test/testing_common.c \
|
||||
src/test/testhelper.c \
|
||||
src/ext/tinytest.c
|
||||
|
||||
src_test_test_slow_SOURCES = \
|
||||
@@ -119,10 +120,12 @@ src_test_test_workqueue_LDADD = src/or/libtor-testing.a \
|
||||
noinst_HEADERS+= \
|
||||
src/test/fakechans.h \
|
||||
src/test/test.h \
|
||||
src/test/testhelper.h \
|
||||
src/test/test_descriptors.inc \
|
||||
src/test/example_extrainfo.inc \
|
||||
src/test/failing_routerdescs.inc \
|
||||
src/test/ed25519_vectors.inc
|
||||
src/test/ed25519_vectors.inc \
|
||||
src/test/test_descriptors.inc
|
||||
|
||||
noinst_PROGRAMS+= src/test/test-ntor-cl
|
||||
src_test_test_ntor_cl_SOURCES = src/test/test_ntor_cl.c
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "statefile.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "test_descriptors.inc"
|
||||
#include "testhelper.h"
|
||||
|
||||
/* TODO:
|
||||
* choose_random_entry() test with state set.
|
||||
@@ -37,62 +37,6 @@ get_or_state_replacement(void)
|
||||
return dummy_state;
|
||||
}
|
||||
|
||||
/* NOP replacement for router_descriptor_is_older_than() */
|
||||
static int
|
||||
router_descriptor_is_older_than_replacement(const routerinfo_t *router,
|
||||
int seconds)
|
||||
{
|
||||
(void) router;
|
||||
(void) seconds;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Number of descriptors contained in test_descriptors.txt. */
|
||||
#define NUMBER_OF_DESCRIPTORS 8
|
||||
|
||||
/** Parse a file containing router descriptors and load them to our
|
||||
routerlist. This function is used to setup an artificial network
|
||||
so that we can conduct entry guard tests. */
|
||||
static void
|
||||
setup_fake_routerlist(void)
|
||||
{
|
||||
int retval;
|
||||
routerlist_t *our_routerlist = NULL;
|
||||
smartlist_t *our_nodelist = NULL;
|
||||
|
||||
/* Read the file that contains our test descriptors. */
|
||||
|
||||
/* We need to mock this function otherwise the descriptors will not
|
||||
accepted as they are too old. */
|
||||
MOCK(router_descriptor_is_older_than,
|
||||
router_descriptor_is_older_than_replacement);
|
||||
|
||||
/* Load all the test descriptors to the routerlist. */
|
||||
retval = router_load_routers_from_string(TEST_DESCRIPTORS,
|
||||
NULL, SAVED_IN_JOURNAL,
|
||||
NULL, 0, NULL);
|
||||
tt_int_op(retval, OP_EQ, NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
/* Sanity checking of routerlist and nodelist. */
|
||||
our_routerlist = router_get_routerlist();
|
||||
tt_int_op(smartlist_len(our_routerlist->routers), OP_EQ,
|
||||
NUMBER_OF_DESCRIPTORS);
|
||||
routerlist_assert_ok(our_routerlist);
|
||||
|
||||
our_nodelist = nodelist_get_list();
|
||||
tt_int_op(smartlist_len(our_nodelist), OP_EQ, NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
/* Mark all routers as non-guards but up and running! */
|
||||
SMARTLIST_FOREACH_BEGIN(our_nodelist, node_t *, node) {
|
||||
node->is_running = 1;
|
||||
node->is_valid = 1;
|
||||
node->is_possible_guard = 0;
|
||||
} SMARTLIST_FOREACH_END(node);
|
||||
|
||||
done:
|
||||
UNMOCK(router_descriptor_is_older_than);
|
||||
}
|
||||
|
||||
/* Unittest cleanup function: Cleanup the fake network. */
|
||||
static int
|
||||
fake_network_cleanup(const struct testcase_t *testcase, void *ptr)
|
||||
@@ -120,7 +64,7 @@ fake_network_setup(const struct testcase_t *testcase)
|
||||
get_or_state_replacement);
|
||||
|
||||
/* Setup fake routerlist. */
|
||||
setup_fake_routerlist();
|
||||
helper_setup_fake_routerlist();
|
||||
|
||||
/* Return anything but NULL (it's interpreted as test fail) */
|
||||
return dummy_state;
|
||||
@@ -197,7 +141,7 @@ populate_live_entry_guards_test_helper(int num_needed)
|
||||
|
||||
/* Walk the nodelist and add all nodes as entry guards. */
|
||||
our_nodelist = nodelist_get_list();
|
||||
tt_int_op(smartlist_len(our_nodelist), OP_EQ, NUMBER_OF_DESCRIPTORS);
|
||||
tt_int_op(smartlist_len(our_nodelist), OP_EQ, HELPER_NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(our_nodelist, const node_t *, node) {
|
||||
const node_t *node_tmp;
|
||||
@@ -206,7 +150,7 @@ populate_live_entry_guards_test_helper(int num_needed)
|
||||
} SMARTLIST_FOREACH_END(node);
|
||||
|
||||
/* Make sure the nodes were added as entry guards. */
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, NUMBER_OF_DESCRIPTORS);
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, HELPER_NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
/* Ensure that all the possible entry guards are enough to satisfy us. */
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_GE, num_needed);
|
||||
@@ -647,7 +591,7 @@ test_entry_is_live(void *arg)
|
||||
|
||||
/* Walk the nodelist and add all nodes as entry guards. */
|
||||
our_nodelist = nodelist_get_list();
|
||||
tt_int_op(smartlist_len(our_nodelist), OP_EQ, NUMBER_OF_DESCRIPTORS);
|
||||
tt_int_op(smartlist_len(our_nodelist), OP_EQ, HELPER_NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
SMARTLIST_FOREACH_BEGIN(our_nodelist, const node_t *, node) {
|
||||
const node_t *node_tmp;
|
||||
@@ -659,7 +603,7 @@ test_entry_is_live(void *arg)
|
||||
} SMARTLIST_FOREACH_END(node);
|
||||
|
||||
/* Make sure the nodes were added as entry guards. */
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, NUMBER_OF_DESCRIPTORS);
|
||||
tt_int_op(smartlist_len(all_entry_guards), OP_EQ, HELPER_NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
/* Now get a random test entry that we will use for this unit test. */
|
||||
which_node = 3; /* (chosen by fair dice roll) */
|
||||
|
||||
@@ -7,9 +7,15 @@
|
||||
**/
|
||||
|
||||
#define CONTROL_PRIVATE
|
||||
#define CIRCUITBUILD_PRIVATE
|
||||
|
||||
#include "or.h"
|
||||
#include "test.h"
|
||||
#include "control.h"
|
||||
#include "testhelper.h"
|
||||
#include "config.h"
|
||||
#include "routerset.h"
|
||||
#include "circuitbuild.h"
|
||||
|
||||
/* mock ID digest and longname for node that's in nodelist */
|
||||
#define HSDIR_EXIST_ID "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" \
|
||||
@@ -123,9 +129,83 @@ test_hs_desc_event(void *arg)
|
||||
tor_free(received_msg);
|
||||
}
|
||||
|
||||
/* Make sure we always pick the right RP, given a well formatted
|
||||
* Tor2webRendezvousPoints value. */
|
||||
static void
|
||||
test_pick_tor2web_rendezvous_node(void *arg)
|
||||
{
|
||||
or_options_t *options = get_options_mutable();
|
||||
const node_t *chosen_rp = NULL;
|
||||
router_crn_flags_t flags = CRN_NEED_DESC;
|
||||
int retval, i;
|
||||
const char *tor2web_rendezvous_str = "test003r";
|
||||
|
||||
(void) arg;
|
||||
|
||||
/* Setup fake routerlist. */
|
||||
helper_setup_fake_routerlist();
|
||||
|
||||
/* Parse Tor2webRendezvousPoints as a routerset. */
|
||||
options->Tor2webRendezvousPoints = routerset_new();
|
||||
retval = routerset_parse(options->Tor2webRendezvousPoints,
|
||||
tor2web_rendezvous_str,
|
||||
"test_tor2web_rp");
|
||||
tt_int_op(retval, >=, 0);
|
||||
|
||||
/* Pick rendezvous point. Make sure the correct one is
|
||||
picked. Repeat many times to make sure it works properly. */
|
||||
for (i = 0; i < 50 ; i++) {
|
||||
chosen_rp = pick_tor2web_rendezvous_node(flags, options);
|
||||
tt_assert(chosen_rp);
|
||||
tt_str_op(chosen_rp->ri->nickname, ==, tor2web_rendezvous_str);
|
||||
}
|
||||
|
||||
done:
|
||||
routerset_free(options->Tor2webRendezvousPoints);
|
||||
}
|
||||
|
||||
/* Make sure we never pick an RP if Tor2webRendezvousPoints doesn't
|
||||
* correspond to an actual node. */
|
||||
static void
|
||||
test_pick_bad_tor2web_rendezvous_node(void *arg)
|
||||
{
|
||||
or_options_t *options = get_options_mutable();
|
||||
const node_t *chosen_rp = NULL;
|
||||
router_crn_flags_t flags = CRN_NEED_DESC;
|
||||
int retval, i;
|
||||
const char *tor2web_rendezvous_str = "dummy";
|
||||
|
||||
(void) arg;
|
||||
|
||||
/* Setup fake routerlist. */
|
||||
helper_setup_fake_routerlist();
|
||||
|
||||
/* Parse Tor2webRendezvousPoints as a routerset. */
|
||||
options->Tor2webRendezvousPoints = routerset_new();
|
||||
retval = routerset_parse(options->Tor2webRendezvousPoints,
|
||||
tor2web_rendezvous_str,
|
||||
"test_tor2web_rp");
|
||||
tt_int_op(retval, >=, 0);
|
||||
|
||||
/* Pick rendezvous point. Since Tor2webRendezvousPoints was set to a
|
||||
dummy value, we shouldn't find any eligible RPs. */
|
||||
for (i = 0; i < 50 ; i++) {
|
||||
chosen_rp = pick_tor2web_rendezvous_node(flags, options);
|
||||
tt_assert(!chosen_rp);
|
||||
}
|
||||
|
||||
done:
|
||||
routerset_free(options->Tor2webRendezvousPoints);
|
||||
}
|
||||
|
||||
struct testcase_t hs_tests[] = {
|
||||
{ "hs_desc_event", test_hs_desc_event, TT_FORK,
|
||||
NULL, NULL },
|
||||
{ "pick_tor2web_rendezvous_node", test_pick_tor2web_rendezvous_node, TT_FORK,
|
||||
NULL, NULL },
|
||||
{ "pick_bad_tor2web_rendezvous_node",
|
||||
test_pick_bad_tor2web_rendezvous_node, TT_FORK,
|
||||
NULL, NULL },
|
||||
END_OF_TESTCASES
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/* Copyright (c) 2014, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
#define ROUTERLIST_PRIVATE
|
||||
|
||||
#include "or.h"
|
||||
#include "routerlist.h"
|
||||
#include "testhelper.h"
|
||||
#include "nodelist.h"
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "test_descriptors.inc"
|
||||
|
||||
/* NOP replacement for router_descriptor_is_older_than() */
|
||||
static int
|
||||
router_descriptor_is_older_than_replacement(const routerinfo_t *router,
|
||||
int seconds)
|
||||
{
|
||||
(void) router;
|
||||
(void) seconds;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Parse a file containing router descriptors and load them to our
|
||||
routerlist. This function is used to setup an artificial network
|
||||
so that we can conduct tests on it. */
|
||||
void
|
||||
helper_setup_fake_routerlist(void)
|
||||
{
|
||||
int retval;
|
||||
routerlist_t *our_routerlist = NULL;
|
||||
smartlist_t *our_nodelist = NULL;
|
||||
|
||||
/* Read the file that contains our test descriptors. */
|
||||
|
||||
/* We need to mock this function otherwise the descriptors will not
|
||||
accepted as they are too old. */
|
||||
MOCK(router_descriptor_is_older_than,
|
||||
router_descriptor_is_older_than_replacement);
|
||||
|
||||
/* Load all the test descriptors to the routerlist. */
|
||||
retval = router_load_routers_from_string(TEST_DESCRIPTORS,
|
||||
NULL, SAVED_IN_JOURNAL,
|
||||
NULL, 0, NULL);
|
||||
tt_int_op(retval, ==, HELPER_NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
/* Sanity checking of routerlist and nodelist. */
|
||||
our_routerlist = router_get_routerlist();
|
||||
tt_int_op(smartlist_len(our_routerlist->routers), ==,
|
||||
HELPER_NUMBER_OF_DESCRIPTORS);
|
||||
routerlist_assert_ok(our_routerlist);
|
||||
|
||||
our_nodelist = nodelist_get_list();
|
||||
tt_int_op(smartlist_len(our_nodelist), ==, HELPER_NUMBER_OF_DESCRIPTORS);
|
||||
|
||||
/* Mark all routers as non-guards but up and running! */
|
||||
SMARTLIST_FOREACH_BEGIN(our_nodelist, node_t *, node) {
|
||||
node->is_running = 1;
|
||||
node->is_valid = 1;
|
||||
node->is_possible_guard = 0;
|
||||
} SMARTLIST_FOREACH_END(node);
|
||||
|
||||
done:
|
||||
UNMOCK(router_descriptor_is_older_than);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#ifndef TOR_TEST_HELPER_H
|
||||
#define TOR_TEST_HELPER_H
|
||||
|
||||
/* Number of descriptors contained in test_descriptors.txt. */
|
||||
#define HELPER_NUMBER_OF_DESCRIPTORS 8
|
||||
|
||||
void helper_setup_fake_routerlist(void);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user