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 "
174 "(%"TOR_PRIuSZ
" > %"TOR_PRIuSZ
" bytes). "
175 "Pruned %"TOR_PRIuSZ
" bytes during an HS descriptor upload.",
176 current_cache_bytes, max_cache_bytes, removed);
182 if (cache_entry != NULL) {
187 log_info(
LD_REND,
"Descriptor revision counter in our cache is "
188 "greater or equal than the one we received (%d/%d). "
201 cache_dir_desc_free(cache_entry);
243 log_info(
LD_REND,
"Unable to decode the v3 HSDir query %s.",
244 safe_str_client(query));
274 const size_t max_remove_bytes,
275 uint64_t *next_lowest)
277 size_t bytes_removed = 0;
284 log_info(
LD_REND,
"Cleaning HS cache for downloaded target of %" PRIu64
285 ". Maximum bytes to removed: %" TOR_PRIuSZ,
286 target, max_remove_bytes);
291 if (entry->n_downloaded > target) {
292 if (lowest == 0 || lowest > entry->n_downloaded) {
293 lowest = entry->n_downloaded;
301 if (bytes_removed >= max_remove_bytes) {
309 log_info(
LD_REND,
"Removing v3 descriptor '%s' from HSDir cache. "
310 "Downloaded %" PRIu64
" times and "
311 "size of %" TOR_PRIuSZ
" bytes",
312 safe_str_client(key_b64), entry->n_downloaded, entry_size);
316 bytes_removed += entry_size;
318 cache_dir_desc_free(entry);
321 } DIGEST256MAP_FOREACH_END;
324 *next_lowest = lowest;
325 return bytes_removed;
335 size_t bytes_removed = 0;
347 time_t cutoff = global_cutoff;
350 cutoff = now - entry->plaintext_data->lifetime_sec;
355 if (entry->created_ts > cutoff) {
361 bytes_removed += entry_size;
363 cache_dir_desc_free(entry);
370 log_info(
LD_REND,
"Removing v3 descriptor '%s' from HSDir cache",
371 safe_str_client(key_b64));
373 } DIGEST256MAP_FOREACH_END;
375 return bytes_removed;
391 if (dir_desc == NULL) {
409 cache_dir_desc_free(dir_desc);
420 const char **desc_out)
473#define cache_client_desc_free(val) \
474 FREE_AND_NULL(hs_cache_client_descriptor_t, cache_client_desc_free_, (val))
483 hs_descriptor_free(desc->desc);
484 memwipe(&desc->key, 0,
sizeof(desc->key));
485 memwipe(desc->encoded_desc, 0, strlen(desc->encoded_desc));
494 hs_cache_client_descriptor_t *desc = ptr;
495 cache_client_desc_free(desc);
507 size +=
sizeof(*entry);
509 if (entry->encoded_desc) {
510 size += strlen(entry->encoded_desc);
535 hs_cache_client_descriptor_t *cached_desc;
545 cache_client_desc_free(cached_desc);
553STATIC hs_cache_client_descriptor_t *
557 hs_cache_client_descriptor_t *cached_desc;
580static hs_cache_client_descriptor_t *
587 hs_cache_client_descriptor_t *client_desc = NULL;
594 if (ret != HS_DESC_DECODE_OK &&
595 ret != HS_DESC_DECODE_NEED_CLIENT_AUTH &&
596 ret != HS_DESC_DECODE_BAD_CLIENT_AUTH) {
602 if (ret == HS_DESC_DECODE_OK) {
605 if (BUG(desc != NULL)) {
613 client_desc = tor_malloc_zero(
sizeof(hs_cache_client_descriptor_t));
619 client_desc->desc = desc;
620 client_desc->encoded_desc = tor_strdup(desc_str);
623 if (decode_status_out) {
624 *decode_status_out = ret;
638#define cache_intro_state_free(val) \
639 FREE_AND_NULL(hs_cache_intro_state_t, cache_intro_state_free_, (val))
665#define cache_client_intro_state_free(val) \
666 FREE_AND_NULL(hs_cache_client_intro_state_t, \
667 cache_client_intro_state_free_, (val))
712 state = digest256map_get(cache->
intro_points, auth_key->pubkey);
727 rend_intro_point_failure_t failure)
731 case INTRO_POINT_FAILURE_GENERIC:
734 case INTRO_POINT_FAILURE_TIMEOUT:
737 case INTRO_POINT_FAILURE_UNREACHABLE:
769 old_entry = digest256map_set(cache->
intro_points, auth_key->pubkey, entry);
772 tor_assert_nonfatal(old_entry == NULL);
790 if (entry->created_ts <= cutoff) {
791 cache_intro_state_free(entry);
794 } DIGEST256MAP_FOREACH_END;
810 hs_cache_client_descriptor_t *cache_entry;
822 if (cache_entry != NULL) {
830 cache_client_desc_free(cache_entry);
839 if (cache_entry->desc->plaintext_data.revision_counter >
840 client_desc->desc->plaintext_data.revision_counter) {
841 cache_client_desc_free(client_desc);
853 cache_client_desc_free(cache_entry);
868 const hs_cache_client_descriptor_t *cached_desc)
882 if (cached_desc->expiration_ts <= ns->
valid_after) {
894 size_t bytes_removed = 0;
901 hs_cache_client_descriptor_t *, entry) {
911 bytes_removed += entry_size;
922 cache_client_desc_free(entry);
930 log_info(
LD_REND,
"Removing hidden service v3 descriptor '%s' "
932 safe_str_client(key_b64));
934 } DIGEST256MAP_FOREACH_END;
936 return bytes_removed;
944 hs_cache_client_descriptor_t *cached_desc = NULL;
951 return cached_desc->encoded_desc;
964 hs_cache_client_descriptor_t *cached_desc = NULL;
970 return cached_desc->desc;
997 hs_cache_client_descriptor_t *client_desc = NULL;
1005 log_warn(
LD_GENERAL,
"HSDesc parsing failed!");
1012 ret = HS_DESC_DECODE_GENERIC_ERROR;
1019 cache_client_desc_free(client_desc);
1031 hs_cache_client_descriptor_t *cached_desc = NULL;
1047 cache_client_desc_free(cached_desc);
1053 log_info(
LD_REND,
"Onion service v3 descriptor '%s' removed "
1054 "from client cache",
1055 safe_str_client(key_b64));
1073 hs_cache_client_descriptor_t *, entry) {
1076 cache_client_desc_free(entry);
1080 } DIGEST256MAP_FOREACH_END;
1082 log_info(
LD_REND,
"Hidden service client descriptor cache purged.");
1090 rend_intro_point_failure_t failure)
1132 cache_client_intro_state_free(cache);
1135 } DIGEST256MAP_FOREACH_END;
1145 cache_client_intro_state_free(cache);
1146 } DIGEST256MAP_FOREACH_END;
1148 log_info(
LD_REND,
"Hidden service client introduction point state "
1160 hs_cache_client_descriptor_t *cached_desc = NULL;
1176 &cached_desc->desc) == HS_DESC_DECODE_OK) {
1193 size_t bytes_removed = 0;
1196 uint64_t target = 0;
1205 size_t bytes_to_free = (min_remove_bytes - bytes_removed);
1206 size_t bytes_freed =
1208 if (bytes_freed == 0 && target == 0) {
1212 bytes_removed += bytes_freed;
1213 }
while (bytes_removed < min_remove_bytes);
1215 return bytes_removed;
1223 "HSV3MaxDescriptorSize",
1255 hs_cache_total_allocation = 0;
1268hs_cache_get_total_allocation(
void)
1270 return hs_cache_total_allocation;
1277 static int have_underflowed = 0;
1279 if (hs_cache_total_allocation >= n) {
1280 hs_cache_total_allocation -= n;
1282 hs_cache_total_allocation = 0;
1283 if (! have_underflowed) {
1284 have_underflowed = 1;
1285 log_warn(
LD_BUG,
"Underflow in hs_cache_decrement_allocation");
1294 static int have_overflowed = 0;
1295 if (hs_cache_total_allocation <= SIZE_MAX - n) {
1296 hs_cache_total_allocation += n;
1298 hs_cache_total_allocation = SIZE_MAX;
1299 if (! have_overflowed) {
1300 have_overflowed = 1;
1301 log_warn(
LD_BUG,
"Overflow in hs_cache_increment_allocation");
1306#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()