mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Retry non-final-hop rendezvous failures
svn:r1625
This commit is contained in:
@@ -161,7 +161,7 @@ Rendezvous service:
|
||||
- cannibalize general circs?
|
||||
D how to set up multiple locations for a hidden service?
|
||||
o make bob publish only established intro circs?
|
||||
- when bob tries to connect to alice's chosen rend point, but
|
||||
o when bob tries to connect to alice's chosen rend point, but
|
||||
can't, but it's not the fault of the last hop in the rend
|
||||
circ, then he should retry?
|
||||
|
||||
|
||||
+15
-2
@@ -1253,7 +1253,14 @@ static void circuit_build_failed(circuit_t *circ) {
|
||||
/* we should examine circ and see if it failed because of
|
||||
* the last hop or an earlier hop. then use this info below.
|
||||
*/
|
||||
//int failed_at_last_hop;
|
||||
int failed_at_last_hop = 0;
|
||||
/* If the last hop isn't open, and the second-to-last is, we failed
|
||||
* at the last hop. */
|
||||
if (circ->cpath &&
|
||||
circ->cpath->prev->state != CPATH_STATE_OPEN &&
|
||||
circ->cpath->prev->prev->state == CPATH_STATE_OPEN) {
|
||||
failed_at_last_hop = 1;
|
||||
}
|
||||
|
||||
switch(circ->purpose) {
|
||||
case CIRCUIT_PURPOSE_C_GENERAL:
|
||||
@@ -1291,7 +1298,13 @@ static void circuit_build_failed(circuit_t *circ) {
|
||||
/* at Bob, connecting to rend point */
|
||||
/* Don't increment failure count, since Alice may have picked
|
||||
* the rendezvous point maliciously */
|
||||
log_fn(LOG_INFO,"Couldn't connect to Alice's chosen rend point %s. Sucks to be Alice.", circ->build_state->chosen_exit);
|
||||
if (failed_at_last_hop) {
|
||||
log_fn(LOG_INFO,"Couldn't connect to Alice's chosen rend point %s. Sucks to be Alice.", circ->build_state->chosen_exit);
|
||||
} else {
|
||||
log_fn(LOG_INFO,"Couldn't connect to Alice's chosen rend point %s, because an earlier node failed.",
|
||||
circ->build_state->chosen_exit);
|
||||
rend_service_relaunch_rendezvous(circ);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Other cases are impossible, since this function is only called with
|
||||
|
||||
@@ -500,6 +500,8 @@ typedef struct {
|
||||
char *chosen_exit;
|
||||
/* cpath to append after rendezvous. */
|
||||
struct crypt_path_t *pending_final_cpath;
|
||||
/* How many times has building a circuit for this task failed? */
|
||||
int failure_count;
|
||||
} cpath_build_state_t;
|
||||
|
||||
/* struct for a path (circuit) through the network */
|
||||
@@ -1095,6 +1097,7 @@ void rend_service_intro_is_ready(circuit_t *circuit);
|
||||
int rend_service_intro_established(circuit_t *circuit, const char *request, int request_len);
|
||||
void rend_service_rendezvous_is_ready(circuit_t *circuit);
|
||||
int rend_service_introduce(circuit_t *circuit, const char *request, int request_len);
|
||||
void rend_service_relaunch_rendezvous(circuit_t *oldcirc);
|
||||
int rend_service_set_connection_addr_port(connection_t *conn, circuit_t *circ);
|
||||
void rend_service_dump_stats(int severity);
|
||||
|
||||
|
||||
@@ -457,6 +457,44 @@ rend_service_introduce(circuit_t *circuit, const char *request, int request_len)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define MAX_REND_FAILURES 3
|
||||
void
|
||||
rend_service_relaunch_rendezvous(circuit_t *oldcirc)
|
||||
{
|
||||
circuit_t *newcirc;
|
||||
cpath_build_state_t *newstate, *oldstate;
|
||||
|
||||
/* XXXX assert type and build_state */
|
||||
|
||||
if (!oldcirc->build_state ||
|
||||
oldcirc->build_state->failure_count > MAX_REND_FAILURES) {
|
||||
log_fn(LOG_INFO,"Attempt to build circuit to %s for rendezvous has failed too many times; giving up.",
|
||||
oldcirc->build_state->chosen_exit);
|
||||
return;
|
||||
}
|
||||
|
||||
log_fn(LOG_INFO,"Reattempting rendezvous circuit to %s",
|
||||
oldcirc->build_state->chosen_exit);
|
||||
|
||||
newcirc = circuit_launch_new(CIRCUIT_PURPOSE_S_CONNECT_REND,
|
||||
oldcirc->build_state->chosen_exit);
|
||||
if (!newcirc) {
|
||||
log_fn(LOG_WARN,"Couldn't relaunch rendezvous circuit to %s",
|
||||
oldcirc->build_state->chosen_exit);
|
||||
return;
|
||||
}
|
||||
oldstate = oldcirc->build_state;
|
||||
newstate = newcirc->build_state;
|
||||
assert(newstate && oldstate);
|
||||
newstate->failure_count = oldstate->failure_count+1;
|
||||
newstate->pending_final_cpath = oldstate->pending_final_cpath;
|
||||
oldstate->pending_final_cpath = NULL;
|
||||
|
||||
memcpy(newcirc->rend_query, oldcirc->rend_query, REND_SERVICE_ID_LEN+1);
|
||||
memcpy(newcirc->rend_pk_digest, oldcirc->rend_pk_digest, DIGEST_LEN);
|
||||
memcpy(newcirc->rend_splice, oldcirc->rend_splice, REND_COOKIE_LEN);
|
||||
}
|
||||
|
||||
/* Launch a circuit to serve as an introduction point.
|
||||
*/
|
||||
static int
|
||||
|
||||
Reference in New Issue
Block a user