summaryrefslogtreecommitdiff
path: root/src/feature/hs/hs_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/feature/hs/hs_cache.c')
-rw-r--r--src/feature/hs/hs_cache.c89
1 files changed, 61 insertions, 28 deletions
diff --git a/src/feature/hs/hs_cache.c b/src/feature/hs/hs_cache.c
index c1334a7d27..bb1532f808 100644
--- a/src/feature/hs/hs_cache.c
+++ b/src/feature/hs/hs_cache.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2020, The Tor Project, Inc. */
+/* Copyright (c) 2016-2021, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -19,12 +19,15 @@
#include "feature/hs/hs_descriptor.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
-#include "feature/rend/rendcache.h"
+#include "feature/stats/rephist.h"
#include "feature/hs/hs_cache.h"
#include "feature/nodelist/networkstatus_st.h"
+/* Total counter of the cache size. */
+static size_t hs_cache_total_allocation = 0;
+
static int cached_client_descriptor_has_expired(time_t now,
const hs_cache_client_descriptor_t *cached_desc);
@@ -163,7 +166,7 @@ cache_store_v3_as_dir(hs_cache_dir_descriptor_t *desc)
* remove the entry we currently have from our cache so we can then
* store the new one. */
remove_v3_desc_as_dir(cache_entry);
- rend_cache_decrement_allocation(cache_get_dir_entry_size(cache_entry));
+ hs_cache_decrement_allocation(cache_get_dir_entry_size(cache_entry));
cache_dir_desc_free(cache_entry);
}
/* Store the descriptor we just got. We are sure here that either we
@@ -173,9 +176,12 @@ cache_store_v3_as_dir(hs_cache_dir_descriptor_t *desc)
/* Update our total cache size with this entry for the OOM. This uses the
* old HS protocol cache subsystem for which we are tied with. */
- rend_cache_increment_allocation(cache_get_dir_entry_size(desc));
+ hs_cache_increment_allocation(cache_get_dir_entry_size(desc));
- /* XXX: Update HS statistics. We should have specific stats for v3. */
+ /* Update HSv3 statistics */
+ if (get_options()->HiddenServiceStatistics) {
+ rep_hist_hsdir_stored_maybe_new_v3_onion(desc->key);
+ }
return 0;
@@ -255,7 +261,7 @@ cache_clean_v3_as_dir(time_t now, time_t global_cutoff)
/* Entry is not in the cache anymore, destroy it. */
cache_dir_desc_free(entry);
/* Update our cache entry allocation size for the OOM. */
- rend_cache_decrement_allocation(entry_size);
+ hs_cache_decrement_allocation(entry_size);
/* Logging. */
{
char key_b64[BASE64_DIGEST256_LEN + 1];
@@ -332,12 +338,6 @@ hs_cache_lookup_as_dir(uint32_t version, const char *query,
void
hs_cache_clean_as_dir(time_t now)
{
- time_t cutoff;
-
- /* Start with v2 cache cleaning. */
- cutoff = now - rend_cache_max_entry_lifetime();
- rend_cache_clean_v2_descs_as_dir(cutoff);
-
/* Now, clean the v3 cache. Set the cutoff to 0 telling the cleanup function
* to compute the cutoff by itself using the lifetime value. */
cache_clean_v3_as_dir(now, 0);
@@ -383,7 +383,7 @@ remove_v3_desc_as_client(const hs_cache_client_descriptor_t *desc)
tor_assert(desc);
digest256map_remove(hs_cache_v3_client, desc->key.pubkey);
/* Update cache size with this entry for the OOM handler. */
- rend_cache_decrement_allocation(cache_get_client_entry_size(desc));
+ hs_cache_decrement_allocation(cache_get_client_entry_size(desc));
}
/** Store a given descriptor in our cache. */
@@ -393,7 +393,7 @@ store_v3_desc_as_client(hs_cache_client_descriptor_t *desc)
tor_assert(desc);
digest256map_set(hs_cache_v3_client, desc->key.pubkey, desc);
/* Update cache size with this entry for the OOM handler. */
- rend_cache_increment_allocation(cache_get_client_entry_size(desc));
+ hs_cache_increment_allocation(cache_get_client_entry_size(desc));
}
/** Query our cache and return the entry or NULL if not found or if expired. */
@@ -792,7 +792,7 @@ cache_clean_v3_as_client(time_t now)
cache_client_desc_free(entry);
/* Update our OOM. We didn't use the remove() function because we are in
* a loop so we have to explicitly decrement. */
- rend_cache_decrement_allocation(entry_size);
+ hs_cache_decrement_allocation(entry_size);
/* Logging. */
{
char key_b64[BASE64_DIGEST256_LEN + 1];
@@ -930,8 +930,6 @@ hs_cache_remove_as_client(const ed25519_public_key_t *key)
void
hs_cache_clean_as_client(time_t now)
{
- /* Start with v2 cache cleaning. */
- rend_cache_clean(now, REND_CACHE_TYPE_CLIENT);
/* Now, clean the v3 cache. Set the cutoff to 0 telling the cleanup function
* to compute the cutoff by itself using the lifetime value. */
cache_clean_v3_as_client(now);
@@ -948,7 +946,7 @@ hs_cache_purge_as_client(void)
cache_client_desc_free(entry);
/* Update our OOM. We didn't use the remove() function because we are in
* a loop so we have to explicitly decrement. */
- rend_cache_decrement_allocation(entry_size);
+ hs_cache_decrement_allocation(entry_size);
} DIGEST256MAP_FOREACH_END;
log_info(LD_REND, "Hidden service client descriptor cache purged.");
@@ -1070,19 +1068,16 @@ hs_cache_handle_oom(time_t now, size_t min_remove_bytes)
/* The algorithm is as follow. K is the oldest expected descriptor age.
*
- * 1) Deallocate all entries from v2 cache that are older than K hours.
- * 1.1) If the amount of remove bytes has been reached, stop.
- * 2) Deallocate all entries from v3 cache that are older than K hours
+ * 1) Deallocate all entries from v3 cache that are older than K hours
* 2.1) If the amount of remove bytes has been reached, stop.
- * 3) Set K = K - RendPostPeriod and repeat process until K is < 0.
+ * 2) Set K = K - RendPostPeriod and repeat process until K is < 0.
*
* This ends up being O(Kn).
*/
/* Set K to the oldest expected age in seconds which is the maximum
- * lifetime of a cache entry. We'll use the v2 lifetime because it's much
- * bigger than the v3 thus leading to cleaning older descriptors. */
- k = rend_cache_max_entry_lifetime();
+ * lifetime of a cache entry. */
+ k = hs_cache_max_entry_lifetime();
do {
time_t cutoff;
@@ -1095,9 +1090,6 @@ hs_cache_handle_oom(time_t now, size_t min_remove_bytes)
/* Compute a cutoff value with K and the current time. */
cutoff = now - k;
- /* Start by cleaning the v2 cache with that cutoff. */
- bytes_removed += rend_cache_clean_v2_descs_as_dir(cutoff);
-
if (bytes_removed < min_remove_bytes) {
/* We haven't remove enough bytes so clean v3 cache. */
bytes_removed += cache_clean_v3_as_dir(now, cutoff);
@@ -1146,4 +1138,45 @@ hs_cache_free_all(void)
digest256map_free(hs_cache_client_intro_state,
cache_client_intro_state_free_void);
hs_cache_client_intro_state = NULL;
+ hs_cache_total_allocation = 0;
+}
+
+/* Return total size of the cache. */
+size_t
+hs_cache_get_total_allocation(void)
+{
+ return hs_cache_total_allocation;
+}
+
+/** Decrement the total bytes attributed to the rendezvous cache by n. */
+void
+hs_cache_decrement_allocation(size_t n)
+{
+ static int have_underflowed = 0;
+
+ if (hs_cache_total_allocation >= n) {
+ hs_cache_total_allocation -= n;
+ } else {
+ hs_cache_total_allocation = 0;
+ if (! have_underflowed) {
+ have_underflowed = 1;
+ log_warn(LD_BUG, "Underflow in hs_cache_decrement_allocation");
+ }
+ }
+}
+
+/** Increase the total bytes attributed to the rendezvous cache by n. */
+void
+hs_cache_increment_allocation(size_t n)
+{
+ static int have_overflowed = 0;
+ if (hs_cache_total_allocation <= SIZE_MAX - n) {
+ hs_cache_total_allocation += n;
+ } else {
+ hs_cache_total_allocation = SIZE_MAX;
+ if (! have_overflowed) {
+ have_overflowed = 1;
+ log_warn(LD_BUG, "Overflow in hs_cache_increment_allocation");
+ }
+ }
}