diff options
Diffstat (limited to 'spec/tor-spec/tearing-down-circuits.md')
-rw-r--r-- | spec/tor-spec/tearing-down-circuits.md | 108 |
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) +``` |