Current Implementation
These are only approximate as I familiarize myself with the code and may be subject to revision as more information emerges
All multi-byte fields are in “network byte order” (big endian)
Control Packet Format
|3 2 1 0 | |1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0| |---------------------------------------------------------------| |C| Type | (unused) | |---------------------------------------------------------------| | Control Data | |_______________________________________________________________|
C: Control bit (this is a control packet so always 1)
Type: 15-bit value identifying the type of control signal
Control Data: optional 32-bit integer whose meaning is determined by the packet type
Control Signals
- 0: ACK
Data packet received
Control data contains the sequence number of the received data packet
- 1: Handshake
Request a new connection
Control data contains the initial (random) sequence number for one direction in the new connection
- 2: Handshake ACK
Connection request received and acknowledged
Control data contains the initial (random) sequence number for the other direction in the new connection
- 3: Handshake Request
Connection is having issues, please force-reset it and renegotiate
No control data
Data Packet Format
|3 2 1 0 | |1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0| |---------------------------------------------------------------| |C|R|M| O | Sequence Number | |---------------------------------------------------------------| | P | Message Number | |---------------------------------------------------------------| | Message Part Number | |---------------------------------------------------------------| | | | Payload (described below) | |_______________________________________________________________|
C: Control bit (this is a data packet so always 0)
R: Reliable bit (if set then packet retry is attempted)
M: Message bit (if set then this is part of a multi-packet message)
- O: Obfuscation (if non-zero then the contents of the message are XORed with the key)
00 - no obfuscation
01 - 0x6362726973736574
10 - 0x7362697261726461
11 - 0x72687566666d616e
Sequence Number: The incrementing ID identifying this data packet within the datastream
The following fields are only present in the packet if the M (Message) bit is set:
- P: Position - the packet’s position within the message:
00 - this is the only packet in the message
10 - first packet in multi-packet message
11 - middle packet in multi-packet message (i.e. neither first nor last)
01 - last packet in multi-packet message
Message Number: The incrementing ID identifying this message within the datastream
Message Part Number: The packet number identifying this packet within its message
Reference: this was an excerpt from networking/src/udt/Packet.h:
// Packet Header Format // // 0 1 2 3 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // |C|R|M| O | Sequence Number | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | P | Message Number | Optional (only if M = 1) // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // | Message Part Number | Optional (only if M = 1) // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // // C: Control bit // R: Reliable bit // M: Message bit // O: Obfuscation level // P: Position bits
STUN Packet Format
These packets follow RFC 5389:
|3 2 1 0 | |1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0| |---------------------------------------------------------------| |0 0| Message Type | Message Length | |---------------------------------------------------------------| | Magic Cookie | |---------------------------------------------------------------| | | | Transaction ID (96 bits) | |_______________________________________________________________|
The Magic Cookie in this packet is always the fixed value 0x2112A442 (in network byte order)
This packet if received in the middle of a UDT stream would identify itself as a data packet. While there is no obvious logic in the code to prevent this from being interpreted as a data packet (which would be unlikely unless we had a UDT connection with a STUN server and the message number matched the Cookie), there is logic that receives all UDT packets and checks to see if they might be a STUN response packet.