]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
test: Add HS cache OOM cleanup test
authorDavid Goulet <dgoulet@torproject.org>
Wed, 18 Dec 2024 16:28:59 +0000 (11:28 -0500)
committerDavid Goulet <dgoulet@torproject.org>
Wed, 18 Dec 2024 17:04:02 +0000 (12:04 -0500)
Part of #40996

Signed-off-by: David Goulet <dgoulet@torproject.org>
src/feature/hs/hs_cache.c
src/feature/hs/hs_cache.h
src/test/test_hs_cache.c

index 4977446945706c8860799646b45ebc486e89a6cc..103c5ddf1f34a1c42d6c51086af3250449b5f4ce 100644 (file)
@@ -68,7 +68,7 @@ store_v3_desc_as_dir(hs_cache_dir_descriptor_t *desc)
 }
 
 /** Query our cache and return the entry or NULL if not found. */
-static hs_cache_dir_descriptor_t *
+STATIC hs_cache_dir_descriptor_t *
 lookup_v3_desc_as_dir(const uint8_t *key)
 {
   tor_assert(key);
@@ -1258,3 +1258,17 @@ hs_cache_increment_allocation(size_t n)
     }
   }
 }
+
+#ifdef TOR_UNIT_TESTS
+
+/** Test only: Set the downloaded counter value of a HSDir cache entry. */
+void
+dir_set_downloaded(const ed25519_public_key_t *pk, uint64_t value)
+{
+  hs_cache_dir_descriptor_t *entry = lookup_v3_desc_as_dir(pk->pubkey);
+  if (entry) {
+    entry->n_downloaded = value;
+  }
+}
+
+#endif /* TOR_UNIT_TESTS */
index b6d6cc50b984d6fc2f41b0c5f999ba184df24061..2f78f8479a3c1d741687cba666309dd5039398d2 100644 (file)
@@ -153,10 +153,15 @@ STATIC size_t cache_clean_v3_as_dir(time_t now, time_t global_cutoff);
 STATIC size_t cache_clean_v3_by_downloaded_as_dir(const uint64_t target,
                                            const size_t min_remove_bytes,
                                            uint64_t *next_lowest);
+STATIC hs_cache_dir_descriptor_t *lookup_v3_desc_as_dir(const uint8_t *key);
 
 STATIC hs_cache_client_descriptor_t *
 lookup_v3_desc_as_client(const uint8_t *key);
 
+#ifdef TOR_UNIT_TESTS
+void dir_set_downloaded(const ed25519_public_key_t *pk, uint64_t value);
+#endif /* TOR_UNIT_TESTS */
+
 #endif /* defined(HS_CACHE_PRIVATE) */
 
 #endif /* !defined(TOR_HS_CACHE_H) */
index a0b698b9789c5c8d8485470564218154dd249954..100a90e86ae60c5368e523a09137d186575aa89f 100644 (file)
@@ -224,6 +224,61 @@ test_clean_as_dir(void *arg)
   tor_free(desc1_str);
 }
 
+static void
+test_clean_oom_as_dir(void *arg)
+{
+  size_t ret;
+  char *desc1_str = NULL, *desc2_str = NULL;
+  hs_descriptor_t *desc1 = NULL, *desc2 = NULL;
+  ed25519_keypair_t signing_kp1, signing_kp2;
+
+  (void) arg;
+
+  init_test();
+
+  /* Generate two valid descriptors. */
+  ret = ed25519_keypair_generate(&signing_kp1, 0);
+  tt_int_op(ret, OP_EQ, 0);
+  ret = ed25519_keypair_generate(&signing_kp2, 0);
+  tt_int_op(ret, OP_EQ, 0);
+  desc1 = hs_helper_build_hs_desc_with_ip(&signing_kp1);
+  tt_assert(desc1);
+  desc2 = hs_helper_build_hs_desc_with_ip(&signing_kp2);
+  tt_assert(desc2);
+  ret = hs_desc_encode_descriptor(desc1, &signing_kp1, NULL, &desc1_str);
+  tt_int_op(ret, OP_EQ, 0);
+  ret = hs_cache_store_as_dir(desc1_str);
+  tt_int_op(ret, OP_EQ, 0);
+  ret = hs_desc_encode_descriptor(desc2, &signing_kp2, NULL, &desc2_str);
+  tt_int_op(ret, OP_EQ, 0);
+  ret = hs_cache_store_as_dir(desc2_str);
+  tt_int_op(ret, OP_EQ, 0);
+
+  /* Set the downloaded count to 42 for the second one. */
+  dir_set_downloaded(&desc2->plaintext_data.blinded_pubkey, 42);
+  const hs_cache_dir_descriptor_t *entry =
+    lookup_v3_desc_as_dir(desc2->plaintext_data.blinded_pubkey.pubkey);
+  tt_u64_op(entry->n_downloaded, OP_EQ, 42);
+
+  /* Spin the OOM cleanup for only 1 descriptor (very low amount of bytes). We
+   * expect desc1 to be cleaned up because its downloaded counter is 0. */
+  size_t removed = hs_cache_handle_oom(1);
+  tt_size_op(removed, OP_GT, 0);
+
+  /* Desc1 is gone. */
+  entry = lookup_v3_desc_as_dir(desc1->plaintext_data.blinded_pubkey.pubkey);
+  tt_assert(!entry);
+  /* Desc2 is still there. */
+  entry = lookup_v3_desc_as_dir(desc2->plaintext_data.blinded_pubkey.pubkey);
+  tt_assert(entry);
+
+ done:
+  hs_descriptor_free(desc1);
+  hs_descriptor_free(desc2);
+  tor_free(desc1_str);
+  tor_free(desc2_str);
+}
+
 /* Test helper: Fetch an HS descriptor from an HSDir (for the hidden service
    with <b>blinded_key</b>. Return the received descriptor string. */
 static char *
@@ -705,6 +760,8 @@ struct testcase_t hs_cache[] = {
     NULL, NULL },
   { "clean_as_dir", test_clean_as_dir, TT_FORK,
     NULL, NULL },
+  { "clean_oom_as_dir", test_clean_oom_as_dir, TT_FORK,
+    NULL, NULL },
   { "hsdir_revision_counter_check", test_hsdir_revision_counter_check, TT_FORK,
     NULL, NULL },
   { "upload_and_download_hs_desc", test_upload_and_download_hs_desc, TT_FORK,