PRUDP probably stands for Protected Reliable User Datagram Protocol, as it is designed for adding reliability, encryption and compression to UDP. To do this, it adds connections, acknowledgements, ordering, fragmentation, compression, encryption and checksums.
Every packet, sent by both the client and the server, has the following base information:
| Name | Description | Type |
|---|---|---|
| Source | The virtual stream that the packet is being sent from. | Stream |
| Destination | The virtual stream that the packet is being sent to. | Stream |
| Type and Flags | Type of the packet, and flags indicating how the client should treat this packet. | Type and Flags |
| Session ID | Unknown. | u8 |
| Packet Signature | Unknown. | u32 |
| Sequence ID | A strictly monotonically increasing integer used for acknowledgements and ordering. | u16 |
SYNThis packet establishes a connection with the server.
| Name | Description | Type |
|---|---|---|
| Connection Signature | Unknown. | u32 |
| Name | Description | Type |
|---|---|---|
| Connection Signature | Unknown. | u32 |
CONNECTThis stage is used to execute a Diffie-Hellman key exchange, and then derive a shared secret key.
The key exchange operation is $S = d \times Q$, where $S$ is the resulting key, $d$ is the server's private key, and $Q$ is the client's public key. The resulting y co-ordinate of this exchange is discarded.
The shared key, used for DATA packet encryption and decryption, is derived using the first 16 bytes of a SHA1 hash on the Diffie-Hellman exchange result.
The server may also use this stage to affirm the client's connection signature.
| Name | Description | Type |
|---|---|---|
| Connection Signature | Unknown. | u32 |
| Public Key | The client's public key. | Public Key |
| Name | Description | Type |
|---|---|---|
| Connection Signature | Unknown. | u32 |
| Public Key Signature | The server's public key signed by the server's certification private key. | Buffer |
| Public Key | The server's public key. | Public Key |
| Tag | A HMAC-SHA256 signature on both the client's key and the [server's key](client's key) concatenated, signed using the Diffie-Hellman exchange result (NOT the shared key). | Buffer |
DATAThe whole data is first fragmented, then compressed, then encrypted.
This means that the data in this packet, if fragmented, should be decrypted first, then de-compressed (if applicable), and then re-assembled.
The compressed payload (before encryption) is prefixed with a single byte indicating the compression ratio. 0 means that the remaining data is not compressed. The client appears to only ever use 0x02 for this byte, however.
The fragmented payload (before compression) is suffixed with the 2-byte sequence id of the data packet being sent.
| Name | Description | Type |
|---|---|---|
| Fragment ID | Used to re-assemble fragmented data packets, starting from 1 (if multiple fragments exist), and ending in 0 to indicate a final fragment. |
u32 |
| ... | Encrypted and compressed data | any |
DISCONNECTPINGPublic KeyAn uncompressed SEC1 formatted key, without the preceeding compression tag (0x04).
StreamA packed u8 containing
| Name | Description | Type |
|------|---------------------------------------------------|------------------------------------|
| Port | The virtual port for this stream. | u4 |
| Port | The type of stream that the connection is using. | Stream Type |
Type and FlagsA packed u8 containing
| Name | Description | Type |
|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------|
| Type | The type of packet that is being sent. | Packet Type |
| Ack | This packet is an acknowledgement packet for a reliable packet sent by the recipient. | bool |
| Reliable | This packet must be acknowledged by the recipient, or it will be re-sent. | bool |
| Need Ack | The sender is expecting an acknowledgement for this packet. | bool |
| Has Size | The packet contains a u16 size following the packet header (or, for SYN and CONNECT, after the connection signature, and for DATA, after the fragment ID). | bool |
| Multi Ack | Unknown, doesn't appear to be supported, but if a packet flagged with Need Ack has this flag, the recipient should send an Ack with this flag set too. | bool |
Stream TypeA u4 containing these values:
| Name | Value |
|---|---|
RV Authentication |
2 |
RV Secure |
3 |
Sandbox Management |
4 |
NAT |
5 |
Session Discovery |
6 |
Nat Echo |
7 |
[!IMPORTANT]
Hyperscape appears to exclusively use theRV Secure(3) type.
Packet TypeA u3 containing these values:
| Name | Value |
|---|---|
SYN |
0 |
CONNECT |
1 |
DATA |
2 |
DISCONNECT |
3 |
PING |
4 |
USER |
6 |