tor  0.4.2.1-alpha-dev
Macros | Functions | Variables
rendcache.c File Reference
#include "feature/rend/rendcache.h"
#include "app/config/config.h"
#include "feature/stats/rephist.h"
#include "feature/nodelist/routerlist.h"
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendparse.h"
#include "core/or/extend_info_st.h"
#include "feature/rend/rend_intro_point_st.h"
#include "feature/rend/rend_service_descriptor_st.h"
#include "lib/ctime/di_ops.h"

Go to the source code of this file.

Functions

void rend_cache_init (void)
 
STATIC size_t rend_cache_entry_allocation (const rend_cache_entry_t *e)
 
size_t rend_cache_get_total_allocation (void)
 
void rend_cache_decrement_allocation (size_t n)
 
void rend_cache_increment_allocation (size_t n)
 
STATIC void rend_cache_failure_intro_entry_free_ (rend_cache_failure_intro_t *entry)
 
static void rend_cache_failure_intro_entry_free_void (void *entry)
 
STATIC rend_cache_failure_intro_trend_cache_failure_intro_entry_new (rend_intro_point_failure_t failure)
 
STATIC void rend_cache_failure_entry_free_ (rend_cache_failure_t *entry)
 
STATIC void rend_cache_failure_entry_free_void (void *entry)
 
STATIC rend_cache_failure_trend_cache_failure_entry_new (void)
 
STATIC void rend_cache_failure_remove (rend_service_descriptor_t *desc)
 
STATIC void rend_cache_entry_free_ (rend_cache_entry_t *e)
 
static void rend_cache_entry_free_void (void *p)
 
void rend_cache_free_all (void)
 
void rend_cache_failure_clean (time_t now)
 
void rend_cache_clean (time_t now, rend_cache_type_t cache_type)
 
void rend_cache_purge (void)
 
void rend_cache_failure_purge (void)
 
STATIC int cache_failure_intro_lookup (const uint8_t *identity, const char *service_id, rend_cache_failure_intro_t **intro_entry)
 
static rend_cache_failure_intro_tcache_failure_intro_dup (const rend_cache_failure_intro_t *entry)
 
STATIC void cache_failure_intro_add (const uint8_t *identity, const char *service_id, rend_intro_point_failure_t failure)
 
STATIC void validate_intro_point_failure (const rend_service_descriptor_t *desc, const char *service_id)
 
void rend_cache_intro_failure_note (rend_intro_point_failure_t failure, const uint8_t *identity, const char *service_id)
 
size_t rend_cache_clean_v2_descs_as_dir (time_t cutoff)
 
int rend_cache_lookup_entry (const char *query, int version, rend_cache_entry_t **e)
 
int rend_cache_lookup_v2_desc_as_service (const char *query, rend_cache_entry_t **e)
 
int rend_cache_lookup_v2_desc_as_dir (const char *desc_id, const char **desc)
 
int rend_cache_store_v2_desc_as_dir (const char *desc)
 
int rend_cache_store_v2_desc_as_service (const char *desc)
 
int rend_cache_store_v2_desc_as_client (const char *desc, const char *desc_id_base32, const rend_data_t *rend_query, rend_cache_entry_t **entry)
 

Variables

STATIC strmap_t * rend_cache = NULL
 
static strmap_t * rend_cache_local_service = NULL
 
STATIC digestmap_t * rend_cache_v2_dir = NULL
 
STATIC strmap_t * rend_cache_failure = NULL
 
STATIC size_t rend_cache_total_allocation = 0
 

Detailed Description

Hidden service descriptor cache.

Definition in file rendcache.c.

Function Documentation

◆ cache_failure_intro_add()

STATIC void cache_failure_intro_add ( const uint8_t *  identity,
const char *  service_id,
rend_intro_point_failure_t  failure 
)

Add an intro point failure to the failure cache using the relay identity and service ID service_id. Record the failure in that object.

Definition at line 379 of file rendcache.c.

References rend_cache_failure, rend_cache_failure_entry_new(), rend_cache_failure_intro_entry_new(), strmap_get_lc(), and strmap_set_lc().

Referenced by rend_cache_intro_failure_note().

◆ cache_failure_intro_dup()

static rend_cache_failure_intro_t* cache_failure_intro_dup ( const rend_cache_failure_intro_t entry)
static

Allocate a new cache failure intro object and copy the content from entry to this newly allocated object. Return it.

Definition at line 367 of file rendcache.c.

References rend_cache_failure_intro_entry_new().

◆ cache_failure_intro_lookup()

STATIC int cache_failure_intro_lookup ( const uint8_t *  identity,
const char *  service_id,
rend_cache_failure_intro_t **  intro_entry 
)

Lookup the rend failure cache using a relay identity digest in identity which has DIGEST_LEN bytes and service ID service_id which is a null-terminated string. If found, the intro failure is set in intro_entry else it stays untouched. Return 1 iff found else 0.

Definition at line 335 of file rendcache.c.

References rend_cache_failure, strmap_get_lc(), and tor_assert().

Referenced by rend_cache_intro_failure_note().

◆ rend_cache_clean()

void rend_cache_clean ( time_t  now,
rend_cache_type_t  cache_type 
)

Removes all old entries from the client or service descriptor cache.

Definition at line 278 of file rendcache.c.

References REND_CACHE_MAX_AGE, and REND_CACHE_MAX_SKEW.

Referenced by clean_caches_callback().

◆ rend_cache_clean_v2_descs_as_dir()

size_t rend_cache_clean_v2_descs_as_dir ( time_t  cutoff)

Remove all old v2 descriptors and those for which this hidden service directory is not responsible for any more. The cutoff is the time limit for which we want to keep the cache entry. In other words, any entry created before will be removed.

Definition at line 475 of file rendcache.c.

References base32_encode(), DIGEST_LEN, rend_cache_entry_t::parsed, rend_cache_v2_dir, REND_DESC_ID_V2_LEN_BASE32, and rend_service_descriptor_t::timestamp.

◆ rend_cache_decrement_allocation()

void rend_cache_decrement_allocation ( size_t  n)

Decrement the total bytes attributed to the rendezvous cache by n.

Definition at line 96 of file rendcache.c.

Referenced by rend_cache_entry_free_().

◆ rend_cache_entry_allocation()

STATIC size_t rend_cache_entry_allocation ( const rend_cache_entry_t e)

Return the approximate number of bytes needed to hold e.

Definition at line 78 of file rendcache.c.

References rend_cache_entry_t::len, and rend_cache_entry_t::parsed.

Referenced by rend_cache_entry_free_().

◆ rend_cache_entry_free_()

STATIC void rend_cache_entry_free_ ( rend_cache_entry_t e)

Helper: free storage held by a single service descriptor cache entry.

Definition at line 210 of file rendcache.c.

References rend_cache_entry_t::parsed, rend_cache_decrement_allocation(), rend_cache_entry_allocation(), and rend_cache_failure_remove().

Referenced by rend_cache_entry_free_void().

◆ rend_cache_entry_free_void()

static void rend_cache_entry_free_void ( void *  p)
static

Helper: deallocate a rend_cache_entry_t. (Used with strmap_free(), which requires a function pointer whose argument is void*).

Definition at line 226 of file rendcache.c.

References rend_cache_entry_free_().

◆ rend_cache_failure_clean()

void rend_cache_failure_clean ( time_t  now)

Remove all entries that re REND_CACHE_FAILURE_MAX_AGE old. This is called every second.

We have to clean these regurlarly else if for whatever reasons an hidden service goes offline and a client tries to connect to it during that time, a failure entry is created and the client will be unable to connect for a while even though the service has return online.

Definition at line 254 of file rendcache.c.

References REND_CACHE_FAILURE_MAX_AGE.

Referenced by rend_cache_failure_clean_callback().

◆ rend_cache_failure_entry_free_()

STATIC void rend_cache_failure_entry_free_ ( rend_cache_failure_t entry)

Helper: free a rend cache failure object.

Definition at line 156 of file rendcache.c.

Referenced by rend_cache_failure_entry_free_void().

◆ rend_cache_failure_entry_free_void()

STATIC void rend_cache_failure_entry_free_void ( void *  entry)

Helper: deallocate a rend_cache_failure_t. (Used with strmap_free(), which requires a function pointer whose argument is void*).

Definition at line 172 of file rendcache.c.

References rend_cache_failure_entry_free_().

◆ rend_cache_failure_entry_new()

STATIC rend_cache_failure_t* rend_cache_failure_entry_new ( void  )

Allocate a rend cache failure object and return it. This function can not fail.

Definition at line 180 of file rendcache.c.

Referenced by cache_failure_intro_add().

◆ rend_cache_failure_intro_entry_free_()

STATIC void rend_cache_failure_intro_entry_free_ ( rend_cache_failure_intro_t entry)

Helper: free a rend cache failure intro object.

Definition at line 129 of file rendcache.c.

References tor_free.

◆ rend_cache_failure_intro_entry_new()

STATIC rend_cache_failure_intro_t* rend_cache_failure_intro_entry_new ( rend_intro_point_failure_t  failure)

Allocate a rend cache failure intro object and return it. failure is set into the object. This function can not fail.

Definition at line 146 of file rendcache.c.

Referenced by cache_failure_intro_add(), and cache_failure_intro_dup().

◆ rend_cache_failure_purge()

void rend_cache_failure_purge ( void  )

Remove ALL entries from the failure cache. This is also called when a NEWNYM signal is received.

Definition at line 321 of file rendcache.c.

References rend_cache_failure.

Referenced by rend_client_purge_state().

◆ rend_cache_failure_remove()

STATIC void rend_cache_failure_remove ( rend_service_descriptor_t desc)

Remove failure cache entry for the service ID in the given descriptor desc.

Definition at line 190 of file rendcache.c.

References rend_service_descriptor_t::pk, rend_cache_failure, rend_get_service_id(), REND_SERVICE_ID_LEN_BASE32, strmap_get_lc(), and strmap_remove_lc().

Referenced by rend_cache_entry_free_().

◆ rend_cache_free_all()

void rend_cache_free_all ( void  )

Free all storage held by the service descriptor cache.

Definition at line 233 of file rendcache.c.

◆ rend_cache_increment_allocation()

void rend_cache_increment_allocation ( size_t  n)

Increase the total bytes attributed to the rendezvous cache by n.

Definition at line 113 of file rendcache.c.

◆ rend_cache_init()

void rend_cache_init ( void  )

Initializes the service descriptor cache.

Definition at line 68 of file rendcache.c.

References rend_cache, rend_cache_failure, rend_cache_local_service, and rend_cache_v2_dir.

Referenced by tor_init().

◆ rend_cache_intro_failure_note()

void rend_cache_intro_failure_note ( rend_intro_point_failure_t  failure,
const uint8_t *  identity,
const char *  service_id 
)

Note down an intro failure in the rend failure cache using the type of failure in failure for the relay identity digest in identity and service ID service_id. If an entry already exists in the cache, the failure type is changed with failure.

Definition at line 454 of file rendcache.c.

References cache_failure_intro_add(), and cache_failure_intro_lookup().

◆ rend_cache_lookup_entry()

int rend_cache_lookup_entry ( const char *  query,
int  version,
rend_cache_entry_t **  e 
)

Lookup in the client cache the given service ID query for version.

Return 0 if found and if e is non NULL, set it with the entry found. Else, a negative value is returned and e is untouched. -EINVAL means that query is not a valid service id. -ENOENT means that no entry in the cache was found.

Definition at line 511 of file rendcache.c.

References rend_cache, REND_SERVICE_ID_LEN_BASE32, rend_valid_v2_service_id(), and tor_assert().

◆ rend_cache_lookup_v2_desc_as_dir()

int rend_cache_lookup_v2_desc_as_dir ( const char *  desc_id,
const char **  desc 
)

Lookup the v2 service descriptor with base32-encoded desc_id and copy the pointer to it to *desc. Return 1 on success, 0 on well-formed-but-not-found, and -1 on failure.

Definition at line 592 of file rendcache.c.

References base32_decode(), DIGEST_LEN, log_fn, rend_cache_v2_dir, REND_DESC_ID_V2_LEN_BASE32, and tor_assert().

◆ rend_cache_purge()

void rend_cache_purge ( void  )

Remove ALL entries from the rendezvous service descriptor cache.

Definition at line 309 of file rendcache.c.

References rend_cache.

Referenced by rend_client_purge_state().

◆ rend_cache_store_v2_desc_as_client()

int rend_cache_store_v2_desc_as_client ( const char *  desc,
const char *  desc_id_base32,
const rend_data_t rend_query,
rend_cache_entry_t **  entry 
)

Parse the v2 service descriptor in desc, decrypt the included list of introduction points with descriptor_cookie (which may also be NULL if decryption is not necessary), and store the descriptor to the local cache under its version and service id.

If we have a newer v2 descriptor with the same ID, ignore this one. If we have an older descriptor with the same ID, replace it. If the descriptor's service ID does not match rend_query->onion_address, reject it.

If the descriptor's descriptor ID doesn't match desc_id_base32, reject it.

Return 0 on success, or -1 if we rejected the descriptor. If entry is not NULL, set it with the cache entry pointer of the descriptor.

Definition at line 817 of file rendcache.c.

References DIGEST_LEN, and REND_SERVICE_ID_LEN_BASE32.

◆ rend_cache_store_v2_desc_as_dir()

int rend_cache_store_v2_desc_as_dir ( const char *  desc)

Parse the v2 service descriptor(s) in desc and store it/them to the local rend cache. Don't attempt to decrypt the included list of introduction points (as we don't have a descriptor cookie for it).

If we have a newer descriptor with the same ID, ignore this one. If we have an older descriptor with the same ID, replace it.

Return 0 on success, or -1 if we couldn't parse any of them.

We should only call this function for public (e.g. non bridge) relays.

Definition at line 627 of file rendcache.c.

References base32_encode(), DIGEST_LEN, REND_CACHE_MAX_AGE, REND_CACHE_MAX_SKEW, rend_cache_v2_dir, REND_DESC_ID_V2_LEN_BASE32, rend_parse_v2_service_descriptor(), rend_service_descriptor_t::timestamp, tor_assert(), and tor_free.

◆ rend_cache_store_v2_desc_as_service()

int rend_cache_store_v2_desc_as_service ( const char *  desc)

Parse the v2 service descriptor in desc and store it to the local service rend cache. Don't attempt to decrypt the included list of introduction points.

If we have a newer descriptor with the same ID, ignore this one. If we have an older descriptor with the same ID, replace it.

Return 0 on success, or -1 if we couldn't understand the descriptor.

Definition at line 736 of file rendcache.c.

References DIGEST_LEN, rend_cache_local_service, rend_parse_v2_service_descriptor(), REND_SERVICE_ID_LEN_BASE32, and tor_assert().

◆ validate_intro_point_failure()

STATIC void validate_intro_point_failure ( const rend_service_descriptor_t desc,
const char *  service_id 
)

Using a parsed descriptor desc, check if the introduction points are present in the failure cache and if so they are removed from the descriptor and kept into the failure cache. Then, each intro points that are NOT in the descriptor but in the failure cache for the given service_id are removed from the failure cache.

Definition at line 406 of file rendcache.c.

Variable Documentation

◆ rend_cache

STATIC strmap_t* rend_cache = NULL

Map from service id (as generated by rend_get_service_id) to rend_cache_entry_t.

Definition at line 26 of file rendcache.c.

Referenced by rend_cache_init(), rend_cache_lookup_entry(), and rend_cache_purge().

◆ rend_cache_failure

STATIC strmap_t* rend_cache_failure = NULL

(Client side only) Map from service id to rend_cache_failure_t. This cache is used to track intro point(IP) failures so we know when to keep or discard a new descriptor we just fetched. Here is a description of the cache behavior.

Everytime tor discards an IP (ex: receives a NACK), we add an entry to this cache noting the identity digest of the IP and it's failure type for the service ID. The reason we indexed this cache by service ID is to differentiate errors that can occur only for a specific service like a NACK for instance. It applies for one but maybe not for the others.

Once a service descriptor is fetched and considered valid, each IP is looked up in this cache and if present, it is discarded from the fetched descriptor. At the end, all IP(s) in the cache, for a specific service ID, that were NOT present in the descriptor are removed from this cache. Which means that if at least one IP was not in this cache, thus usable, it's considered a new descriptor so we keep it. Else, if all IPs were in this cache, we discard the descriptor as it's considered unusable.

Once a descriptor is removed from the rend cache or expires, the entry in this cache is also removed for the service ID.

This scheme allows us to not rely on the descriptor's timestamp (which is rounded down to the hour) to know if we have a newer descriptor. We only rely on the usability of intro points from an internal state.

Definition at line 60 of file rendcache.c.

Referenced by cache_failure_intro_add(), cache_failure_intro_lookup(), rend_cache_failure_purge(), rend_cache_failure_remove(), and rend_cache_init().

◆ rend_cache_local_service

strmap_t* rend_cache_local_service = NULL
static

Map from service id to rend_cache_entry_t; only for hidden services.

Definition at line 29 of file rendcache.c.

Referenced by rend_cache_init(), and rend_cache_store_v2_desc_as_service().

◆ rend_cache_v2_dir

STATIC digestmap_t* rend_cache_v2_dir = NULL

Map from descriptor id to rend_cache_entry_t; only for hidden service directories.

Definition at line 33 of file rendcache.c.

Referenced by rend_cache_clean_v2_descs_as_dir(), rend_cache_init(), rend_cache_lookup_v2_desc_as_dir(), and rend_cache_store_v2_desc_as_dir().