Documentation

Support

Relay

Relay

Relay message protocol

Understand how the Relay message protocol transmits data between clients and servers in the Relay service.
Read time 10 minutesLast updated 14 hours ago

If you’re using the Relay SDK with UTP or with NGO for your project, the Relay message protocol is already supported. However, if you want to use an alternative engine or networking solution, you’ll need to implement the Relay message protocol before using it. Use the Relay message protocol specifications to implement the Relay message protocol. The Relay message protocol expects you to express field values in big-endian order, also known as the “network order,” where the most significant byte occurs first. Messages aren't authenticated except for the
BIND
message
, which uses an HMAC signature.
Players can only connect and relay messages with other players from the same Unity project and environment. Relay rejects any attempts to communicate across Unity environments. All messages have a standard header and a message-specific body. Check out Standard header and Message bodies.

Message types

CodeNameDescription
0
BIND message
A
BIND
message indicates a bind request sent from a client to a Relay server.
1
BIND_RECEIVED message
A
BIND_RECEIVED
message indicates a successful response from the Relay server to a client after receiving a
BIND request
.
2
PING message
A
PING
message indicates a ping message sent between a client and a Relay server (both directions) to keep the connection alive.
3
CONNECT_REQUEST message
A
CONNECT_REQUEST
message indicates a request from a player (the requesting client) to connect to another player (the target client).
4
Reserved.
5
Reserved.
6
ACCEPTED message
An
ACCEPTED
message indicates a confirmation message sent from a Relay server to a requesting client after a successful connection to a target client.
7
Reserved.
8
Reserved.
9
DISCONNECT message
A
DISCONNECT
message indicates a request to disconnect two connected players.
10
RELAY message
A
RELAY
message indicates a request to send a message between two players (clients).
11
CLOSE message
A
CLOSE
message indicates a request from a client to unbind from a Relay server.
12
ERROR message
An
ERROR
message indicates an error that has occurred.

Accept mode types

The accept mode defines how a Relay server handles requests from clients trying to connect. Relay only supports the
AUTO
accept mode. A connection mode of
AUTO
means the Relay server automatically accepts the connection if its capacity allows it (the number of connections must not exceed the maximum number of allowed connections).
CodeNameDescription
0
AcceptModeAuto
AcceptModeAuto
indicates that connections to clients will be automatically accepted by the Relay server.
1
 Reserved.

Standard header

All message types share a standard header that has a signature, the Relay message protocol version, and the message contained in the body of the packet.
Bytes1 .. 234
Purpose
Signature
Version
Type
The following table describes each field found in the standard header.
FieldTypeDescription
Signature
[]byteThe
Signature
is always
0xDA72
.
Version
uint8The
Version
is the Relay message protocol version.The value should be 0 for the initial release.
Type
uint8The
Type
is an integer representing the message type contained in the body. Check out Message types.

Message bodies

BIND message

BIND
messages are sent from a client to a Relay server to create a mapping from a client’s IP address and port for a specific allocation. This message is authenticated to verify the identity of the client.
The response received from the Allocations service has the information necessary for the client to authenticate its
BIND
messages. The response from the Allocations service to the
BIND
message shows the binding status.
Clients can send identical
BIND
messages as long as the client’s IP address and port haven't changed. For example, if a client sends a
BIND
message on a following connection after changing its IP address or port, the
Nonce
value must be greater than the previously supplied value.
Bytes1 .. 456 .. 789 .. NN+1 .. 33
PurposeHeader (Type 0)
AcceptMode
Nonce
ConnectionDataLength
ConnectionData
HMAC
The following table describes each field found in a
BIND
message.
FieldTypeDescription
AcceptMode
uint8
AcceptMode
defines how a Relay server should handle requests from clients trying to connect to the owner of this allocation.Currently, only the
AUTO
accept mode is supported.See Accept mode types.
Nonce
uint16
Nonce
is a single-use cryptographic nonce. Each following
BIND
message must have an incremented nonce value. It's conventional to start the nonce value at 0.
ConnectionDataLength
uint8
ConnectionDataLength
describes the byte length of
ConnectionData
.The maximum allowed value is 255.
ConnectionData
[]byte
ConnectionData
is the encrypted connection data of the <madcap:glossaryterm glossterm="relay-glossary.Term4">connecting client</madcap:glossaryterm>.This field’s length is variable. The maximum length is 255 bytes.
HMAC
[32]byte
HMAC
is a hash-based message authentication code generated using a known key and the preceding bytes in the message, including the header.See Authentication.

Security

You must sign the HMAC with the secret key returned from the Allocations service. If the HMAC is invalid, the Relay server silently rejects the
BIND message
.
The Relay server also validates the nonce value to mitigate message replay attacks by bad actors. If the Relay server determines that a nonce is invalid, it silently rejects it. If it’s the first time the client is binding to a Relay server with a
BIND message
, the nonce value can be 0.

BIND_RECEIVED message

Relay servers send
BIND_RECEIVED
messages to requesting clients to confirm they have successfully bound to the Relay server through a
BIND message
. After receiving the confirmation, the requesting client can initiate communication with a target client using a
CONNECT_REQUEST message
.
Bytes1 .. 4
PurposeHeader (Type 1)

PING message

PING
messages are simple messages that keep the binding between a client and a Relay server alive by resetting the client timeout. Relay servers automatically disconnect clients after 10 seconds of inactivity. Any message received by the Relay server involving this client, either as a sender or receiver, resets this timeout. For games with a lower message frequency, the
PING
message allows clients to reset the disconnection timer.
Each
PING
message has the client’s allocation ID and an arbitrary number that identifies the message.
When a Relay server receives a
PING
message from a client, it sends the packet back to the client without altering it. This allows you to use
PING
messages to check connectivity and measure round trip time.
The Relay server doesn't send back an error message if the allocation ID has expired.
Bytes1 .. 45 .. 2021 .. 22
PurposeHeader (Type 2)
AllocationID
Number
The following table describes each field found in a
PING
message.
FieldTypeDescription
AllocationID
[16]byte
AllocationID
is a 16-byte UUID identifying the allocated client sending the ping.
Number
uint16
Number
is an arbitrary unsigned integer the Relay server echoes back to the client. This can be used by the client to correlate
PING
messages that are sent and received.

CONNECT_REQUEST message

CONNECT_REQUEST
messages are sent from a requesting client to a Relay server to establish a connection to a target client. The target player the requesting client wants to connect to (or the target client) is represented by
ToConnectionData
, which the Relay server decrypts to determine which player to connect with.
Bytes1 .. 45 .. 202122 ..
PurposeHeader (Type 3)
AllocationID
ToConnectionData Length
ToConnectionData
The following table describes each field found in a
CONNECT_REQUEST
message.
FieldTypeDescription
AllocationID
[16]byte
AllocationID
is a 16-byte UUID that identifies the allocated client that's requesting the connection.
ToConnectionDataLength
uint8
ToConnectionDataLength
is the byte length of
ToConnectionData
.The maximum allowed value is 255.
ToConnectionData
[]byte
ToConnectionData
is an encrypted data blob that describes the client to connect to. See Connection data.This field has a variable length. The maximum byte length is 255.

ACCEPTED message

A Relay server sends an
ACCEPTED
message to a requesting client after a successful connection to a target client.
Bytes1 .. 45 .. 2021 .. 36
PurposeHeader (Type 6)
FromAllocationID
ToAllocationID
The following table describes each field found in an
ACCEPTED
message.
FieldTypeDescription
FromAllocationID
[16]byte
FromAllocationID
is a 16-byte UUID that identifies the target client.
ToAllocationID
[16]byte
ToAllocationID
is a 16-byte UUID that identifies the allocated client that requested the connection (the requesting client).

DISCONNECT message

The
DISCONNECT
message is the inverse of the
CONNECT_REQUEST
handshake and allows a client to disconnect from another client. A client can disconnect from any other client it has connected with by sending a
DISCONNECT
message to the Relay server.
When the Relay server receives the message, it removes the specified allocation ID from the requesting client’s list of connected players. The Relay server also forwards the
DISCONNECT
request to the host client so the client can update its map of connected players to remove the requesting client's Allocation ID.
The Relay server then sends the
DISCONNECT
message back to the client as a confirmation. If either of the allocation IDs in the message body is invalid, the Relay server sends an
ERROR message
instead.
Once a client has disconnected, the Relay server rejects all
RELAY
messages
sent to that client’s allocation ID. A disconnected client can re-establish a connection with a
CONNECT_REQUEST message
.
Bytes1 .. 45 .. 2021 .. 36
PurposeHeader (Type 9)
FromAllocationID
ToAllocationID
The following table describes each field found in a
DISCONNECT
message.
FieldTypeDescription
FromAllocationID
[16]byte
FromAllocationID
is a 16-byte UUID that identifies the allocated client that's requesting to close the connection (the requesting client).
ToAllocationID
[16]byte
ToAllocationID
is a 16-byte UUID that identifies the allocated client whose connection is being closed (the target client).

RELAY message

RELAY
messages allow clients to send messages containing any arbitrary payload of bytes between each other without awareness of each other’s IP addresses and ports.
Before sending a
RELAY
message between clients, the Relay server ensures the client sending the packet has previously been authenticated as the
FromAllocationID
through a
BIND message
. If the client hasn't previously bound, the Relay server returns an
ErrClientPlayerMismatch
ERROR
message
.
The Relay server also ensures the two clients have an established connection through a earlier
CONNECT_REQUEST
exchange. The Relay server returns an
ErrNotConnected
ERROR message
if the clients aren't connected.
If all validations pass, the Relay server sends the entire message to the
ToAllocationID
as-is. The Relay server doesn't send any confirmation message to the
FromAllocationID
.
Bytes1 .. 45 .. 2021 .. 3637 .. 3839 ..
PurposeHeader (Type 10)
FromAllocationID
ToAllocationID
Length
Content
The following table describes each field found in a
RELAY
message.
FieldTypeDescription
FromAllocationID
[16]byte
FromAllocationID
is a 16-byte UUID that identifies the allocated client sending the message (the requesting client).
ToAllocationID
[16]byte
ToAllocateID
is a 16-byte UUID that identifies the allocated client receiving the message (the target client).
Length
uint16
Length
specifies the length of the message content in bytes.The maximum value is 1400.
Content
[]byte
Content
has the content of the message.

CLOSE message

CLOSE
messages are idempotent messages that allow a client to unbind and deallocate from a Relay server. Clients should send a
CLOSE
message to the Relay server when leaving their game session or when closing the game client. Clients can only close their own bindings to the Relay server; they can't close another client’s binding.
Clients should send
CLOSE
messages multiple times to increase the chance of successful delivery. Because
CLOSE
messages are idempotent, there’s no risk of the Relay server sending an
ERROR
message
if the client has already been disconnected.
The
CLOSE
message is a best effort to gracefully terminate an allocation, and there is no guarantee it will succeed. Because Relay servers can deallocate clients with a timeout, Relay servers don't rely on a
CLOSE
message to remove a client allocation.
The client sending the
CLOSE
message must be bound to the Relay server through a earlier
BIND
request
. If the client isn't bound to the Relay server (or the client’s IP address has changed), the Relay server will silently reject the message. Use
PING
messages to prevent unintended allocation timeouts.
Bytes1 .. 45 .. 20
PurposeHeader (Type 11)
AllocationID
The following table describes each field found in a
CLOSE
message.
FieldTypeDescription
AllocationID
[16]byte
AllocationID
is a 16-byte UUID that identifies the client's allocation.

ERROR message

Relay servers use
ERROR
messages strictly to inform the client that an error has occurred.
Bytes1 .. 45 .. 2021
PurposeHeader (Type 12)
AllocationID
ErrorCode
The following table describes each field found in an
ERROR
message.
FieldTypeDescription
AllocationID
[16]byte
AllocationID
is a 16-byte UUID that identifies the client's allocation.
ErrorCode
uint8
ErrorCode
represents an error code. See Error codes below.

Error codes

The following table describes each of the possible error messages a Relay server can send to a client.
CodeNameDescription
0
Invalid protocol version (
ErrInvalidProtocolVersion
)
ErrInvalidProtocolVersion
is returned when a parsed message has an unexpected protocol version.
1
Player timed out due to inactivity (
ErrTimeout
)
ErrTimeout
is returned when a client’s binding to a Relay server has timed out. See Client timeouts.Clients should use
PING messages
to prevent this error.
2
Unauthorized (
ErrUnauthorized
)
ErrUnauthorized
is returned when a client attempts to perform an operation that it's not authorized to perform.
3
Allocation ID client mismatch (
ErrClientPlayerMismatch
)
ErrClientPlayerMismatch
is returned when a client has sent a
RELAY
message to the server using an unknown network connection.It's intended to inform the client that the IP address they're using has changed from the one the Relay server is aware of.This error message indicates the client should re-bind with a new
BIND message
.
4
Allocation ID not found (
ErrAllocationNotFound
)
ErrAllocationNotFound
is returned when the Relay server can't find an allocation for the given allocation ID.
5
Not connected (
ErrNotConnected
)
ErrNotConnected
is returned when a client attempts to communicate with a client to whom it's not connected.
6
Self-connect not allowed (
ErrSelfConnectNotAllowed
)
ErrSelfConnectNotAllowed
is returned when a client sends a
CONNECT_REQUEST message
to a client with the same allocation ID.