From d06182f0bd1f4f5944d20f73a86143b7566ec8dd Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Wed, 15 Oct 2008 18:52:06 +0000 Subject: [PATCH] add patch2 from proposal 155: Launch a second client-side introduction circuit in parallel after a delay of 15 seconds (based on work by Christian Wilms). svn:r17108 --- ChangeLog | 6 ++++-- src/or/circuituse.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0c380f83b..428c30c1c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,8 +3,10 @@ Changes in version 0.2.1.7-alpha - 2008-10-xx - Now NodeFamily and MyFamily config options allow spaces in identity fingerprints, so it's easier to paste them in. Suggested by Lucky Green. - - Reduce extension timeout for introduction circuits from 60 to 30 - seconds. + - Reduce extension timeout for introduction circuits on the hidden + service side from 60 to 30 seconds. + - Launch a second client-side introduction circuit in parallel + after a delay of 15 seconds (based on work by Christian Wilms). o Minor bugfixes: - Minor fix in the warning messages when you're having problems diff --git a/src/or/circuituse.c b/src/or/circuituse.c index 7da550888..3537a7387 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -194,6 +194,7 @@ circuit_get_best(edge_connection_t *conn, int must_be_open, uint8_t purpose, { circuit_t *circ, *best=NULL; time_t now = time(NULL); + int intro_going_on_but_too_old = 0; tor_assert(conn); @@ -206,6 +207,16 @@ circuit_get_best(edge_connection_t *conn, int must_be_open, uint8_t purpose, need_uptime,need_internal,now)) continue; +/* XXX022 make this 15 be a function of circuit finishing times we've + * seen lately, a la Fallon Chen's GSoC work -RD */ +#define REND_PARALLEL_INTRO_DELAY 15 + if (purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT && + !must_be_open && circ->state != CIRCUIT_STATE_OPEN && + circ->timestamp_created + REND_PARALLEL_INTRO_DELAY < now) { + intro_going_on_but_too_old = 1; + continue; + } + /* now this is an acceptable circ to hand back. but that doesn't * mean it's the *best* circ to hand back. try to decide. */ @@ -213,6 +224,11 @@ circuit_get_best(edge_connection_t *conn, int must_be_open, uint8_t purpose, best = circ; } + if (!best && intro_going_on_but_too_old) + log_info(LD_REND|LD_CIRC, "There is an intro circuit being created " + "right now, but it has already taken quite a while. Starting " + "one in parallel."); + return best ? TO_ORIGIN_CIRCUIT(best) : NULL; } @@ -1448,12 +1464,27 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn) if (retval > 0) { /* one has already sent the intro. keep waiting. */ + circuit_t *c = NULL; tor_assert(introcirc); log_info(LD_REND, "Intro circ %d present and awaiting ack (rend %d). " "Stalling. (stream %d sec old)", introcirc->_base.n_circ_id, rendcirc ? rendcirc->_base.n_circ_id : 0, conn_age); + /* abort parallel intro circs, if any */ + for (c = global_circuitlist; c; c = c->next) { + if (c->purpose == CIRCUIT_PURPOSE_C_INTRODUCING && + CIRCUIT_IS_ORIGIN(c)) { + origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(c); + if (oc->rend_data && + !rend_cmp_service_ids(conn->rend_data->onion_address, + oc->rend_data->onion_address)) { + log_info(LD_REND|LD_CIRC, "Closing introduction circuit that we " + "built in parallel."); + circuit_mark_for_close(c, END_CIRC_REASON_TIMEOUT); + } + } + } return 0; }