TSDNS: verified fully implemented in chanora_resolver (port 41144, magic bytes, TCP query). File transfer: verified fully implemented for avatars/icons (ftinitdownload, TCP data, cacache). p256 PR draft reviewed and corrected (function path, probability figure).
88 lines
2.5 KiB
Markdown
88 lines
2.5 KiB
Markdown
# TSDNS Protocol Design
|
|
|
|
**Date:** 2026-06-11
|
|
**Status:** Implemented
|
|
**Location:** `crates/chanora_resolver/src/lib.rs`
|
|
|
|
## Overview
|
|
|
|
TSDNS (TeamSpeak DNS) is a lightweight DNS-like protocol for resolving TeamSpeak server addresses. It operates over TCP port 41144 and provides a simple query-response mechanism.
|
|
|
|
## Protocol Specification
|
|
|
|
### Query Format
|
|
|
|
1. Convert input to lowercase
|
|
2. Encode as UTF-8/CESU-8
|
|
3. Append magic bytes: `0x0A 0x0D 0x0D 0x0D 0x0A`
|
|
4. Send via TCP to port 41144
|
|
|
|
### Response Format
|
|
|
|
- **Success:** IP address or hostname (optionally with port)
|
|
- **Not found:** Literal string `404`
|
|
- **Port placeholder:** `$PORT` means "use the port from the user's input"
|
|
|
|
### Example
|
|
|
|
```
|
|
Query: "voice.example.com\n\r\r\r\n"
|
|
Response: "185.250.249.77:9987"
|
|
```
|
|
|
|
## Implementation Details
|
|
|
|
### Constants
|
|
|
|
```rust
|
|
const TSDNS_PORT: u16 = 41144;
|
|
const TSDNS_TERMINATOR: &[u8] = b"\n\r\r\r\n";
|
|
const TSDNS_TIMEOUT: Duration = Duration::from_secs(3);
|
|
```
|
|
|
|
### Resolution Flow
|
|
|
|
1. **TSDNS SRV lookup** (`_tsdns._tcp.DOMAIN`) - checks for SRV records first
|
|
2. **TSDNS TCP fallback** - direct connection to port 41144
|
|
3. **Candidate hosts** - tries parent domain then full domain (e.g., `teamspeak.com` then `voice.teamspeak.com`)
|
|
|
|
### Code Location
|
|
|
|
- `query_tsdns_socket()` (lines 529-563) - core protocol implementation
|
|
- `resolve_tsdns_tcp_candidates()` (lines 454-476) - TCP fallback resolution
|
|
- `resolve_tsdns_srv_candidates()` (lines 414-433) - SRV-based resolution
|
|
- `tsdns_candidate_hosts()` (lines 977-997) - generates candidate hostnames
|
|
|
|
### Features Implemented
|
|
|
|
- [x] TCP port 41144 communication
|
|
- [x] Lowercase domain normalization
|
|
- [x] Magic bytes terminator (`0x0A 0x0D 0x0D 0x0D 0x0A`)
|
|
- [x] TSDNS SRV record support (`_tsdns._tcp.DOMAIN`)
|
|
- [x] TCP fallback when no SRV records
|
|
- [x] `$PORT` placeholder support
|
|
- [x] 3-second timeout per connection
|
|
- [x] `404` not-found handling
|
|
- [x] IPv4 and IPv6 address support
|
|
- [x] Port parsing from response
|
|
|
|
## DNS Resolution Order (per spec)
|
|
|
|
1. **SRV TS3:** `_ts3._udp.INPUT` — port overrides user input
|
|
2. **SRV TSDNS:** `_tsdns._tcp.DOMAIN`
|
|
3. **TSDNS:** Port 41144
|
|
4. **DNS:** AAAA, A records (CNAME implicit)
|
|
|
|
First complete resolution wins. No fallback on connection failure.
|
|
|
|
## Testing
|
|
|
|
Unit tests in `crates/chanora_resolver/src/lib.rs`:
|
|
- `tsdns_candidates_include_parent_then_full_host` (line 1384)
|
|
- `tsdns_endpoint_preserves_srv_method_metadata` (line 1252)
|
|
|
|
## References
|
|
|
|
- YaTQA Reference §8.4: TSDNS protocol details
|
|
- YaTQA Reference §8.5: DNS resolution order
|