diff options
Diffstat (limited to 'spec/tor-spec/cell-packet-format.md')
-rw-r--r-- | spec/tor-spec/cell-packet-format.md | 196 |
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. + |