Add configurable media-aware managed session reaping

This commit is contained in:
2026-09-15 22:58:16 +02:00
parent 05eacb3092
commit 274b85025c
14 changed files with 291 additions and 32 deletions
+14 -3
View File
@@ -181,7 +181,14 @@ owns each `TlsSession`; handlers exchange envelopes through bounded queues.
This checkpoint caps connections at 64, queued input at 32 envelopes, queued output
at 64 envelopes, and each control payload at 64 KiB (stricter than the shared framer's
16 MiB limit). Queue exhaustion disconnects slow consumers. Handshake timeout is
15 seconds; completed TLS connections have a 60-second receive-idle timeout.
15 seconds by default. Completed TLS connections use the server's media-aware reaper.
The existing `VoiceServer(directory, endpoint, allowGuests, name)` constructor remains
available. An overload accepts `VoiceServerOptions` and an optional `TimeProvider`.
Options configure server name, guest access, connection limit (default 64), handshake
timeout (15 seconds), idle timeout (45 seconds) and reaper interval (15 seconds).
Zero idle timeout disables reaping; active reaping requires a positive interval.
Invalid options fail before creating credentials, databases or sockets.
Authentication starts users in unprotected Lobby (id 1), subject to its capacity.
Success returns permissions, then a cloned snapshot; peers receive joined/updated/left
@@ -218,8 +225,12 @@ Control handlers publish immutable routing snapshots. Crypto is created within t
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.
UDP keepalives are echoed for bound endpoints. Any parsed control envelope, authenticated
voice from an active owned stream, or exact header-only keepalive from a bound endpoint
refreshes a shared monotonic activity timestamp. Invalid media does not refresh it.
The reaper sends a fatal disconnect, removes presence/routing and broadcasts one LEFT
event. Valid UDP activity keeps a TCP-idle client alive. Shutdown cancels and awaits
the accept, reaper, control and media loops before disposing credentials/storage.
`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.
+6 -2
View File
@@ -745,8 +745,12 @@ BouncyCastle crypto fallback are excluded from its zero-allocation guarantee.
Two real C++ `vccli` processes also pass join/text/bidirectional voice tests using
finite `--test-tone-ms` external capture/playback. The transport load test delivers
all 2,500 recipient packets from a sender paced at 50 pps to 50 subscribers.
Administration, protected joins, production configuration and media-aware reaping
still remain before Phase 4 completion.
**Reaper checkpoint:** configurable 45-second idle expiry / 15-second sweep replaces
the TCP-only idle timeout. Control envelopes, authenticated voice and bound-endpoint
keepalives refresh shared monotonic activity; invalid media does not. Reaping removes
presence and media routing, and can be disabled. Tests inject a clock to cover silent
clients, UDP-only activity, forged media, single departure events and disabled expiry.
Administration, protected joins and production configuration remain before Phase 4 completion.
1. `VoiceCat.Server`: accept loop, `ConnSession` protocol handling, session registry.
2. `Db` on `Microsoft.Data.Sqlite` — same schema. **Resolve the Argon2id hash-compat
+4
View File
@@ -305,6 +305,10 @@ message TextMessage {
laptop sleep) that never produce a TCP EOF are cleaned up, and peers' audio engines
`remove_stream` and stop PLC. The timeout and sweep interval are configurable via
`server::Config::reaper_timeout_ms` / `reaper_sweep_ms` (set to 0 to disable).
The managed server uses `VoiceServerOptions.IdleTimeout` / `ReaperInterval` with the
same 45-second / 15-second defaults (zero idle timeout disables reaping). It refreshes
activity on parsed control envelopes, authenticated owned-stream voice, and exact
bound-endpoint keepalives; rejected media does not refresh activity. Timing is monotonic.
- **UDP:** a separate lightweight keepalive on the media channel (voice.md §6) keeps NAT
bindings alive and detects media-path failure independently of the control channel.
- **Graceful disconnect.** A client ending its session sends `Disconnect { code = 0;
+4 -2
View File
@@ -16,8 +16,10 @@ packaging and TLS/server/client migration remain later checkpoints.
desktop packaging, and managed control/UDP server slices are implemented. Two C++
`vccli` processes authenticate, join, chat and exchange mono/stereo voice through
the managed server. The 50-subscriber fan-out core has an allocation regression test.
- **Next:** finish managed server administration, protected joins, production configuration
and media-aware reaping, then audio/client core, Windows cutover, C# AppKit and UIKit.
- **Media-aware reaping:** monotonic control/valid-UDP activity, configurable 45-second
idle timeout / 15-second sweep, and graceful shutdown are implemented and tested.
- **Next:** finish managed server administration, protected joins and production configuration,
then audio/client core, Windows cutover, C# AppKit and UIKit.
Keep the Swift ReplayKit extension and its shared ring; defer C++ removal until parity.
- See `docs/porting-to-dotnet.md` and `dotnet/README.md`.