2014-09-29 15:59:55 +02:00
|
|
|
/* Copyright (c) 2014, The Tor Project, Inc. */
|
|
|
|
/* See LICENSE for licensing information */
|
|
|
|
|
|
|
|
#define ROUTERLIST_PRIVATE
|
|
|
|
#include "or.h"
|
|
|
|
#include "routerlist.h"
|
|
|
|
#include "directory.h"
|
2015-12-18 01:29:47 +01:00
|
|
|
#include "connection.h"
|
2014-09-29 15:59:55 +02:00
|
|
|
#include "test.h"
|
|
|
|
|
|
|
|
/* 4 digests + 3 sep + pre + post + NULL */
|
|
|
|
static char output[4*BASE64_DIGEST256_LEN+3+2+2+1];
|
|
|
|
|
|
|
|
static void
|
|
|
|
mock_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
|
2015-12-07 07:47:10 +01:00
|
|
|
const char *resource, int pds_flags,
|
|
|
|
download_want_authority_t want_authority)
|
2014-09-29 15:59:55 +02:00
|
|
|
{
|
|
|
|
(void)dir_purpose;
|
|
|
|
(void)router_purpose;
|
|
|
|
(void)pds_flags;
|
2015-12-07 07:47:10 +01:00
|
|
|
(void)want_authority;
|
2015-01-23 15:36:00 +01:00
|
|
|
tt_assert(resource);
|
2014-09-29 15:59:55 +02:00
|
|
|
strlcpy(output, resource, sizeof(output));
|
|
|
|
done:
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_routerlist_initiate_descriptor_downloads(void *arg)
|
|
|
|
{
|
|
|
|
const char *prose = "unhurried and wise, we perceive.";
|
|
|
|
smartlist_t *digests = smartlist_new();
|
|
|
|
(void)arg;
|
|
|
|
|
|
|
|
for (int i = 0; i < 20; i++) {
|
|
|
|
smartlist_add(digests, (char*)prose);
|
|
|
|
}
|
|
|
|
|
|
|
|
MOCK(directory_get_from_dirserver, mock_get_from_dirserver);
|
|
|
|
initiate_descriptor_downloads(NULL, DIR_PURPOSE_FETCH_MICRODESC,
|
|
|
|
digests, 3, 7, 0);
|
|
|
|
UNMOCK(directory_get_from_dirserver);
|
|
|
|
|
2015-01-23 15:36:00 +01:00
|
|
|
tt_str_op(output, OP_EQ, "d/"
|
|
|
|
"dW5odXJyaWVkIGFuZCB3aXNlLCB3ZSBwZXJjZWl2ZS4-"
|
|
|
|
"dW5odXJyaWVkIGFuZCB3aXNlLCB3ZSBwZXJjZWl2ZS4-"
|
|
|
|
"dW5odXJyaWVkIGFuZCB3aXNlLCB3ZSBwZXJjZWl2ZS4-"
|
|
|
|
"dW5odXJyaWVkIGFuZCB3aXNlLCB3ZSBwZXJjZWl2ZS4"
|
|
|
|
".z");
|
2014-09-29 15:59:55 +02:00
|
|
|
|
|
|
|
done:
|
|
|
|
smartlist_free(digests);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int count = 0;
|
|
|
|
|
|
|
|
static void
|
|
|
|
mock_initiate_descriptor_downloads(const routerstatus_t *source,
|
|
|
|
int purpose, smartlist_t *digests,
|
|
|
|
int lo, int hi, int pds_flags)
|
|
|
|
{
|
|
|
|
(void)source;
|
|
|
|
(void)purpose;
|
|
|
|
(void)digests;
|
|
|
|
(void)pds_flags;
|
|
|
|
(void)hi;
|
|
|
|
(void)lo;
|
|
|
|
count += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_routerlist_launch_descriptor_downloads(void *arg)
|
|
|
|
{
|
|
|
|
smartlist_t *downloadable = smartlist_new();
|
|
|
|
time_t now = time(NULL);
|
|
|
|
char *cp;
|
|
|
|
(void)arg;
|
|
|
|
|
|
|
|
for (int i = 0; i < 100; i++) {
|
|
|
|
cp = tor_malloc(DIGEST256_LEN);
|
2015-01-23 15:36:00 +01:00
|
|
|
tt_assert(cp);
|
2014-09-29 15:59:55 +02:00
|
|
|
crypto_rand(cp, DIGEST256_LEN);
|
|
|
|
smartlist_add(downloadable, cp);
|
|
|
|
}
|
|
|
|
|
|
|
|
MOCK(initiate_descriptor_downloads, mock_initiate_descriptor_downloads);
|
|
|
|
launch_descriptor_downloads(DIR_PURPOSE_FETCH_MICRODESC, downloadable,
|
|
|
|
NULL, now);
|
|
|
|
tt_int_op(3, ==, count);
|
|
|
|
UNMOCK(initiate_descriptor_downloads);
|
|
|
|
|
|
|
|
done:
|
|
|
|
SMARTLIST_FOREACH(downloadable, char *, cp1, tor_free(cp1));
|
|
|
|
smartlist_free(downloadable);
|
|
|
|
}
|
|
|
|
|
2015-12-18 01:29:47 +01:00
|
|
|
connection_t *mocked_connection = NULL;
|
|
|
|
|
|
|
|
/* Mock connection_get_by_type_addr_port_purpose by returning
|
|
|
|
* mocked_connection. */
|
|
|
|
static connection_t *
|
|
|
|
mock_connection_get_by_type_addr_port_purpose(int type,
|
|
|
|
const tor_addr_t *addr,
|
|
|
|
uint16_t port, int purpose)
|
|
|
|
{
|
|
|
|
(void)type;
|
|
|
|
(void)addr;
|
|
|
|
(void)port;
|
|
|
|
(void)purpose;
|
|
|
|
|
|
|
|
return mocked_connection;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define TEST_ADDR_STR "127.0.0.1"
|
|
|
|
#define TEST_DIR_PORT 12345
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_routerlist_router_is_already_dir_fetching(void *arg)
|
|
|
|
{
|
|
|
|
(void)arg;
|
|
|
|
tor_addr_port_t test_ap, null_addr_ap, zero_port_ap;
|
|
|
|
|
|
|
|
/* Setup */
|
|
|
|
tor_addr_parse(&test_ap.addr, TEST_ADDR_STR);
|
|
|
|
test_ap.port = TEST_DIR_PORT;
|
|
|
|
tor_addr_make_null(&null_addr_ap.addr, AF_INET6);
|
|
|
|
null_addr_ap.port = TEST_DIR_PORT;
|
|
|
|
tor_addr_parse(&zero_port_ap.addr, TEST_ADDR_STR);
|
|
|
|
zero_port_ap.port = 0;
|
|
|
|
MOCK(connection_get_by_type_addr_port_purpose,
|
|
|
|
mock_connection_get_by_type_addr_port_purpose);
|
|
|
|
|
|
|
|
/* Test that we never get 1 from a NULL connection */
|
|
|
|
mocked_connection = NULL;
|
|
|
|
tt_assert(router_is_already_dir_fetching(&test_ap, 1, 1) == 0);
|
|
|
|
tt_assert(router_is_already_dir_fetching(&test_ap, 1, 0) == 0);
|
|
|
|
tt_assert(router_is_already_dir_fetching(&test_ap, 0, 1) == 0);
|
|
|
|
/* We always expect 0 in these cases */
|
|
|
|
tt_assert(router_is_already_dir_fetching(&test_ap, 0, 0) == 0);
|
|
|
|
tt_assert(router_is_already_dir_fetching(NULL, 1, 1) == 0);
|
|
|
|
tt_assert(router_is_already_dir_fetching(&null_addr_ap, 1, 1) == 0);
|
|
|
|
tt_assert(router_is_already_dir_fetching(&zero_port_ap, 1, 1) == 0);
|
|
|
|
|
|
|
|
/* Test that we get 1 with a connection in the appropriate circumstances */
|
|
|
|
mocked_connection = connection_new(CONN_TYPE_DIR, AF_INET);
|
|
|
|
tt_assert(router_is_already_dir_fetching(&test_ap, 1, 1) == 1);
|
|
|
|
tt_assert(router_is_already_dir_fetching(&test_ap, 1, 0) == 1);
|
|
|
|
tt_assert(router_is_already_dir_fetching(&test_ap, 0, 1) == 1);
|
|
|
|
|
|
|
|
/* Test that we get 0 even with a connection in the appropriate
|
|
|
|
* circumstances */
|
|
|
|
tt_assert(router_is_already_dir_fetching(&test_ap, 0, 0) == 0);
|
|
|
|
tt_assert(router_is_already_dir_fetching(NULL, 1, 1) == 0);
|
|
|
|
tt_assert(router_is_already_dir_fetching(&null_addr_ap, 1, 1) == 0);
|
|
|
|
tt_assert(router_is_already_dir_fetching(&zero_port_ap, 1, 1) == 0);
|
|
|
|
|
|
|
|
done:
|
|
|
|
/* If a connection is never set up, connection_free chokes on it. */
|
|
|
|
buf_free(mocked_connection->inbuf);
|
|
|
|
buf_free(mocked_connection->outbuf);
|
|
|
|
tor_free(mocked_connection);
|
|
|
|
UNMOCK(connection_get_by_type_addr_port_purpose);
|
|
|
|
}
|
|
|
|
|
|
|
|
#undef TEST_ADDR_STR
|
|
|
|
#undef TEST_DIR_PORT
|
|
|
|
|
2014-09-29 15:59:55 +02:00
|
|
|
#define NODE(name, flags) \
|
|
|
|
{ #name, test_routerlist_##name, (flags), NULL, NULL }
|
|
|
|
|
|
|
|
struct testcase_t routerlist_tests[] = {
|
|
|
|
NODE(initiate_descriptor_downloads, 0),
|
|
|
|
NODE(launch_descriptor_downloads, 0),
|
2015-12-18 01:29:47 +01:00
|
|
|
NODE(router_is_already_dir_fetching, TT_FORK),
|
2014-09-29 15:59:55 +02:00
|
|
|
END_OF_TESTCASES
|
|
|
|
};
|
2015-01-23 17:18:28 +01:00
|
|
|
|