fix(server): bind UDP media to the TCP port so self-host needs one forward rule
Some checks failed
Build Linux Binaries / linux/amd64 (push) Has been cancelled
Build Linux Binaries / linux/arm64 (push) Has been cancelled

media_port defaulted to 0 (OS-assigned) and --port only set the TCP bind_port,
so the UDP relay bound a random high port and advertised it to clients in HELLO.
Self-hosters forwarding only 8384/udp saw connect-OK-but-no-voice, contradicting
docs/deployment.md (control and media share one port). Media now follows
bind_port when media_port is unset; 0=OS-assigned survives when bind_port is also
0 so ephemeral-port tests are unaffected. Banner now reads TCP :8384 UDP :8384.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 12:48:13 +02:00
parent 5e18dfa1c9
commit 483f889910
3 changed files with 23 additions and 3 deletions

View File

@@ -10,6 +10,22 @@ up instantly. Newest status at the top.
## ▶ Where we left off / next action
- **Done (2026-06-22):** **UDP media now shares the TCP port (self-host port-forward fix).** Symptom: a
remote self-hosted server (`iamtalon.me:8384`, TCP+UDP 8384 forwarded) accepted TCP connections but
passed no voice. Root cause: `Config::media_port` defaulted to `0` = OS-assigned, and `main.cpp`'s
`--port` only set `bind_port` (TCP) — so the UDP relay bound a *random high port*, advertised it to
clients in HELLO (`udp_port`), and clients sent voice there. With only `8384/udp` forwarded those
packets were dropped → connect OK, no audio. This contradicted `docs/deployment.md` ("Control and media
share one port number on TCP+UDP"). **Fix (`server/src/server.cpp`):** media follows bind_port when
`media_port == 0``media_want = cfg_.media_port != 0 ? cfg_.media_port : cfg_.bind_port`. The
`0 = OS-assigned` escape hatch survives when `bind_port` is also 0, so tests that bind ephemeral ports
are unaffected (kept the logic in server.cpp rather than hardcoding 8384 as the default, which would
collide parallel tests on UDP 8384). Banner now reads `TCP :8384 UDP :8384`. Build + `ctest --preset
dev` green (24/24); live-verified banner with `--port 8390``UDP :8390`. **Action for self-hosters:**
redeploy and confirm the startup banner shows matching TCP/UDP ports; the existing single forward rule
is now correct. If voice still fails, watch the server's rate-limited `[media] dropped frames —
unmapped-endpoint=…` line (NAT source-port rewrite would be the next suspect).
- **Awaiting on-device verification (2026-06-22):** **iOS real echo cancellation / noise suppression
via native VPIO.** Root cause of "voice chat doesn't sound like a call" (echo + no NR): real iOS
AEC/NS/AGC come only from Apple's Voice-Processing I/O unit (VPIO), but the core uses miniaudio's