10#define HS_CACHE_PRIVATE
29static size_t hs_cache_total_allocation = 0;
32 const hs_cache_client_descriptor_t *cached_desc);
46 return (entry->desc != NULL);
78#define cache_dir_desc_free(val) \
79 FREE_AND_NULL(hs_cache_dir_descriptor_t, cache_dir_desc_free_, (val))
117 log_debug(
LD_DIR,
"Unable to decode descriptor. Rejecting.");
127 cache_dir_desc_free(dir_desc);
153 if (cache_entry != NULL) {
158 log_info(
LD_REND,
"Descriptor revision counter in our cache is "
159 "greater or equal than the one we received (%d/%d). "
170 cache_dir_desc_free(cache_entry);
208 log_info(
LD_REND,
"Unable to decode the v3 HSDir query %s.",
209 safe_str_client(query));
234 size_t bytes_removed = 0;
246 time_t cutoff = global_cutoff;
249 cutoff = now - entry->plaintext_data->lifetime_sec;
254 if (entry->created_ts > cutoff) {
260 bytes_removed += entry_size;
262 cache_dir_desc_free(entry);
269 log_info(
LD_REND,
"Removing v3 descriptor '%s' from HSDir cache",
270 safe_str_client(key_b64));
272 } DIGEST256MAP_FOREACH_END;
274 return bytes_removed;
290 if (dir_desc == NULL) {
308 cache_dir_desc_free(dir_desc);
319 const char **desc_out)
356#define cache_client_desc_free(val) \
357 FREE_AND_NULL(hs_cache_client_descriptor_t, cache_client_desc_free_, (val))
366 hs_descriptor_free(desc->desc);
367 memwipe(&desc->key, 0,
sizeof(desc->key));
368 memwipe(desc->encoded_desc, 0, strlen(desc->encoded_desc));
377 hs_cache_client_descriptor_t *desc = ptr;
378 cache_client_desc_free(desc);
390 size +=
sizeof(*entry);
392 if (entry->encoded_desc) {
393 size += strlen(entry->encoded_desc);
418 hs_cache_client_descriptor_t *cached_desc;
428 cache_client_desc_free(cached_desc);
436STATIC hs_cache_client_descriptor_t *
440 hs_cache_client_descriptor_t *cached_desc;
463static hs_cache_client_descriptor_t *
470 hs_cache_client_descriptor_t *client_desc = NULL;
477 if (ret != HS_DESC_DECODE_OK &&
478 ret != HS_DESC_DECODE_NEED_CLIENT_AUTH &&
479 ret != HS_DESC_DECODE_BAD_CLIENT_AUTH) {
485 if (ret == HS_DESC_DECODE_OK) {
488 if (BUG(desc != NULL)) {
496 client_desc = tor_malloc_zero(
sizeof(hs_cache_client_descriptor_t));
502 client_desc->desc = desc;
503 client_desc->encoded_desc = tor_strdup(desc_str);
506 if (decode_status_out) {
507 *decode_status_out = ret;
521#define cache_intro_state_free(val) \
522 FREE_AND_NULL(hs_cache_intro_state_t, cache_intro_state_free_, (val))
548#define cache_client_intro_state_free(val) \
549 FREE_AND_NULL(hs_cache_client_intro_state_t, \
550 cache_client_intro_state_free_, (val))
595 state = digest256map_get(cache->
intro_points, auth_key->pubkey);
610 rend_intro_point_failure_t failure)
614 case INTRO_POINT_FAILURE_GENERIC:
617 case INTRO_POINT_FAILURE_TIMEOUT:
620 case INTRO_POINT_FAILURE_UNREACHABLE:
652 old_entry = digest256map_set(cache->
intro_points, auth_key->pubkey, entry);
655 tor_assert_nonfatal(old_entry == NULL);
673 if (entry->created_ts <= cutoff) {
674 cache_intro_state_free(entry);
677 } DIGEST256MAP_FOREACH_END;
693 hs_cache_client_descriptor_t *cache_entry;
705 if (cache_entry != NULL) {
713 cache_client_desc_free(cache_entry);
722 if (cache_entry->desc->plaintext_data.revision_counter >
723 client_desc->desc->plaintext_data.revision_counter) {
724 cache_client_desc_free(client_desc);
736 cache_client_desc_free(cache_entry);
751 const hs_cache_client_descriptor_t *cached_desc)
765 if (cached_desc->expiration_ts <= ns->
valid_after) {
777 size_t bytes_removed = 0;
784 hs_cache_client_descriptor_t *, entry) {
794 bytes_removed += entry_size;
805 cache_client_desc_free(entry);
813 log_info(
LD_REND,
"Removing hidden service v3 descriptor '%s' "
815 safe_str_client(key_b64));
817 } DIGEST256MAP_FOREACH_END;
819 return bytes_removed;
827 hs_cache_client_descriptor_t *cached_desc = NULL;
834 return cached_desc->encoded_desc;
847 hs_cache_client_descriptor_t *cached_desc = NULL;
853 return cached_desc->desc;
880 hs_cache_client_descriptor_t *client_desc = NULL;
888 log_warn(
LD_GENERAL,
"HSDesc parsing failed!");
895 ret = HS_DESC_DECODE_GENERIC_ERROR;
902 cache_client_desc_free(client_desc);
914 hs_cache_client_descriptor_t *cached_desc = NULL;
930 cache_client_desc_free(cached_desc);
936 log_info(
LD_REND,
"Onion service v3 descriptor '%s' removed "
938 safe_str_client(key_b64));
956 hs_cache_client_descriptor_t *, entry) {
959 cache_client_desc_free(entry);
963 } DIGEST256MAP_FOREACH_END;
965 log_info(
LD_REND,
"Hidden service client descriptor cache purged.");
973 rend_intro_point_failure_t failure)
1015 cache_client_intro_state_free(cache);
1018 } DIGEST256MAP_FOREACH_END;
1028 cache_client_intro_state_free(cache);
1029 } DIGEST256MAP_FOREACH_END;
1031 log_info(
LD_REND,
"Hidden service client introduction point state "
1043 hs_cache_client_descriptor_t *cached_desc = NULL;
1059 &cached_desc->desc) == HS_DESC_DECODE_OK) {
1077 size_t bytes_removed = 0;
1093 k = hs_cache_max_entry_lifetime();
1106 if (bytes_removed < min_remove_bytes) {
1113 }
while (bytes_removed < min_remove_bytes);
1115 return bytes_removed;
1123 "HSV3MaxDescriptorSize",
1155 hs_cache_total_allocation = 0;
1160hs_cache_get_total_allocation(
void)
1162 return hs_cache_total_allocation;
1169 static int have_underflowed = 0;
1171 if (hs_cache_total_allocation >= n) {
1172 hs_cache_total_allocation -= n;
1174 hs_cache_total_allocation = 0;
1175 if (! have_underflowed) {
1176 have_underflowed = 1;
1177 log_warn(
LD_BUG,
"Underflow in hs_cache_decrement_allocation");
1186 static int have_overflowed = 0;
1187 if (hs_cache_total_allocation <= SIZE_MAX - n) {
1188 hs_cache_total_allocation += n;
1190 hs_cache_total_allocation = SIZE_MAX;
1191 if (! have_overflowed) {
1192 have_overflowed = 1;
1193 log_warn(
LD_BUG,
"Overflow in hs_cache_increment_allocation");
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)
size_t hs_cache_handle_oom(time_t now, size_t min_remove_bytes)
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)
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 hs_cache_dir_descriptor_t * lookup_v3_desc_as_dir(const uint8_t *key)
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)
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 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
#define tor_assert_nonfatal_unreached()