Skip to content
Snippets Groups Projects
Commit ff249ee4 authored by George Kadianakis's avatar George Kadianakis Committed by Nick Mathewson
Browse files

Start caching disaster SRV values.

Also add some unittests.
parent 101ce6da
No related branches found
No related tags found
No related merge requests found
......@@ -503,7 +503,7 @@ rend_data_get_pk_digest(const rend_data_t *rend_data, size_t *len_out)
/* Using the given time period number, compute the disaster shared random
* value and put it in srv_out. It MUST be at least DIGEST256_LEN bytes. */
static void
get_disaster_srv(uint64_t time_period_num, uint8_t *srv_out)
compute_disaster_srv(uint64_t time_period_num, uint8_t *srv_out)
{
crypto_digest_t *digest;
......@@ -534,6 +534,60 @@ get_disaster_srv(uint64_t time_period_num, uint8_t *srv_out)
crypto_digest_free(digest);
}
/** Due to the high cost of computing the disaster SRV and that potentially we
* would have to do it thousands of times in a row, we always cache the
* computer disaster SRV (and its corresponding time period num) in case we
* want to reuse it soon after. We need to cache two SRVs, one for each active
* time period (in case of overlap mode).
*/
static uint8_t cached_disaster_srv[2][DIGEST256_LEN];
static uint64_t cached_time_period_nums[2] = {0};
/** Compute the disaster SRV value for this <b>time_period_num</b> and put it
* in <b>srv_out</b> (of size at least DIGEST256_LEN). First check our caches
* to see if we have already computed it. */
STATIC void
get_disaster_srv(uint64_t time_period_num, uint8_t *srv_out)
{
if (time_period_num == cached_time_period_nums[0]) {
memcpy(srv_out, cached_disaster_srv[0], DIGEST256_LEN);
return;
} else if (time_period_num == cached_time_period_nums[1]) {
memcpy(srv_out, cached_disaster_srv[1], DIGEST256_LEN);
return;
} else {
int replace_idx;
// Replace the lower period number.
if (cached_time_period_nums[0] <= cached_time_period_nums[1]) {
replace_idx = 0;
} else {
replace_idx = 1;
}
cached_time_period_nums[replace_idx] = time_period_num;
compute_disaster_srv(time_period_num, cached_disaster_srv[replace_idx]);
memcpy(srv_out, cached_disaster_srv[replace_idx], DIGEST256_LEN);
return;
}
}
#ifdef TOR_UNIT_TESTS
/** Get the first cached disaster SRV. Only used by unittests. */
STATIC uint8_t *
get_first_cached_disaster_srv(void)
{
return cached_disaster_srv[0];
}
/** Get the second cached disaster SRV. Only used by unittests. */
STATIC uint8_t *
get_second_cached_disaster_srv(void)
{
return cached_disaster_srv[1];
}
#endif
/* When creating a blinded key, we need a parameter which construction is as
* follow: H(pubkey | [secret] | ed25519-basepoint | nonce).
*
......
......@@ -224,10 +224,15 @@ int hs_set_conn_addr_port(const smartlist_t *ports, edge_connection_t *conn);
#ifdef HS_COMMON_PRIVATE
STATIC void get_disaster_srv(uint64_t time_period_num, uint8_t *srv_out);
#ifdef TOR_UNIT_TESTS
STATIC uint64_t get_time_period_length(void);
STATIC uint8_t *get_first_cached_disaster_srv(void);
STATIC uint8_t *get_second_cached_disaster_srv(void);
#endif /* TOR_UNIT_TESTS */
#endif /* HS_COMMON_PRIVATE */
......
......@@ -434,6 +434,57 @@ test_responsible_hsdirs(void *arg)
networkstatus_vote_free(mock_ns);
}
/** Test disaster SRV computation and caching */
static void
test_disaster_srv(void *arg)
{
uint8_t *cached_disaster_srv_one = NULL;
uint8_t *cached_disaster_srv_two = NULL;
uint8_t srv_one[DIGEST256_LEN] = {0};
uint8_t srv_two[DIGEST256_LEN] = {0};
uint8_t srv_three[DIGEST256_LEN] = {0};
uint8_t srv_four[DIGEST256_LEN] = {0};
uint8_t srv_five[DIGEST256_LEN] = {0};
(void) arg;
/* Get the cached SRVs: we gonna use them later for verification */
cached_disaster_srv_one = get_first_cached_disaster_srv();
cached_disaster_srv_two = get_second_cached_disaster_srv();
/* Compute some srvs */
get_disaster_srv(1, srv_one);
get_disaster_srv(2, srv_two);
/* Check that the cached ones where updated */
tt_mem_op(cached_disaster_srv_one, OP_EQ, srv_one, DIGEST256_LEN);
tt_mem_op(cached_disaster_srv_two, OP_EQ, srv_two, DIGEST256_LEN);
/* Ask for an SRV that has already been computed */
get_disaster_srv(2, srv_two);
/* and check that the cache entries have not changed */
tt_mem_op(cached_disaster_srv_one, OP_EQ, srv_one, DIGEST256_LEN);
tt_mem_op(cached_disaster_srv_two, OP_EQ, srv_two, DIGEST256_LEN);
/* Ask for a new SRV */
get_disaster_srv(3, srv_three);
tt_mem_op(cached_disaster_srv_one, OP_EQ, srv_three, DIGEST256_LEN);
tt_mem_op(cached_disaster_srv_two, OP_EQ, srv_two, DIGEST256_LEN);
/* Ask for another SRV: none of the original SRVs should now be cached */
get_disaster_srv(4, srv_four);
tt_mem_op(cached_disaster_srv_one, OP_EQ, srv_three, DIGEST256_LEN);
tt_mem_op(cached_disaster_srv_two, OP_EQ, srv_four, DIGEST256_LEN);
/* Ask for yet another SRV */
get_disaster_srv(5, srv_five);
tt_mem_op(cached_disaster_srv_one, OP_EQ, srv_five, DIGEST256_LEN);
tt_mem_op(cached_disaster_srv_two, OP_EQ, srv_four, DIGEST256_LEN);
done:
;
}
struct testcase_t hs_common_tests[] = {
{ "build_address", test_build_address, TT_FORK,
NULL, NULL },
......@@ -449,7 +500,7 @@ struct testcase_t hs_common_tests[] = {
NULL, NULL },
{ "desc_responsible_hsdirs", test_responsible_hsdirs, TT_FORK,
NULL, NULL },
{ "disaster_srv", test_disaster_srv, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment