mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 03:24:56 +08:00
Documentation: added XRCON protocol description
This commit is contained in:
committed by
Alibek Omarov
parent
17e167432a
commit
2c0c20dfe6
181
Documentation/extensions/xrcon-protocol.md
Normal file
181
Documentation/extensions/xrcon-protocol.md
Normal file
@@ -0,0 +1,181 @@
|
||||
# XRCON Protocol Specification
|
||||
|
||||
## Overview
|
||||
|
||||
XRCON is a TCP-based remote console protocol implemented as a server within the engine. It provides an alternative to the legacy RCON (which operates over UDP as out-of-band packets). XRCON uses a framed binary protocol over a single persistent TCP connection, accepting at most one client at a time.
|
||||
|
||||
Key characteristics:
|
||||
|
||||
- Based on TCP (stream-oriented, reliable)
|
||||
- Default port is 27000
|
||||
- Maximum only one concurrent client
|
||||
- Binary framed protocol with a 12-byte header + variable-length payload
|
||||
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
The XRCON server is controlled by two configuration variables, both restricted to privileged users:
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `xrcon_enable` | `0` (disabled) | Master switch; when enabled, the server starts listening for connections |
|
||||
| `xrcon_address` | `127.0.0.1:27000` | Bind address and port; supports both IPv4 and IPv6. Changing this at runtime triggers a XRCON server restart (stop + rebind) |
|
||||
|
||||
By default, XRCON binds only to localhost (`127.0.0.1`), providing a degree of access control. The server will not start listening until explicitly enabled.
|
||||
|
||||
|
||||
|
||||
## Frame Format
|
||||
|
||||
All XRCON messages are encapsulated in a framed binary format. Each frame consists of a fixed 12-byte header followed by a variable-length payload.
|
||||
|
||||
### Header (12 bytes)
|
||||
|
||||
| Offset | Size | Field | Description |
|
||||
|---|---|---|---|
|
||||
| 0 | 4 | Type | 4-character message type string (null-terminated, occupies 5 bytes in the structure but the 5th byte is padding) |
|
||||
| 4 | 4 | Version | Protocol version (32-bit unsigned integer, network byte order) |
|
||||
| 8 | 2 | Length | Total frame length in bytes, including the header (16-bit unsigned integer, network byte order) |
|
||||
| 10 | 2 | Handle | Handle or sequence number (16-bit unsigned integer, network byte order; currently always zero) |
|
||||
|
||||
|
||||
### Protocol Version
|
||||
|
||||
The current protocol version is `0x000000D4` (212 decimal). The server also accepts `0x00D40000` for compatibility with certain third-party clients (e.g., CS2RemoteConsole).
|
||||
|
||||
### Maximum Frame Size
|
||||
|
||||
- Maximum payload per frame: 4096 bytes
|
||||
- Maximum total packet size (header + payload): approximately 4136 bytes
|
||||
- Receive buffer size: 4096 + 64 bytes
|
||||
- Transmit buffer size: 16384 bytes (4 × maximum frame size)
|
||||
|
||||
### Byte Order
|
||||
|
||||
Multi-byte integer fields (version, length, handle) are transmitted in **network byte order** (big-endian).
|
||||
|
||||
|
||||
|
||||
## Message Types
|
||||
|
||||
| Type | Direction | Description |
|
||||
|---|---|---|
|
||||
| `CMND` | Client → Server | Execute a console command |
|
||||
| `PRNT` | Server → Client | Console output / print message |
|
||||
| `CHAN` | Server → Client | Channel list (channel metadata) |
|
||||
| `AINF` | Server → Client | Application / server info |
|
||||
| `ADON` | Server → Client | Additional info / server name |
|
||||
|
||||
### CMND — Client Command
|
||||
|
||||
**Direction**: Client → Server
|
||||
|
||||
Sent by the client to execute a console command on the server.
|
||||
|
||||
| Section | Size | Description |
|
||||
|---|---|---|
|
||||
| Header | 12 bytes | Type = `"CMND"`, version, length, handle |
|
||||
| Payload | Variable | Raw command string (null-terminated) |
|
||||
|
||||
The command string is injected into the engine's command buffer for execution. There is **no authentication** — any connected client may execute arbitrary commands.
|
||||
|
||||
### PRNT — Server Print
|
||||
|
||||
**Direction**: Server → Client
|
||||
|
||||
Sent by the server to stream console output to the connected client.
|
||||
|
||||
| Section | Size | Description |
|
||||
|---|---|---|
|
||||
| Header | 12 bytes | Type = `"PRNT"`, version, length, handle |
|
||||
| Channel ID | 4 bytes | Channel identifier (unsigned 32-bit integer; always 0 for "Console") |
|
||||
| Padding | 20 bytes | Reserved (5 × 32-bit unsigned integers, all zero) |
|
||||
| Red | 1 byte | Red color component (always 255) |
|
||||
| Green | 1 byte | Green color component (always 255) |
|
||||
| Blue | 1 byte | Blue color component (always 255) |
|
||||
| Alpha | 1 byte | Alpha / opacity component (always 255) |
|
||||
| Text | Variable | The console output text (up to 4096 bytes) |
|
||||
|
||||
|
||||
### CHAN — Channel List
|
||||
|
||||
**Direction**: Server → Client
|
||||
|
||||
Sent by the server during the initial handshake (and potentially later) to describe the available console output channels.
|
||||
|
||||
| Section | Size | Description |
|
||||
|---|---|---|
|
||||
| Header | 12 bytes | Type = `"CHAN"`, version, length, handle |
|
||||
| Channel Count | 2 bytes | Number of channel records (unsigned 16-bit integer; always 1) |
|
||||
|
||||
Each channel record (58 bytes):
|
||||
|
||||
| Field | Size | Description |
|
||||
|---|---|---|
|
||||
| Channel ID | 4 bytes | Unique channel identifier (unsigned 32-bit integer; always 0) |
|
||||
| Unknown 1 | 4 bytes | Reserved (unsigned 32-bit integer; always 0) |
|
||||
| Unknown 2 | 4 bytes | Reserved (unsigned 32-bit integer; always 0) |
|
||||
| Default Verbosity | 4 bytes | Default verbosity level (unsigned 32-bit integer; always 5) |
|
||||
| Current Verbosity | 4 bytes | Current verbosity level (unsigned 32-bit integer; always 5) |
|
||||
| Red | 1 byte | Red color component for the channel (always 255) |
|
||||
| Green | 1 byte | Green color component (always 255) |
|
||||
| Blue | 1 byte | Blue color component (always 255) |
|
||||
| Alpha | 1 byte | Alpha component (always 255) |
|
||||
| Name | 34 bytes | Channel name string, null-padded (always `"Console"`) |
|
||||
|
||||
Total payload size for this frame: 2 + 58 = 60 bytes.
|
||||
|
||||
### AINF — Application Info
|
||||
|
||||
**Direction**: Server → Client
|
||||
|
||||
Sent by the server immediately after a client connects, before `ADON` and `CHAN`.
|
||||
|
||||
| Section | Size | Description |
|
||||
|---|---|---|
|
||||
| Header | 12 bytes | Type = `"AINF"`, version, length, handle |
|
||||
| Payload | 77 bytes | All zeros (placeholder / reserved for structured application information) |
|
||||
|
||||
This packet currently serves as a placeholder and contains no meaningful data. It may be extended in future versions to carry structured metadata about the server application.
|
||||
|
||||
### ADON — Additional Info
|
||||
|
||||
**Direction**: Server → Client
|
||||
|
||||
Sent by the server immediately after `AINF` during the connection handshake.
|
||||
|
||||
| Section | Size | Description |
|
||||
|---|---|---|
|
||||
| Header | 12 bytes | Type = `"ADON"`, version, length, handle |
|
||||
| Unknown | 2 bytes | Reserved (unsigned 16-bit integer; always 0) |
|
||||
| Name Length | 2 bytes | Length of the name string (unsigned 16-bit integer) |
|
||||
| Name | Variable | Server name / identifier string (e.g., `"HLDS"`) |
|
||||
|
||||
This packet carries the server application name, which is a short string identifying the server type (e.g., `"HLDS"` for Half-Life Dedicated Server).
|
||||
|
||||
|
||||
|
||||
## Security
|
||||
|
||||
XRCON has **no built-in authentication or encryption**. There is no password validation or transport-layer security. Any client that can establish a TCP connection to the XRCON port has full command execution access to the engine console.
|
||||
|
||||
The only security measures are:
|
||||
|
||||
1. **Default localhost binding**: The server binds to `127.0.0.1` by default, accepting connections only from the local machine.
|
||||
2. **Disabled by default**: The `xrcon_enable` variable defaults to `0`, so the server does not listen unless explicitly enabled.
|
||||
3. **Privileged variables**: Both configuration variables are restricted to privileged users and cannot be modified through unprivileged console commands or external access.
|
||||
|
||||
|
||||
|
||||
## Comparison with Legacy RCON
|
||||
|
||||
| Feature | XRCON | Legacy RCON |
|
||||
|---|---|---|
|
||||
| Transport | TCP (stream) | UDP (datagram, out-of-band) |
|
||||
| Port | Configurable, default 27000 | Game port (default 27015) |
|
||||
| Framing | Binary frame header | Plain text over UDP |
|
||||
| Authentication | None | Password-based |
|
||||
| Max clients | 1 | Multiple |
|
||||
| Interaction format | Full console access | Request-response only for submitted command |
|
||||
| Supported environments | Client and server | Server only |
|
||||
Reference in New Issue
Block a user