diff options
Diffstat (limited to 'src/feature/hs/hs_cache.c')
-rw-r--r-- | src/feature/hs/hs_cache.c | 89 |
1 files changed, 61 insertions, 28 deletions
diff --git a/src/feature/hs/hs_cache.c b/src/feature/hs/hs_cache.c index 9c35936748..cf8e377313 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); @@ -408,7 +408,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. */ @@ -429,7 +429,7 @@ store_v3_desc_as_client(hs_cache_client_descriptor_t *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. */ @@ -803,7 +803,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]; @@ -941,8 +941,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); @@ -959,7 +957,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."); @@ -1081,19 +1079,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; @@ -1106,9 +1101,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); @@ -1157,4 +1149,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"); + } + } } |