aboutsummaryrefslogtreecommitdiff
path: root/src/test/test_routerlist.c
diff options
context:
space:
mode:
authorGeorge Kadianakis <desnacked@riseup.net>2017-10-25 19:25:53 +0300
committerGeorge Kadianakis <desnacked@riseup.net>2017-10-25 20:22:52 +0300
commit8c8d3b90f767076508944f4eb355180e14b6189e (patch)
tree9c031adf7333fc73bd2ffcf002a42965e646bf9e /src/test/test_routerlist.c
parentc7a1a987d6dfcb65a5fd639cc3d37b76809c37d5 (diff)
downloadtor-8c8d3b90f767076508944f4eb355180e14b6189e.tar.gz
tor-8c8d3b90f767076508944f4eb355180e14b6189e.zip
Add a unittest that reveals the offending case of #23862.
Diffstat (limited to 'src/test/test_routerlist.c')
-rw-r--r--src/test/test_routerlist.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/test/test_routerlist.c b/src/test/test_routerlist.c
index 3b0e943ce5..b131dd9592 100644
--- a/src/test/test_routerlist.c
+++ b/src/test/test_routerlist.c
@@ -6,13 +6,17 @@
#include <time.h>
#define DIRVOTE_PRIVATE
+#define ENTRYNODES_PRIVATE
+#define DIRECTORY_PRIVATE
#define NETWORKSTATUS_PRIVATE
+#define CONNECTION_PRIVATE
#define ROUTERLIST_PRIVATE
#define TOR_UNIT_TESTING
#include "or.h"
#include "config.h"
#include "connection.h"
#include "container.h"
+#include "control.h"
#include "directory.h"
#include "dirvote.h"
#include "entrynodes.h"
@@ -22,10 +26,13 @@
#include "policies.h"
#include "router.h"
#include "routerlist.h"
+#include "routerset.h"
#include "routerparse.h"
#include "shared_random.h"
+#include "statefile.h"
#include "test.h"
#include "test_dir_common.h"
+#include "log_test_helpers.h"
void construct_consensus(char **consensus_text_md);
@@ -411,6 +418,107 @@ test_router_pick_directory_server_impl(void *arg)
networkstatus_vote_free(con_md);
}
+static or_state_t *dummy_state = NULL;
+static or_state_t *
+get_or_state_replacement(void)
+{
+ return dummy_state;
+}
+
+static void
+mock_directory_initiate_request(directory_request_t *req)
+{
+ (void)req;
+ return;
+}
+
+static circuit_guard_state_t *
+mock_circuit_guard_state_new(entry_guard_t *guard, unsigned state,
+ entry_guard_restriction_t *rst)
+{
+ (void) guard;
+ (void) state;
+ (void) rst;
+ return NULL;
+}
+
+/** Test that we will use our directory guards to fetch mds even if we don't
+ * have any dirinfo (tests bug #23862). */
+static void
+test_directory_guard_fetch_with_no_dirinfo(void *arg)
+{
+ int retval;
+ char *consensus_text_md = NULL;
+ or_options_t *options = get_options_mutable();
+
+ (void) arg;
+
+ /* Initialize the SRV subsystem */
+ sr_init(0);
+
+ /* Initialize the entry node configuration from the ticket */
+ options->UseEntryGuards = 1;
+ options->StrictNodes = 1;
+ get_options_mutable()->EntryNodes = routerset_new();
+ routerset_parse(get_options_mutable()->EntryNodes,
+ "2121212121212121212121212121212121212121", "foo");
+
+ /* Mock some functions */
+ dummy_state = tor_malloc_zero(sizeof(or_state_t));
+ MOCK(get_or_state, get_or_state_replacement);
+ MOCK(directory_initiate_request, mock_directory_initiate_request);
+ /* we need to mock this one to avoid memleaks */
+ MOCK(circuit_guard_state_new, mock_circuit_guard_state_new);
+
+ /* Call guards_update_all() to simulate loading our state file (see
+ * entry_guards_load_guards_from_state() and ticket #23989). */
+ guards_update_all();
+
+ /* Test logic: Simulate the arrival of a new consensus when we have no
+ * dirinfo at all. Tor will need to fetch the mds from the consensus. Make
+ * sure that Tor will use the specified entry guard instead of relying on the
+ * fallback directories. */
+
+ /* Fixup the dirconn that will deliver the consensus */
+ dir_connection_t *conn = dir_connection_new(AF_INET);
+ tor_addr_from_ipv4h(&conn->base_.addr, 0x7f000001);
+ conn->base_.port = 8800;
+ TO_CONN(conn)->address = tor_strdup("127.0.0.1");
+ conn->base_.purpose = DIR_PURPOSE_FETCH_CONSENSUS;
+ conn->requested_resource = tor_strdup("ns");
+
+ /* Construct a consensus */
+ construct_consensus(&consensus_text_md);
+ tt_assert(consensus_text_md);
+
+ /* Place the consensus in the dirconn */
+ response_handler_args_t args;
+ memset(&args, 0, sizeof(response_handler_args_t));
+ args.status_code = 200;
+ args.body = consensus_text_md;
+ args.body_len = strlen(consensus_text_md);
+
+ /* Update approx time so that the consensus is considered live */
+ update_approx_time(time(NULL)+1010);
+
+ setup_capture_of_logs(LOG_DEBUG);
+
+ /* Now handle the consensus */
+ retval = handle_response_fetch_consensus(conn, &args);
+ tt_int_op(retval, OP_EQ, 0);
+
+ /* Make sure that our primary guard was chosen */
+ /* BUG #23862 falls back to dirserver list!! */
+ expect_log_msg_containing("falling back to dirserver list");
+
+ done:
+ tor_free(consensus_text_md);
+ tor_free(dummy_state);
+ connection_free_(TO_CONN(conn));
+ entry_guards_free_all();
+ teardown_capture_of_logs();
+}
+
static connection_t *mocked_connection = NULL;
/* Mock connection_get_by_type_addr_port_purpose by returning
@@ -494,6 +602,8 @@ struct testcase_t routerlist_tests[] = {
NODE(launch_descriptor_downloads, 0),
NODE(router_is_already_dir_fetching, TT_FORK),
ROUTER(pick_directory_server_impl, TT_FORK),
+ { "directory_guard_fetch_with_no_dirinfo",
+ test_directory_guard_fetch_with_no_dirinfo, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};