mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-23 22:47:12 +01:00
r14678@tombo: nickm | 2007-11-03 16:12:31 -0400
Try to make hidden service directory lookup functions a bit more efficient: go for fewer O(n) operations, and look at the consensus rather than the routerinfo list. svn:r12361
This commit is contained in:
parent
c217be996d
commit
bf2717ff3d
7 changed files with 148 additions and 140 deletions
|
@ -3084,12 +3084,11 @@ dir_split_resource_into_fingerprints(const char *resource,
|
||||||
/* I guess they should. -KL */
|
/* I guess they should. -KL */
|
||||||
void
|
void
|
||||||
directory_post_to_hs_dir(smartlist_t *desc_ids, smartlist_t *desc_strs,
|
directory_post_to_hs_dir(smartlist_t *desc_ids, smartlist_t *desc_strs,
|
||||||
const char *service_id, int seconds_valid,
|
const char *service_id, int seconds_valid)
|
||||||
smartlist_t *hs_dirs)
|
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
smartlist_t *responsible_dirs;
|
smartlist_t *responsible_dirs;
|
||||||
routerinfo_t *hs_dir;
|
routerstatus_t *hs_dir;
|
||||||
if (smartlist_len(desc_ids) != REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS ||
|
if (smartlist_len(desc_ids) != REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS ||
|
||||||
smartlist_len(desc_strs) != REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS) {
|
smartlist_len(desc_strs) != REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS) {
|
||||||
log_warn(LD_BUG, "Could not post descriptors to hidden service "
|
log_warn(LD_BUG, "Could not post descriptors to hidden service "
|
||||||
|
@ -3102,8 +3101,7 @@ directory_post_to_hs_dir(smartlist_t *desc_ids, smartlist_t *desc_strs,
|
||||||
const char *desc_id = smartlist_get(desc_ids, i);
|
const char *desc_id = smartlist_get(desc_ids, i);
|
||||||
const char *desc_str = smartlist_get(desc_strs, i);
|
const char *desc_str = smartlist_get(desc_strs, i);
|
||||||
/* Determine responsible dirs. */
|
/* Determine responsible dirs. */
|
||||||
if (hid_serv_get_responsible_directories(responsible_dirs, desc_id,
|
if (hid_serv_get_responsible_directories(responsible_dirs, desc_id) < 0) {
|
||||||
hs_dirs) < 0) {
|
|
||||||
log_warn(LD_REND, "Could not determine the responsible hidden service "
|
log_warn(LD_REND, "Could not determine the responsible hidden service "
|
||||||
"directories to post descriptors to.");
|
"directories to post descriptors to.");
|
||||||
smartlist_free(responsible_dirs);
|
smartlist_free(responsible_dirs);
|
||||||
|
@ -3115,9 +3113,7 @@ directory_post_to_hs_dir(smartlist_t *desc_ids, smartlist_t *desc_strs,
|
||||||
char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
|
char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
|
||||||
hs_dir = smartlist_get(responsible_dirs, j);
|
hs_dir = smartlist_get(responsible_dirs, j);
|
||||||
/* Send publish request. */
|
/* Send publish request. */
|
||||||
directory_initiate_command(hs_dir->address, hs_dir->addr,
|
directory_initiate_command_routerstatus(hs_dir,
|
||||||
hs_dir->or_port, hs_dir->dir_port, 1,
|
|
||||||
hs_dir->cache_info.identity_digest,
|
|
||||||
DIR_PURPOSE_UPLOAD_RENDDESC_V2,
|
DIR_PURPOSE_UPLOAD_RENDDESC_V2,
|
||||||
ROUTER_PURPOSE_GENERAL,
|
ROUTER_PURPOSE_GENERAL,
|
||||||
1, NULL, desc_str, strlen(desc_str), 0);
|
1, NULL, desc_str, strlen(desc_str), 0);
|
||||||
|
@ -3142,18 +3138,16 @@ directory_post_to_hs_dir(smartlist_t *desc_ids, smartlist_t *desc_strs,
|
||||||
* and fetch the descriptor belonging to this ID from one of them;
|
* and fetch the descriptor belonging to this ID from one of them;
|
||||||
* <b>query</b> is only passed for pretty log statements. */
|
* <b>query</b> is only passed for pretty log statements. */
|
||||||
void
|
void
|
||||||
directory_get_from_hs_dir(const char *desc_id, const char *query,
|
directory_get_from_hs_dir(const char *desc_id, const char *query)
|
||||||
smartlist_t *hs_dirs)
|
|
||||||
{
|
{
|
||||||
smartlist_t *responsible_dirs = smartlist_create();
|
smartlist_t *responsible_dirs = smartlist_create();
|
||||||
routerinfo_t *hs_dir;
|
routerstatus_t *hs_dir;
|
||||||
char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
|
char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
|
||||||
tor_assert(desc_id);
|
tor_assert(desc_id);
|
||||||
tor_assert(query);
|
tor_assert(query);
|
||||||
tor_assert(strlen(query) == REND_SERVICE_ID_LEN);
|
tor_assert(strlen(query) == REND_SERVICE_ID_LEN);
|
||||||
/* Determine responsible dirs. */
|
/* Determine responsible dirs. */
|
||||||
if (hid_serv_get_responsible_directories(responsible_dirs, desc_id,
|
if (hid_serv_get_responsible_directories(responsible_dirs, desc_id) < 0) {
|
||||||
hs_dirs) < 0) {
|
|
||||||
log_warn(LD_REND, "Could not determine the responsible hidden service "
|
log_warn(LD_REND, "Could not determine the responsible hidden service "
|
||||||
"directories to fetch descriptors.");
|
"directories to fetch descriptors.");
|
||||||
smartlist_free(responsible_dirs);
|
smartlist_free(responsible_dirs);
|
||||||
|
@ -3170,9 +3164,8 @@ directory_get_from_hs_dir(const char *desc_id, const char *query,
|
||||||
base32_encode(desc_id_base32, sizeof(desc_id_base32),
|
base32_encode(desc_id_base32, sizeof(desc_id_base32),
|
||||||
desc_id, DIGEST_LEN);
|
desc_id, DIGEST_LEN);
|
||||||
/* Send fetch request. */
|
/* Send fetch request. */
|
||||||
directory_initiate_command(hs_dir->address, hs_dir->addr,
|
directory_initiate_command_routerstatus(
|
||||||
hs_dir->or_port, hs_dir->dir_port, 1,
|
hs_dir,
|
||||||
hs_dir->cache_info.identity_digest,
|
|
||||||
DIR_PURPOSE_FETCH_RENDDESC_V2,
|
DIR_PURPOSE_FETCH_RENDDESC_V2,
|
||||||
ROUTER_PURPOSE_GENERAL,
|
ROUTER_PURPOSE_GENERAL,
|
||||||
1, desc_id_base32, NULL, 0, 0);
|
1, desc_id_base32, NULL, 0, 0);
|
||||||
|
|
|
@ -754,6 +754,17 @@ networkstatus_vote_find_entry(networkstatus_vote_t *ns, const char *digest)
|
||||||
_compare_digest_to_routerstatus_entry);
|
_compare_digest_to_routerstatus_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*XXXX020 make this static once functions are moved into this file. */
|
||||||
|
/** DOCDOC */
|
||||||
|
int
|
||||||
|
networkstatus_vote_find_entry_idx(networkstatus_vote_t *ns,
|
||||||
|
const char *digest, int *found_out)
|
||||||
|
{
|
||||||
|
return smartlist_bsearch_idx(ns->routerstatus_list, digest,
|
||||||
|
_compare_digest_to_routerstatus_entry,
|
||||||
|
found_out);
|
||||||
|
}
|
||||||
|
|
||||||
/** Return a list of the v2 networkstatus documents. */
|
/** Return a list of the v2 networkstatus documents. */
|
||||||
const smartlist_t *
|
const smartlist_t *
|
||||||
networkstatus_get_v2_list(void)
|
networkstatus_get_v2_list(void)
|
||||||
|
|
19
src/or/or.h
19
src/or/or.h
|
@ -2912,10 +2912,8 @@ char *directory_dump_request_log(void);
|
||||||
int router_supports_extrainfo(const char *identity_digest, int is_authority);
|
int router_supports_extrainfo(const char *identity_digest, int is_authority);
|
||||||
|
|
||||||
void directory_post_to_hs_dir(smartlist_t *desc_ids, smartlist_t *descs,
|
void directory_post_to_hs_dir(smartlist_t *desc_ids, smartlist_t *descs,
|
||||||
const char *service_id, int seconds_valid,
|
const char *service_id, int seconds_valid);
|
||||||
smartlist_t *hs_dirs);
|
void directory_get_from_hs_dir(const char *desc_id, const char *query);
|
||||||
void directory_get_from_hs_dir(const char *desc_id, const char *query,
|
|
||||||
smartlist_t *hs_dirs);
|
|
||||||
|
|
||||||
time_t download_status_increment_failure(download_status_t *dls,
|
time_t download_status_increment_failure(download_status_t *dls,
|
||||||
int status_code, const char *item,
|
int status_code, const char *item,
|
||||||
|
@ -3191,6 +3189,8 @@ routerstatus_t *networkstatus_v2_find_entry(networkstatus_v2_t *ns,
|
||||||
const char *digest);
|
const char *digest);
|
||||||
routerstatus_t *networkstatus_vote_find_entry(networkstatus_vote_t *ns,
|
routerstatus_t *networkstatus_vote_find_entry(networkstatus_vote_t *ns,
|
||||||
const char *digest);
|
const char *digest);
|
||||||
|
int networkstatus_vote_find_entry_idx(networkstatus_vote_t *ns,
|
||||||
|
const char *digest, int *found_out);
|
||||||
const smartlist_t *networkstatus_get_v2_list(void);
|
const smartlist_t *networkstatus_get_v2_list(void);
|
||||||
download_status_t *router_get_dl_status_by_descriptor_digest(const char *d);
|
download_status_t *router_get_dl_status_by_descriptor_digest(const char *d);
|
||||||
routerstatus_t *router_get_consensus_status_by_id(const char *digest);
|
routerstatus_t *router_get_consensus_status_by_id(const char *digest);
|
||||||
|
@ -3779,17 +3779,18 @@ void routerlist_assert_ok(routerlist_t *rl);
|
||||||
const char *esc_router_info(routerinfo_t *router);
|
const char *esc_router_info(routerinfo_t *router);
|
||||||
void routers_sort_by_identity(smartlist_t *routers);
|
void routers_sort_by_identity(smartlist_t *routers);
|
||||||
|
|
||||||
smartlist_t *hid_serv_create_routing_table(void);
|
smartlist_t *hid_serv_create_routing_table_st(void);
|
||||||
int hid_serv_have_enough_directories(const smartlist_t *hs_dirs);
|
int hid_serv_have_enough_directories(const smartlist_t *hs_dirs);
|
||||||
int hid_serv_get_responsible_directories(smartlist_t *responsible_dirs,
|
int hid_serv_get_responsible_directories(smartlist_t *responsible_dirs,
|
||||||
const char *id,
|
const char *id);
|
||||||
const smartlist_t *hs_dirs);
|
#if 0
|
||||||
routerinfo_t *hid_serv_next_directory(const char *id,
|
routerinfo_t *hid_serv_next_directory(const char *id,
|
||||||
const smartlist_t *hs_dirs);
|
const smartlist_t *hs_dirs);
|
||||||
routerinfo_t *hid_serv_previous_directory(const char *id,
|
routerinfo_t *hid_serv_previous_directory(const char *id,
|
||||||
const smartlist_t *hs_dirs);
|
const smartlist_t *hs_dirs);
|
||||||
int hid_serv_acting_as_directory(const smartlist_t *hs_dirs);
|
#endif
|
||||||
int hid_serv_responsible_for_desc_id(const char *id, smartlist_t *hs_dirs);
|
int hid_serv_acting_as_directory(void);
|
||||||
|
int hid_serv_responsible_for_desc_id(const char *id);
|
||||||
|
|
||||||
/********************************* routerparse.c ************************/
|
/********************************* routerparse.c ************************/
|
||||||
|
|
||||||
|
|
|
@ -288,7 +288,6 @@ rend_client_refetch_v2_renddesc(const char *query)
|
||||||
{
|
{
|
||||||
char descriptor_id[DIGEST_LEN];
|
char descriptor_id[DIGEST_LEN];
|
||||||
int replica;
|
int replica;
|
||||||
smartlist_t *hs_dirs;
|
|
||||||
tor_assert(query);
|
tor_assert(query);
|
||||||
tor_assert(strlen(query) == REND_SERVICE_ID_LEN);
|
tor_assert(strlen(query) == REND_SERVICE_ID_LEN);
|
||||||
/* Are we configured to fetch descriptors? */
|
/* Are we configured to fetch descriptors? */
|
||||||
|
@ -306,9 +305,7 @@ rend_client_refetch_v2_renddesc(const char *query)
|
||||||
"descriptor ID did not succeed.");
|
"descriptor ID did not succeed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
hs_dirs = hid_serv_create_routing_table();
|
directory_get_from_hs_dir(descriptor_id, query);
|
||||||
directory_get_from_hs_dir(descriptor_id, query, hs_dirs);
|
|
||||||
smartlist_free(hs_dirs);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -681,7 +681,6 @@ void
|
||||||
rend_cache_clean_v2_descs_as_dir(void)
|
rend_cache_clean_v2_descs_as_dir(void)
|
||||||
{
|
{
|
||||||
digestmap_iter_t *iter;
|
digestmap_iter_t *iter;
|
||||||
smartlist_t *hs_dirs = hid_serv_create_routing_table();
|
|
||||||
time_t cutoff = time(NULL) - REND_CACHE_MAX_AGE - REND_CACHE_MAX_SKEW;
|
time_t cutoff = time(NULL) - REND_CACHE_MAX_AGE - REND_CACHE_MAX_SKEW;
|
||||||
for (iter = digestmap_iter_init(rend_cache_v2_dir);
|
for (iter = digestmap_iter_init(rend_cache_v2_dir);
|
||||||
!digestmap_iter_done(iter); ) {
|
!digestmap_iter_done(iter); ) {
|
||||||
|
@ -691,7 +690,7 @@ rend_cache_clean_v2_descs_as_dir(void)
|
||||||
digestmap_iter_get(iter, &key, &val);
|
digestmap_iter_get(iter, &key, &val);
|
||||||
ent = val;
|
ent = val;
|
||||||
if (ent->parsed->timestamp < cutoff ||
|
if (ent->parsed->timestamp < cutoff ||
|
||||||
!hid_serv_responsible_for_desc_id(key, hs_dirs)) {
|
!hid_serv_responsible_for_desc_id(key)) {
|
||||||
char key_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
|
char key_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
|
||||||
base32_encode(key_base32, sizeof(key_base32), key, DIGEST_LEN);
|
base32_encode(key_base32, sizeof(key_base32), key, DIGEST_LEN);
|
||||||
log_info(LD_REND, "Removing descriptor with ID '%s' from cache",
|
log_info(LD_REND, "Removing descriptor with ID '%s' from cache",
|
||||||
|
@ -702,7 +701,6 @@ rend_cache_clean_v2_descs_as_dir(void)
|
||||||
iter = digestmap_iter_next(rend_cache_v2_dir, iter);
|
iter = digestmap_iter_next(rend_cache_v2_dir, iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
smartlist_free(hs_dirs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Determines whether <b>a</b> is in the interval of <b>b</b> (excluded) and
|
/** Determines whether <b>a</b> is in the interval of <b>b</b> (excluded) and
|
||||||
|
@ -807,7 +805,6 @@ rend_cache_lookup_v2_desc_as_dir(const char *desc_id, const char **desc)
|
||||||
{
|
{
|
||||||
rend_cache_entry_t *e;
|
rend_cache_entry_t *e;
|
||||||
char desc_id_digest[DIGEST_LEN];
|
char desc_id_digest[DIGEST_LEN];
|
||||||
smartlist_t *hs_dirs;
|
|
||||||
tor_assert(rend_cache_v2_dir);
|
tor_assert(rend_cache_v2_dir);
|
||||||
if (base32_decode(desc_id_digest, DIGEST_LEN,
|
if (base32_decode(desc_id_digest, DIGEST_LEN,
|
||||||
desc_id, REND_DESC_ID_V2_LEN_BASE32) < 0) {
|
desc_id, REND_DESC_ID_V2_LEN_BASE32) < 0) {
|
||||||
|
@ -816,15 +813,12 @@ rend_cache_lookup_v2_desc_as_dir(const char *desc_id, const char **desc)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* Determine if we are responsible. */
|
/* Determine if we are responsible. */
|
||||||
hs_dirs = hid_serv_create_routing_table();
|
if (hid_serv_responsible_for_desc_id(desc_id_digest) < 0) {
|
||||||
if (hid_serv_responsible_for_desc_id(desc_id_digest, hs_dirs) < 0) {
|
|
||||||
log_info(LD_REND, "Could not answer fetch request for v2 descriptor; "
|
log_info(LD_REND, "Could not answer fetch request for v2 descriptor; "
|
||||||
"either we are no hidden service directory, or we are "
|
"either we are no hidden service directory, or we are "
|
||||||
"not responsible for the requested ID.");
|
"not responsible for the requested ID.");
|
||||||
smartlist_free(hs_dirs);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
smartlist_free(hs_dirs);
|
|
||||||
/* Lookup descriptor and return. */
|
/* Lookup descriptor and return. */
|
||||||
e = digestmap_get(rend_cache_v2_dir, desc_id_digest);
|
e = digestmap_get(rend_cache_v2_dir, desc_id_digest);
|
||||||
if (e) {
|
if (e) {
|
||||||
|
@ -940,14 +934,12 @@ rend_cache_store_v2_desc_as_dir(const char *desc)
|
||||||
const char *next_desc;
|
const char *next_desc;
|
||||||
rend_cache_entry_t *e;
|
rend_cache_entry_t *e;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
smartlist_t *hs_dirs = hid_serv_create_routing_table();
|
|
||||||
tor_assert(rend_cache_v2_dir);
|
tor_assert(rend_cache_v2_dir);
|
||||||
tor_assert(desc);
|
tor_assert(desc);
|
||||||
if (!hid_serv_acting_as_directory(hs_dirs)) {
|
if (!hid_serv_acting_as_directory()) {
|
||||||
/* Cannot store descs, because we are (currently) not acting as
|
/* Cannot store descs, because we are (currently) not acting as
|
||||||
* hidden service directory. */
|
* hidden service directory. */
|
||||||
log_info(LD_REND, "Cannot store descs: Not acting as hs dir");
|
log_info(LD_REND, "Cannot store descs: Not acting as hs dir");
|
||||||
smartlist_free(hs_dirs);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
while (rend_parse_v2_service_descriptor(&parsed, desc_id, &intro_content,
|
while (rend_parse_v2_service_descriptor(&parsed, desc_id, &intro_content,
|
||||||
|
@ -960,7 +952,7 @@ rend_cache_store_v2_desc_as_dir(const char *desc)
|
||||||
desc_id, DIGEST_LEN);
|
desc_id, DIGEST_LEN);
|
||||||
/* Is desc ID in the range that we are (directly or indirectly) responsible
|
/* Is desc ID in the range that we are (directly or indirectly) responsible
|
||||||
* for? */
|
* for? */
|
||||||
if (!hid_serv_responsible_for_desc_id(desc_id, hs_dirs)) {
|
if (!hid_serv_responsible_for_desc_id(desc_id)) {
|
||||||
log_info(LD_REND, "Service descriptor with desc ID %s is not in "
|
log_info(LD_REND, "Service descriptor with desc ID %s is not in "
|
||||||
"interval that we are responsible for.",
|
"interval that we are responsible for.",
|
||||||
desc_id_base32);
|
desc_id_base32);
|
||||||
|
|
|
@ -1100,7 +1100,7 @@ upload_service_descriptor(rend_service_t *service)
|
||||||
/* Upload v2 descriptor? */
|
/* Upload v2 descriptor? */
|
||||||
if (service->descriptor_versions & (1 << 2) &&
|
if (service->descriptor_versions & (1 << 2) &&
|
||||||
get_options()->PublishHidServDescriptors) {
|
get_options()->PublishHidServDescriptors) {
|
||||||
smartlist_t *hs_dirs = hid_serv_create_routing_table();
|
smartlist_t *hs_dirs = hid_serv_create_routing_table_st();
|
||||||
if (hid_serv_have_enough_directories(hs_dirs)) {
|
if (hid_serv_have_enough_directories(hs_dirs)) {
|
||||||
int seconds_valid;
|
int seconds_valid;
|
||||||
smartlist_t *desc_strs = smartlist_create();
|
smartlist_t *desc_strs = smartlist_create();
|
||||||
|
@ -1119,8 +1119,7 @@ upload_service_descriptor(rend_service_t *service)
|
||||||
rend_get_service_id(service->desc->pk, serviceid);
|
rend_get_service_id(service->desc->pk, serviceid);
|
||||||
log_info(LD_REND, "Sending publish request for hidden service %s",
|
log_info(LD_REND, "Sending publish request for hidden service %s",
|
||||||
serviceid);
|
serviceid);
|
||||||
directory_post_to_hs_dir(desc_ids, desc_strs, serviceid, seconds_valid,
|
directory_post_to_hs_dir(desc_ids, desc_strs, serviceid, seconds_valid);
|
||||||
hs_dirs);
|
|
||||||
/* Free memory for descriptors. */
|
/* Free memory for descriptors. */
|
||||||
for (i = 0; i < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; i++) {
|
for (i = 0; i < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; i++) {
|
||||||
tor_free(smartlist_get(desc_strs, i));
|
tor_free(smartlist_get(desc_strs, i));
|
||||||
|
@ -1148,7 +1147,7 @@ upload_service_descriptor(rend_service_t *service)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
directory_post_to_hs_dir(desc_ids, desc_strs, serviceid,
|
directory_post_to_hs_dir(desc_ids, desc_strs, serviceid,
|
||||||
seconds_valid, hs_dirs);
|
seconds_valid);
|
||||||
/* Free memory for descriptors. */
|
/* Free memory for descriptors. */
|
||||||
for (i = 0; i < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; i++) {
|
for (i = 0; i < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; i++) {
|
||||||
tor_free(smartlist_get(desc_strs, i));
|
tor_free(smartlist_get(desc_strs, i));
|
||||||
|
@ -1157,10 +1156,10 @@ upload_service_descriptor(rend_service_t *service)
|
||||||
smartlist_free(desc_strs);
|
smartlist_free(desc_strs);
|
||||||
smartlist_free(desc_ids);
|
smartlist_free(desc_ids);
|
||||||
}
|
}
|
||||||
smartlist_free(hs_dirs);
|
|
||||||
uploaded = 1;
|
uploaded = 1;
|
||||||
log_info(LD_REND, "Successfully uploaded v2 rend descriptors!");
|
log_info(LD_REND, "Successfully uploaded v2 rend descriptors!");
|
||||||
}
|
}
|
||||||
|
smartlist_free(hs_dirs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If not uploaded, try again in one minute. */
|
/* If not uploaded, try again in one minute. */
|
||||||
|
|
|
@ -4289,24 +4289,31 @@ routers_sort_by_identity(smartlist_t *routers)
|
||||||
smartlist_sort(routers, _compare_routerinfo_by_id_digest);
|
smartlist_sort(routers, _compare_routerinfo_by_id_digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/** Return the first router that is acting as hidden service directory and that
|
/** Return the first router that is acting as hidden service directory and that
|
||||||
* has a greater ID than <b>id</b>; if all routers have smaller IDs than
|
* has a greater ID than <b>id</b>; if all routers have smaller IDs than
|
||||||
* <b>id</b>, return the router with the smallest ID; if the router list is
|
* <b>id</b>, return the router with the smallest ID; if the router list is
|
||||||
* NULL, or has no elements, return NULL.
|
* NULL, or has no elements, return NULL.
|
||||||
*/
|
*/
|
||||||
routerinfo_t *
|
routerstatus_t *
|
||||||
hid_serv_next_directory(const char *id, const smartlist_t *hs_dirs)
|
hid_serv_next_directory(const char *id)
|
||||||
{
|
{
|
||||||
int i;
|
networkstatus_vote_t *c = networkstatus_get_latest_consensus();
|
||||||
if (!hs_dirs) return NULL;
|
int idx, i, f;
|
||||||
if (smartlist_len(hs_dirs) == 0) return NULL;
|
if (!c || !smartlist_len(c->routerstatus_list)) return NULL;
|
||||||
for (i = 0; i < smartlist_len(hs_dirs); i++) {
|
idx = networkstatus_vote_find_entry_idx(c, id, &f);
|
||||||
routerinfo_t *router = smartlist_get(hs_dirs, i);
|
if (f) ++idx;
|
||||||
if (memcmp(router->cache_info.identity_digest, id, DIGEST_LEN) > 0) {
|
if (idx >= smartlist_len(c->routerstatus_list))
|
||||||
return router;
|
idx = 0;
|
||||||
}
|
i = idx;
|
||||||
}
|
do {
|
||||||
return smartlist_get(hs_dirs, 0);
|
routerstatus_t *rs = smartlist_get(c->routerstatus_list, i);
|
||||||
|
if (rs->is_hs_dir)
|
||||||
|
return rs;
|
||||||
|
if (++i == smartlist_len(c->routerstatus_list))
|
||||||
|
i = 0;
|
||||||
|
} while (i != idx);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the first router that is acting as hidden service directory and that
|
/** Return the first router that is acting as hidden service directory and that
|
||||||
|
@ -4314,20 +4321,27 @@ hid_serv_next_directory(const char *id, const smartlist_t *hs_dirs)
|
||||||
* <b>id</b>, return the router with the highest ID; if the router list is
|
* <b>id</b>, return the router with the highest ID; if the router list is
|
||||||
* NULL, or has no elements, return NULL.
|
* NULL, or has no elements, return NULL.
|
||||||
*/
|
*/
|
||||||
routerinfo_t *
|
routerstatus_t *
|
||||||
hid_serv_previous_directory(const char *id, const smartlist_t *hs_dirs)
|
hid_serv_previous_directory(const char *id)
|
||||||
{
|
{
|
||||||
int i;
|
networkstatus_vote_t *c = networkstatus_get_latest_consensus();
|
||||||
if (!hs_dirs) return NULL;
|
int idx, i, f;
|
||||||
if (smartlist_len(hs_dirs) == 0) return NULL;
|
if (!c || !smartlist_len(c->routerstatus_list)) return NULL;
|
||||||
for (i = smartlist_len(hs_dirs) - 1; i >= 0; i--) {
|
idx = networkstatus_vote_find_entry_idx(c, id, &f);
|
||||||
routerinfo_t *router = smartlist_get(hs_dirs, i);
|
--idx;
|
||||||
if (memcmp(router->cache_info.identity_digest, id, DIGEST_LEN) < 0) {
|
if (idx < 0)
|
||||||
return router;
|
idx = smartlist_len(c->routerstatus_list) - 1;
|
||||||
}
|
i = idx;
|
||||||
}
|
do {
|
||||||
return smartlist_get(hs_dirs, smartlist_len(hs_dirs) - 1);
|
routerstatus_t *rs = smartlist_get(c->routerstatus_list, i);
|
||||||
|
if (rs->is_hs_dir)
|
||||||
|
return rs;
|
||||||
|
if (--i < 0)
|
||||||
|
i = smartlist_len(c->routerstatus_list) - 1;
|
||||||
|
} while (i != idx);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Returns true, if we are aware of enough hidden service directory to
|
/** Returns true, if we are aware of enough hidden service directory to
|
||||||
* usefully perform v2 rend operations on them (publish, fetch, replicate),
|
* usefully perform v2 rend operations on them (publish, fetch, replicate),
|
||||||
|
@ -4340,100 +4354,93 @@ hid_serv_have_enough_directories(const smartlist_t *hs_dirs)
|
||||||
|
|
||||||
/** Determine the REND_NUMBER_OF_CONSECUTIVE_REPLICAS routers that are
|
/** Determine the REND_NUMBER_OF_CONSECUTIVE_REPLICAS routers that are
|
||||||
* responsible for <b>id</b> (binary) and add pointers to those routers'
|
* responsible for <b>id</b> (binary) and add pointers to those routers'
|
||||||
* routerinfo_t to <b>responsible_dirs</b>. If we don't have enough
|
* routerstatus_t to <b>responsible_dirs</b>. If we don't have enough
|
||||||
* hidden service directories, return -1, else 0. */
|
* hidden service directories, return -1, else 0. */
|
||||||
/*XXXX020 yield routerstatus_t, not routerinfo_t! */
|
|
||||||
int
|
int
|
||||||
hid_serv_get_responsible_directories(smartlist_t *responsible_dirs,
|
hid_serv_get_responsible_directories(smartlist_t *responsible_dirs,
|
||||||
const char *id,
|
const char *id)
|
||||||
const smartlist_t *hs_dirs)
|
|
||||||
{
|
{
|
||||||
const char *digest;
|
int start, found, n_added = 0, i;
|
||||||
int i;
|
networkstatus_vote_t *c = networkstatus_get_latest_consensus();
|
||||||
routerinfo_t *router;
|
if (!c || !smartlist_len(c->routerstatus_list)) {
|
||||||
char id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
|
log_warn(LD_REND, "We don't have a consensus, so we can't perform v2 "
|
||||||
|
"rendezvous operations.");
|
||||||
|
}
|
||||||
tor_assert(id);
|
tor_assert(id);
|
||||||
base32_encode(id_base32, sizeof(id_base32), id, DIGEST_LEN);
|
start = networkstatus_vote_find_entry_idx(c, id, &found);
|
||||||
if (!hid_serv_have_enough_directories(hs_dirs)) {
|
if (found) ++start;
|
||||||
log_warn(LD_REND, "We don't have enough hidden service directories to "
|
if (start == smartlist_len(c->routerstatus_list)) start = 0;
|
||||||
"perform v2 rendezvous operations!");
|
i = start;
|
||||||
return -1;
|
do {
|
||||||
}
|
routerstatus_t *r = smartlist_get(c->routerstatus_list, i);
|
||||||
digest = id;
|
if (r->is_hs_dir) {
|
||||||
for (i = 0; i < REND_NUMBER_OF_CONSECUTIVE_REPLICAS; i++) {
|
smartlist_add(responsible_dirs, r);
|
||||||
router = hid_serv_next_directory(digest, hs_dirs);
|
if (++n_added == REND_NUMBER_OF_CONSECUTIVE_REPLICAS)
|
||||||
digest = router->cache_info.identity_digest;
|
return 0;
|
||||||
if (!router) {
|
|
||||||
log_warn(LD_REND, "Could not determine next router in "
|
|
||||||
"hidden service routing table.");
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
smartlist_add(responsible_dirs, router);
|
if (++i == smartlist_len(c->routerstatus_list))
|
||||||
}
|
i = 0;
|
||||||
return 0;
|
} while (i != start);
|
||||||
|
|
||||||
|
log_warn(LD_REND, "We don't have enough hidden service directories to "
|
||||||
|
"perform v2 rendezvous operations!");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a list of routerinfo_t in ascending order of identity digests
|
/** Create a list of routerstatus_t in ascending order of identity digests
|
||||||
* containing all routers that have been assigned as hidden service
|
* containing all routers that have been assigned as hidden service
|
||||||
* directories by the directory authorities; this list can be used as
|
* directories by the directory authorities; this list can be used as
|
||||||
* hidden service routing table. */
|
* hidden service routing table. */
|
||||||
/*XXXX020 using routerinfo_t here instead of routerstatus_t is error-prone.
|
|
||||||
* Best change that. */
|
|
||||||
smartlist_t *
|
smartlist_t *
|
||||||
hid_serv_create_routing_table(void)
|
hid_serv_create_routing_table_st(void)
|
||||||
{
|
{
|
||||||
smartlist_t *hs_dirs = smartlist_create();
|
smartlist_t *hs_dirs = smartlist_create();
|
||||||
tor_assert(routerlist);
|
networkstatus_vote_t *c = networkstatus_get_latest_consensus();
|
||||||
/* Copy the routerinfo_t's of all hidden service directories to a new
|
if (!c) return hs_dirs;
|
||||||
|
/* Copy the routerstatus_t's of all hidden service directories to a new
|
||||||
* smartlist. */
|
* smartlist. */
|
||||||
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, r,
|
SMARTLIST_FOREACH(c->routerstatus_list, routerstatus_t *, r,
|
||||||
{
|
{
|
||||||
if (r->is_hs_dir)
|
if (r->is_hs_dir)
|
||||||
smartlist_add(hs_dirs, r);
|
smartlist_add(hs_dirs, r);
|
||||||
});
|
});
|
||||||
routers_sort_by_identity(hs_dirs);
|
/* It's already sorted by ID. */
|
||||||
return hs_dirs;
|
return hs_dirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return true if this node is currently acting as hidden service
|
/** Return true if this node is currently acting as hidden service
|
||||||
* directory, false otherwise. */
|
* directory, false otherwise. */
|
||||||
int
|
int
|
||||||
hid_serv_acting_as_directory(const smartlist_t *hs_dirs)
|
hid_serv_acting_as_directory(void)
|
||||||
{
|
{
|
||||||
routerinfo_t *me = routerlist_find_my_routerinfo();
|
routerinfo_t *me = router_get_my_routerinfo();
|
||||||
int found_me = 0;
|
networkstatus_vote_t *c;
|
||||||
if (!me) {
|
routerstatus_t *rs;
|
||||||
|
if (!me)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
if (!get_options()->HidServDirectoryV2) {
|
if (!get_options()->HidServDirectoryV2) {
|
||||||
log_info(LD_REND, "We are not acting as hidden service directory, "
|
log_info(LD_REND, "We are not acting as hidden service directory, "
|
||||||
"because we have not been configured as such.");
|
"because we have not been configured as such.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!hs_dirs) {
|
if (!(c = networkstatus_get_latest_consensus())) {
|
||||||
/* routing table is NULL */
|
log_info(LD_REND, "There's no consensus, so I can't tell if I'm a hidden "
|
||||||
log_info(LD_REND, "We are not acting as hidden service directory, "
|
"service directory");
|
||||||
"because our own routing table is NULL.");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
SMARTLIST_FOREACH(hs_dirs, routerinfo_t *, router,
|
rs = networkstatus_vote_find_entry(c, me->cache_info.identity_digest);
|
||||||
{
|
if (!rs) {
|
||||||
if (router_is_me(router)) {
|
log_info(LD_REND, "We're not listed in the consensus, so we're not "
|
||||||
found_me = 1;
|
"being a hidden service directory.");
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (!found_me) {
|
|
||||||
/* not acting as HS Dir */
|
|
||||||
char me_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
|
|
||||||
base32_encode(me_base32, sizeof(me_base32),
|
|
||||||
me->cache_info.identity_digest, DIGEST_LEN);
|
|
||||||
log_info(LD_REND, "We are not acting as hidden service directory, "
|
|
||||||
"because we are not listed as such in our own "
|
|
||||||
"routing table. me=%s, num entries in RT=%d",
|
|
||||||
me_base32, smartlist_len(hs_dirs));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (!rs->is_hs_dir) {
|
||||||
|
log_info(LD_REND, "We're not listed as a hidden service directory in "
|
||||||
|
"the consensus, so we won't be one.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (smartlist_len(hs_dirs) <= REND_NUMBER_OF_CONSECUTIVE_REPLICAS) {
|
if (smartlist_len(hs_dirs) <= REND_NUMBER_OF_CONSECUTIVE_REPLICAS) {
|
||||||
/* too few HS Dirs -- that won't work */
|
/* too few HS Dirs -- that won't work */
|
||||||
log_info(LD_REND, "We are not acting as hidden service directory, "
|
log_info(LD_REND, "We are not acting as hidden service directory, "
|
||||||
|
@ -4441,26 +4448,34 @@ hid_serv_acting_as_directory(const smartlist_t *hs_dirs)
|
||||||
"directories in the routing table.");
|
"directories in the routing table.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return true if this node is responsible for storing the descriptor ID
|
/** Return true if this node is responsible for storing the descriptor ID
|
||||||
* in <b>query</b> and false otherwise. */
|
* in <b>query</b> and false otherwise. */
|
||||||
int
|
int
|
||||||
hid_serv_responsible_for_desc_id(const char *query, smartlist_t *hs_dirs)
|
hid_serv_responsible_for_desc_id(const char *query)
|
||||||
{
|
{
|
||||||
const char *me;
|
routerinfo_t *me;
|
||||||
const char *predecessor;
|
routerstatus_t *last_rs;
|
||||||
routerinfo_t *router;
|
const char *my_id, *last_id;
|
||||||
int i;
|
int result;
|
||||||
if (!hid_serv_acting_as_directory(hs_dirs))
|
smartlist_t *responsible;
|
||||||
|
if (!hid_serv_acting_as_directory())
|
||||||
|
return 0;
|
||||||
|
if (!(me = router_get_my_routerinfo()))
|
||||||
|
return 0; /* This is redundant, but let's be paranoid. */
|
||||||
|
my_id = me->cache_info.identity_digest;
|
||||||
|
responsible = smartlist_create();
|
||||||
|
if (hid_serv_get_responsible_directories(responsible, query)<0) {
|
||||||
|
smartlist_free(responsible);
|
||||||
return 0;
|
return 0;
|
||||||
me = router_get_my_routerinfo()->cache_info.identity_digest;
|
|
||||||
predecessor = me;
|
|
||||||
for (i = 0; i < REND_NUMBER_OF_CONSECUTIVE_REPLICAS; i++) {
|
|
||||||
router = hid_serv_previous_directory(predecessor, hs_dirs);
|
|
||||||
predecessor = router->cache_info.identity_digest;
|
|
||||||
}
|
}
|
||||||
return rend_id_is_in_interval(query, predecessor, me);
|
last_rs = smartlist_get(responsible, smartlist_len(responsible)-1);
|
||||||
|
last_id = last_rs->identity_digest;
|
||||||
|
result = rend_id_is_in_interval(my_id, query, last_id);
|
||||||
|
smartlist_free(responsible);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue