Merge remote-tracking branch 'asn/bug23862_v2'

This commit is contained in:
Nick Mathewson
2017-10-26 09:09:14 -04:00
7 changed files with 126 additions and 7 deletions
+5
View File
@@ -0,0 +1,5 @@
o Minor bugfixes (entry guards):
- Tor now updates its guard state when it reads a consensus regardless of
whether it's missing descriptors. That makes tor use its primary guards
to fetch descriptors in some edge cases where it would have used fallback
directories in the past. Fixes bug 23862; bugfix on 0.3.0.1-alpha.
+1 -3
View File
@@ -2237,8 +2237,6 @@ load_downloaded_routers(const char *body, smartlist_t *which,
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 *,
const response_handler_args_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
* router requests as reachable.
**/
static int
STATIC int
handle_response_fetch_consensus(dir_connection_t *conn,
const response_handler_args_t *args)
{
+3
View File
@@ -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,
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) */
#ifdef TOR_UNIT_TESTS
+3 -3
View File
@@ -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
* of using <b>guard</b> for a given operation. */
static circuit_guard_state_t *
circuit_guard_state_new(entry_guard_t *guard, unsigned state,
entry_guard_restriction_t *rst)
MOCK_IMPL(STATIC circuit_guard_state_t *,
circuit_guard_state_new,(entry_guard_t *guard, unsigned state,
entry_guard_restriction_t *rst))
{
circuit_guard_state_t *result;
+4
View File
@@ -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 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,
const node_t *node);
STATIC entry_guard_t *entry_guards_expand_sample(guard_selection_t *gs);
+1 -1
View File
@@ -1720,7 +1720,7 @@ networkstatus_set_current_consensus(const char *consensus,
{
networkstatus_t *c=NULL;
int r, result = -1;
time_t now = time(NULL);
time_t now = approx_time();
const or_options_t *options = get_options();
char *unverified_fname = NULL, *consensus_fname = NULL;
int flav = networkstatus_parse_flavor_name(flavor);
+109
View File
@@ -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,106 @@ 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 */
expect_log_msg_containing("Selected primary guard router3");
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 +601,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
};