aboutsummaryrefslogtreecommitdiff
path: root/spec/tor-spec/tearing-down-circuits.md
diff options
context:
space:
mode:
Diffstat (limited to 'spec/tor-spec/tearing-down-circuits.md')
-rw-r--r--spec/tor-spec/tearing-down-circuits.md108
1 files changed, 108 insertions, 0 deletions
diff --git a/spec/tor-spec/tearing-down-circuits.md b/spec/tor-spec/tearing-down-circuits.md
new file mode 100644
index 0000000..3fde693
--- /dev/null
+++ b/spec/tor-spec/tearing-down-circuits.md
@@ -0,0 +1,108 @@
+<a id="tor-spec.txt-5.4"></a>
+
+# Tearing down circuits{#tearing-down-circuits}
+
+Circuits are torn down when an unrecoverable error occurs along
+the circuit, or when all streams on a circuit are closed and the
+circuit's intended lifetime is over.
+
+ORs SHOULD also tear down circuits which attempt to create:
+
+- streams with RELAY_BEGIN, or
+- rendezvous points with ESTABLISH_RENDEZVOUS,
+ ending at the first hop. Letting Tor be used as a single hop proxy makes
+ exit and rendezvous nodes a more attractive target for compromise.
+
+ORs MAY use multiple methods to check if they are the first hop:
+
+```text
+ * If an OR sees a circuit created with CREATE_FAST, the OR is sure to be
+ the first hop of a circuit.
+ * If an OR is the responder, and the initiator:
+ * did not authenticate the link, or
+ * authenticated with a key that is not in the consensus,
+ then the OR is probably the first hop of a circuit (or the second hop of
+ a circuit via a bridge relay).
+
+ Circuits may be torn down either completely or hop-by-hop.
+```
+
+To tear down a circuit completely, an OR or OP sends a DESTROY
+cell to the adjacent nodes on that circuit, using the appropriate
+direction's circID.
+
+Upon receiving an outgoing DESTROY cell, an OR frees resources
+associated with the corresponding circuit. If it's not the end of
+the circuit, it sends a DESTROY cell for that circuit to the next OR
+in the circuit. If the node is the end of the circuit, then it tears
+down any associated edge connections (see
+[Calculating the 'Digest' field](./relay-cells.md#digest-field)).
+
+After a DESTROY cell has been processed, an OR ignores all data or
+DESTROY cells for the corresponding circuit.
+
+To tear down part of a circuit, the OP may send a RELAY_TRUNCATE message
+signaling a given OR (Stream ID zero). That OR sends a DESTROY
+cell to the next node in the circuit, and replies to the OP with a
+RELAY_TRUNCATED message.
+
+\[Note: If an OR receives a TRUNCATE message and it has any relay cells
+still queued on the circuit for the next node it will drop them
+without sending them. This is not considered conformant behavior,
+but it probably won't get fixed until a later version of Tor. Thus,
+clients SHOULD NOT send a TRUNCATE message to a node running any current
+version of Tor if a) they have sent relay cells through that node,
+and b) they aren't sure whether those cells have been sent on yet.\]
+
+```text
+ When an unrecoverable error occurs along one a circuit, the nodes
+ must report it as follows:
+ * If possible, send a DESTROY cell to ORs _away_ from the client.
+ * If possible, send *either* a DESTROY cell towards the client, or
+ a RELAY_TRUNCATED cell towards the client.
+```
+
+Current versions of Tor do not reuse truncated RELAY_TRUNCATED
+circuits: An OP, upon receiving a RELAY_TRUNCATED, will send
+forward a DESTROY cell in order to entirely tear down the circuit.
+Because of this, we recommend that relays should send DESTROY
+towards the client, not RELAY_TRUNCATED.
+
+```text
+ NOTE:
+ In tor versions before 0.4.5.13, 0.4.6.11 and 0.4.7.9, relays would
+ handle an inbound DESTROY by sending the client a RELAY_TRUNCATED
+ message. Beginning with those versions, relays now propagate
+ DESTROY cells in either direction, in order to tell every
+ intermediary ORs to stop queuing data on the circuit. The earlier
+ behavior created queuing pressure on the intermediary ORs.
+```
+
+The body of a DESTROY cell or RELAY_TRUNCATED message contains a single
+octet, describing the reason that the circuit was
+closed. RELAY_TRUNCATED message, and DESTROY cells sent \_towards the
+client, should contain the actual reason from the list of error codes
+below. Reasons in DESTROY cell SHOULD NOT be propagated downward or
+upward, due to potential side channel risk: An OR receiving a DESTROY
+command should use the DESTROYED reason for its next cell. An OP
+should always use the NONE reason for its own DESTROY cells.
+
+The error codes are:
+
+```text
+ 0 -- NONE (No reason given.)
+ 1 -- PROTOCOL (Tor protocol violation.)
+ 2 -- INTERNAL (Internal error.)
+ 3 -- REQUESTED (A client sent a TRUNCATE command.)
+ 4 -- HIBERNATING (Not currently operating; trying to save bandwidth.)
+ 5 -- RESOURCELIMIT (Out of memory, sockets, or circuit IDs.)
+ 6 -- CONNECTFAILED (Unable to reach relay.)
+ 7 -- OR_IDENTITY (Connected to relay, but its OR identity was not
+ as expected.)
+ 8 -- CHANNEL_CLOSED (The OR connection that was carrying this circuit
+ died.)
+ 9 -- FINISHED (The circuit has expired for being dirty or old.)
+ 10 -- TIMEOUT (Circuit construction took too long)
+ 11 -- DESTROYED (The circuit was destroyed w/o client TRUNCATE)
+ 12 -- NOSUCHSERVICE (Request for unknown hidden service)
+```