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

@@ -69,8 +69,12 @@ int Server::run() {
// ── UDP media relay (M2) ─────────────────────────────────────────────────
auto media_relay = std::make_shared<MediaRelay>(io, registry);
if (!media_relay->bind(cfg_.media_port)) {
std::fprintf(stderr, "[server] failed to bind UDP media port %u\n", cfg_.media_port);
// Control and media share one port number on TCP+UDP (docs/deployment.md): when media_port
// is left at 0, follow bind_port so a single forward rule covers both. If bind_port is also 0
// (tests), this stays 0 and the OS picks the UDP port (reported via on_media_ready).
uint16_t media_want = cfg_.media_port != 0 ? cfg_.media_port : cfg_.bind_port;
if (!media_relay->bind(media_want)) {
std::fprintf(stderr, "[server] failed to bind UDP media port %u\n", media_want);
return 1;
}
media_relay->start();

View File

@@ -18,7 +18,7 @@ struct Config {
std::string server_name = "VoiceCat Server";
std::string data_dir = "voicecat-data";
uint16_t bind_port = 8384; // 0 = let OS pick (useful for tests)
uint16_t media_port = 0; // M2 UDP media port; 0 = OS-assigned
uint16_t media_port = 0; // M2 UDP media; 0 = follow bind_port (or OS-pick if that's 0)
bool allow_guests = true;
// Called with the actual bound TCP port once the acceptor is ready.
std::function<void(uint16_t)> on_ready;