Source RCON Protocol: Difference between revisions
ColdFusion (talk | contribs) m (More death links) |
No edit summary |
||
Line 1: | Line 1: | ||
The '''Source RCON Protocol''' is a TCP/IP-based communication protocol used by [[Source Dedicated Server]], which allows console commands to be issued to the server via a "remote console", or RCON. The most common use of RCON is to allow server owners to control their game servers without direct access to the machine the server is running on. In order for commands to be accepted, the connection must first be authenticated using the server's RCON password, which can be set using the [[ConVar|console variable]] ''rcon_password''. | |||
==Basic Packet Structure== | |||
Both requests and responses packets take the following basic structure: | |||
* | * packet size in bytes (int) | ||
* | * packet id (int) | ||
* packet type (int) | |||
* | * packet body (string) | ||
* | * empty string (string) | ||
* | |||
The fields marked "int" above are 32-bit [[wiki:Endianness|little endian]] signed integers. The fields marked "string" are ASCIIZ ([[wiki:Null-terminated string|null-terminated strings]] encoded in [[wiki:ASCII|ASCII]]). | |||
===Packet Size=== | |||
The '''packet size''' field is a 32-bit little endian integer, representing the length of the request in bytes. Note that the '''packet size''' field itself is '''not''' included when determining the size of the packet, so the value of this field is always 4 less than the packet's actual length. The minimum possible value for '''packet size''' is 10: | |||
* exactly 4 bytes for the request/response ID | |||
* exactly 4 bytes for the request/response type | |||
* minimum 1 byte for the potentially empty packet body | |||
* exactly 1 byte for the additional empty string at the end of every packet | |||
Since the only one of these values that can change in length is the body, an easy way to calculate the size of a packet is to find the byte-length of the '''packet body''', then add 10 to it. | |||
===Packet ID=== | |||
The '''packet id''' field is a 32-bit little endian integer chosen by the client for each request. It may be set to any positive integer. When the server responds to the request, the response packet will have the same '''packet id''' as the original request (unless it is a failed '''SERVERDATA_AUTH_RESPONSE''' packet - see below.) If a unique '''packet id''' is assigned for each outgoing request, the '''packet id''' can be used to match incoming responses to their corresponding requests. | |||
===Packet Type=== | |||
The '''packet type''' field is a 32-bit little endian integer. It will always take one of the following values: | |||
'''Requests:''' | |||
* SERVERDATA_AUTH = 3 | |||
* SERVERDATA_EXECCOMMAND = 2 | |||
'''Responses:''' | |||
* SERVERDATA_AUTH_RESPONSE = 2 | |||
* SERVERDATA_RESPONSE_VALUE = 0 | |||
''(Note that the repetition above is not an error - EXECCOMMAND and AUTH_RESPONSE are both 2)'' | |||
The '''SERVERDATA_AUTH''' type ('''packet type''' = 3) indicates that the packet is an authentication request. This is sent from the client to the server, usually as the first packet of a new connection. | |||
* '''packet body''' should contain the RCON password of the server you are trying to authenticate with | |||
* The server will respond with a '''SERVERDATA_AUTH_RESPONSE''' packet. | |||
** If the password was correct, the response's '''packet id''' will be equal to the original request's '''packet id'''. | |||
** If the password was incorrect, the response's '''packet id''' will be -1 | |||
The '''SERVERDATA_EXECCOMAND''' type ('''packet type''' = 2) indicates that the packet is a command request. This is sent from the client to the server, instructing the server to execute a command on the console. | |||
* '''packet body''' should contain the command to be executed (e.g. "sv_cheats 1" or "mp_switchteams") | |||
* If the command was successfully executed, the server will respond with a '''SERVERDATA_RESPONSE_VALUE''' packet | |||
** '''packet id''' will be equal to the original request's '''packet id''' | |||
** '''packet body''' will be the server's response to the command - depending on the command, this may sometimes be an empty string (such as setting a cvar, changing the map, etc.) | |||
The '''SERVERDATA_AUTH_RESPONSE''' type ('''packet type''' = 2) indicates that the packet contains information regarding the connection's authentication status. Usually, this will be in response to a '''SERVERDATA_AUTH''' packet, but may be sent in response to a '''SERVERDATA_EXECCOMMAND''' packet if the connection needs to be authenticated (such as at the beginning of a new RCON connection, or if the RCON password changes while connected.) | |||
* '''packet body''' will always be empty | |||
* If the packet is indicating that authentication was successful, '''packet id''' will be equal to the original auth request's ID | |||
* If the packet is indicating that authentication failed or needs to be re-established, '''packet id''' will be equal to -1 | |||
= | The '''SERVERDATA_RESPONSE_VALUE''' type ('''packet type''' = 0) indicates that the packet is the response to a '''SERVERDATA_EXECCOMMAND''' packet. | ||
* '''packet body''' will contain the server's response to the original request - depending on the command, this may sometimes be an empty string | |||
* '''packet | ** Note that the '''packet body''' will never be longer than 4096 characters - if the response is longer than this, it will be sent in multiple packets. Usually this isn't a problem, but when executing commands like ''status'' or ''cvarlist'' the response may be split. | ||
** One common way to address this problem is for the client to send an empty '''SERVERDATA_RESPONSE_VALUE''' packet immediately after every '''SERVERDATA_EXECCOMMAND'''. The server will respond to the empty response packet with an empty response packet of its own, without writing anything to the log file like an empty '''SERVERDATA_EXECCOMMAND''' would. Because Source Dedicated Server always executes RCON commands in the order they are issued, receiving an empty '''SERVERDATA_RESPONSE_VALUE''' packet guarantees that you have already been sent the full response. (Special thanks to [[User:Koraktor]] for discovering this trick.) | |||
** | * '''packet id''' will be equal to the original request's '''packet id''' | ||
* ''' | |||
===Packet Body=== | |||
The '''packet body''' field is a null-terminated string encoded in ASCII (i.e. ASCIIZ). Depending on the '''packet type''', it contains either the RCON password for the server, the command to be executed, or the server's response to a request. See ''"Packet Type"'' above for details. | |||
== | ===Empty String=== | ||
The end of a Source RCON Protocol packet is marked by an empty ASCIIZ string - essentially just 8 bits of 0. In languages that do not null-terminate strings automatically, you can simply write 16 bits of 0 immediately after the '''packet body''' (8 to terminate the '''packet body''' and 8 for the empty string afterwards). | |||
==Example Packets== | |||
The log below sho | |||
For a detailed packet structure, run Wireshark (ethereal) in tandem with hlsw and follow the TCP packet stream. | For a detailed packet structure, run Wireshark (ethereal) in tandem with hlsw and follow the TCP packet stream. | ||
Line 126: | Line 157: | ||
</source> | </source> | ||
== | ==Source RCON Libraries== | ||
A (hopefully comprehensive) listing of library implementations of the Source RCON protocol. | A (hopefully comprehensive) listing of library implementations of the Source RCON protocol in various languages. | ||
* [http://rubyforge.org/projects/rcon/ Ruby RCon] RCon library for Source and Quake RCON derivatives (such as HLDS) written in Ruby. | * [http://rubyforge.org/projects/rcon/ Ruby RCon] RCon library for Source and Quake RCON derivatives (such as HLDS) written in Ruby. |
Revision as of 15:04, 31 October 2012
The Source RCON Protocol is a TCP/IP-based communication protocol used by Source Dedicated Server, which allows console commands to be issued to the server via a "remote console", or RCON. The most common use of RCON is to allow server owners to control their game servers without direct access to the machine the server is running on. In order for commands to be accepted, the connection must first be authenticated using the server's RCON password, which can be set using the console variable rcon_password.
Basic Packet Structure
Both requests and responses packets take the following basic structure:
- packet size in bytes (int)
- packet id (int)
- packet type (int)
- packet body (string)
- empty string (string)
The fields marked "int" above are 32-bit little endian signed integers. The fields marked "string" are ASCIIZ (null-terminated strings encoded in ASCII).
Packet Size
The packet size field is a 32-bit little endian integer, representing the length of the request in bytes. Note that the packet size field itself is not included when determining the size of the packet, so the value of this field is always 4 less than the packet's actual length. The minimum possible value for packet size is 10:
- exactly 4 bytes for the request/response ID
- exactly 4 bytes for the request/response type
- minimum 1 byte for the potentially empty packet body
- exactly 1 byte for the additional empty string at the end of every packet
Since the only one of these values that can change in length is the body, an easy way to calculate the size of a packet is to find the byte-length of the packet body, then add 10 to it.
Packet ID
The packet id field is a 32-bit little endian integer chosen by the client for each request. It may be set to any positive integer. When the server responds to the request, the response packet will have the same packet id as the original request (unless it is a failed SERVERDATA_AUTH_RESPONSE packet - see below.) If a unique packet id is assigned for each outgoing request, the packet id can be used to match incoming responses to their corresponding requests.
Packet Type
The packet type field is a 32-bit little endian integer. It will always take one of the following values:
Requests:
- SERVERDATA_AUTH = 3
- SERVERDATA_EXECCOMMAND = 2
Responses:
- SERVERDATA_AUTH_RESPONSE = 2
- SERVERDATA_RESPONSE_VALUE = 0
(Note that the repetition above is not an error - EXECCOMMAND and AUTH_RESPONSE are both 2)
The SERVERDATA_AUTH type (packet type = 3) indicates that the packet is an authentication request. This is sent from the client to the server, usually as the first packet of a new connection.
- packet body should contain the RCON password of the server you are trying to authenticate with
- The server will respond with a SERVERDATA_AUTH_RESPONSE packet.
- If the password was correct, the response's packet id will be equal to the original request's packet id.
- If the password was incorrect, the response's packet id will be -1
The SERVERDATA_EXECCOMAND type (packet type = 2) indicates that the packet is a command request. This is sent from the client to the server, instructing the server to execute a command on the console.
- packet body should contain the command to be executed (e.g. "sv_cheats 1" or "mp_switchteams")
- If the command was successfully executed, the server will respond with a SERVERDATA_RESPONSE_VALUE packet
- packet id will be equal to the original request's packet id
- packet body will be the server's response to the command - depending on the command, this may sometimes be an empty string (such as setting a cvar, changing the map, etc.)
The SERVERDATA_AUTH_RESPONSE type (packet type = 2) indicates that the packet contains information regarding the connection's authentication status. Usually, this will be in response to a SERVERDATA_AUTH packet, but may be sent in response to a SERVERDATA_EXECCOMMAND packet if the connection needs to be authenticated (such as at the beginning of a new RCON connection, or if the RCON password changes while connected.)
- packet body will always be empty
- If the packet is indicating that authentication was successful, packet id will be equal to the original auth request's ID
- If the packet is indicating that authentication failed or needs to be re-established, packet id will be equal to -1
The SERVERDATA_RESPONSE_VALUE type (packet type = 0) indicates that the packet is the response to a SERVERDATA_EXECCOMMAND packet.
- packet body will contain the server's response to the original request - depending on the command, this may sometimes be an empty string
- Note that the packet body will never be longer than 4096 characters - if the response is longer than this, it will be sent in multiple packets. Usually this isn't a problem, but when executing commands like status or cvarlist the response may be split.
- One common way to address this problem is for the client to send an empty SERVERDATA_RESPONSE_VALUE packet immediately after every SERVERDATA_EXECCOMMAND. The server will respond to the empty response packet with an empty response packet of its own, without writing anything to the log file like an empty SERVERDATA_EXECCOMMAND would. Because Source Dedicated Server always executes RCON commands in the order they are issued, receiving an empty SERVERDATA_RESPONSE_VALUE packet guarantees that you have already been sent the full response. (Special thanks to User:Koraktor for discovering this trick.)
- packet id will be equal to the original request's packet id
Packet Body
The packet body field is a null-terminated string encoded in ASCII (i.e. ASCIIZ). Depending on the packet type, it contains either the RCON password for the server, the command to be executed, or the server's response to a request. See "Packet Type" above for details.
Empty String
The end of a Source RCON Protocol packet is marked by an empty ASCIIZ string - essentially just 8 bits of 0. In languages that do not null-terminate strings automatically, you can simply write 16 bits of 0 immediately after the packet body (8 to terminate the packet body and 8 for the empty string afterwards).
Example Packets
The log below sho
For a detailed packet structure, run Wireshark (ethereal) in tandem with hlsw and follow the TCP packet stream.
Example of TCP communication authentication request with rcon password "passwrd", then subsequent rcon commands and responses for "echo HLSW: Test", "log", and "status" --TGAcid 13:22, 13 Jan 2008 (PST)
00000000 11 00 00 00 00 00 00 00 03 00 00 00 0a 61 73 73 ........ ....pass 00000010 77 72 64 00 00 wrd.. 00000000 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 ........ ...... 0000000E 0a 00 00 00 00 00 00 00 02 00 00 00 00 00 ........ ...... 00000015 19 00 00 00 00 00 00 00 02 00 00 00 65 63 68 6f ........ ....echo 00000025 20 48 4c 53 57 3a 20 54 65 73 74 00 00 HLSW: T est.. 0000001C 17 00 00 00 00 00 00 00 00 00 00 00 48 4c 53 57 ........ ....HLSW 0000002C 20 3a 20 54 65 73 74 20 0a 00 00 : Test ... 00000032 0d 00 00 00 00 00 00 00 02 00 00 00 6c 6f 67 00 ........ ....log. 00000042 00 . 00000037 4c 00 00 00 00 00 00 00 00 00 00 00 55 73 61 67 L....... ....Usag 00000047 65 3a 20 20 6c 6f 67 20 3c 20 6f 6e 20 7c 20 6f e: log < on | o 00000057 66 66 20 3e 0a 63 75 72 72 65 6e 74 6c 79 20 6c ff >.cur rently l 00000067 6f 67 67 69 6e 67 20 74 6f 3a 20 66 69 6c 65 2c ogging t o: file, 00000077 20 63 6f 6e 73 6f 6c 65 2c 20 75 64 70 0a 00 00 console , udp... 000000D6 10 00 00 00 00 00 00 00 02 00 00 00 73 74 61 74 ........ ....stat 000000E6 75 73 00 00 us.. 00000134 e4 00 00 00 00 00 00 00 00 00 00 00 68 6f 73 74 ........ ....host 00000144 6e 61 6d 65 3a 20 54 61 73 6b 66 6f 72 63 65 72 name: Ta skforcer 00000154 61 6e 67 65 72 2e 6e 65 74 20 54 46 32 20 2d 20 anger.ne t TF2 - 00000164 54 65 61 6d 77 6f 72 6b 21 0a 76 65 72 73 69 6f Teamwork !.versio 00000174 6e 20 3a 20 31 2e 30 2e 31 2e 34 2f 31 34 20 33 n : 1.0. 1.4/14 3 00000184 33 34 35 20 73 65 63 75 72 65 20 0a 75 64 70 2f 345 secu re .udp/ 00000194 69 70 20 20 3a 20 20 38 2e 32 2e 30 2e 32 38 3a ip : 8 .2.0.28: 000001A4 32 37 30 31 35 0a 6d 61 70 20 20 20 20 20 3a 20 27015.ma p : 000001B4 74 63 5f 68 79 64 72 6f 20 61 74 3a 20 30 20 78 tc_hydro at: 0 x 000001C4 2c 20 30 20 79 2c 20 30 20 7a 0a 70 6c 61 79 65 , 0 y, 0 z.playe 000001D4 72 73 20 3a 20 30 20 28 32 30 20 6d 61 78 29 0a rs : 0 ( 20 max). 000001E4 0a 23 20 75 73 65 72 69 64 20 6e 61 6d 65 20 75 .# useri d name u 000001F4 6e 69 71 75 65 69 64 20 63 6f 6e 6e 65 63 74 65 niqueid connecte 00000204 64 20 70 69 6e 67 20 6c 6f 73 73 20 73 74 61 74 d ping l oss stat 00000214 65 20 61 64 72 0a 00 00 e adr...
VB.Net Example
Coded by Tuck and veN.
Private Function RCON_Command(ByVal Command As String, ByVal ServerData As Integer) As Byte()
Dim Packet As Byte() = New Byte(CByte((13 + Command.Length))) {}
Packet(0) = Command.Length + 9 'Packet Size (Integer)
Packet(4) = 0 'Request Id (Integer)
Packet(8) = ServerData 'SERVERDATA_EXECCOMMAND / SERVERDATA_AUTH (Integer)
For X As Integer = 0 To Command.Length - 1
Packet(12 + X) = System.Text.Encoding.Default.GetBytes(Command(X))(0)
Next
Return Packet
End Function
C++ Example
Coded by ILOVEPIE.
.h file code:
#include <string>
unsigned char *RCON_Command(std::string Command, int ServerData);
.cpp file code:
unsigned char[] RCON_Command(std::string Command, int ServerData)
{
unsigned char Packet[static_cast<unsigned char>((13 + Command.length())) + 1];
Packet[0] = Command.length() + 9; //Packet Size (Integer)
Packet[4] = 0; //Request Id (Integer)
Packet[8] = ServerData; //SERVERDATA_EXECCOMMAND / SERVERDATA_AUTH (Integer)
for (int X = 0; X < Command.length(); X++)
{
Packet[12 + X] = System::Text::Encoding::Default->GetBytes(Command[X])[0];
}
return Packet;
}
Source RCON Libraries
A (hopefully comprehensive) listing of library implementations of the Source RCON protocol in various languages.
- Ruby RCon RCon library for Source and Quake RCON derivatives (such as HLDS) written in Ruby.
- PHP Rcon Class for Source.
- C++ with wxWidgets Tool including attemt to recreate a C++ Class in the platform-independent framework
- Python SRCDSpy Python Library to handle all Source Queries, including RCON
- C# Library and Sample Program
- Java Java RCON Library for Source (also HL1, COD/2, and BF2)
- Steam Condenser Java, PHP, and Ruby library
- SourceLib Yet another Python implementation of Valve Source Dedicated Server Query/RCON/Log protocols