diff options
author | Roger Dingledine <arma@torproject.org> | 2008-01-24 03:28:50 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2008-01-24 03:28:50 +0000 |
commit | 6b1374556e877478f8bf0d394b379a8e29513967 (patch) | |
tree | 6c00c7cb13df04d6c7393651504f336eebcb4f61 /src/or/rendclient.c | |
parent | 980fcb1ca79fe812bf6033c35424fc1c112389d5 (diff) | |
download | tor-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.c | 47 |
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; } |