diff options
author | Nick Mathewson <nickm@torproject.org> | 2011-07-19 13:51:43 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2011-07-19 13:51:43 -0400 |
commit | e8b9815711e7cd1ef0b83153aefcc0d05e817f4e (patch) | |
tree | 70bedadab8572d9333232e51c2b835006c7cd4d1 /src/or/circuituse.c | |
parent | 12dfb4f5d8cfb0f244b4a1ae3cc3af237a3034e7 (diff) | |
download | tor-e8b9815711e7cd1ef0b83153aefcc0d05e817f4e.tar.gz tor-e8b9815711e7cd1ef0b83153aefcc0d05e817f4e.zip |
Take a smarter approach to clearing isolation info
Back when I added this logic in 20c0581a79, the rule was that whenever
a circuit finished building, we cleared its isolation info. I did that
so that we would still use the circuit even if all the streams that
had previously led us to tentatively set its isolation info had closed.
But there were problems with that approach: We could pretty easily get
into a case where S1 had led us to launch C1 and S2 had led us to
launch C2, but when C1 finished, we cleared its isolation and attached
S2 first. Since C2 was still marked in a way that made S1
unattachable to it, we'd then launch another circuit needlessly.
So instead, we try the following approach now: when a circuit is done
building, we try to attach streams to it. If it remains unused after
we try attaching streams, then we clear its isolation info, and try
again to attach streams.
Thanks to Sebastian for helping me figure this out.
Diffstat (limited to 'src/or/circuituse.c')
-rw-r--r-- | src/or/circuituse.c | 16 |
1 files changed, 16 insertions, 0 deletions
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. |