# ReSpeak Project Knowledge Base > **Source**: https://github.com/ReSpeak/tsclientlib > **Last synced**: 2026-06-13 > **License**: MIT OR Apache-2.0 ## Overview ReSpeak is an open-source project that provides a Rust implementation of the **TeamSpeak 3 protocol**. The primary goal is to enable building TeamSpeak clients and bots in Rust. The project is **not** an official TeamSpeak product — it was created for fun and to gain features/bugfixes not available in the official client. The organization maintains a single monorepo (`ReSpeak/tsclientlib`) containing multiple crates that layer from low-level protocol handling up to a high-level client library. **Key principle**: ReSpeak does **not** publish server-side code. They earn revenue by selling servers and ReSpeak respects that business model. ## Repository Map | Crate | Path | Purpose | Version | |-------|------|---------|---------| | `tsclientlib` | `tsclientlib/` | High-level client/bot library | 0.2.0 | | `tsproto` | `tsproto/` | Low-level TeamSpeak 3 protocol implementation | 0.2.0 | | `ts-bookkeeping` | `utils/ts-bookkeeping/` | Server state tracking (clients, channels) | 0.1.x | | `tsproto-packets` | `utils/tsproto-packets/` | Packet and command parsing/serialization | 0.1.x | | `tsproto-types` | `utils/tsproto-types/` | Core types, enums, crypto primitives | 0.1.x | | `tsproto-structs` | `utils/tsproto-structs/` | Generated structs from tsdeclarations | 0.1.x | **External dependency**: [tsdeclarations](https://github.com/ReSpeak/tsdeclarations) — machine-readable TeamSpeak protocol declarations (embedded as git submodule). ## tsclientlib ### Architecture `tsclientlib` is the **top-level crate** — the one consumers use. It provides: - `Connection` struct: manages a single connection to a TeamSpeak server - Async API built on `tokio` + `futures` - DNS SRV resolution for server discovery (`resolver.rs`) - Audio handling via `audiopus` (Opus codec) behind the `audio` feature flag - Sync wrapper (`sync.rs`) for non-async contexts - Prelude module for convenient imports ### Features | Feature | Default | Description | |---------|---------|-------------| | `audio` | yes | Opus encode/decode, `AudioHandler` for jitter buffer + mixing | | `unstable` | no | Expose internal protocol API (may break on minor releases) | | `default-tls` | yes | reqwest with default TLS for HTTP/HTTPS | | `bundled` | no | Bundle SDL2 | | `static-link` | no | Statically link SDL2 | | `audiopus-unstable` | no | Extended audiopus API from Flakebi's fork | ### Key Dependencies - `tsproto` — protocol layer - `ts-bookkeeping` — state management - `tsproto-packets` — packet parsing - `tsproto-types` — types + crypto - `tokio` — async runtime - `hickory-proto` / `hickory-resolver` — DNS resolution - `reqwest` — HTTP client - `audiopus` — Opus codec (optional) ### Source Files | File | Purpose | |------|---------| | `lib.rs` | Core types, re-exports, `Connection` entry point | | `audio.rs` | Audio subsystem — Opus encode/decode, `AudioHandler` | | `resolver.rs` | DNS SRV resolution for TeamSpeak servers | | `sync.rs` | Synchronous wrapper API | | `prelude.rs` | Convenience re-exports | | `tests.rs` | Integration tests | ### Examples - `simple.rs` — minimal async client - `simple-sync.rs` — minimal sync client - `audio.rs` — audio streaming client - `audio-latency.rs` — latency measurement - `channeltree.rs` — channel navigation - `many.rs` / `sync.rs` — stress tests ## tsproto ### Architecture `tsproto` implements the **low-level TeamSpeak 3 protocol**: - Connection establishment and handshake - UDP packet delivery with reliability (resend logic) - Packet encryption and compression - Command parsing ### Source Files | File | Purpose | |------|---------| | `algorithms.rs` | Packet splitting, encryption/decryption, compression, hash cash | | `client.rs` | Client-side connection logic | | `connection.rs` | Connection state machine, packet queuing | | `packet_codec.rs` | Packet encoding/decoding codec | | `resend.rs` | Reliable packet delivery with retransmission | | `license.rs` | License system implementation | | `log.rs` | Logging utilities | | `utils.rs` | Helper functions | ### Protocol Details #### Packet Types | Type | Description | |------|-------------| | `Command` | High-priority commands | | `CommandLow` | Low-priority commands | | `Voice` | Voice data | | `VoiceWhisper` | Whisper voice data | | `Ack` / `AckLow` | Acknowledgments | | `Ping` / `Pong` | Keepalive | | `Init` | Connection initialization | #### Packet Limits - **Max UDP packet size**: 1500 bytes (ethernet MTU) - **Max command packet size**: 500 bytes (including header) - **Max fragments length**: 40960 bytes - **Max decompressed size**: 2 MiB (for large servers with 2000+ channels) - **Max out-of-order queue**: 200 packets #### Compression - Uses **QuickLZ** level 1 for command packets - Compression only applied if result is smaller than original - Fragmentation occurs when compressed data exceeds 500 bytes ### Cryptography #### Key Types | Type | Curve | Usage | |------|-------|-------| | `EccKeyPubP256` | P-256 (secp256r1) | Public identity key | | `EccKeyPrivP256` | P-256 | Private identity key | | `EccKeyPubEd25519` | Ed25519 | Public ephemeral key (handshake) | | `EccKeyPrivEd25519` | Ed25519 | Private ephemeral key (handshake) | #### Encryption Algorithm 1. **Key derivation**: `SHA-256(packet_type || generation_id || shared_iv)` → 16-byte key + 16-byte nonce 2. **Cipher**: AES-128 in EAX mode with 8-byte MAC 3. **Key caching**: Derived keys are cached per generation to avoid recomputation 4. **Packet ID mixing**: `key[0] ^= (packet_id >> 8)`, `key[1] ^= (packet_id & 0xff)` #### Shared IV Computation (`compute_iv_mac`) 1. ECDH shared secret via Ed25519 2. `shared_iv = SHA-512(shared_secret)` 3. XOR with `alpha` (10 bytes) and `beta` (54 bytes) from handshake 4. `shared_mac = SHA-1(shared_iv)[..8]` #### Hash Cash (Identity Proof-of-Work) - Identity level = number of leading zero bits in `SHA-1(public_key_string || counter)` - `upgrade_level(target)` iterates counter until desired level is reached - Default target level: 8 #### Identity Format ``` Format: counter || 'V' || base64(private_key) Example: "2792354VMG8DAgeAAgEgAiEA..." ``` #### Fake Encryption - Used for unencrypted packet types (voice, ack, ping, etc.) - Fixed key: `c:\windows\syste` (16 bytes) - Fixed nonce: `m\firewall32.cpl` (16 bytes) ## ts-bookkeeping Tracks the **server state** by processing incoming commands: - Maintains client list, channel tree, server info - Generates events from state changes - Provides methods to create outgoing command packets - Main struct: `data::Connection` ## tsproto-packets Handles **packet serialization/deserialization**: - `packets.rs` — packet structures (`InPacket`, `OutPacket`, `OutAck`, etc.) - `commands.rs` — TeamSpeak command parsing - Header constants: `C2S_HEADER_LEN`, `S2C_HEADER_LEN` ## tsproto-types Core **types and primitives**: - `crypto.rs` — ECC key types (P-256, Ed25519), ECDH, signatures, identity obfuscation - `versions.rs` — TeamSpeak version strings - `errors.rs` — Protocol error codes ### Key Crypto Functions | Function | Description | |----------|-------------| | `EccKeyPrivP256::create()` | Generate new P-256 keypair | | `EccKeyPrivP256::import_str()` | Import from base64/tomcrypt/obfuscated formats | | `EccKeyPrivP256::create_shared_secret()` | ECDH with P-256 | | `EccKeyPrivP256::sign()` | ECDSA signature | | `EccKeyPubP256::verify()` | ECDSA verification | | `EccKeyPubP256::get_uid()` | `base64(SHA-1(ts_encoded_key))` | | `encode_password()` | `base64(SHA-1(password))` | | `EccKeyPrivEd25519::create_shared_secret()` | ECDH with Ed25519 | ### Identity Obfuscation TeamSpeak stores identities XOR'd with a static 128-byte pattern + SHA-1 hash of trailing data. ReSpeak implements both obfuscation and deobfuscation. ## How Chanora Uses ReSpeak Chanora depends on **four crates** from the ReSpeak monorepo, all pinned to revision `04aa2491`: ### Dependency Chain ``` chanora_protocol/ ├── tsclientlib (rev 04aa2491, features=["audio"]) ├── tsproto-packets (rev 04aa2491) ├── tsproto-types (rev 04aa2491) └── ts-bookkeeping (rev 04aa2491) chanora_audio/ └── tsclientlib (rev 04aa2491, features=["audio"]) ``` ### Architectural Constraint (SAD-067 / SysDes-011 / SysDes-029) Chanora's `chanora_protocol` crate acts as an **isolation boundary**: > No tsclientlib types may cross out of this crate. This prevents ReSpeak API changes from cascading through Chanora's codebase. ### Patched Fork Chanora patches `tsproto-types` to fix **P-256 short coordinate padding**: ```toml [patch."https://github.com/ReSpeak/tsclientlib.git"] tsproto-types = { git = "https://github.com/EdisonJwa/tsclientlib.git", branch = "fix/p256-short-coordinate-pad" } ``` This handles cases where P-256 coordinates are shorter than 32 bytes and need left-padding. ### Key Usage Points 1. **Protocol connection**: `tsclientlib::Connection` for TeamSpeak server connections 2. **Audio handling**: `AudioHandler` from tsclientlib for decode, jitter buffer, mixing 3. **Packet types**: `tsproto-packets` for `OutAudio`, `InAudioBuf`, `AudioData`, `CodecType`, `Direction` 4. **State tracking**: `ts-bookkeeping` for server state management ## External References - **Qint** (https://github.com/ReSpeak/Qint) — Cross-platform TeamSpeak client built on tsclientlib (not yet ready) - **SimpleBot** (https://github.com/ReSpeak/SimpleBot) — Example chat bot - **tsdeclarations** (https://github.com/ReSpeak/tsdeclarations) — Machine-readable protocol declarations - **TSIdentityTool** (https://github.com/landave/TSIdentityTool) — Identity deobfuscation reference (MIT) ## Performance Benchmarks From i7-5280K @ 3.6 GHz (single-threaded): | Operation | Time | Throughput | |-----------|------|------------| | Connection creation | 199 ms | 6.5 conn/sec | | Message send | 189 µs | 5300 msg/sec | Bottleneck: RSA puzzle solving at connection time. Use `--features rug` for efficient big integer implementation.