support regex and player name sniff

This commit is contained in:
iceBear67
2026-07-15 21:26:50 +08:00
parent 3a5ad7e318
commit ada07e0e36
11 changed files with 250 additions and 49 deletions
+12 -5
View File
@@ -51,7 +51,7 @@ Client Hub
│─ Frame#1 [magic=0x01, rand, ts] ──────▶ check |now-ts| ≤ window
│ (both switch to Phase-B keys = ChaCha20(SHA3-256(rand‖ts ‖ dir)))
│◀──────────── Frame [SessionReady] ─────│
│─ Register("mc.example.com") ──────────▶ patterns["mc.example.com"] = session
│─ Register("mc\.example\.com") ────────▶ patterns["mc\.example\.com"] = (regex, session)
│◀──────────── RegisterAck ──────────────│
│ ... periodic Ping/Pong ... │
```
@@ -64,10 +64,10 @@ share a keystream beyond that first frame.
```
Player Hub Client Destination
│─ Handshake(addr="mc.example.com", Intent=2)─▶ normalize+match
│─ Handshake(addr="mc.example.com", Intent=2)─▶ normalize + regex-match
│ (+ maybe pipelined Login Start) │ pause player socket,
│ │ buffer bytes, mint CID
│ │─ ControlRequest(CID, pattern, ip:port) ─▶
│ │─ ControlRequest(CID, pattern, ip:port, user) ─▶
│ │ allocate worker+stream
│ │◀──────── SYN(streamId, CID) ────────────│
│ │ takePending(CID) → bind dial destination,
@@ -81,6 +81,12 @@ Player Hub Client Destinatio
Key points:
* **Patterns are regexes.** Each registered pattern is a case-insensitive
regular expression, matched against the *whole* normalized hostname (anchored,
first match wins). The hub echoes the **matched pattern string** — not the
player's hostname — in `ControlRequest`, so the client can look it straight up
in its own route table. Invalid patterns are rejected at registration with a
non-zero `RegisterAck` status.
* The hub **pauses** the player socket the instant it matches, so no player
bytes are lost while the takeover is arranged; the buffered handshake is
forwarded **verbatim**, so the real server sees exactly what the player sent
@@ -187,8 +193,9 @@ trade for a near-zero-overhead mux.
2. No per-stream flow control (see §6).
3. Single-event-loop hub (see §5) bounds throughput to one core.
4. `Intent 18` is reserved but only stubbed (the hub logs and closes).
5. Pattern ownership is last-writer-wins; two clients registering the same
hostname will silently reassign it.
5. Pattern ownership is last-writer-wins; two clients registering the identical
pattern string will silently reassign it. Overlapping-but-distinct regexes are
both kept, and when several match one hostname the winner is unspecified.
These are deliberate scope choices for a connectivity-focused P2P tool, not
oversights; each is a small, well-isolated change away from being hardened.