aboutsummaryrefslogtreecommitdiff
path: root/spec/tor-spec/cell-packet-format.md
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2023-11-08 14:03:13 -0500
committerNick Mathewson <nickm@torproject.org>2023-11-09 09:12:48 -0500
commit3a4fc58ab74b8fe92ec8a9a0c95590ba3ca3e6f4 (patch)
treeef143176386829ec56399de17ca2bd0becac66b1 /spec/tor-spec/cell-packet-format.md
parentb567eaf9e6b84111ea019d7c89a39e671fbaaf13 (diff)
downloadtorspec-3a4fc58ab74b8fe92ec8a9a0c95590ba3ca3e6f4.tar.gz
torspec-3a4fc58ab74b8fe92ec8a9a0c95590ba3ca3e6f4.zip
Start to re-explan channel cells
Diffstat (limited to 'spec/tor-spec/cell-packet-format.md')
-rw-r--r--spec/tor-spec/cell-packet-format.md126
1 files changed, 78 insertions, 48 deletions
diff --git a/spec/tor-spec/cell-packet-format.md b/spec/tor-spec/cell-packet-format.md
index 7251db0..39e6009 100644
--- a/spec/tor-spec/cell-packet-format.md
+++ b/spec/tor-spec/cell-packet-format.md
@@ -2,54 +2,84 @@
# Cells (messages on channels) {#cell-packet-format}
-The basic unit of communication for onion routers and onion
-proxies is a "cell".
-
-Once a TLS connection is established, the two sides send cells
-to one another. Cells are sent serially. Standard
-cells are CELL_LEN(link_proto) bytes long, but variable-length cells
-also exist.
-
-Cells may be sent embedded in TLS records
-of any size or divided across TLS records, but the framing of TLS
-records MUST NOT leak information about the type or contents of the
-cells.
-
-On a version 1 connection, each cell contains the following
-fields:
-
-| Field | Notes | Size |
-|-----------|---------------------------|------------- |
-| `CircID` | | `CIRCID_LEN` bytes |
-| `Command` | | 1 byte |
-| `Payload` | padded with padding bytes | `PAYLOAD_LEN` |
-
-On a version 2 or higher connection, all cells are as in version 1
-connections, except for variable-length cells, whose format is:
-
-| Field | Notes | Size |
-|-----------|-----------------------|-------------- |
-| `CircID` | | `CIRCID_LEN` octets |
-| `Command` | | 1 octet |
-| `Length` | | 2 octets; big-endian integer |
-| `Payload` | some commands MAY pad | `Length` bytes |
-
-Most variable-length cells MAY be padded with padding bytes, except
-for `VERSIONS` cells, which MUST NOT contain any additional bytes.
-(The payload of `VPADDING` cells consists of padding bytes.)
-
-On a version 2 connection, variable-length cells are indicated by a
-command byte equal to 7 (`VERSIONS`). On a version 3 or
-higher connection, variable-length cells are indicated by a command
-byte equal to 7 (`VERSIONS`), or greater than or equal to 128.
-
-`CIRCID_LEN` is 2 for link protocol versions 1, 2, and 3. `CIRCID_LEN`
-is 4 for link protocol version 4 or higher. The first `VERSIONS` cell,
-and any cells sent before the first `VERSIONS` cell, always have
-`CIRCID_LEN` == 2 for backward compatibility.
-
-The `CircID` field determines which circuit, if any, the cell is
-associated with.
+The basic unit of communication on a Tor channel is a "cell".
+
+Once a TLS connection is established,
+the two parties send cells to each other.
+Cells are sent serially, one after another.
+
+Cells may be sent embedded in TLS records of any size,
+or divided across TLS records,
+but the framing of TLS records MUST NOT leak information
+about the type or contents of the cells.
+
+Most cells are of fixed length,
+with the actual length depending
+on the negotiated link protocol on the channel.
+Below we designate the negotiated protocol as `v`.
+
+As an exception, [`VERSIONS` cells] are always sent with `v = 0`,
+since no version has yet been negotiated.
+
+<span id="fixed-length-cell">A fixed-length cell has this format:</span>
+
+| Field | Size in bytes | Notes |
+|-----------|-------------------|-------|
+| `CircID` | [`CIRCID_LEN(v)`] | |
+| `Command` | 1 | |
+| `Payload` ] [`PAYLOAD_LEN]` | Padded to fit |
+
+The value of `CIRCID_LEN` depends on the negotiated link protocol.
+
+Some cells have variable length;
+the length of these cells is encoded in their header.
+
+A variable-length cell has this format:
+
+| Field | Size in bytes | Notes |
+|-----------|-----------------|-------|
+| `CircID` | `CIRCID_LEN(v)` | |
+| `Command` | 1 | |
+| `Length` | 2 | A big-endian integer |
+| `Payload` | `Length` | |
+
+[`CIRCID_LEN(v)`]: ./preliminaries.md#msg-len
+[`PAYLOAD_LEN`]: ./preliminaries.md#msg-len
+[`VERSIONS` cells]: ./negotiating-channels.md#VERSIONS-cells
+
+Fixed-length and variable-length cells are distinguished
+based on the value of their Command field:
+
+- Command 7 (`VERSIONS`) is variable-length.
+- Every other command less than 128 denotes a fixed-length cell.
+- Every command greater than or equal to 128 denotes
+ a variable-length cell.
+
+> Historical note:
+>
+> On version 1 connections, all cells were fixed-length.
+>
+> On version 2 connections,
+> only the `VERSIONS` command was variable-length,
+> and all others were fixed-length.
+>
+> These link protocols are obsolete,
+> and implementations SHOULD NOT support them.
+
+## Interpreting the fields: CircID {#circid}
+
+The `CircID` field determines which [circuit](./circuit-management.md),
+if any, the cell is associated with.
+If the cell is not associated with any circuit,
+its `CircID` is set to 0.
+
+> Note that a CircID is a channel-local identifier.
+>
+> A single multi-hop circuit
+> will have a different CircID
+> on every channel that is used to transmit its data.
+
+## Interpreting the fields: Command {#command}
The `Command` field of a fixed-length cell holds one of the following
values: