mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 14:23:30 +01:00
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>
This commit is contained in:
parent
7aef3ec0fd
commit
912c11761c
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user