# 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. A fixed-length cell has this format: | 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} 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} 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.