commit e6a581f126bac80d1d0c61ae026d81076f03b77b Author: David Goulet dgoulet@ev0ke.net Date: Tue Apr 28 11:01:58 2015 -0400
Add a create function for rend_data_t object
Ground works for fixing #15816. This adds the rend_data_create() function in order to have a single place where we initialize that data structure.
Furthermore, an array of descriptor IDs is added (one per replica) so we can keep a copy of the current id in the object. It will be used to purge the last hid serv request cache using those descriptor IDs. When they change, they will be replaced and the old ones will be purged from the cache.
Signed-off-by: David Goulet dgoulet@ev0ke.net --- src/or/or.h | 10 ++++-- src/or/rendclient.c | 4 +-- src/or/rendcommon.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/or/rendcommon.h | 8 +++++ 4 files changed, 115 insertions(+), 4 deletions(-)
diff --git a/src/or/or.h b/src/or/or.h index dee1881..d9be1be 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -793,6 +793,11 @@ typedef struct rend_data_t { /** Onion address (without the .onion part) that a client requests. */ char onion_address[REND_SERVICE_ID_LEN_BASE32+1];
+ /** Descriptor ID for each replicas computed from the onion address. If + * the onion address is empty, this array MUST be empty. We keep them so + * we know when to purge our entry in the last hsdir request table. */ + char descriptor_id[REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS][DIGEST_LEN]; + /** (Optional) descriptor cookie that is used by a client. */ char descriptor_cookie[REND_DESC_COOKIE_LEN];
@@ -800,8 +805,9 @@ typedef struct rend_data_t { rend_auth_type_t auth_type;
/** Descriptor ID for a client request. The control port command HSFETCH - * can use this. */ - char descriptor_id[DIGEST_LEN]; + * uses this. It's set if the descriptor query should only use this + * descriptor ID. */ + char desc_id_fetch[DIGEST_LEN];
/** Hash of the hidden service's PK used by a service. */ char rend_pk_digest[DIGEST_LEN]; diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 13781c2..8a8d8f7 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -860,8 +860,8 @@ rend_client_fetch_v2_desc(const rend_data_t *query,
if (query->onion_address[0] != '\0') { ret = fetch_v2_desc_by_addr(query, hsdirs); - } else if (query->descriptor_id[0] != '\0') { - ret = fetch_v2_desc_by_descid(query->descriptor_id, query, hsdirs); + } else if (!tor_digest_is_zero(query->desc_id_fetch)) { + ret = fetch_v2_desc_by_descid(query->desc_id_fetch, query, hsdirs); } else { /* Query data is invalid. */ ret = -1; diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index 03dd757..1b042f9 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -1404,3 +1404,100 @@ rend_data_dup(const rend_data_t *data) return tor_memdup(data, sizeof(rend_data_t)); }
+/** Compute descriptor ID for each replicas and save them. A valid onion + * address must be present in the <b>rend_data</b>. + * + * Return 0 on success else -1. */ +static int +compute_desc_id(rend_data_t *rend_data) +{ + int ret, replica; + time_t now = time(NULL); + + tor_assert(rend_data); + + /* Compute descriptor ID for each replicas. */ + for (replica = 0; replica < ARRAY_LENGTH(rend_data->descriptor_id); + replica++) { + ret = rend_compute_v2_desc_id(rend_data->descriptor_id[replica], + rend_data->onion_address, + rend_data->descriptor_cookie, + now, replica); + if (ret < 0) { + goto end; + } + } + +end: + return ret; +} + +/** Allocate and initialize a rend_data_t object for a service using the + * given arguments. Only the <b>onion_address</b> is not optional. + * + * Return a valid rend_data_t pointer. */ +rend_data_t * +rend_data_service_create(const char *onion_address, const char *pk_digest, + const uint8_t *cookie, rend_auth_type_t auth_type) +{ + rend_data_t *rend_data = tor_malloc_zero(sizeof(*rend_data)); + + /* We need at least one else the call is wrong. */ + tor_assert(onion_address != NULL); + + if (pk_digest) { + memcpy(rend_data->rend_pk_digest, pk_digest, + sizeof(rend_data->rend_pk_digest)); + } + if (cookie) { + memcpy(rend_data->rend_cookie, cookie, + sizeof(rend_data->rend_cookie)); + } + + strlcpy(rend_data->onion_address, onion_address, + sizeof(rend_data->onion_address)); + rend_data->auth_type = auth_type; + + return rend_data; +} + +/** Allocate and initialize a rend_data_t object for a client request using + * the given arguments. Either an onion address or a descriptor ID is + * needed. Both can be given but only the onion address will be used to make + * the descriptor fetch. + * + * Return a valid rend_data_t pointer or NULL on error meaning the + * descriptor IDs couldn't be computed from the given data. */ +rend_data_t * +rend_data_client_create(const char *onion_address, const char *desc_id, + const char *cookie, rend_auth_type_t auth_type) +{ + rend_data_t *rend_data = tor_malloc_zero(sizeof(*rend_data)); + + /* We need at least one else the call is wrong. */ + tor_assert(onion_address != NULL || desc_id != NULL); + + if (cookie) { + memcpy(rend_data->descriptor_cookie, cookie, + sizeof(rend_data->descriptor_cookie)); + } + if (desc_id) { + memcpy(rend_data->desc_id_fetch, desc_id, + sizeof(rend_data->desc_id_fetch)); + } + if (onion_address) { + strlcpy(rend_data->onion_address, onion_address, + sizeof(rend_data->onion_address)); + if (compute_desc_id(rend_data) < 0) { + goto error; + } + } + + rend_data->auth_type = auth_type; + + return rend_data; + +error: + rend_data_free(rend_data); + return NULL; +} diff --git a/src/or/rendcommon.h b/src/or/rendcommon.h index b86cdb7..a4d55d2 100644 --- a/src/or/rendcommon.h +++ b/src/or/rendcommon.h @@ -67,5 +67,13 @@ void rend_get_descriptor_id_bytes(char *descriptor_id_out, const char *secret_id_part); size_t rend_cache_get_total_allocation(void);
+rend_data_t *rend_data_client_create(const char *onion_address, + const char *desc_id, + const char *cookie, + rend_auth_type_t auth_type); +rend_data_t *rend_data_service_create(const char *onion_address, + const char *pk_digest, + const uint8_t *cookie, + rend_auth_type_t auth_type); #endif