Browse Source

prop224: Move some rendclient.c code to hs_common.c

Specifically move the pick_hsdir() function and all the HSDir request tracking
code. We plan to use all that code both for v2 and v3.

This commit only moves code.

Signed-off-by: David Goulet <dgoulet@torproject.org>
George Kadianakis 6 years ago
parent
commit
912c11761c
4 changed files with 235 additions and 225 deletions
  1. 224 0
      src/or/hs_common.c
  2. 11 0
      src/or/hs_common.h
  3. 0 224
      src/or/rendclient.c
  4. 0 1
      src/or/rendclient.h

+ 224 - 0
src/or/hs_common.c

@@ -22,6 +22,7 @@
 #include "rendcommon.h"
 #include "rendservice.h"
 #include "router.h"
+#include "routerset.h"
 #include "shared_random.h"
 #include "shared_random_state.h"
 
@@ -1320,6 +1321,229 @@ hs_get_responsible_hsdirs(const ed25519_public_key_t *blinded_pk,
   smartlist_free(sorted_nodes);
 }
 
+/*********************** HSDir request tracking ***************************/
+
+/** Return the period for which a hidden service directory cannot be queried
+ * for the same descriptor ID again, taking TestingTorNetwork into account. */
+static time_t
+hsdir_requery_period(const or_options_t *options)
+{
+  tor_assert(options);
+
+  if (options->TestingTorNetwork) {
+    return REND_HID_SERV_DIR_REQUERY_PERIOD_TESTING;
+  } else {
+    return REND_HID_SERV_DIR_REQUERY_PERIOD;
+  }
+}
+
+/** Contains the last request times to hidden service directories for
+ * certain queries; each key is a string consisting of the
+ * concatenation of a base32-encoded HS directory identity digest and
+ * base32-encoded HS descriptor ID; each value is a pointer to a time_t
+ * holding the time of the last request for that descriptor ID to that
+ * HS directory. */
+static strmap_t *last_hid_serv_requests_ = NULL;
+
+/** Returns last_hid_serv_requests_, initializing it to a new strmap if
+ * necessary. */
+static strmap_t *
+get_last_hid_serv_requests(void)
+{
+  if (!last_hid_serv_requests_)
+    last_hid_serv_requests_ = strmap_new();
+  return last_hid_serv_requests_;
+}
+
+#define LAST_HID_SERV_REQUEST_KEY_LEN (REND_DESC_ID_V2_LEN_BASE32 + \
+                                       REND_DESC_ID_V2_LEN_BASE32)
+
+/** Look up the last request time to hidden service directory <b>hs_dir</b>
+ * for descriptor ID <b>desc_id_base32</b>. If <b>set</b> is non-zero,
+ * assign the current time <b>now</b> and return that. Otherwise, return the
+ * most recent request time, or 0 if no such request has been sent before.
+ */
+static time_t
+lookup_last_hid_serv_request(routerstatus_t *hs_dir,
+                             const char *desc_id_base32,
+                             time_t now, int set)
+{
+  char hsdir_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
+  char hsdir_desc_comb_id[LAST_HID_SERV_REQUEST_KEY_LEN + 1];
+  time_t *last_request_ptr;
+  strmap_t *last_hid_serv_requests = get_last_hid_serv_requests();
+  base32_encode(hsdir_id_base32, sizeof(hsdir_id_base32),
+                hs_dir->identity_digest, DIGEST_LEN);
+  tor_snprintf(hsdir_desc_comb_id, sizeof(hsdir_desc_comb_id), "%s%s",
+               hsdir_id_base32,
+               desc_id_base32);
+  /* XXX++?? tor_assert(strlen(hsdir_desc_comb_id) ==
+                       LAST_HID_SERV_REQUEST_KEY_LEN); */
+  if (set) {
+    time_t *oldptr;
+    last_request_ptr = tor_malloc_zero(sizeof(time_t));
+    *last_request_ptr = now;
+    oldptr = strmap_set(last_hid_serv_requests, hsdir_desc_comb_id,
+                        last_request_ptr);
+    tor_free(oldptr);
+  } else
+    last_request_ptr = strmap_get_lc(last_hid_serv_requests,
+                                     hsdir_desc_comb_id);
+  return (last_request_ptr) ? *last_request_ptr : 0;
+}
+
+/** Clean the history of request times to hidden service directories, so that
+ * it does not contain requests older than REND_HID_SERV_DIR_REQUERY_PERIOD
+ * seconds any more. */
+static void
+directory_clean_last_hid_serv_requests(time_t now)
+{
+  strmap_iter_t *iter;
+  time_t cutoff = now - hsdir_requery_period(get_options());
+  strmap_t *last_hid_serv_requests = get_last_hid_serv_requests();
+  for (iter = strmap_iter_init(last_hid_serv_requests);
+       !strmap_iter_done(iter); ) {
+    const char *key;
+    void *val;
+    time_t *ent;
+    strmap_iter_get(iter, &key, &val);
+    ent = (time_t *) val;
+    if (*ent < cutoff) {
+      iter = strmap_iter_next_rmv(last_hid_serv_requests, iter);
+      tor_free(ent);
+    } else {
+      iter = strmap_iter_next(last_hid_serv_requests, iter);
+    }
+  }
+}
+
+/** Remove all requests related to the descriptor ID <b>desc_id</b> from the
+ * history of times of requests to hidden service directories.
+ * <b>desc_id</b> is an unencoded descriptor ID of size DIGEST_LEN.
+ *
+ * This is called from rend_client_note_connection_attempt_ended(), which
+ * must be idempotent, so any future changes to this function must leave it
+ * idempotent too. */
+void
+purge_hid_serv_from_last_hid_serv_requests(const char *desc_id)
+{
+  strmap_iter_t *iter;
+  strmap_t *last_hid_serv_requests = get_last_hid_serv_requests();
+  char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
+
+  /* Key is stored with the base32 encoded desc_id. */
+  base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_id,
+                DIGEST_LEN);
+  for (iter = strmap_iter_init(last_hid_serv_requests);
+       !strmap_iter_done(iter); ) {
+    const char *key;
+    void *val;
+    strmap_iter_get(iter, &key, &val);
+    /* XXX++?? tor_assert(strlen(key) == LAST_HID_SERV_REQUEST_KEY_LEN); */
+    if (tor_memeq(key + LAST_HID_SERV_REQUEST_KEY_LEN -
+                  REND_DESC_ID_V2_LEN_BASE32,
+                  desc_id_base32,
+                  REND_DESC_ID_V2_LEN_BASE32)) {
+      iter = strmap_iter_next_rmv(last_hid_serv_requests, iter);
+      tor_free(val);
+    } else {
+      iter = strmap_iter_next(last_hid_serv_requests, iter);
+    }
+  }
+}
+
+/** Purge the history of request times to hidden service directories,
+ * so that future lookups of an HS descriptor will not fail because we
+ * accessed all of the HSDir relays responsible for the descriptor
+ * recently. */
+void
+rend_client_purge_last_hid_serv_requests(void)
+{
+  /* Don't create the table if it doesn't exist yet (and it may very
+   * well not exist if the user hasn't accessed any HSes)... */
+  strmap_t *old_last_hid_serv_requests = last_hid_serv_requests_;
+  /* ... and let get_last_hid_serv_requests re-create it for us if
+   * necessary. */
+  last_hid_serv_requests_ = NULL;
+
+  if (old_last_hid_serv_requests != NULL) {
+    log_info(LD_REND, "Purging client last-HS-desc-request-time table");
+    strmap_free(old_last_hid_serv_requests, tor_free_);
+  }
+}
+
+/***********************************************************************/
+
+/** This returns a good valid hs dir that should be used for the given
+ * descriptor id.
+ *
+ * Return NULL on error else the hsdir node pointer. */
+routerstatus_t *
+pick_hsdir(const char *desc_id, const char *desc_id_base32)
+{
+  smartlist_t *responsible_dirs = smartlist_new();
+  smartlist_t *usable_responsible_dirs = smartlist_new();
+  const or_options_t *options = get_options();
+  routerstatus_t *hs_dir;
+  time_t now = time(NULL);
+  int excluded_some;
+
+  tor_assert(desc_id);
+  tor_assert(desc_id_base32);
+
+  /* Determine responsible dirs. Even if we can't get all we want, work with
+   * the ones we have. If it's empty, we'll notice below. */
+  hid_serv_get_responsible_directories(responsible_dirs, desc_id);
+
+  /* Clean request history first. */
+  directory_clean_last_hid_serv_requests(now);
+
+  /* Only select those hidden service directories to which we did not send a
+   * request recently and for which we have a router descriptor here. */
+  SMARTLIST_FOREACH_BEGIN(responsible_dirs, routerstatus_t *, dir) {
+    time_t last = lookup_last_hid_serv_request(dir, desc_id_base32,
+                                               0, 0);
+    const node_t *node = node_get_by_id(dir->identity_digest);
+    if (last + hsdir_requery_period(options) >= now ||
+        !node || !node_has_descriptor(node)) {
+      SMARTLIST_DEL_CURRENT(responsible_dirs, dir);
+      continue;
+    }
+    if (!routerset_contains_node(options->ExcludeNodes, node)) {
+      smartlist_add(usable_responsible_dirs, dir);
+    }
+  } SMARTLIST_FOREACH_END(dir);
+
+  excluded_some =
+    smartlist_len(usable_responsible_dirs) < smartlist_len(responsible_dirs);
+
+  hs_dir = smartlist_choose(usable_responsible_dirs);
+  if (!hs_dir && !options->StrictNodes) {
+    hs_dir = smartlist_choose(responsible_dirs);
+  }
+
+  smartlist_free(responsible_dirs);
+  smartlist_free(usable_responsible_dirs);
+  if (!hs_dir) {
+    log_info(LD_REND, "Could not pick one of the responsible hidden "
+                      "service directories, because we requested them all "
+                      "recently without success.");
+    if (options->StrictNodes && excluded_some) {
+      log_warn(LD_REND, "Could not pick a hidden service directory for the "
+               "requested hidden service: they are all either down or "
+               "excluded, and StrictNodes is set.");
+    }
+  } else {
+    /* Remember that we are requesting a descriptor from this hidden service
+     * directory now. */
+    lookup_last_hid_serv_request(hs_dir, desc_id_base32, now, 1);
+  }
+
+  return hs_dir;
+}
+
+/***********************************************************************/
+
 /* Initialize the entire HS subsytem. This is called in tor_init() before any
  * torrc options are loaded. Only for >= v3. */
 void

+ 11 - 0
src/or/hs_common.h

@@ -187,6 +187,10 @@ const char *rend_data_get_desc_id(const rend_data_t *rend_data,
 const uint8_t *rend_data_get_pk_digest(const rend_data_t *rend_data,
                                        size_t *len_out);
 
+void rend_client_purge_last_hid_serv_requests(void);
+void purge_hid_serv_from_last_hid_serv_requests(const char *desc_id);
+routerstatus_t *pick_hsdir(const char *desc_id, const char *desc_id_base32);
+
 void hs_get_subcredential(const ed25519_public_key_t *identity_pk,
                           const ed25519_public_key_t *blinded_pk,
                           uint8_t *subcred_out);
@@ -229,6 +233,13 @@ void hs_dec_rdv_stream_counter(origin_circuit_t *circ);
 
 STATIC void get_disaster_srv(uint64_t time_period_num, uint8_t *srv_out);
 
+/** The period for which a hidden service directory cannot be queried for
+ * the same descriptor ID again. */
+#define REND_HID_SERV_DIR_REQUERY_PERIOD (15 * 60)
+/** Test networks generate a new consensus every 5 or 10 seconds.
+ * So allow them to requery HSDirs much faster. */
+#define REND_HID_SERV_DIR_REQUERY_PERIOD_TESTING (5)
+
 #ifdef TOR_UNIT_TESTS
 
 STATIC uint64_t get_time_period_length(void);

+ 0 - 224
src/or/rendclient.c

@@ -465,230 +465,6 @@ rend_client_introduction_acked(origin_circuit_t *circ,
   return 0;
 }
 
-/** The period for which a hidden service directory cannot be queried for
- * the same descriptor ID again. */
-#define REND_HID_SERV_DIR_REQUERY_PERIOD (15 * 60)
-/** Test networks generate a new consensus every 5 or 10 seconds.
- * So allow them to requery HSDirs much faster. */
-#define REND_HID_SERV_DIR_REQUERY_PERIOD_TESTING (5)
-
-/** Return the period for which a hidden service directory cannot be queried
- * for the same descriptor ID again, taking TestingTorNetwork into account. */
-static time_t
-hsdir_requery_period(const or_options_t *options)
-{
-  tor_assert(options);
-
-  if (options->TestingTorNetwork) {
-    return REND_HID_SERV_DIR_REQUERY_PERIOD_TESTING;
-  } else {
-    return REND_HID_SERV_DIR_REQUERY_PERIOD;
-  }
-}
-
-/** Contains the last request times to hidden service directories for
- * certain queries; each key is a string consisting of the
- * concatenation of a base32-encoded HS directory identity digest and
- * base32-encoded HS descriptor ID; each value is a pointer to a time_t
- * holding the time of the last request for that descriptor ID to that
- * HS directory. */
-static strmap_t *last_hid_serv_requests_ = NULL;
-
-/** Returns last_hid_serv_requests_, initializing it to a new strmap if
- * necessary. */
-static strmap_t *
-get_last_hid_serv_requests(void)
-{
-  if (!last_hid_serv_requests_)
-    last_hid_serv_requests_ = strmap_new();
-  return last_hid_serv_requests_;
-}
-
-#define LAST_HID_SERV_REQUEST_KEY_LEN (REND_DESC_ID_V2_LEN_BASE32 + \
-                                       REND_DESC_ID_V2_LEN_BASE32)
-
-/** Look up the last request time to hidden service directory <b>hs_dir</b>
- * for descriptor ID <b>desc_id_base32</b>. If <b>set</b> is non-zero,
- * assign the current time <b>now</b> and return that. Otherwise, return the
- * most recent request time, or 0 if no such request has been sent before.
- */
-static time_t
-lookup_last_hid_serv_request(routerstatus_t *hs_dir,
-                             const char *desc_id_base32,
-                             time_t now, int set)
-{
-  char hsdir_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
-  char hsdir_desc_comb_id[LAST_HID_SERV_REQUEST_KEY_LEN + 1];
-  time_t *last_request_ptr;
-  strmap_t *last_hid_serv_requests = get_last_hid_serv_requests();
-  base32_encode(hsdir_id_base32, sizeof(hsdir_id_base32),
-                hs_dir->identity_digest, DIGEST_LEN);
-  tor_snprintf(hsdir_desc_comb_id, sizeof(hsdir_desc_comb_id), "%s%s",
-               hsdir_id_base32,
-               desc_id_base32);
-  /* XXX++?? tor_assert(strlen(hsdir_desc_comb_id) ==
-                       LAST_HID_SERV_REQUEST_KEY_LEN); */
-  if (set) {
-    time_t *oldptr;
-    last_request_ptr = tor_malloc_zero(sizeof(time_t));
-    *last_request_ptr = now;
-    oldptr = strmap_set(last_hid_serv_requests, hsdir_desc_comb_id,
-                        last_request_ptr);
-    tor_free(oldptr);
-  } else
-    last_request_ptr = strmap_get_lc(last_hid_serv_requests,
-                                     hsdir_desc_comb_id);
-  return (last_request_ptr) ? *last_request_ptr : 0;
-}
-
-/** Clean the history of request times to hidden service directories, so that
- * it does not contain requests older than REND_HID_SERV_DIR_REQUERY_PERIOD
- * seconds any more. */
-static void
-directory_clean_last_hid_serv_requests(time_t now)
-{
-  strmap_iter_t *iter;
-  time_t cutoff = now - hsdir_requery_period(get_options());
-  strmap_t *last_hid_serv_requests = get_last_hid_serv_requests();
-  for (iter = strmap_iter_init(last_hid_serv_requests);
-       !strmap_iter_done(iter); ) {
-    const char *key;
-    void *val;
-    time_t *ent;
-    strmap_iter_get(iter, &key, &val);
-    ent = (time_t *) val;
-    if (*ent < cutoff) {
-      iter = strmap_iter_next_rmv(last_hid_serv_requests, iter);
-      tor_free(ent);
-    } else {
-      iter = strmap_iter_next(last_hid_serv_requests, iter);
-    }
-  }
-}
-
-/** Remove all requests related to the descriptor ID <b>desc_id</b> from the
- * history of times of requests to hidden service directories.
- * <b>desc_id</b> is an unencoded descriptor ID of size DIGEST_LEN.
- *
- * This is called from rend_client_note_connection_attempt_ended(), which
- * must be idempotent, so any future changes to this function must leave it
- * idempotent too. */
-static void
-purge_hid_serv_from_last_hid_serv_requests(const char *desc_id)
-{
-  strmap_iter_t *iter;
-  strmap_t *last_hid_serv_requests = get_last_hid_serv_requests();
-  char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
-
-  /* Key is stored with the base32 encoded desc_id. */
-  base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_id,
-                DIGEST_LEN);
-  for (iter = strmap_iter_init(last_hid_serv_requests);
-       !strmap_iter_done(iter); ) {
-    const char *key;
-    void *val;
-    strmap_iter_get(iter, &key, &val);
-    /* XXX++?? tor_assert(strlen(key) == LAST_HID_SERV_REQUEST_KEY_LEN); */
-    if (tor_memeq(key + LAST_HID_SERV_REQUEST_KEY_LEN -
-                  REND_DESC_ID_V2_LEN_BASE32,
-                  desc_id_base32,
-                  REND_DESC_ID_V2_LEN_BASE32)) {
-      iter = strmap_iter_next_rmv(last_hid_serv_requests, iter);
-      tor_free(val);
-    } else {
-      iter = strmap_iter_next(last_hid_serv_requests, iter);
-    }
-  }
-}
-
-/** Purge the history of request times to hidden service directories,
- * so that future lookups of an HS descriptor will not fail because we
- * accessed all of the HSDir relays responsible for the descriptor
- * recently. */
-void
-rend_client_purge_last_hid_serv_requests(void)
-{
-  /* Don't create the table if it doesn't exist yet (and it may very
-   * well not exist if the user hasn't accessed any HSes)... */
-  strmap_t *old_last_hid_serv_requests = last_hid_serv_requests_;
-  /* ... and let get_last_hid_serv_requests re-create it for us if
-   * necessary. */
-  last_hid_serv_requests_ = NULL;
-
-  if (old_last_hid_serv_requests != NULL) {
-    log_info(LD_REND, "Purging client last-HS-desc-request-time table");
-    strmap_free(old_last_hid_serv_requests, tor_free_);
-  }
-}
-
-/** This returns a good valid hs dir that should be used for the given
- * descriptor id.
- *
- * Return NULL on error else the hsdir node pointer. */
-static routerstatus_t *
-pick_hsdir(const char *desc_id, const char *desc_id_base32)
-{
-  smartlist_t *responsible_dirs = smartlist_new();
-  smartlist_t *usable_responsible_dirs = smartlist_new();
-  const or_options_t *options = get_options();
-  routerstatus_t *hs_dir;
-  time_t now = time(NULL);
-  int excluded_some;
-
-  tor_assert(desc_id);
-  tor_assert(desc_id_base32);
-
-  /* Determine responsible dirs. Even if we can't get all we want, work with
-   * the ones we have. If it's empty, we'll notice below. */
-  hid_serv_get_responsible_directories(responsible_dirs, desc_id);
-
-  /* Clean request history first. */
-  directory_clean_last_hid_serv_requests(now);
-
-  /* Only select those hidden service directories to which we did not send a
-   * request recently and for which we have a router descriptor here. */
-  SMARTLIST_FOREACH_BEGIN(responsible_dirs, routerstatus_t *, dir) {
-    time_t last = lookup_last_hid_serv_request(dir, desc_id_base32,
-                                               0, 0);
-    const node_t *node = node_get_by_id(dir->identity_digest);
-    if (last + hsdir_requery_period(options) >= now ||
-        !node || !node_has_descriptor(node)) {
-      SMARTLIST_DEL_CURRENT(responsible_dirs, dir);
-      continue;
-    }
-    if (!routerset_contains_node(options->ExcludeNodes, node)) {
-      smartlist_add(usable_responsible_dirs, dir);
-    }
-  } SMARTLIST_FOREACH_END(dir);
-
-  excluded_some =
-    smartlist_len(usable_responsible_dirs) < smartlist_len(responsible_dirs);
-
-  hs_dir = smartlist_choose(usable_responsible_dirs);
-  if (!hs_dir && !options->StrictNodes) {
-    hs_dir = smartlist_choose(responsible_dirs);
-  }
-
-  smartlist_free(responsible_dirs);
-  smartlist_free(usable_responsible_dirs);
-  if (!hs_dir) {
-    log_info(LD_REND, "Could not pick one of the responsible hidden "
-                      "service directories, because we requested them all "
-                      "recently without success.");
-    if (options->StrictNodes && excluded_some) {
-      log_warn(LD_REND, "Could not pick a hidden service directory for the "
-               "requested hidden service: they are all either down or "
-               "excluded, and StrictNodes is set.");
-    }
-  } else {
-    /* Remember that we are requesting a descriptor from this hidden service
-     * directory now. */
-    lookup_last_hid_serv_request(hs_dir, desc_id_base32, now, 1);
-  }
-
-  return hs_dir;
-}
-
 /** Determine the responsible hidden service directories for <b>desc_id</b>
  * and fetch the descriptor with that ID from one of them. Only
  * send a request to a hidden service directory that we have not yet tried

+ 0 - 1
src/or/rendclient.h

@@ -24,7 +24,6 @@ int rend_client_introduction_acked(origin_circuit_t *circ,
 void rend_client_refetch_v2_renddesc(rend_data_t *rend_query);
 int rend_client_fetch_v2_desc(rend_data_t *query, smartlist_t *hsdirs);
 void rend_client_cancel_descriptor_fetches(void);
-void rend_client_purge_last_hid_serv_requests(void);
 
 int rend_client_report_intro_point_failure(extend_info_t *failed_intro,
                                            rend_data_t *rend_data,