Start .NET rewrite with wire and media crypto conformance
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# Porting VoiceCat to pure .NET / C#
|
||||
|
||||
**Status:** proposal / plan. Nothing here is implemented yet.
|
||||
**Status:** initial wire/crypto slice implemented under `dotnet/`; later phases remain planned.
|
||||
See `dotnet/README.md`, `docs/api-dotnet.md`, and `PROGRESS.md` for verification and next steps.
|
||||
**Target runtime:** .NET 10 LTS (in-service to Nov 2028), with .NET 11 as the follow-on.
|
||||
**Scope:** replace the C++ core (`libvoicecat`), the C++ server, the C++ `vccli`, and the
|
||||
Swift macOS/iOS clients with a single C# codebase. The Windows WinForms client is already C#
|
||||
@@ -418,7 +419,7 @@ The most mechanical part of the project. Straight `async`/`await` network code.
|
||||
| `server.cpp` — accept loop | `Socket.AcceptAsync` loop + `Task` per connection. Trivial. |
|
||||
| `conn_session.cpp` (34 K) — per-conn protocol | The bulk. A big `switch` on `Envelope.BodyCase`. Mechanical; write it against the ported xUnit tests. |
|
||||
| `session_registry.cpp` | `ConcurrentDictionary<ulong, Session>` + a channel-membership index. Simpler than the C++. |
|
||||
| `media_relay.cpp` — the SFU | ⚠️ **The one hot path on the server.** Per inbound datagram: parse 20-byte header → look up ssrc → fan out unmodified to N subscribers. Must be allocation-free: `Socket.ReceiveFromAsync(Memory<byte>, SocketAddress)` into a pooled buffer, `SendToAsync` per subscriber. Do **not** decrypt — the design already forbids it, which is what keeps this cheap. Benchmark this specifically (§11.5). |
|
||||
| `media_relay.cpp` — the SFU | **The server hot path.** Authenticate/decrypt using the sender's directional key, then reseal for each recipient with its directional key and next counter. Preserve SSRC, timestamp, flags, and encoded Opus bytes; replace sequence and ciphertext/tag. Use pooled buffers and `Socket.ReceiveFromAsync(Memory<byte>, SocketAddress)`. Never decode audio. Benchmark fan-out and allocations. |
|
||||
| `db.cpp` (26 K) — SQLite | `Microsoft.Data.Sqlite`, same schema, same file. Keep raw SQL — do not introduce EF Core; the schema is 4 tables and EF's startup cost hurts the "single binary, instant start" goal. |
|
||||
| `identity.cpp` | `CertificateRequest` + BouncyCastle Ed25519. Reads the same on-disk files. |
|
||||
| Keepalive reaper | `PeriodicTimer` — cleaner than the `asio::steady_timer`. |
|
||||
@@ -618,7 +619,10 @@ not delete anything until the C# equivalent passes the same test against it. Thi
|
||||
possible because Option A (§3.2) preserves wire compatibility — which is the main reason to
|
||||
choose it.
|
||||
|
||||
Work on a long-lived branch (`cs-port` already exists). Each phase ends with a green build,
|
||||
The rewrite lives under `dotnet/`; initial implementation branch: `dotnet/foundations`,
|
||||
created from `cs-port`. Keep the existing schema at `core/proto/voicecat.proto` during migration.
|
||||
Native packaging is deferred until the codec/audio phase rather than blocking the wire slice.
|
||||
Each phase ends with a green build,
|
||||
green tests, and an updated `PROGRESS.md` entry.
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user