mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Start caching disaster SRV values.
Also add some unittests.
This commit is contained in:
committed by
Nick Mathewson
parent
101ce6da01
commit
ff249ee4a6
+55
-1
@@ -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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user