Browse Source

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>
David Goulet 9 years ago
parent
commit
e6a581f126
4 changed files with 115 additions and 4 deletions
  1. 8 2
      src/or/or.h
  2. 2 2
      src/or/rendclient.c
  3. 97 0
      src/or/rendcommon.c
  4. 8 0
      src/or/rendcommon.h

+ 8 - 2
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];

+ 2 - 2
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;

+ 97 - 0
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;
+}

+ 8 - 0
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