aboutsummaryrefslogtreecommitdiff
path: root/src/or/hs_circuit.c
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2017-12-04 11:49:48 -0500
committerDavid Goulet <dgoulet@torproject.org>2017-12-05 10:55:41 -0500
commite80893e51b0c0320838cbed8c46fd5b0fe608bef (patch)
tree86baba40b85f098f6e5954dc7aa303a84d95e806 /src/or/hs_circuit.c
parentba63c4099a491c3f96160005f94cf3a61433c145 (diff)
downloadtor-e80893e51b0c0320838cbed8c46fd5b0fe608bef.tar.gz
tor-e80893e51b0c0320838cbed8c46fd5b0fe608bef.zip
hs-v3: Cleanup HS circuits when marking as closed
First, hs_service_intro_circ_has_closed() is now called in circuit_mark_for close() because the HS subsystem needs to learn when an intro point is actually not established anymore as soon as possible. There is a time window between a close and a free. Second, when we mark for close, we also remove it from the circuitmap because between the close and the free, a service can launch an new circuit to that same intro point and thus register it which only succeeds if the intro point authentication key is not already in the map. However, we still do a remove from the circuitmap in circuit_free() in order to also cleanup the circuit if it wasn't marked for close prior to the free. Fixes #23603 Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/or/hs_circuit.c')
-rw-r--r--src/or/hs_circuit.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/or/hs_circuit.c b/src/or/hs_circuit.c
index ee952f4d68..a58166ccde 100644
--- a/src/or/hs_circuit.c
+++ b/src/or/hs_circuit.c
@@ -1178,3 +1178,31 @@ hs_circ_send_establish_rendezvous(origin_circuit_t *circ)
return -1;
}
+/* We are about to close or free this <b>circ</b>. Clean it up from any
+ * related HS data structures. This function can be called multiple times
+ * safely for the same circuit. */
+void
+hs_circ_cleanup(circuit_t *circ)
+{
+ tor_assert(circ);
+
+ /* If it's a service-side intro circ, notify the HS subsystem for the intro
+ * point circuit closing so it can be dealt with cleanly. */
+ if (circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
+ circ->purpose == CIRCUIT_PURPOSE_S_INTRO) {
+ hs_service_intro_circ_has_closed(TO_ORIGIN_CIRCUIT(circ));
+ }
+
+ /* Clear HS circuitmap token for this circ (if any). Very important to be
+ * done after the HS subsystem has been notified of the close else the
+ * circuit will not be found.
+ *
+ * We do this at the close if possible because from that point on, the
+ * circuit is good as dead. We can't rely on removing it in the circuit
+ * free() function because we open a race window between the close and free
+ * where we can't register a new circuit for the same intro point. */
+ if (circ->hs_token) {
+ hs_circuitmap_remove_circuit(circ);
+ }
+}
+