Skip to content

The Source RCON Protocol

Archie Jaskowicz edited this page Dec 24, 2023 · 2 revisions

The Source RCON protocol is a TCP protocol made by Valve, originally for Source Dedicated Servers which many other games took use of. The community that run the documentation for this explain it pretty well over at this page, however, I do feel like some details are missing or just easily skipped. So, I'm going to re-document the RCON protocol here.

Packet Structure

The packet structure for RCON is pretty simple:

|---------------------|-----------------------------------|---------------|
|Field                |Type                               |Value          |
|---------------------|-----------------------------------|---------------|
|Size (4 bytes)       |32-bit little-endian Signed Integer|See below      |
|ID (4 bytes)         |32-bit little-endian Signed Integer|See below      |
|Type (4 bytes)       |32-bit little-endian Signed Integer|See below      |
|Body (1+ byte)       |Null Terminated ASCII String       |See below      |
|Empty String (1 byte)|Null Terminator                    |0x00 (\0)      |
|---------------------|-----------------------------------|---------------|

A minimum packet length is 14, whilst the minimum "size" is 10 (more information about size below). It is important that you understand the difference between the two.

Packet Size

The packet size is always, at minimum, 10 bytes (formed by the ID, Type, Body, and Empty String). You should add 4 to this if you want the actual length from there (or take off 4 from the length if you need the size of the packet).

The maximum possible size of the packet is 4096 (4100 in length). If the response exceeds this amount, it will be split and sent as mutliple packets.

A neat trick to find out the size of the packet is by getting the length of the body in bytes and adding 10 to it.

Packet ID

The packet ID is a number chosen by the user/client for each request. The ID can be anything you wish, the server will send back the same ID as the original request (There is an exception to this, view the SERVERDATA_AUTH_RESPONSE section). This field exists to help you match incoming responses to their corresponding requests.

Packet Type

The packet type indicates the purpose of the packet. The types are:

|-----|-------------------------|
|Value|Type                     |
|-----|-------------------------|
|3    |SERVERDATA_AUTH          |
|2    |SERVERDATA_AUTH_RESPONSE |
|2    |SERVERDATA_EXECCOMMAND   |
|0    |SERVERDATA_RESPONSE_VALUE|
|-----|-------------------------|

Note that the repetition in the above table is not an error: SERVERDATA_AUTH_RESPONSE and SERVERDATA_EXECCOMMAND both have a numeric value of 2.

See Requests and Responses below for an explanation for each packet type.

Packet Body

The packet body field is a string encoded in ASCII.

If the packet type is SERVERDATA_AUTH, you should send the server password as the body. Otherwise, if your packet type is SERVERDATA_EXECCOMMAND, you should send whatever you want to run as the body.

Empty String

The end of each RCON packet is marked by an empty string (essentially 8 bits of 0). However, languages like C++ don't null-terminate strings automatically, so you should write 16 bits (2 bytes) of 0 (1 byte to terminate the packet body, 1 byte for the empty string afterwards).

Requests and Responses

Requests that are sent asynchronously can have their responses sent out-of-order. You can counter this by simply waiting for each request to come back before allowing another one. However, the ID field can help you figure out which response is for what request.

Rcon++ already accounts for this.

SERVERDATA_AUTH

This is the first packet that gets sent to the server, before any other request.

SERVERDATA_AUTH_RESPONSE

This packet comes after the SERVERDATA_AUTH packet. These packets will tell you if the connection was successful or not.

If the connection was successful, the ID will be the same ID you gave in the request. If the connection was a failure, the ID will be -1 (or 0xFF FF FF FF in hex)

SERVERDATA_EXECCOMMAND

This packet represents a command. Most servers will issue a response packet after this (that being SERVERDATA_RESPONSE_VALUE, explained below), however, some servers (like a Factorio dedicated server) may not issue a response packet (for example, doing an incorrect command will result in no response). More on that below.

The body of this packet should be what you intent to fire on the server. An empty body should ideally not be sent here, but if it is, the server will simply reject it (rcon++ will refuse to send blank commands).

SERVERDATA_RESPONSE_VALUE

This packet represents the response from a server, to a SERVERDATA_EXECCOMMAND request.

If the packet was sent correctly, your ID will match the one you sent in the request. Along with the body being the information the server has sent in response to your request. Sometimes, the body can be empty if the server didn't have anything to respond with, but still sent the packet (as intended).

Sometimes, the server may not issue this packet which can cause some confusion. This is not a common occurance and doesn't happen in Source Dedicated Servers.