10#define HS_CACHE_PRIVATE
32#define HSCACHE_PRUNE_SPARE_ROOM (1000 * HS_DESC_MAX_LEN)
35static size_t hs_cache_total_allocation = 0;
38 const hs_cache_client_descriptor_t *cached_desc);
52 return (entry->desc != NULL);
84#define cache_dir_desc_free(val) \
85 FREE_AND_NULL(hs_cache_dir_descriptor_t, cache_dir_desc_free_, (val))
123 log_debug(
LD_DIR,
"Unable to decode descriptor. Rejecting.");
133 cache_dir_desc_free(dir_desc);
159 const size_t current_cache_bytes = hs_cache_get_total_allocation();
160 if (max_cache_bytes > 0 && current_cache_bytes > max_cache_bytes) {
164 size_t bytes_to_remove = current_cache_bytes/2;
167 bytes_to_remove = current_cache_bytes -
171 static ratelim_t hs_cache_oom_ratelim = RATELIM_INIT(600);
173 "HSDir cache exceeded limit (%zu > %zu bytes). "
174 "Pruned %zu bytes during an HS descriptor upload.",
175 current_cache_bytes, max_cache_bytes, removed);
181 if (cache_entry != NULL) {
186 log_info(
LD_REND,
"Descriptor revision counter in our cache is "
187 "greater or equal than the one we received (%d/%d). "
200 cache_dir_desc_free(cache_entry);
242 log_info(
LD_REND,
"Unable to decode the v3 HSDir query %s.",
243 safe_str_client(query));
273 const size_t max_remove_bytes,
274 uint64_t *next_lowest)
276 size_t bytes_removed = 0;
283 log_info(
LD_REND,
"Cleaning HS cache for downloaded target of %" PRIu64
284 ". Maximum bytes to removed: %" TOR_PRIuSZ,
285 target, max_remove_bytes);
290 if (entry->n_downloaded > target) {
291 if (lowest == 0 || lowest > entry->n_downloaded) {
292 lowest = entry->n_downloaded;
300 if (bytes_removed >= max_remove_bytes) {
308 log_info(
LD_REND,
"Removing v3 descriptor '%s' from HSDir cache. "
309 "Downloaded %" PRIu64
" times and "
310 "size of %" TOR_PRIuSZ
" bytes",
311 safe_str_client(key_b64), entry->n_downloaded, entry_size);
315 bytes_removed += entry_size;
317 cache_dir_desc_free(entry);
320 } DIGEST256MAP_FOREACH_END;
323 *next_lowest = lowest;
324 return bytes_removed;
334 size_t bytes_removed = 0;
346 time_t cutoff = global_cutoff;
349 cutoff = now - entry->plaintext_data->lifetime_sec;
354 if (entry->created_ts > cutoff) {
360 bytes_removed += entry_size;
362 cache_dir_desc_free(entry);
369 log_info(
LD_REND,
"Removing v3 descriptor '%s' from HSDir cache",
370 safe_str_client(key_b64));
372 } DIGEST256MAP_FOREACH_END;
374 return bytes_removed;
390 if (dir_desc == NULL) {
408 cache_dir_desc_free(dir_desc);
419 const char **desc_out)
472#define cache_client_desc_free(val) \
473 FREE_AND_NULL(hs_cache_client_descriptor_t, cache_client_desc_free_, (val))
482 hs_descriptor_free(desc->desc);
483 memwipe(&desc->key, 0,
sizeof(desc->key));
484 memwipe(desc->encoded_desc, 0, strlen(desc->encoded_desc));
493 hs_cache_client_descriptor_t *desc = ptr;
494 cache_client_desc_free(desc);
506 size +=
sizeof(*entry);
508 if (entry->encoded_desc) {
509 size += strlen(entry->encoded_desc);
534 hs_cache_client_descriptor_t *cached_desc;
544 cache_client_desc_free(cached_desc);
552STATIC hs_cache_client_descriptor_t *
556 hs_cache_client_descriptor_t *cached_desc;
579static hs_cache_client_descriptor_t *
586 hs_cache_client_descriptor_t *client_desc = NULL;
593 if (ret != HS_DESC_DECODE_OK &&
594 ret != HS_DESC_DECODE_NEED_CLIENT_AUTH &&
595 ret != HS_DESC_DECODE_BAD_CLIENT_AUTH) {
601 if (ret == HS_DESC_DECODE_OK) {
604 if (BUG(desc != NULL)) {
612 client_desc = tor_malloc_zero(
sizeof(hs_cache_client_descriptor_t));
618 client_desc->desc = desc;
619 client_desc->encoded_desc = tor_strdup(desc_str);
622 if (decode_status_out) {
623 *decode_status_out = ret;
637#define cache_intro_state_free(val) \
638 FREE_AND_NULL(hs_cache_intro_state_t, cache_intro_state_free_, (val))
664#define cache_client_intro_state_free(val) \
665 FREE_AND_NULL(hs_cache_client_intro_state_t, \
666 cache_client_intro_state_free_, (val))
711 state = digest256map_get(cache->
intro_points, auth_key->pubkey);
726 rend_intro_point_failure_t failure)
730 case INTRO_POINT_FAILURE_GENERIC:
733 case INTRO_POINT_FAILURE_TIMEOUT:
736 case INTRO_POINT_FAILURE_UNREACHABLE:
768 old_entry = digest256map_set(cache->
intro_points, auth_key->pubkey, entry);
771 tor_assert_nonfatal(old_entry == NULL);
789 if (entry->created_ts <= cutoff) {
790 cache_intro_state_free(entry);
793 } DIGEST256MAP_FOREACH_END;
809 hs_cache_client_descriptor_t *cache_entry;
821 if (cache_entry != NULL) {
829 cache_client_desc_free(cache_entry);
838 if (cache_entry->desc->plaintext_data.revision_counter >
839 client_desc->desc->plaintext_data.revision_counter) {
840 cache_client_desc_free(client_desc);
852 cache_client_desc_free(cache_entry);
867 const hs_cache_client_descriptor_t *cached_desc)
881 if (cached_desc->expiration_ts <= ns->
valid_after) {
893 size_t bytes_removed = 0;
900 hs_cache_client_descriptor_t *, entry) {
910 bytes_removed += entry_size;
921 cache_client_desc_free(entry);
929 log_info(
LD_REND,
"Removing hidden service v3 descriptor '%s' "
931 safe_str_client(key_b64));
933 } DIGEST256MAP_FOREACH_END;
935 return bytes_removed;
943 hs_cache_client_descriptor_t *cached_desc = NULL;
950 return cached_desc->encoded_desc;
963 hs_cache_client_descriptor_t *cached_desc = NULL;
969 return cached_desc->desc;
996 hs_cache_client_descriptor_t *client_desc = NULL;
1004 log_warn(
LD_GENERAL,
"HSDesc parsing failed!");
1011 ret = HS_DESC_DECODE_GENERIC_ERROR;
1018 cache_client_desc_free(client_desc);
1030 hs_cache_client_descriptor_t *cached_desc = NULL;
1046 cache_client_desc_free(cached_desc);
1052 log_info(
LD_REND,
"Onion service v3 descriptor '%s' removed "
1053 "from client cache",
1054 safe_str_client(key_b64));
1072 hs_cache_client_descriptor_t *, entry) {
1075 cache_client_desc_free(entry);
1079 } DIGEST256MAP_FOREACH_END;
1081 log_info(
LD_REND,
"Hidden service client descriptor cache purged.");
1089 rend_intro_point_failure_t failure)
1131 cache_client_intro_state_free(cache);
1134 } DIGEST256MAP_FOREACH_END;
1144 cache_client_intro_state_free(cache);
1145 } DIGEST256MAP_FOREACH_END;
1147 log_info(
LD_REND,
"Hidden service client introduction point state "
1159 hs_cache_client_descriptor_t *cached_desc = NULL;
1175 &cached_desc->desc) == HS_DESC_DECODE_OK) {
1192 size_t bytes_removed = 0;
1195 uint64_t target = 0;
1204 size_t bytes_to_free = (min_remove_bytes - bytes_removed);
1205 size_t bytes_freed =
1207 if (bytes_freed == 0 && target == 0) {
1211 bytes_removed += bytes_freed;
1212 }
while (bytes_removed < min_remove_bytes);
1214 return bytes_removed;
1222 "HSV3MaxDescriptorSize",
1254 hs_cache_total_allocation = 0;
1267hs_cache_get_total_allocation(
void)
1269 return hs_cache_total_allocation;
1276 static int have_underflowed = 0;
1278 if (hs_cache_total_allocation >= n) {
1279 hs_cache_total_allocation -= n;
1281 hs_cache_total_allocation = 0;
1282 if (! have_underflowed) {
1283 have_underflowed = 1;
1284 log_warn(
LD_BUG,
"Underflow in hs_cache_decrement_allocation");
1293 static int have_overflowed = 0;
1294 if (hs_cache_total_allocation <= SIZE_MAX - n) {
1295 hs_cache_total_allocation += n;
1297 hs_cache_total_allocation = SIZE_MAX;
1298 if (! have_overflowed) {
1299 have_overflowed = 1;
1300 log_warn(
LD_BUG,
"Overflow in hs_cache_increment_allocation");
1305#ifdef TOR_UNIT_TESTS
const or_options_t * get_options(void)
Header file for config.c.
#define BASE64_DIGEST256_LEN
void ed25519_pubkey_copy(ed25519_public_key_t *dest, const ed25519_public_key_t *src)
int ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
void memwipe(void *mem, uint8_t byte, size_t sz)
Common functions for cryptographic routines.
const char * escaped(const char *s)
static void cache_intro_state_free_(hs_cache_intro_state_t *state)
static void cache_dir_desc_free_(hs_cache_dir_descriptor_t *desc)
static void remove_v3_desc_as_client(const hs_cache_client_descriptor_t *desc)
void hs_cache_client_intro_state_clean(time_t now)
void hs_cache_clean_as_client(time_t now)
static digest256map_t * hs_cache_v3_client
uint64_t hs_cache_get_max_bytes(void)
static digest256map_t * hs_cache_v3_dir
static void cache_dir_desc_free_void(void *ptr)
static void cache_client_intro_state_add(const ed25519_public_key_t *service_pk, const ed25519_public_key_t *auth_key, hs_cache_intro_state_t **state)
static int cache_lookup_v3_as_dir(const char *query, const char **desc_out)
void hs_cache_client_intro_state_purge(void)
size_t hs_cache_handle_oom(size_t min_remove_bytes)
static void remove_v3_desc_as_dir(const hs_cache_dir_descriptor_t *desc)
hs_desc_decode_status_t hs_cache_store_as_client(const char *desc_str, const ed25519_public_key_t *identity_pk)
static int cache_client_intro_state_is_empty(const hs_cache_client_intro_state_t *cache)
void hs_cache_remove_as_client(const ed25519_public_key_t *key)
static size_t cache_get_dir_entry_size(const hs_cache_dir_descriptor_t *entry)
static hs_cache_dir_descriptor_t * cache_dir_desc_new(const char *desc)
static void cache_client_intro_state_free_(hs_cache_client_intro_state_t *cache)
void hs_cache_free_all(void)
int hs_cache_lookup_as_dir(uint32_t version, const char *query, const char **desc_out)
static hs_cache_intro_state_t * cache_intro_state_new(void)
static void cache_intro_state_free_void(void *state)
static void cache_client_intro_state_clean(time_t cutoff, hs_cache_client_intro_state_t *cache)
static void store_v3_desc_as_client(hs_cache_client_descriptor_t *desc)
static int cached_client_descriptor_has_expired(time_t now, const hs_cache_client_descriptor_t *cached_desc)
STATIC size_t cache_clean_v3_by_downloaded_as_dir(const uint64_t target, const size_t max_remove_bytes, uint64_t *next_lowest)
void hs_cache_mark_dowloaded_as_dir(const hs_ident_dir_conn_t *ident)
void hs_cache_decrement_allocation(size_t n)
const char * hs_cache_lookup_encoded_as_client(const ed25519_public_key_t *key)
STATIC size_t cache_clean_v3_as_dir(time_t now, time_t global_cutoff)
static bool entry_has_decrypted_descriptor(const hs_cache_client_descriptor_t *entry)
static void cache_client_desc_free_void(void *ptr)
int hs_cache_store_as_dir(const char *desc)
static digest256map_t * hs_cache_client_intro_state
static int cache_store_as_client(hs_cache_client_descriptor_t *client_desc)
const hs_cache_intro_state_t * hs_cache_client_intro_state_find(const ed25519_public_key_t *service_pk, const ed25519_public_key_t *auth_key)
unsigned int hs_cache_get_max_descriptor_size(void)
void hs_cache_clean_as_dir(time_t now)
void hs_cache_client_intro_state_note(const ed25519_public_key_t *service_pk, const ed25519_public_key_t *auth_key, rend_intro_point_failure_t failure)
static void store_v3_desc_as_dir(hs_cache_dir_descriptor_t *desc)
static hs_cache_client_descriptor_t * cache_client_desc_new(const char *desc_str, const ed25519_public_key_t *service_identity_pk, hs_desc_decode_status_t *decode_status_out)
void hs_cache_purge_as_client(void)
static int cache_client_intro_state_lookup(const ed25519_public_key_t *service_pk, const ed25519_public_key_t *auth_key, hs_cache_intro_state_t **entry)
static size_t cache_clean_v3_as_client(time_t now)
static int cache_store_v3_as_dir(hs_cache_dir_descriptor_t *desc)
void hs_cache_increment_allocation(size_t n)
#define HSCACHE_PRUNE_SPARE_ROOM
STATIC hs_cache_dir_descriptor_t * lookup_v3_desc_as_dir(const uint8_t *key)
static size_t cache_get_client_entry_size(const hs_cache_client_descriptor_t *entry)
static void cache_client_desc_free_(hs_cache_client_descriptor_t *desc)
const hs_descriptor_t * hs_cache_lookup_as_client(const ed25519_public_key_t *key)
static hs_cache_client_intro_state_t * cache_client_intro_state_new(void)
static void cache_client_intro_state_note(hs_cache_intro_state_t *state, rend_intro_point_failure_t failure)
static void cache_client_intro_state_free_void(void *entry)
STATIC hs_cache_client_descriptor_t * lookup_v3_desc_as_client(const uint8_t *key)
Header file for hs_cache.c.
#define HS_CACHE_CLIENT_INTRO_STATE_MAX_AGE
void hs_client_close_intro_circuits_from_desc(const hs_descriptor_t *desc)
hs_desc_decode_status_t hs_client_decode_descriptor(const char *desc_str, const ed25519_public_key_t *service_identity_pk, hs_descriptor_t **desc)
Header file containing client data for the HS subsystem.
time_t hs_get_start_time_of_next_time_period(time_t now)
Header file containing common data for the whole HS subsystem.
size_t hs_desc_plaintext_obj_size(const hs_desc_plaintext_data_t *data)
size_t hs_desc_obj_size(const hs_descriptor_t *data)
hs_desc_decode_status_t hs_desc_decode_plaintext(const char *encoded, hs_desc_plaintext_data_t *plaintext)
Header file for hs_descriptor.c.
static int hs_desc_is_supported_version(uint32_t version)
Header file containing circuit and connection identifier data for the whole HS subsystem.
#define log_fn_ratelim(ratelim, severity, domain, args,...)
#define MAP_DEL_CURRENT(keyvar)
int usable_consensus_flavor(void)
Header file for microdesc.c.
networkstatus_t * networkstatus_get_reasonably_live_consensus(time_t now, int flavor)
int32_t networkstatus_get_param(const networkstatus_t *ns, const char *param_name, int32_t default_val, int32_t min_val, int32_t max_val)
Header file for networkstatus.c.
Networkstatus consensus/vote structure.
Master header file for Tor-specific functionality.
void rep_hist_hsdir_stored_maybe_new_v3_onion(const uint8_t *blinded_key)
Header file for rephist.c.
digest256map_t * intro_points
hs_desc_plaintext_data_t * plaintext_data
uint32_t unreachable_count
uint64_t revision_counter
ed25519_public_key_t blinded_pubkey
ed25519_public_key_t blinded_pk
uint64_t MaxHSDirCacheBytes
Integer definitions used throughout Tor.
#define tor_assert_nonfatal_unreached()