diff options
author | Roger Dingledine <arma@torproject.org> | 2008-01-26 00:42:13 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2008-01-26 00:42:13 +0000 |
commit | af4b735e9a54a88fecfff5a1c7bd8b41a594d044 (patch) | |
tree | 2eed04a588e0616566f7f98505311b3e972cdf81 /src/or | |
parent | aa25bf14052ca908dd892231d3e23561de3d55d9 (diff) | |
download | tor-af4b735e9a54a88fecfff5a1c7bd8b41a594d044.tar.gz tor-af4b735e9a54a88fecfff5a1c7bd8b41a594d044.zip |
move hidden-service stuff out of directory.c
svn:r13287
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/directory.c | 169 | ||||
-rw-r--r-- | src/or/or.h | 4 | ||||
-rw-r--r-- | src/or/rendclient.c | 122 | ||||
-rw-r--r-- | src/or/rendservice.c | 47 |
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. |