rendcommon.c File Reference

Rendezvous implementation: shared code between introducers, services, clients, and rendezvous points. More...

#include "or.h"

Defines

#define REND_DESC_COOKIE_LEN   16
#define REND_REPLICA_LEN   1
#define REND_CACHE_MAX_AGE   (2*24*60*60)
#define REND_CACHE_MAX_SKEW   (24*60*60)

Functions

int rend_cmp_service_ids (const char *one, const char *two)
void rend_service_descriptor_free (rend_service_descriptor_t *desc)
void rend_get_descriptor_id_bytes (char *descriptor_id_out, const char *service_id, const char *secret_id_part)
static void get_secret_id_part_bytes (char *secret_id_part, uint32_t time_period, const char *descriptor_cookie, uint8_t replica)
static uint32_t get_time_period (time_t now, uint8_t deviation, const char *service_id)
static uint32_t get_seconds_valid (time_t now, const char *service_id)
int rend_compute_v2_desc_id (char *desc_id_out, const char *service_id, const char *descriptor_cookie, time_t now, uint8_t replica)
static int rend_encode_v2_intro_points (char **encoded, rend_service_descriptor_t *desc)
static int rend_encrypt_v2_intro_points_basic (char **encrypted_out, size_t *encrypted_len_out, const char *encoded, smartlist_t *client_cookies)
static int rend_encrypt_v2_intro_points_stealth (char **encrypted_out, size_t *encrypted_len_out, const char *encoded, const char *descriptor_cookie)
static int rend_desc_v2_is_parsable (rend_encoded_v2_service_descriptor_t *desc)
void rend_encoded_v2_service_descriptor_free (rend_encoded_v2_service_descriptor_t *desc)
void rend_intro_point_free (rend_intro_point_t *intro)
int rend_encode_v2_descriptors (smartlist_t *descs_out, rend_service_descriptor_t *desc, time_t now, uint8_t period, rend_auth_type_t auth_type, crypto_pk_env_t *client_key, smartlist_t *client_cookies)
rend_service_descriptor_trend_parse_service_descriptor (const char *str, size_t len)
int rend_get_service_id (crypto_pk_env_t *pk, char *out)
void rend_cache_init (void)
static void rend_cache_entry_free (rend_cache_entry_t *e)
static void _rend_cache_entry_free (void *p)
void rend_cache_free_all (void)
void rend_cache_clean (void)
void rend_cache_clean_v2_descs_as_dir (void)
int rend_id_is_in_interval (const char *a, const char *b, const char *c)
int rend_valid_service_id (const char *query)
int rend_cache_lookup_entry (const char *query, int version, rend_cache_entry_t **e)
int rend_cache_lookup_desc (const char *query, int version, const char **desc, size_t *desc_len)
int rend_cache_lookup_v2_desc_as_dir (const char *desc_id, const char **desc)
int rend_cache_store (const char *desc, size_t desc_len, int published)
int rend_cache_store_v2_desc_as_dir (const char *desc)
int rend_cache_store_v2_desc_as_client (const char *desc, const rend_data_t *rend_query)
void rend_process_relay_cell (circuit_t *circ, const crypt_path_t *layer_hint, int command, size_t length, const char *payload)
int rend_cache_size (void)
rend_data_trend_data_dup (const rend_data_t *data)

Variables

static strmap_t * rend_cache = NULL
static digestmap_t * rend_cache_v2_dir = NULL


Detailed Description

Rendezvous implementation: shared code between introducers, services, clients, and rendezvous points.


Define Documentation

#define REND_CACHE_MAX_AGE   (2*24*60*60)

How old do we let hidden service descriptors get before discarding them as too old?

Referenced by rend_cache_clean(), rend_cache_clean_v2_descs_as_dir(), rend_cache_store(), rend_cache_store_v2_desc_as_client(), and rend_cache_store_v2_desc_as_dir().

#define REND_CACHE_MAX_SKEW   (24*60*60)

How wrong do we assume our clock may be when checking whether hidden services are too old or too new?

Referenced by rend_cache_clean(), rend_cache_clean_v2_descs_as_dir(), rend_cache_store(), rend_cache_store_v2_desc_as_client(), and rend_cache_store_v2_desc_as_dir().

#define REND_DESC_COOKIE_LEN   16

Length of the descriptor cookie that is used for versioned hidden service descriptors.

#define REND_REPLICA_LEN   1

Length of the replica number that is used to determine the secret ID part of versioned hidden service descriptors.

Referenced by get_secret_id_part_bytes().


Function Documentation

static uint32_t get_seconds_valid ( time_t  now,
const char *  service_id 
) [static]

Compute the time in seconds that a descriptor that is generated now for service_id will be valid.

References REND_TIME_PERIOD_V2_DESC_VALIDITY.

Referenced by rend_encode_v2_descriptors().

static void get_secret_id_part_bytes ( char *  secret_id_part,
uint32_t  time_period,
const char *  descriptor_cookie,
uint8_t  replica 
) [static]

Compute the secret ID part for time_period, a descriptor_cookie of length REND_DESC_COOKIE_LEN which may also be NULL if no descriptor_cookie shall be used, and replica, and write it to secret_id_part of length DIGEST_LEN.

References crypto_digest_add_bytes(), crypto_digest_get_digest(), crypto_free_digest_env(), crypto_new_digest_env(), DIGEST_LEN, REND_DESC_COOKIE_LEN, and REND_REPLICA_LEN.

Referenced by rend_compute_v2_desc_id(), and rend_encode_v2_descriptors().

static uint32_t get_time_period ( time_t  now,
uint8_t  deviation,
const char *  service_id 
) [static]

Return the time period for time now plus a potentially intended deviation of one or more periods, based on the first byte of service_id.

References REND_TIME_PERIOD_V2_DESC_VALIDITY.

Referenced by rend_compute_v2_desc_id(), and rend_encode_v2_descriptors().

void rend_cache_clean ( void   ) 

void rend_cache_clean_v2_descs_as_dir ( void   ) 

static void rend_cache_entry_free ( rend_cache_entry_t e  )  [static]

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

References rend_cache_entry_t::desc, rend_cache_entry_t::parsed, rend_service_descriptor_free(), and tor_free.

Referenced by rend_cache_clean(), and rend_cache_clean_v2_descs_as_dir().

void rend_cache_free_all ( void   ) 

Free all storage held by the service descriptor cache.

References digestmap_free(), rend_cache, rend_cache_v2_dir, and strmap_free().

Referenced by tor_free_all().

void rend_cache_init ( void   ) 

Initializes the service descriptor cache.

References digestmap_new(), rend_cache, and rend_cache_v2_dir.

Referenced by tor_init().

int rend_cache_lookup_desc ( const char *  query,
int  version,
const char **  desc,
size_t *  desc_len 
)

query is a base-32'ed service id. If it's malformed, return -1. Else look it up.

  • If it is found, point *desc to it, and write its length into *desc_len, and return 1.
  • If it is not found, return 0. Note: calls to rend_cache_clean or rend_cache_store may invalidate *desc.

References rend_cache_entry_t::desc, rend_cache_entry_t::len, and rend_cache_lookup_entry().

Referenced by directory_handle_command_get().

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

If we have a cached rend_cache_entry_t for the service ID query with version, set *e to that entry and return 1. Else return 0. If version is nonnegative, only return an entry in that descriptor format version. Otherwise (if version is negative), return the most recent format we have.

References rend_cache, REND_SERVICE_ID_LEN_BASE32, rend_valid_service_id(), strmap_get_lc(), tor_assert, and tor_snprintf().

Referenced by rend_cache_lookup_desc(), rend_client_desc_trynow(), rend_client_get_random_intro(), rend_client_refetch_v2_renddesc(), rend_client_remove_intro_point(), and rend_client_send_introduction().

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.

References base32_decode(), rend_cache_entry_t::desc, DIGEST_LEN, digestmap_get(), hid_serv_responsible_for_desc_id(), LD_REND, rend_cache_v2_dir, REND_DESC_ID_V2_LEN_BASE32, safe_str(), and tor_assert.

Referenced by directory_handle_command_get().

int rend_cache_size ( void   ) 

Return the number of entries in our rendezvous descriptor cache.

References rend_cache, and strmap_size().

int rend_cache_store ( const char *  desc,
size_t  desc_len,
int  published 
)

Parse *desc, calculate its service id, and store it in the cache. If we have a newer v0 descriptor with the same ID, ignore this one. If we have an older descriptor with the same ID, replace it. If we are acting as client due to the published flag and have any v2 descriptor with the same ID, reject this one in order to not get confused with having both versions for the same service.

Return -2 if it's malformed or otherwise rejected; return -1 if we already have a v2 descriptor here; return 0 if it's the same or older than one we've already got; return 1 if it's novel.

The published flag tells us if we store the descriptor in our role as directory (1) or if we cache it as client (0).

References rend_cache_entry_t::desc, LD_BUG, LD_PROTOCOL, LD_REND, rend_cache_entry_t::len, rend_cache_entry_t::parsed, rend_service_descriptor_t::pk, rend_cache_entry_t::received, rend_cache, REND_CACHE_MAX_AGE, REND_CACHE_MAX_SKEW, rend_get_service_id(), rend_parse_service_descriptor(), rend_service_descriptor_free(), REND_SERVICE_ID_LEN_BASE32, safe_str_client(), strmap_get_lc(), strmap_set_lc(), rend_service_descriptor_t::timestamp, tor_assert, tor_free, and tor_snprintf().

Referenced by connection_dir_client_reached_eof(), and directory_handle_command_post().

int rend_cache_store_v2_desc_as_client ( const char *  desc,
const rend_data_t rend_query 
)

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 we have any v0 descriptor with the same ID, reject this one in order to not get confused with having both versions for the same service. Return -2 if it's malformed or otherwise rejected; return -1 if we already have a v0 descriptor here; return 0 if it's the same or older than one we've already got; return 1 if it's novel.

References rend_data_t::auth_type, rend_cache_entry_t::desc, rend_data_t::descriptor_cookie, DIGEST_LEN, rend_service_descriptor_t::intro_nodes, LD_REND, rend_cache_entry_t::len, rend_cache_entry_t::parsed, rend_service_descriptor_t::pk, rend_cache_entry_t::received, rend_cache, REND_CACHE_MAX_AGE, REND_CACHE_MAX_SKEW, rend_decrypt_introduction_points(), rend_get_service_id(), rend_parse_introduction_points(), rend_parse_v2_service_descriptor(), rend_service_descriptor_free(), REND_SERVICE_ID_LEN_BASE32, safe_str_client(), smartlist_create(), strmap_get_lc(), strmap_set_lc(), rend_service_descriptor_t::timestamp, tor_assert, tor_free, tor_mem_is_zero(), and tor_snprintf().

Referenced by connection_dir_client_reached_eof().

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 -2 if we are not acting as hidden service directory; return -1 if the descriptor(s) were not parsable; return 0 if all descriptors are the same or older than those we've already got; return a positive number for the number of novel stored descriptors.

References base32_encode(), rend_cache_entry_t::desc, DIGEST_LEN, digestmap_get(), digestmap_set(), hid_serv_acting_as_directory(), hid_serv_responsible_for_desc_id(), LD_REND, rend_cache_entry_t::len, rend_cache_entry_t::parsed, rend_cache_entry_t::received, 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_free(), safe_str(), safe_str_client(), strcmpstart(), rend_service_descriptor_t::timestamp, tor_assert, and tor_free.

Referenced by directory_handle_command_post().

int rend_cmp_service_ids ( const char *  one,
const char *  two 
)

int rend_compute_v2_desc_id ( char *  desc_id_out,
const char *  service_id,
const char *  descriptor_cookie,
time_t  now,
uint8_t  replica 
)

Compute the binary desc_id_out (DIGEST_LEN bytes long) for a given base32-encoded service_id and optional unencoded descriptor_cookie of length REND_DESC_COOKIE_LEN, at time now for replica number replica. desc_id needs to have DIGEST_LEN bytes free. Return 0 for success, -1 otherwise.

References base32_decode(), DIGEST_LEN, get_secret_id_part_bytes(), get_time_period(), LD_REND, rend_get_descriptor_id_bytes(), REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS, REND_SERVICE_ID_LEN, REND_SERVICE_ID_LEN_BASE32, safe_str(), and safe_str_client().

Referenced by rend_client_refetch_v2_renddesc().

rend_data_t* rend_data_dup ( const rend_data_t data  ) 

Allocate and return a new rend_data_t with the same contents as query.

References tor_assert.

Referenced by circuit_get_open_circ_or_launch(), connection_exit_begin_conn(), directory_initiate_command_rend(), and rend_service_relaunch_rendezvous().

static int rend_desc_v2_is_parsable ( rend_encoded_v2_service_descriptor_t desc  )  [static]

Attempt to parse the given desc_str and return true if this succeeds, false otherwise.

References rend_encoded_v2_service_descriptor_t::desc_str, DIGEST_LEN, rend_parse_v2_service_descriptor(), rend_service_descriptor_free(), and tor_free.

Referenced by rend_encode_v2_descriptors().

int rend_encode_v2_descriptors ( smartlist_t descs_out,
rend_service_descriptor_t desc,
time_t  now,
uint8_t  period,
rend_auth_type_t  auth_type,
crypto_pk_env_t client_key,
smartlist_t client_cookies 
)

static int rend_encode_v2_intro_points ( char **  encoded,
rend_service_descriptor_t desc 
) [static]

void rend_encoded_v2_service_descriptor_free ( rend_encoded_v2_service_descriptor_t desc  ) 

Free the storage held by an encoded v2 service descriptor.

References rend_encoded_v2_service_descriptor_t::desc_str, and tor_free.

Referenced by rend_encode_v2_descriptors(), and upload_service_descriptor().

static int rend_encrypt_v2_intro_points_basic ( char **  encrypted_out,
size_t *  encrypted_len_out,
const char *  encoded,
smartlist_t client_cookies 
) [static]

Encrypt the encoded introduction points in encoded using authorization type 'basic' with client_cookies and write the result to a newly allocated string pointed to by encrypted_out of length encrypted_len_out. Return 0 for success, -1 otherwise.

References CIPHER_IV_LEN, CIPHER_KEY_LEN, crypto_cipher_encrypt(), crypto_cipher_encrypt_with_iv(), crypto_create_init_cipher(), crypto_digest_add_bytes(), crypto_digest_get_digest(), crypto_free_cipher_env(), crypto_free_digest_env(), crypto_new_digest_env(), crypto_rand(), LD_REND, REND_BASIC_AUTH_CLIENT_ENTRY_LEN, REND_BASIC_AUTH_CLIENT_ID_LEN, REND_BASIC_AUTH_CLIENT_MULTIPLE, REND_DESC_COOKIE_LEN, smartlist_add(), smartlist_create(), smartlist_free(), smartlist_sort_digests(), tor_assert, and tor_free.

Referenced by rend_encode_v2_descriptors().

static int rend_encrypt_v2_intro_points_stealth ( char **  encrypted_out,
size_t *  encrypted_len_out,
const char *  encoded,
const char *  descriptor_cookie 
) [static]

Encrypt the encoded introduction points in encoded using authorization type 'stealth' with descriptor_cookie of length REND_DESC_COOKIE_LEN and write the result to a newly allocated string pointed to by encrypted_out of length encrypted_len_out. Return 0 for success, -1 otherwise.

References CIPHER_IV_LEN, crypto_cipher_encrypt_with_iv(), crypto_create_init_cipher(), crypto_free_cipher_env(), LD_REND, tor_assert, and tor_free.

Referenced by rend_encode_v2_descriptors().

void rend_get_descriptor_id_bytes ( char *  descriptor_id_out,
const char *  service_id,
const char *  secret_id_part 
)

Compute the descriptor ID for service_id of length REND_SERVICE_ID_LEN and secret_id_part of length DIGEST_LEN, and write it to descriptor_id_out of length DIGEST_LEN.

References crypto_digest_add_bytes(), crypto_digest_get_digest(), crypto_free_digest_env(), crypto_new_digest_env(), DIGEST_LEN, and REND_SERVICE_ID_LEN.

Referenced by rend_compute_v2_desc_id(), rend_encode_v2_descriptors(), and rend_parse_v2_service_descriptor().

int rend_get_service_id ( crypto_pk_env_t pk,
char *  out 
)

Sets out to the first 10 bytes of the digest of pk, base32 encoded. NUL-terminates out. (We use this string to identify services in directory requests and .onion URLs.)

References base32_encode(), crypto_pk_get_digest(), DIGEST_LEN, REND_SERVICE_ID_LEN, REND_SERVICE_ID_LEN_BASE32, and tor_assert.

Referenced by rend_cache_store(), rend_cache_store_v2_desc_as_client(), rend_service_load_keys(), and upload_service_descriptor().

int rend_id_is_in_interval ( const char *  a,
const char *  b,
const char *  c 
)

Determines whether a is in the interval of b (excluded) and c (included) in a circular digest ring; returns 1 if this is the case, and 0 otherwise.

References DIGEST_LEN, and tor_assert.

Referenced by hid_serv_responsible_for_desc_id().

void rend_intro_point_free ( rend_intro_point_t intro  ) 

rend_service_descriptor_t* rend_parse_service_descriptor ( const char *  str,
size_t  len 
)

void rend_process_relay_cell ( circuit_t circ,
const crypt_path_t layer_hint,
int  command,
size_t  length,
const char *  payload 
)

void rend_service_descriptor_free ( rend_service_descriptor_t desc  ) 

int rend_valid_service_id ( const char *  query  ) 

Return true iff query is a syntactically valid service ID (as generated by rend_get_service_id).

References BASE32_CHARS, and REND_SERVICE_ID_LEN_BASE32.

Referenced by parse_extended_hostname(), rend_cache_lookup_entry(), and rend_parse_service_authorization().


Variable Documentation

strmap_t* rend_cache = NULL [static]

digestmap_t* rend_cache_v2_dir = NULL [static]


Generated on Tue May 25 00:30:49 2010 for tor by  doxygen 1.5.6