summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/or/circuitlist.c18
-rw-r--r--src/or/circuituse.c16
-rw-r--r--src/or/connection_edge.c6
3 files changed, 21 insertions, 19 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 28a7181f26..0fefe9871e 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -210,23 +210,9 @@ circuit_set_state(circuit_t *circ, uint8_t state)
/* add to waiting-circuit list. */
smartlist_add(circuits_pending_or_conns, circ);
}
-
- circ->state = state;
-
- if (state == CIRCUIT_STATE_OPEN) {
+ if (state == CIRCUIT_STATE_OPEN)
tor_assert(!circ->n_conn_onionskin);
- if (CIRCUIT_IS_ORIGIN(circ)) {
- origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
- if (origin_circ->isolation_values_set &&
- !origin_circ->isolation_any_streams_attached) {
- /* If we have any isolation information set on this circuit,
- * but we never attached any streams to it, then all of the
- * isolation information was hypothetical. Clear it.
- */
- circuit_clear_isolation(origin_circ);
- }
- }
- }
+ circ->state = state;
}
/** Add <b>circ</b> to the global list of circuits. This is called only from
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index dcb6bfa501..b4860440cb 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -998,6 +998,7 @@ circuit_testing_failed(origin_circuit_t *circ, int at_last_hop)
void
circuit_has_opened(origin_circuit_t *circ)
{
+ int can_try_clearing_isolation = 0, tried_clearing_isolation = 0;
control_event_circuit_status(circ, CIRC_EVENT_BUILT, 0);
/* Remember that this circuit has finished building. Now if we start
@@ -1005,9 +1006,12 @@ circuit_has_opened(origin_circuit_t *circ)
* to consider its build time. */
circ->has_opened = 1;
+ again:
+
switch (TO_CIRCUIT(circ)->purpose) {
case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
rend_client_rendcirc_has_opened(circ);
+ can_try_clearing_isolation = 1;
connection_ap_attach_pending();
break;
case CIRCUIT_PURPOSE_C_INTRODUCING:
@@ -1016,6 +1020,7 @@ circuit_has_opened(origin_circuit_t *circ)
case CIRCUIT_PURPOSE_C_GENERAL:
/* Tell any AP connections that have been waiting for a new
* circuit that one is ready. */
+ can_try_clearing_isolation = 1;
connection_ap_attach_pending();
break;
case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
@@ -1033,6 +1038,17 @@ circuit_has_opened(origin_circuit_t *circ)
* This won't happen in normal operation, but might happen if the
* controller did it. Just let it slide. */
}
+
+ if (can_try_clearing_isolation && !tried_clearing_isolation &&
+ circ->isolation_values_set &&
+ !circ->isolation_any_streams_attached) {
+ /* If we have any isolation information set on this circuit, and
+ * we didn't manage to attach any streams to it, then we can
+ * and should clear it and try again. */
+ circuit_clear_isolation(circ);
+ tried_clearing_isolation = 1;
+ goto again;
+ }
}
/** Called whenever a circuit could not be successfully built.
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 63779f25cd..4bbb080124 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -3461,9 +3461,9 @@ connection_edge_update_circuit_isolation(const edge_connection_t *conn,
* it, and whose isolation settings are hypothetical. (We set hypothetical
* isolation settings on circuits as we're launching them, so that we
* know whether they can handle more streams or whether we need to launch
- * even more circuits. We clear the flags once the circuits are open,
- * in case the streams that made us launch the circuits have closed
- * since we began launching the circuits.)
+ * even more circuits. Once the circuit is open, if it turns out that
+ * we no longer have any streams to attach to it, we clear the isolation flags
+ * and data so that other streams can have a chance.)
*/
void
circuit_clear_isolation(origin_circuit_t *circ)