An ID is equivalent to a [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier), which is a 16-byte long random number. Its function is similar to a token. An ID looks like: `de305d54-75b4-431b-adb2-eb6b9e546014`, it is almost entirely random and can be generated using any UUID generator, such as [this one](https://www.uuidgenerator.net/).
VMess is a stateless protocol, which means that data can be transmitted directly between the client and the server without the need for a handshake. Each data transmission has no impact on other data transmissions before or after it.
When a VMess client initiates a request, the server checks whether the request comes from a legitimate client. If the validation passes, the server forwards the request and sends the obtained response back to the client.
| Version | Data Encryption IV | Data Encryption Key | Response Authentication Value | Options | Reserved | Encryption Method | Reserved | Command | Port | Address Type | Address | Random Value | Checksum |
- S (0x01): Standard format data stream (recommended);
- R (0x02): Client expects to reuse TCP connection (deprecated in Xray 2.23+);
- This item only takes effect when S is enabled;
- M (0x04): Enable metadata obfuscation (recommended);
- This item only takes effect when S is enabled;
- When this item is enabled, the client and server need to construct two Shake instances respectively, RequestMask = Shake (request data IV), ResponseMask = Shake (response data IV).
- X: Reserved
- Redundancy P: Random value added before checksum value;
- Encryption Method: Specify the encryption method for the data part, and the optional values are:
- 0x00: AES-128-CFB;
- 0x01: No encryption;
- 0x02: AES-128-GCM;
- 0x03: ChaCha20-Poly1305;
- Instruction Cmd:
- 0x01: TCP data;
- 0x02: UDP data;
- Port Port: Integer port number in Big Endian format;
- Address Type T:
- 0x01: IPv4
- 0x02: Domain name
- 0x03: IPv6
- Address A:
- When T = 0x01, A is a 4-byte IPv4 address;
- When T = 0x02, A is a 1-byte length (L) + L-byte domain name;
- When T = 0x03, A is a 16-byte IPv6 address;
- Check F: FNV1a hash of all content in the instruction except F.
### Data Section
When Opt(S) is enabled, this format is used for the data section. The actual request data is divided into several small chunks, and each chunk has the following format. After the server verifies all the small chunks, it will be forwarded in the basic format.
| 2 Bytes | L Bytes |
| :------: | :---------: |
| Length L | Data Packet |
in which:
- Length L: A big-endian integer with a maximum value of 2^14.
- When Opt(M) is enabled, the value of L is equal to the true value xor Mask. Mask = (RequestMask.NextByte() <<8)+RequestMask.NextByte();
- Packet: A data packet encrypted by the specified encryption method.
Before the transmission is completed, the data packet must contain actual data, in addition to the length and authentication data. When the transmission is complete, the client must send an empty data packet, that is, L = 0 (unencrypted) or the length of the authentication data (encrypted), to indicate the end of the transmission.
The packets are formatted as follows, depending on the encryption method:
- Unencrypted:
- L bytes: actual data;
- AES-128-CFB: The entire data section is encrypted using AES-128-CFB.
- 4 bytes: FNV1a hash of actual data;
- L - 4 bytes: actual data;
- AES-128-GCM: Key is the Key of the instruction section, IV = count (2 bytes) + IV (10 bytes). count starts at 0 and increases by 1 for each packet; IV is the 3rd to 12th byte of the instruction section IV.
- L - 16 bytes: actual data;
- 16 bytes: GCM authentication information
- ChaCha20-Poly1305: Key = MD5 (instruction part Key) + MD5 (MD5 (instruction part Key)), IV = count (2 bytes) + IV (10 bytes). count starts at 0 and increases by 1 for each packet; IV is the 3rd to 12th byte of the instruction section IV.
- L - 16 bytes: actual data;
- 16 bytes: Poly1305 authentication information
## Server Response
The header data is encrypted using AES-128-CFB encryption. The IV is MD5 of the data encryption IV, and the Key is MD5 of the data encryption Key. The actual response data varies depending on the encryption settings.
| 1 Byte | 1 Byte | 1 Byte | 1 Byte | M Bytes | Remaining Part |
When the client receives a dynamic port command, the server opens a new port for communication. The client can then send data to the new port. After T minutes, the port will expire, and the client must use the main port to communicate again.