summaryrefslogtreecommitdiff
path: root/src/or/rendclient.c
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2008-01-24 03:28:50 +0000
committerRoger Dingledine <arma@torproject.org>2008-01-24 03:28:50 +0000
commit6b1374556e877478f8bf0d394b379a8e29513967 (patch)
tree6c00c7cb13df04d6c7393651504f336eebcb4f61 /src/or/rendclient.c
parent980fcb1ca79fe812bf6033c35424fc1c112389d5 (diff)
downloadtor-6b1374556e877478f8bf0d394b379a8e29513967.tar.gz
tor-6b1374556e877478f8bf0d394b379a8e29513967.zip
put in karsten's "patch 14". needs a lot of cleanup and a changelog.
svn:r13250
Diffstat (limited to 'src/or/rendclient.c')
-rw-r--r--src/or/rendclient.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 3c5f75552c..2dfc50580f 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -295,7 +295,8 @@ void
rend_client_refetch_v2_renddesc(const char *query)
{
char descriptor_id[DIGEST_LEN];
- int replica;
+ int replicas_left_to_try[REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS];
+ int i, tries_left;
tor_assert(query);
tor_assert(strlen(query) == REND_SERVICE_ID_LEN_BASE32);
/* Are we configured to fetch descriptors? */
@@ -306,14 +307,44 @@ rend_client_refetch_v2_renddesc(const char *query)
}
log_debug(LD_REND, "Fetching v2 rendezvous descriptor for service %s",
query);
- replica = crypto_rand_int(REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS);
- if (rend_compute_v2_desc_id(descriptor_id, query, NULL, time(NULL),
- replica) < 0) {
- log_warn(LD_REND, "Internal error: Computing v2 rendezvous "
- "descriptor ID did not succeed.");
- return;
+ /* Randomly iterate over the replicas until a descriptor can be fetched
+ * from one of the consecutive nodes, or no options are left. */
+ tries_left = REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS;
+ for (i = 0; i < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; i++)
+ replicas_left_to_try[i] = i;
+ while (tries_left > 0) {
+ int rand = crypto_rand_int(tries_left);
+ int chosen_replica = replicas_left_to_try[rand];
+ replicas_left_to_try[rand] = replicas_left_to_try[--tries_left];
+
+ if (rend_compute_v2_desc_id(descriptor_id, query, NULL, time(NULL),
+ chosen_replica) < 0) {
+ log_warn(LD_REND, "Internal error: Computing v2 rendezvous "
+ "descriptor ID did not succeed.");
+ return;
+ }
+ switch (directory_get_from_hs_dir(descriptor_id, query)) {
+ case -1:
+ /* Whatever error this was, it was already logged. */
+ log_info(LD_REND, "Error while trying to fetch descriptor from "
+ "hidden service directory!");
+ return;
+ case 0:
+ /* Try the next replica, if available. */
+ log_info(LD_REND, "No hidden service directory left for this replica; "
+ "trying another.");
+ continue;
+ case 1:
+ /* Request was sent, we are done here. */
+ log_info(LD_REND, "Request to fetch descriptor from hidden service "
+ "directory sent; waiting for response.");
+ return;
+ }
}
- directory_get_from_hs_dir(descriptor_id, query);
+ /* If we come here, there are no hidden service directories left. */
+ log_info(LD_REND, "Could not pick one of the responsible hidden "
+ "service directories to fetch descriptors, because "
+ "we already tried them all unsuccessfully.");
return;
}