summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2008-01-26 00:42:13 +0000
committerRoger Dingledine <arma@torproject.org>2008-01-26 00:42:13 +0000
commitaf4b735e9a54a88fecfff5a1c7bd8b41a594d044 (patch)
tree2eed04a588e0616566f7f98505311b3e972cdf81
parentaa25bf14052ca908dd892231d3e23561de3d55d9 (diff)
downloadtor-af4b735e9a54a88fecfff5a1c7bd8b41a594d044.tar.gz
tor-af4b735e9a54a88fecfff5a1c7bd8b41a594d044.zip
move hidden-service stuff out of directory.c
svn:r13287
-rw-r--r--src/or/directory.c169
-rw-r--r--src/or/or.h4
-rw-r--r--src/or/rendclient.c122
-rw-r--r--src/or/rendservice.c47
4 files changed, 169 insertions, 173 deletions
diff --git a/src/or/directory.c b/src/or/directory.c
index e4d127e650..8c0f0f33f4 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -3198,172 +3198,3 @@ dir_split_resource_into_fingerprints(const char *resource,
return 0;
}
-/** Determine the responsible hidden service directories for the
- * rend_encoded_v2_service_descriptor_t's in <b>descs</b> and upload them;
- * <b>service_id</b> and <b>seconds_valid</b> are only passed for logging
- * purposes. */
-void
-directory_post_to_hs_dir(smartlist_t *descs, const char *service_id,
- int seconds_valid)
-{
- int i, j;
- smartlist_t *responsible_dirs = smartlist_create();
- routerstatus_t *hs_dir;
- for (i = 0; i < smartlist_len(descs); i++) {
- rend_encoded_v2_service_descriptor_t *desc = smartlist_get(descs, i);
- /* Determine responsible dirs. */
- if (hid_serv_get_responsible_directories(responsible_dirs,
- desc->desc_id) < 0) {
- log_warn(LD_REND, "Could not determine the responsible hidden service "
- "directories to post descriptors to.");
- smartlist_free(responsible_dirs);
- return;
- }
- for (j = 0; j < smartlist_len(responsible_dirs); j++) {
- char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
- hs_dir = smartlist_get(responsible_dirs, j);
- /* Send publish request. */
- directory_initiate_command_routerstatus(hs_dir,
- DIR_PURPOSE_UPLOAD_RENDDESC_V2,
- ROUTER_PURPOSE_GENERAL,
- 1, NULL, desc->desc_str,
- strlen(desc->desc_str), 0);
- base32_encode(desc_id_base32, sizeof(desc_id_base32),
- desc->desc_id, DIGEST_LEN);
- log_info(LD_REND, "Sending publish request for v2 descriptor for "
- "service '%s' with descriptor ID '%s' with validity "
- "of %d seconds to hidden service directory '%s' on "
- "port %d.",
- service_id,
- desc_id_base32,
- seconds_valid,
- hs_dir->nickname,
- hs_dir->dir_port);
- }
- smartlist_clear(responsible_dirs);
- }
- smartlist_free(responsible_dirs);
-}
-
-/** 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)
-
-/** Contains the last request times to hidden service directories for
- * certain queries; keys are strings consisting of base32-encoded
- * hidden service directory identities and base32-encoded descriptor IDs;
- * values are pointers to timestamps of the last requests. */
-static strmap_t *last_hid_serv_requests = NULL;
-
-/** 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[2 * REND_DESC_ID_V2_LEN_BASE32 + 1];
- time_t *last_request_ptr;
- 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);
- if (set) {
- last_request_ptr = tor_malloc_zero(sizeof(time_t *));
- *last_request_ptr = now;
- strmap_set(last_hid_serv_requests, hsdir_desc_comb_id, last_request_ptr);
- } 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(void)
-{
- strmap_iter_t *iter;
- time_t cutoff = time(NULL) - REND_HID_SERV_DIR_REQUERY_PERIOD;
- if (!last_hid_serv_requests)
- last_hid_serv_requests = strmap_new();
- 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);
- }
- }
-}
-
-/** Determine the responsible hidden service directories for <b>desc_id</b>
- * and fetch the descriptor belonging to that ID from one of them. Only
- * send a request to hidden service directories that we did not try within
- * the last REND_HID_SERV_DIR_REQUERY_PERIOD seconds; on success, return 1,
- * in the case that no hidden service directory is left to ask for the
- * descriptor, return 0, and in case of a failure -1. <b>query</b> is only
- * passed for pretty log statements. */
-int
-directory_get_from_hs_dir(const char *desc_id, const char *query)
-{
- smartlist_t *responsible_dirs = smartlist_create();
- routerstatus_t *hs_dir;
- char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
- time_t now = time(NULL);
- tor_assert(desc_id);
- tor_assert(query);
- tor_assert(strlen(query) == REND_SERVICE_ID_LEN_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. */
- (int) hid_serv_get_responsible_directories(responsible_dirs, desc_id);
-
- base32_encode(desc_id_base32, sizeof(desc_id_base32),
- desc_id, DIGEST_LEN);
-
- /* Only select those hidden service directories to which we did not send
- * a request recently. */
- directory_clean_last_hid_serv_requests(); /* Clean request history first. */
-
- SMARTLIST_FOREACH(responsible_dirs, routerstatus_t *, dir, {
- if (lookup_last_hid_serv_request(dir, desc_id_base32, 0, 0) +
- REND_HID_SERV_DIR_REQUERY_PERIOD >= now)
- SMARTLIST_DEL_CURRENT(responsible_dirs, dir);
- });
-
- hs_dir = smartlist_choose(responsible_dirs);
- smartlist_free(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.");
- return 0;
- }
-
- /* 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);
-
- /* Send fetch request. (Pass query as payload to write it to the directory
- * connection so that it can be referred to when the response arrives.) */
- directory_initiate_command_routerstatus(hs_dir,
- DIR_PURPOSE_FETCH_RENDDESC_V2,
- ROUTER_PURPOSE_GENERAL,
- 1, desc_id_base32, query, 0, 0);
- log_info(LD_REND, "Sending fetch request for v2 descriptor for "
- "service '%s' with descriptor ID '%s' to hidden "
- "service directory '%s' on port %d.",
- query, desc_id_base32, hs_dir->nickname, hs_dir->dir_port);
- return 1;
-}
-
diff --git a/src/or/or.h b/src/or/or.h
index 22b1ff9416..c867322942 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3030,10 +3030,6 @@ int dir_split_resource_into_fingerprints(const char *resource,
char *directory_dump_request_log(void);
int router_supports_extrainfo(const char *identity_digest, int is_authority);
-void directory_post_to_hs_dir(smartlist_t *descs, const char *service_id,
- int seconds_valid);
-int directory_get_from_hs_dir(const char *desc_id, const char *query);
-
time_t download_status_increment_failure(download_status_t *dls,
int status_code, const char *item,
int server, time_t now);
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 48b6498133..c8f6f43f04 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -267,6 +267,128 @@ 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)
+
+/** Contains the last request times to hidden service directories for
+ * certain queries; keys are strings consisting of base32-encoded
+ * hidden service directory identities and base32-encoded descriptor IDs;
+ * values are pointers to timestamps of the last requests. */
+static strmap_t *last_hid_serv_requests = NULL;
+
+/** 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[2 * REND_DESC_ID_V2_LEN_BASE32 + 1];
+ time_t *last_request_ptr;
+ 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);
+ if (set) {
+ last_request_ptr = tor_malloc_zero(sizeof(time_t *));
+ *last_request_ptr = now;
+ strmap_set(last_hid_serv_requests, hsdir_desc_comb_id, last_request_ptr);
+ } 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(void)
+{
+ strmap_iter_t *iter;
+ time_t cutoff = time(NULL) - REND_HID_SERV_DIR_REQUERY_PERIOD;
+ if (!last_hid_serv_requests)
+ last_hid_serv_requests = strmap_new();
+ 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);
+ }
+ }
+}
+
+/** Determine the responsible hidden service directories for <b>desc_id</b>
+ * and fetch the descriptor belonging to that ID from one of them. Only
+ * send a request to hidden service directories that we did not try within
+ * the last REND_HID_SERV_DIR_REQUERY_PERIOD seconds; on success, return 1,
+ * in the case that no hidden service directory is left to ask for the
+ * descriptor, return 0, and in case of a failure -1. <b>query</b> is only
+ * passed for pretty log statements. */
+static int
+directory_get_from_hs_dir(const char *desc_id, const char *query)
+{
+ smartlist_t *responsible_dirs = smartlist_create();
+ routerstatus_t *hs_dir;
+ char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
+ time_t now = time(NULL);
+ tor_assert(desc_id);
+ tor_assert(query);
+ tor_assert(strlen(query) == REND_SERVICE_ID_LEN_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. */
+ (int) hid_serv_get_responsible_directories(responsible_dirs, desc_id);
+
+ base32_encode(desc_id_base32, sizeof(desc_id_base32),
+ desc_id, DIGEST_LEN);
+
+ /* Only select those hidden service directories to which we did not send
+ * a request recently. */
+ directory_clean_last_hid_serv_requests(); /* Clean request history first. */
+
+ SMARTLIST_FOREACH(responsible_dirs, routerstatus_t *, dir, {
+ if (lookup_last_hid_serv_request(dir, desc_id_base32, 0, 0) +
+ REND_HID_SERV_DIR_REQUERY_PERIOD >= now)
+ SMARTLIST_DEL_CURRENT(responsible_dirs, dir);
+ });
+
+ hs_dir = smartlist_choose(responsible_dirs);
+ smartlist_free(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.");
+ return 0;
+ }
+
+ /* 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);
+
+ /* Send fetch request. (Pass query as payload to write it to the directory
+ * connection so that it can be referred to when the response arrives.) */
+ directory_initiate_command_routerstatus(hs_dir,
+ DIR_PURPOSE_FETCH_RENDDESC_V2,
+ ROUTER_PURPOSE_GENERAL,
+ 1, desc_id_base32, query, 0, 0);
+ log_info(LD_REND, "Sending fetch request for v2 descriptor for "
+ "service '%s' with descriptor ID '%s' to hidden "
+ "service directory '%s' on port %d.",
+ query, desc_id_base32, hs_dir->nickname, hs_dir->dir_port);
+ return 1;
+}
+
/** If we are not currently fetching a rendezvous service descriptor
* for the service ID <b>query</b>, start a directory connection to fetch a
* new one.
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 976ba45573..2894702ee9 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -1030,6 +1030,53 @@ find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest,
return NULL;
}
+/** Determine the responsible hidden service directories for the
+ * rend_encoded_v2_service_descriptor_t's in <b>descs</b> and upload them;
+ * <b>service_id</b> and <b>seconds_valid</b> are only passed for logging
+ * purposes. */
+static void
+directory_post_to_hs_dir(smartlist_t *descs, const char *service_id,
+ int seconds_valid)
+{
+ int i, j;
+ smartlist_t *responsible_dirs = smartlist_create();
+ routerstatus_t *hs_dir;
+ for (i = 0; i < smartlist_len(descs); i++) {
+ rend_encoded_v2_service_descriptor_t *desc = smartlist_get(descs, i);
+ /* Determine responsible dirs. */
+ if (hid_serv_get_responsible_directories(responsible_dirs,
+ desc->desc_id) < 0) {
+ log_warn(LD_REND, "Could not determine the responsible hidden service "
+ "directories to post descriptors to.");
+ smartlist_free(responsible_dirs);
+ return;
+ }
+ for (j = 0; j < smartlist_len(responsible_dirs); j++) {
+ char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
+ hs_dir = smartlist_get(responsible_dirs, j);
+ /* Send publish request. */
+ directory_initiate_command_routerstatus(hs_dir,
+ DIR_PURPOSE_UPLOAD_RENDDESC_V2,
+ ROUTER_PURPOSE_GENERAL,
+ 1, NULL, desc->desc_str,
+ strlen(desc->desc_str), 0);
+ base32_encode(desc_id_base32, sizeof(desc_id_base32),
+ desc->desc_id, DIGEST_LEN);
+ log_info(LD_REND, "Sending publish request for v2 descriptor for "
+ "service '%s' with descriptor ID '%s' with validity "
+ "of %d seconds to hidden service directory '%s' on "
+ "port %d.",
+ service_id,
+ desc_id_base32,
+ seconds_valid,
+ hs_dir->nickname,
+ hs_dir->dir_port);
+ }
+ smartlist_clear(responsible_dirs);
+ }
+ smartlist_free(responsible_dirs);
+}
+
/** Encode and sign up-to-date v0 and/or v2 service descriptors for
* <b>service</b>, and upload it/them to all the dirservers/to the
* responsible hidden service directories.