aboutsummaryrefslogtreecommitdiff
path: root/spec/tor-spec/cell-packet-format.md
diff options
context:
space:
mode:
Diffstat (limited to 'spec/tor-spec/cell-packet-format.md')
-rw-r--r--spec/tor-spec/cell-packet-format.md196
1 files changed, 196 insertions, 0 deletions
diff --git a/spec/tor-spec/cell-packet-format.md b/spec/tor-spec/cell-packet-format.md
new file mode 100644
index 0000000..cfc7f36
--- /dev/null
+++ b/spec/tor-spec/cell-packet-format.md
@@ -0,0 +1,196 @@
+<a id="tor-spec.txt-3"></a>
+
+# Cells (messages on channels) {#cell-packet-format}
+
+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 | |
+| `Body` | [`CELL_BODY_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 |
+| `Body` | `Length` | |
+
+[`CIRCID_LEN(v)`]: ./preliminaries.md#msg-len
+[`CELL_BODY_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:
+
+| Value |C|P| Identifier | Description |
+|-------|-|-|---------------------|--------------------------------------- |
+| 0 |N| | `PADDING` | [Link Padding][PADDING] |
+| 1 |Y| | `CREATE` | [Create circuit][CREATE] (deprecated) |
+| 2 |Y| | `CREATED` | [Acknowledge CREATE][CREATED] (deprecated) |
+| 3 |Y| | `RELAY` | [End-to-end data][RELAY] |
+| 4 |Y| | `DESTROY` | [Destroy circuit][DESTROY] |
+| 5 |Y| | `CREATE_FAST` | [Create circuit, no public key][CREATE_FAST] |
+| 6 |Y| | `CREATED_FAST` | [Acknowledge CREATE_FAST][CREATED_FAST] |
+| 8 |N| | `NETINFO` | [Time and address info][NETINFO] |
+| 9 |Y| | `RELAY_EARLY` | [End-to-end data; limited][RELAY_EARLY] |
+| 10 |Y| | `CREATE2` | [Create circuit][CREATE2] |
+| 11 |Y| | `CREATED2` | [Acknowledge CREATED2][CREATED2] |
+| 12 |Y|5| `PADDING_NEGOTIATE` | [Padding negotiation][PADDING_NEGOTIATE] |
+
+
+[PADDING]: ./flow-control.md#link-padding
+[CREATE]: ./create-created-cells.md#CREATE
+[CREATED]: ./create-created-cells.md#CREATE
+[RELAY]: ./routing-relay-cells.md#routing-relay-cells
+[DESTROY]: ./tearing-down-circuits.md#tearing-down-circuits
+[CREATE_FAST]: ./create-created-cells.md#create_fast
+[CREATED_FAST]: ./create-created-cells.md#create_fast
+[NETINFO]: ./negotiating-channels.md#NETINFO-cells
+[RELAY_EARLY]: ./relay-early.md#handling-relay-early-cells
+[CREATE2]: ./create-created-cells.md#CREATE
+[CREATED2]: ./create-created-cells.md#CREATE
+[PADDING_NEGOTIATE]: ./flow-control.md#link-padding
+
+The variable-length `Command` values are:
+
+| Value |C|P| Identifier | Description |
+|-------|-|-|------------------|----------------------------------------|
+| 7 |N| | `VERSIONS` | [Negotiate link protocol][VERSIONS] |
+| 128 |N| | `VPADDING` | [Variable-length padding][VPADDING] |
+| 129 |N| | `CERTS` | [Certificates][CERTS] |
+| 130 |N| | `AUTH_CHALLENGE` | [Challenge value][AUTH_CHALLENGE] |
+| 131 |N| | `AUTHENTICATE` | [Authenticate initiator][AUTHENTICATE] |
+| 132 |N|n/a| `AUTHORIZE` | (Reserved) |
+
+[VERSIONS]: ./negotiating-channels.md#VERSIONS-cells
+[VPADDING]: ./flow-control.md#link-padding
+[CERTS]: ./negotiating-channels.md#CERTS-cells
+[AUTH_CHALLENGE]: ./negotiating-channels.md#AUTH-CHALLENGE-cells
+[AUTHENTICATE]: ./negotiating-channels.md#AUTHENTICATE-cells
+
+In the tables above,
+**C**=Y indicates that a command must have a nonzero CircId, and
+**C**=N indicates that a command must have a zero CircId.
+Where given, **P** is the first link protocol version
+to support a command.
+Commands with no value given for **P**
+are supported at least in link protocols 3 and above.
+
+No other command values are allowed.
+Implementations SHOULD NOT send undefined command values.
+Upon receiving an unrecognized command,
+an implementation MAY silently drop the cell
+and MAY terminate the channel with an error.
+
+> Extensibility note:
+>
+> When we add new cell command types,
+> we define a new link protocol version
+> to indicate support for that command.
+>
+> Therefore, implementations can now safely assume
+> that other correct implementations
+> will never send them an unrecognized cell command.
+>
+> Historically, before the link protocol was not versioned,
+> implementations would drop cells with unrecognized commands,
+> under the assumption that the command was sent
+> by a more up-to-date version of Tor.
+
+## Interpreting the fields: Cell Body {#body}
+
+<!-- deprecated target --><a id="payload"></a>
+
+The interpretation of a cell's Body depends on the cell's command.
+see the links in the command descriptions above
+for more information on each command.
+
+## Padding fixed-length cell bodies {#body-padding}
+
+<!-- deprecated target --><a id="payload-padding"></a>
+
+Often, the amount of information to be sent
+in a fixed-length cell
+is less than [`CELL_BODY_LEN`] bytes.
+When this happens,
+the sender MUST fill the unused part of the cell's body
+with zero-valued bytes.
+
+Recipients MUST ignore padding bytes.
+
+> [RELAY] and [RELAY_EARLY] cells' bodies
+> contain encrypted data,
+> and are always full
+> from the point of the view of the channel layer.
+>
+> The _plaintext_ of these cells' contents may be padded;
+> this uses a [different mechanism](./relay-cells.md#relay-cell-padding)
+> and does not interact with cell body padding.
+
+Variable-length cells never have extra space,
+so there is no need to pad their bodies.
+Unless otherwise specified,
+variable-length cells have no padding.
+