]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Don't close HS service-side rend circs on timeout
authorRobert Ransom <rransom.8774@gmail.com>
Sat, 24 Dec 2011 12:47:30 +0000 (04:47 -0800)
committerRobert Ransom <rransom.8774@gmail.com>
Tue, 27 Dec 2011 16:02:43 +0000 (08:02 -0800)
changes/bug1297b
src/or/circuituse.c
src/or/or.h
src/or/rendservice.c

index 28b7564e2532959b42ab091d23f2ce2cde9ff8c6..9cf2597b02d758c1461c84ca8c26f5be4baa67f3 100644 (file)
@@ -12,3 +12,7 @@
       CloseHSClientCircuitsImmediatelyOnTimeout option.  Fixes part of
       bug 1297.
 
+    - Don't close hidden-service-side rendezvous circuits when they
+      reach the normal circuit-build timeout.  Previously, we would
+      close them.  Fixes the remaining part of bug 1297.
+
index d9d95bc68aea76a447e43f3770fc2a3312bec47c..9778ae7b2976853dd88da01f98ff30c1bb8e50d3 100644 (file)
@@ -550,6 +550,22 @@ circuit_expire_building(void)
       }
     }
 
+    /* If this is a service-side rendezvous circuit which is far
+     * enough along in connecting to its destination, consider sparing
+     * it. */
+    if (!(TO_ORIGIN_CIRCUIT(victim)->hs_circ_has_timed_out) &&
+        victim->purpose == CIRCUIT_PURPOSE_S_CONNECT_REND) {
+      log_info(LD_CIRC,"Marking circ %s:%d:%d (state %d:%s, purpose %d) "
+               "as timed-out HS circ; relaunching rendezvous attempt.",
+               victim->n_conn->_base.address, victim->n_conn->_base.port,
+               victim->n_circ_id,
+               victim->state, circuit_state_to_string(victim->state),
+               victim->purpose);
+      TO_ORIGIN_CIRCUIT(victim)->hs_circ_has_timed_out = 1;
+      rend_service_relaunch_rendezvous(TO_ORIGIN_CIRCUIT(victim));
+      continue;
+    }
+
     if (victim->n_conn)
       log_info(LD_CIRC,"Abandoning circ %s:%d:%d (state %d:%s, purpose %d)",
                victim->n_conn->_base.address, victim->n_conn->_base.port,
index d84f04b250bb22fc25157ef405cc7655409cda9b..3ac8b925160f1b7018335ac170b5cd35d26e22b5 100644 (file)
@@ -2614,6 +2614,10 @@ typedef struct origin_circuit_t {
    * circuit. */
   unsigned int hs_circ_has_timed_out : 1;
 
+  /** Set iff this is a service-side rendezvous circuit for which a
+   * new connection attempt has been launched. */
+  unsigned int hs_service_side_rend_circ_has_been_relaunched : 1;
+
   /** What commands were sent over this circuit that decremented the
    * RELAY_EARLY counter? This is for debugging task 878. */
   uint8_t relay_early_commands[MAX_RELAY_EARLY_CELLS_PER_CIRCUIT];
index 76caeffd0fa050d687a6d2389300a32e6ea8a0ae..bbc9c91866e53955e3682aec80fa20a3e1b2ea2b 100644 (file)
@@ -1419,6 +1419,17 @@ rend_service_relaunch_rendezvous(origin_circuit_t *oldcirc)
 
   tor_assert(oldcirc->_base.purpose == CIRCUIT_PURPOSE_S_CONNECT_REND);
 
+  /* Don't relaunch the same rend circ twice. */
+  if (oldcirc->hs_service_side_rend_circ_has_been_relaunched) {
+    log_info(LD_REND, "Rendezvous circuit to %s has already been relaunched; "
+             "not relaunching it again.",
+             oldcirc->build_state ?
+             safe_str(extend_info_describe(oldcirc->build_state->chosen_exit))
+             : "*unknown*");
+    return;
+  }
+  oldcirc->hs_service_side_rend_circ_has_been_relaunched = 1;
+
   if (!oldcirc->build_state ||
       oldcirc->build_state->failure_count > MAX_REND_FAILURES ||
       oldcirc->build_state->expiry_time < time(NULL)) {
@@ -1727,6 +1738,11 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
            "cookie %s for service %s",
            circuit->_base.n_circ_id, hexcookie, serviceid);
 
+  /* Clear the 'in-progress HS circ has timed out' flag for
+   * consistency with what happens on the client side; this line has
+   * no effect on Tor's behaviour. */
+  circuit->hs_circ_has_timed_out = 0;
+
   service = rend_service_get_by_pk_digest(
                 circuit->rend_data->rend_pk_digest);
   if (!service) {