Initialized openttd-client repo
This commit is contained in:
33
docs/PROTOCOL.md
Normal file
33
docs/PROTOCOL.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Protocol Internals
|
||||
|
||||
This client supports the modern OpenTTD Game Port protocol (TCP 3979), specifically as implemented in JGRPP.
|
||||
|
||||
## X25519 PAKE Authentication
|
||||
OpenTTD 14+ and JGRPP use a Password-Authenticated Key Exchange to prevent plaintext password leakage.
|
||||
|
||||
### Key Derivation (KDF)
|
||||
We use **Blake2b** (64-byte digest) to derive two 32-byte session keys.
|
||||
- **Input:** `SharedSecret (32)` + `ServerPublicKey (32)` + `ClientPublicKey (32)` + `Password (string)`
|
||||
- **Output:**
|
||||
- `0..31`: Client-to-Server Key
|
||||
- `32..63`: Server-to-Client Key
|
||||
|
||||
### Handshake Nonces
|
||||
The server provides a 24-byte nonce in the `ServerAuthenticationRequest`. This nonce is used for the AEAD challenge during the auth response and for the initial stream encryption setup.
|
||||
|
||||
## Stream Encryption (AEAD)
|
||||
Once `ServerEnableEncryption` is received, all subsequent packets use **XChaCha20-Poly1305** (Authenticated Encryption with Associated Data).
|
||||
|
||||
### Encrypted Packet Format
|
||||
On the wire, encrypted packets have the following structure:
|
||||
1. **Length (2 bytes):** Big-endian uint16 of the *entire* remaining packet.
|
||||
2. **MAC (16 bytes):** The Poly1305 authentication tag.
|
||||
3. **Ciphertext (variable):** The encrypted payload.
|
||||
|
||||
### Decryption Logic
|
||||
The `OpenTTDProtocol` layer uses an `IncrementalAuthenticatedEncryption` state from the Monocypher library. It maintains the nonce state internally. If a MAC check fails (indicating corruption or a wrong key), the client immediately closes the connection (`SocketClosed`).
|
||||
|
||||
## Keep-Alive (Simulation Synchronization)
|
||||
OpenTTD is a lockstep simulation. The server sends `ServerFrame` packets periodically.
|
||||
- **Client Requirement:** You must respond with a `ClientAck` containing the frame number and a one-time `token` provided in the frame packet.
|
||||
- **Timeout:** If the server does not receive an ACK for several in-game days, it will disconnect the client with error code 17 (`TimeoutComputer`).
|
||||
Reference in New Issue
Block a user