mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 12:23:32 +01:00
Add a unittest that reveals the offending case of #23862.
This commit is contained in:
parent
c7a1a987d6
commit
8c8d3b90f7
@ -2237,8 +2237,6 @@ load_downloaded_routers(const char *body, smartlist_t *which,
|
|||||||
return added;
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_response_fetch_consensus(dir_connection_t *,
|
|
||||||
const response_handler_args_t *);
|
|
||||||
static int handle_response_fetch_certificate(dir_connection_t *,
|
static int handle_response_fetch_certificate(dir_connection_t *,
|
||||||
const response_handler_args_t *);
|
const response_handler_args_t *);
|
||||||
static int handle_response_fetch_status_vote(dir_connection_t *,
|
static int handle_response_fetch_status_vote(dir_connection_t *,
|
||||||
@ -2585,7 +2583,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
|
|||||||
* consensus document by checking the consensus, storing it, and marking
|
* consensus document by checking the consensus, storing it, and marking
|
||||||
* router requests as reachable.
|
* router requests as reachable.
|
||||||
**/
|
**/
|
||||||
static int
|
STATIC int
|
||||||
handle_response_fetch_consensus(dir_connection_t *conn,
|
handle_response_fetch_consensus(dir_connection_t *conn,
|
||||||
const response_handler_args_t *args)
|
const response_handler_args_t *args)
|
||||||
{
|
{
|
||||||
|
@ -194,6 +194,9 @@ STATIC void warn_disallowed_anonymous_compression_method(compress_method_t);
|
|||||||
STATIC int handle_response_fetch_hsdesc_v3(dir_connection_t *conn,
|
STATIC int handle_response_fetch_hsdesc_v3(dir_connection_t *conn,
|
||||||
const response_handler_args_t *args);
|
const response_handler_args_t *args);
|
||||||
|
|
||||||
|
STATIC int handle_response_fetch_consensus(dir_connection_t *conn,
|
||||||
|
const response_handler_args_t *args);
|
||||||
|
|
||||||
#endif /* defined(DIRECTORY_PRIVATE) */
|
#endif /* defined(DIRECTORY_PRIVATE) */
|
||||||
|
|
||||||
#ifdef TOR_UNIT_TESTS
|
#ifdef TOR_UNIT_TESTS
|
||||||
|
@ -2126,9 +2126,9 @@ circuit_guard_state_free(circuit_guard_state_t *state)
|
|||||||
|
|
||||||
/** Allocate and return a new circuit_guard_state_t to track the result
|
/** Allocate and return a new circuit_guard_state_t to track the result
|
||||||
* of using <b>guard</b> for a given operation. */
|
* of using <b>guard</b> for a given operation. */
|
||||||
static circuit_guard_state_t *
|
MOCK_IMPL(STATIC circuit_guard_state_t *,
|
||||||
circuit_guard_state_new(entry_guard_t *guard, unsigned state,
|
circuit_guard_state_new,(entry_guard_t *guard, unsigned state,
|
||||||
entry_guard_restriction_t *rst)
|
entry_guard_restriction_t *rst))
|
||||||
{
|
{
|
||||||
circuit_guard_state_t *result;
|
circuit_guard_state_t *result;
|
||||||
|
|
||||||
|
@ -488,6 +488,10 @@ STATIC entry_guard_t *get_sampled_guard_with_id(guard_selection_t *gs,
|
|||||||
|
|
||||||
MOCK_DECL(STATIC time_t, randomize_time, (time_t now, time_t max_backdate));
|
MOCK_DECL(STATIC time_t, randomize_time, (time_t now, time_t max_backdate));
|
||||||
|
|
||||||
|
MOCK_DECL(STATIC circuit_guard_state_t *,
|
||||||
|
circuit_guard_state_new,(entry_guard_t *guard, unsigned state,
|
||||||
|
entry_guard_restriction_t *rst));
|
||||||
|
|
||||||
STATIC entry_guard_t *entry_guard_add_to_sample(guard_selection_t *gs,
|
STATIC entry_guard_t *entry_guard_add_to_sample(guard_selection_t *gs,
|
||||||
const node_t *node);
|
const node_t *node);
|
||||||
STATIC entry_guard_t *entry_guards_expand_sample(guard_selection_t *gs);
|
STATIC entry_guard_t *entry_guards_expand_sample(guard_selection_t *gs);
|
||||||
|
@ -1720,7 +1720,7 @@ networkstatus_set_current_consensus(const char *consensus,
|
|||||||
{
|
{
|
||||||
networkstatus_t *c=NULL;
|
networkstatus_t *c=NULL;
|
||||||
int r, result = -1;
|
int r, result = -1;
|
||||||
time_t now = time(NULL);
|
time_t now = approx_time();
|
||||||
const or_options_t *options = get_options();
|
const or_options_t *options = get_options();
|
||||||
char *unverified_fname = NULL, *consensus_fname = NULL;
|
char *unverified_fname = NULL, *consensus_fname = NULL;
|
||||||
int flav = networkstatus_parse_flavor_name(flavor);
|
int flav = networkstatus_parse_flavor_name(flavor);
|
||||||
|
@ -6,13 +6,17 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#define DIRVOTE_PRIVATE
|
#define DIRVOTE_PRIVATE
|
||||||
|
#define ENTRYNODES_PRIVATE
|
||||||
|
#define DIRECTORY_PRIVATE
|
||||||
#define NETWORKSTATUS_PRIVATE
|
#define NETWORKSTATUS_PRIVATE
|
||||||
|
#define CONNECTION_PRIVATE
|
||||||
#define ROUTERLIST_PRIVATE
|
#define ROUTERLIST_PRIVATE
|
||||||
#define TOR_UNIT_TESTING
|
#define TOR_UNIT_TESTING
|
||||||
#include "or.h"
|
#include "or.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "container.h"
|
#include "container.h"
|
||||||
|
#include "control.h"
|
||||||
#include "directory.h"
|
#include "directory.h"
|
||||||
#include "dirvote.h"
|
#include "dirvote.h"
|
||||||
#include "entrynodes.h"
|
#include "entrynodes.h"
|
||||||
@ -22,10 +26,13 @@
|
|||||||
#include "policies.h"
|
#include "policies.h"
|
||||||
#include "router.h"
|
#include "router.h"
|
||||||
#include "routerlist.h"
|
#include "routerlist.h"
|
||||||
|
#include "routerset.h"
|
||||||
#include "routerparse.h"
|
#include "routerparse.h"
|
||||||
#include "shared_random.h"
|
#include "shared_random.h"
|
||||||
|
#include "statefile.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "test_dir_common.h"
|
#include "test_dir_common.h"
|
||||||
|
#include "log_test_helpers.h"
|
||||||
|
|
||||||
void construct_consensus(char **consensus_text_md);
|
void construct_consensus(char **consensus_text_md);
|
||||||
|
|
||||||
@ -411,6 +418,107 @@ test_router_pick_directory_server_impl(void *arg)
|
|||||||
networkstatus_vote_free(con_md);
|
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;
|
static connection_t *mocked_connection = NULL;
|
||||||
|
|
||||||
/* Mock connection_get_by_type_addr_port_purpose by returning
|
/* 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(launch_descriptor_downloads, 0),
|
||||||
NODE(router_is_already_dir_fetching, TT_FORK),
|
NODE(router_is_already_dir_fetching, TT_FORK),
|
||||||
ROUTER(pick_directory_server_impl, 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
|
END_OF_TESTCASES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user