[tor-commits] [tor/master] Start caching disaster SRV values.

nickm at torproject.org nickm at torproject.org
Wed Aug 9 00:36:38 UTC 2017


commit ff249ee4a6ea665bb7ed1c7ab53d4d6b0eb9db78
Author: George Kadianakis <desnacked at riseup.net>
Date:   Tue Aug 8 11:45:45 2017 +0300

    Start caching disaster SRV values.
    
    Also add some unittests.
---
 src/or/hs_common.c        | 56 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/or/hs_common.h        |  5 +++++
 src/test/test_hs_common.c | 53 +++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 112 insertions(+), 2 deletions(-)

diff --git a/src/or/hs_common.c b/src/or/hs_common.c
index 62cda34bd..2b637eb78 100644
--- a/src/or/hs_common.c
+++ b/src/or/hs_common.c
@@ -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).
  *
diff --git a/src/or/hs_common.h b/src/or/hs_common.h
index 7e37f81e5..5004e0208 100644
--- a/src/or/hs_common.h
+++ b/src/or/hs_common.h
@@ -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 */
diff --git a/src/test/test_hs_common.c b/src/test/test_hs_common.c
index 3041d24a6..d79d80bfa 100644
--- a/src/test/test_hs_common.c
+++ b/src/test/test_hs_common.c
@@ -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
 };





More information about the tor-commits mailing list