10#define HS_CACHE_PRIVATE
30static size_t hs_cache_total_allocation = 0;
33 const hs_cache_client_descriptor_t *cached_desc);
47 return (entry->desc != NULL);
79#define cache_dir_desc_free(val) \
80 FREE_AND_NULL(hs_cache_dir_descriptor_t, cache_dir_desc_free_, (val))
118 log_debug(
LD_DIR,
"Unable to decode descriptor. Rejecting.");
128 cache_dir_desc_free(dir_desc);
154 if (cache_entry != NULL) {
159 log_info(
LD_REND,
"Descriptor revision counter in our cache is "
160 "greater or equal than the one we received (%d/%d). "
171 cache_dir_desc_free(cache_entry);
209 log_info(
LD_REND,
"Unable to decode the v3 HSDir query %s.",
210 safe_str_client(query));
240 const size_t max_remove_bytes,
241 uint64_t *next_lowest)
243 size_t bytes_removed = 0;
250 log_info(
LD_REND,
"Cleaning HS cache for downloaded target of %" PRIu64
251 ". Maximum bytes to removed: %" TOR_PRIuSZ,
252 target, max_remove_bytes);
257 if (entry->n_downloaded > target) {
258 if (lowest == 0 || lowest > entry->n_downloaded) {
259 lowest = entry->n_downloaded;
267 if (bytes_removed >= max_remove_bytes) {
275 log_info(
LD_REND,
"Removing v3 descriptor '%s' from HSDir cache. "
276 "Downloaded %" PRIu64
" times and "
277 "size of %" TOR_PRIuSZ
" bytes",
278 safe_str_client(key_b64), entry->n_downloaded, entry_size);
282 bytes_removed += entry_size;
284 cache_dir_desc_free(entry);
287 } DIGEST256MAP_FOREACH_END;
290 *next_lowest = lowest;
291 return bytes_removed;
301 size_t bytes_removed = 0;
313 time_t cutoff = global_cutoff;
316 cutoff = now - entry->plaintext_data->lifetime_sec;
321 if (entry->created_ts > cutoff) {
327 bytes_removed += entry_size;
329 cache_dir_desc_free(entry);
336 log_info(
LD_REND,
"Removing v3 descriptor '%s' from HSDir cache",
337 safe_str_client(key_b64));
339 } DIGEST256MAP_FOREACH_END;
341 return bytes_removed;
357 if (dir_desc == NULL) {
375 cache_dir_desc_free(dir_desc);
386 const char **desc_out)
439#define cache_client_desc_free(val) \
440 FREE_AND_NULL(hs_cache_client_descriptor_t, cache_client_desc_free_, (val))
449 hs_descriptor_free(desc->desc);
450 memwipe(&desc->key, 0,
sizeof(desc->key));
451 memwipe(desc->encoded_desc, 0, strlen(desc->encoded_desc));
460 hs_cache_client_descriptor_t *desc = ptr;
461 cache_client_desc_free(desc);
473 size +=
sizeof(*entry);
475 if (entry->encoded_desc) {
476 size += strlen(entry->encoded_desc);
501 hs_cache_client_descriptor_t *cached_desc;
511 cache_client_desc_free(cached_desc);
519STATIC hs_cache_client_descriptor_t *
523 hs_cache_client_descriptor_t *cached_desc;
546static hs_cache_client_descriptor_t *
553 hs_cache_client_descriptor_t *client_desc = NULL;
560 if (ret != HS_DESC_DECODE_OK &&
561 ret != HS_DESC_DECODE_NEED_CLIENT_AUTH &&
562 ret != HS_DESC_DECODE_BAD_CLIENT_AUTH) {
568 if (ret == HS_DESC_DECODE_OK) {
571 if (BUG(desc != NULL)) {
579 client_desc = tor_malloc_zero(
sizeof(hs_cache_client_descriptor_t));
585 client_desc->desc = desc;
586 client_desc->encoded_desc = tor_strdup(desc_str);
589 if (decode_status_out) {
590 *decode_status_out = ret;
604#define cache_intro_state_free(val) \
605 FREE_AND_NULL(hs_cache_intro_state_t, cache_intro_state_free_, (val))
631#define cache_client_intro_state_free(val) \
632 FREE_AND_NULL(hs_cache_client_intro_state_t, \
633 cache_client_intro_state_free_, (val))
678 state = digest256map_get(cache->
intro_points, auth_key->pubkey);
693 rend_intro_point_failure_t failure)
697 case INTRO_POINT_FAILURE_GENERIC:
700 case INTRO_POINT_FAILURE_TIMEOUT:
703 case INTRO_POINT_FAILURE_UNREACHABLE:
735 old_entry = digest256map_set(cache->
intro_points, auth_key->pubkey, entry);
738 tor_assert_nonfatal(old_entry == NULL);
756 if (entry->created_ts <= cutoff) {
757 cache_intro_state_free(entry);
760 } DIGEST256MAP_FOREACH_END;
776 hs_cache_client_descriptor_t *cache_entry;
788 if (cache_entry != NULL) {
796 cache_client_desc_free(cache_entry);
805 if (cache_entry->desc->plaintext_data.revision_counter >
806 client_desc->desc->plaintext_data.revision_counter) {
807 cache_client_desc_free(client_desc);
819 cache_client_desc_free(cache_entry);
834 const hs_cache_client_descriptor_t *cached_desc)
848 if (cached_desc->expiration_ts <= ns->
valid_after) {
860 size_t bytes_removed = 0;
867 hs_cache_client_descriptor_t *, entry) {
877 bytes_removed += entry_size;
888 cache_client_desc_free(entry);
896 log_info(
LD_REND,
"Removing hidden service v3 descriptor '%s' "
898 safe_str_client(key_b64));
900 } DIGEST256MAP_FOREACH_END;
902 return bytes_removed;
910 hs_cache_client_descriptor_t *cached_desc = NULL;
917 return cached_desc->encoded_desc;
930 hs_cache_client_descriptor_t *cached_desc = NULL;
936 return cached_desc->desc;
963 hs_cache_client_descriptor_t *client_desc = NULL;
971 log_warn(
LD_GENERAL,
"HSDesc parsing failed!");
978 ret = HS_DESC_DECODE_GENERIC_ERROR;
985 cache_client_desc_free(client_desc);
997 hs_cache_client_descriptor_t *cached_desc = NULL;
1013 cache_client_desc_free(cached_desc);
1019 log_info(
LD_REND,
"Onion service v3 descriptor '%s' removed "
1020 "from client cache",
1021 safe_str_client(key_b64));
1039 hs_cache_client_descriptor_t *, entry) {
1042 cache_client_desc_free(entry);
1046 } DIGEST256MAP_FOREACH_END;
1048 log_info(
LD_REND,
"Hidden service client descriptor cache purged.");
1056 rend_intro_point_failure_t failure)
1098 cache_client_intro_state_free(cache);
1101 } DIGEST256MAP_FOREACH_END;
1111 cache_client_intro_state_free(cache);
1112 } DIGEST256MAP_FOREACH_END;
1114 log_info(
LD_REND,
"Hidden service client introduction point state "
1126 hs_cache_client_descriptor_t *cached_desc = NULL;
1142 &cached_desc->desc) == HS_DESC_DECODE_OK) {
1159 size_t bytes_removed = 0;
1162 uint64_t target = 0;
1171 size_t bytes_to_free = (min_remove_bytes - bytes_removed);
1172 size_t bytes_freed =
1174 if (bytes_freed == 0 && target == 0) {
1178 bytes_removed += bytes_freed;
1179 }
while (bytes_removed < min_remove_bytes);
1181 return bytes_removed;
1189 "HSV3MaxDescriptorSize",
1221 hs_cache_total_allocation = 0;
1226hs_cache_get_total_allocation(
void)
1228 return hs_cache_total_allocation;
1235 static int have_underflowed = 0;
1237 if (hs_cache_total_allocation >= n) {
1238 hs_cache_total_allocation -= n;
1240 hs_cache_total_allocation = 0;
1241 if (! have_underflowed) {
1242 have_underflowed = 1;
1243 log_warn(
LD_BUG,
"Underflow in hs_cache_decrement_allocation");
1252 static int have_overflowed = 0;
1253 if (hs_cache_total_allocation <= SIZE_MAX - n) {
1254 hs_cache_total_allocation += n;
1256 hs_cache_total_allocation = SIZE_MAX;
1257 if (! have_overflowed) {
1258 have_overflowed = 1;
1259 log_warn(
LD_BUG,
"Overflow in hs_cache_increment_allocation");
1264#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
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)
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 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
Integer definitions used throughout Tor.
#define tor_assert_nonfatal_unreached()