Add encrypted managed UDP relay and native voice conformance

This commit is contained in:
2026-09-15 22:53:54 +02:00
parent 4067bab7c2
commit 05eacb3092
19 changed files with 1068 additions and 46 deletions
+32 -2
View File
@@ -188,8 +188,38 @@ Success returns permissions, then a cloned snapshot; peers receive joined/update
events. Server-authoritative text replaces supplied sender ids/timestamps, limits
bodies to 4096 UTF-8 bytes, and acknowledges valid or rejected routing. Channel text
requires membership; private text echoes to sender and recipient. Protected channel
joins and all admin/moderation handlers are pending. No UDP port or media features
are advertised; voice subscription explicitly fails until the SFU is implemented.
joins and all admin/moderation handlers are pending.
`VoiceServer.MediaEndPoint` exposes the bound UDP endpoint; UDP uses the same address
and port number as TCP, and `ServerHello.udp_port` advertises it. Successful authentication
issues a 16-byte binding token. TLS confirmation echoes an acknowledgement; a protocol-v2
bootstrap packet binds the first UDP endpoint. Tokens cannot replace an established
endpoint; reconnect to change endpoints. Invalid tokens and malformed packets are ignored.
Voice subscription, unsubscribe, stream announce/stop and stream-state signaling are
implemented. Announces require subscription and support microphone, screen audio and
auxiliary device streams, with at most 16 streams per user and labels up to 128 characters.
Stream ids are monotonically assigned per user; SSRCs are assigned server-wide.
Channel audio settings are authoritative; requested bitrate may lower the channel ceiling
(nonzero requests below 500 bps fail). User updates include the actor. Stream-state updates
use the authenticated sender id and ignore unknown stream ids.
Channel movement clears active streams; joining the current channel preserves them.
Unsubscribe clears streams. Disconnect removes routing and retires media resources,
even if no UDP traffic follows. Senders must own the SSRC and be subscribed; recipients
must be subscribed, bound, in the same channel and not deafened. Server-muted senders
cannot relay. Every voice packet is authenticated with the sender's directional key;
the SFU reseals encoded bytes for each recipient without decoding, replacing only the
sequence and ciphertext/tag. Replay rejection precedes authentication; successful
authentication advances the replay window.
The UDP loop exclusively owns media crypto, endpoint mutation and packet buffers.
Control handlers publish immutable routing snapshots. Crypto is created within the
TLS owner loop and transferred once. A coalesced notification wakes retired-key cleanup.
The synchronous fan-out core allocates zero managed bytes with platform ChaCha20-Poly1305;
socket scheduling and the allocating BouncyCastle fallback are outside that guarantee.
UDP keepalives are echoed for bound endpoints. The full media-aware reaper remains pending;
the existing 60-second TLS receive-idle timeout still applies.
`AccountStore(path)` retains the C++ schema version 2, accepts version 1 migration,
and rejects unknown revisions. Opening an existing channel table does not reseed it.