Start caching disaster SRV values.

Also add some unittests.
This commit is contained in:
George Kadianakis
2017-08-08 11:45:45 +03:00
committed by Nick Mathewson
parent 101ce6da01
commit ff249ee4a6
3 changed files with 112 additions and 2 deletions
+55 -1
View File
@@ -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).
*
+5
View File
@@ -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 */
+52 -1
View File
@@ -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
};