Skip to content
tryAGIPublic

About

MIT WebRTC transport for .NET 10: bounded ICE/STUN/TURN, DTLS/SRTP, Opus/H264/VP8 and SCTP data channels. Framework-only runtime; experimental 0.x.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

tryAGI.WebRTC

WebRTC transport for .NET 10, authored from standards and licensed under MIT.

Publish NuGet License: MIT .NET 10

Build encrypted audio, video and data transports with explicit network admission, bounded resource use and a runtime that depends only on the .NET shared framework. The library owns ICE, DTLS/SRTP and SCTP channel lifetimes; your application owns signaling, media encoding/decoding and playback.

Experimental 0.x. APIs and supported negotiation profiles are evolving. Independent Pion and Chromium checks pass for the documented scope; real DId/Advantage/Simli sessions and physical Apple Watch playback are still acceptance work. This is not yet a drop-in replacement for those adapters or a security-audited general WebRTC stack. See completion gates.

Install

dotnet add package tryAGI.WebRTC --prerelease

Requires .NET 10 or later. Main builds publish 0.x development packages after all validation jobs succeed; v0.x.y tags create releases. See publication and immutable-source verification.

Start a peer

using System.Net;
using tryAGI.WebRTC;

await using var peer = new PeerConnection(new PeerConnectionOptions
{
    LocalEndPoint = new IPEndPoint(IPAddress.Loopback, 0), // Local testing.
});

string offer = peer.CreateOffer();
// Send offer through your application's authenticated signaling.
// Obtain the remote answer, then:
// peer.SetRemoteAnswer(answer);
// await peer.ConnectAsync(cancellationToken);

For a remote connection, choose a reachable local interface and an application candidate/destination policy. Signal ICE credentials and DTLS fingerprints over an authenticated channel. No public STUN/TURN server or provider endpoint is contacted by default. An answerer uses CreateAnswer(remoteOffer).

Peer lifecycle and API covers gathering/trickle, channels, encoded media, readiness, cancellation and disposal. MediaReady allows authenticated media to start before data-channel setup finishes; callers still observe Completion.

Observe packet delays

Inspect retained establishment evidence for ICE/DTLS/SCTP/DCEP timeout attribution, including after disposal.

Attach diagnostics to a live peer for correlated managed receive/decrypt/queue/send stages, bounded packet capture and .NET metrics. Collection runs in a consumer-owned publication loop, separate from audio processing. Kernel arrival and physical playback remain explicit unknowns. See diagnostics and collection example.

Zero-allocation hot paths

0 managed bytes per operation is enforced for measured, warmed SRTP/SRTCP crypto with preallocated caller buffers, selected packet/STUN operations, and empty-ciphertext GMAC/replay rejection. The exact-zero suite covers147 raw samples per platform on Linux x64/arm64, macOS arm64 and Windows x64, in JIT and NativeAOT. These are regression contracts for those operations, not an allocation-free claim for the complete WebRTC connection or native cryptography.

Scope Managed allocation boundary
Warmed authenticated crypto, selected span/STUN operations 0 B, within measured preallocated/warmed conditions
Empty-ciphertext GMAC and replay rejection 0 B, within the covered profiles/cases
Payload-bearing GCM authentication failure Nonzero framework exception cost
Asynchronous transport and owned packet/frame outputs Nonzero; outputs can outlive the next receive
Setup/rekey, cold pool misses, cancellation and optional tracing Outside the warmed zero-allocation contract

Native allocations/RSS, physical energy and end-to-end audio are separate measurements. See reproduction and limitations and allocation boundaries.

Reusing the socket receive-source address removed about 144 managed bytes per received packet in matched four-platform loopback cohorts; all 96 measured configuration medians decreased. Owned outputs still allocate. See the before/after measurements and validation limits.

An opt-in Apple crypto attribution benchmark compares the same optimized driver against unchanged framework bridge source built-Onone/-O, with checked valid/bad-tag opens and three fresh processes each. Separate timer-only and hostile-load stack controls keep host scheduling effects visible; these are diagnostics, not whole-transport zero-allocation or audio SLO claims.

Empty-ciphertext GCM (GMAC) rejection now has exact zero managed-allocation contracts: empty RTP, header-only encrypted RTCP and authentication-only SRTCP, AES-128/256, bad tags/wrong keys/replays. Payload-bearing GCM authentication failures retain their measured framework exception costs. See before/after results, timing warm-up and matched memory controls.

Warmed empty-ciphertext GCM bad-tag / wrong-key rejection Before managed bytes/failure After
JIT, Linux x64/arm64, macOS arm64, Windows x64 192–464 0
NativeAOT, same platforms 240 0

Caller buffers are preallocated. Replay rejection was already zero. The default macOS SDK retains a separate debug-symbol quality blocker. A pinned source-built compiler/debug-input experiment now passes full rooted execution and DWARF verification with zero raw diagnostics; it does not replace the installed SDK or make earlier warned benchmark builds clean. See the source-level repair and scope.

The opt-in authenticated-media stress lane also injects real bad-tag UDP bursts alongside valid audio, with a deliberate packet-loss control. Four-platform runs completed 3.6 million corrupted sends without observed corrupted plaintext admission; the macOS cohort lost valid traffic under higher bursts. That remains an open reliability issue, not a hostile-load performance guarantee. See the full measurements and limits.

Managed and NativeAOT builds now pass the same 147 exact zero-allocation samples on Linux x64/arm64, macOS arm64 and Windows x64. Separate reviewed NativeAOT ceilings protect all 40 active media/audio/channel/video configurations; owned outputs remain measured allocations. Authentication failures have explicit rejection/state contracts and bounded framework exception costs. See paired results, regression budgets and repeated native-memory controls.

Warmed SRTP/SRTCP crypto with preallocated caller buffers and selected span-based packet parsing/framing, STUN writing and STUN SHA-1/SHA-256 authentication operations have exact zero managed-allocation regression contracts. Small STUN authentication uses bounded stack storage; larger messages require warmed framework-pool reuse. This does not describe the entire asynchronous transport or owned frame outputs.

STUN authentication, small message; valid or wrong key Before managed bytes/call After
SHA-1 / SHA-256, four native platforms ~216–272 0

The expanded gate covers 147 raw zero-byte samples/platform, including writes and larger pooled-message authentication. Cold pool misses can allocate. See exact source, raw results and phase-matched memory methodology.

Authenticated RTP protect + unprotect, 1,200-byte payload AES-CM/SHA1 managed bytes/pair Linux arm64 time/pair
Before reusable block transform ~9,600 ~186 µs
After reusable block transform 0 ~27 µs

Both crypto runs use .NET 10.0.13; zero warmed crypto allocation was measured on Linux x64/arm64, macOS arm64 and Windows x64. Shared-runner timings are observations, not controlled hardware or production latency guarantees. See methodology, suites and reproduction, before artifacts and after artifacts. The opt-in workflow also measures loopback media, SCTP and video reassembly costs. A bounded send-buffer pool and default-token fast path reduced measured loopback media allocation by ~17–18% (60-byte payload) and ~29% (1,000-byte payload) for AES-256-GCM with tracing off and default caller cancellation. These process-wide measurements include harness/receive costs and remain nonzero. See the matched .NET 10.0.13 before and after artifacts on all four native platforms; this is not a production latency or memory-leak claim.

The opt-in suites also measure fresh connection/key-generation costs, complete bidirectional encoded-audio routing and bounded multi-peer retention/disposal soaks. Memory reports distinguish collectible managed peers, heap and whole-process RSS; they do not claim native leak freedom. See the lifecycle methodology.

Idle maintenance now waits on connected-state deadlines instead of polling the handshake/checklist clocks. Four-platform .NET 10.0.13 cohorts observed 43–48% fewer process-wide managed bytes/s and 73–82% less completed threadpool work for one idle audio pair without tracing. This is a scheduling proxy, not kernel wakeups or measured energy. Fresh public-only certificates retain a separately owned ephemeral key; on the CI Mac, whole-identity median fell 78.8 -> 0.67 ms. See before/after evidence and native RSS controls. These hosted-runner observations are not production performance guarantees.

Connected SCTP now stops periodic maintenance only when fully quiescent, retaining the existing cadence for pending protocol work. Matched four-platform cohorts with one open data-channel pair, AES-256-GCM and tracing off observed 76–79% fewer process managed bytes/s and 83–86% less completed threadpool work. Measurements, memory controls and limits include three fresh processes per platform. Reviewed allocation ceilings use two training processes plus an independent holdout; exact-zero crypto/parser guards use raw total bytes and a real injected-allocation control. These gates do not assert whole-transport zero allocation, native leak freedom or physical energy.

Allocation gates also cover 40 active media/audio/data-channel/video configurations per platform. Two runtime-equivalent process captures train fixed ceilings; a fresh four-platform holdout passed without changing limits. These contracts include owned async/frame outputs and remain nonzero. See active budget scope and fresh proof.

Supported scope

Area Implemented and tested Current limits
ICE / STUN UDP checks, nomination, consent, trickle, same-socket mappings, bounded URI/DNS gathering Explicit local interface; no mDNS/SRV, remote candidate DNS or ICE restart
TURN Owned relay allocations over UDP, TCP or TLS; authentication, renewal, permissions, relay-only policy Bounded documented profiles; not proof of every NAT topology
DTLS / SRTP Fingerprint-authenticated DTLS 1.2, directional SRTP/SRTCP, replay and key-use bounds Explicit cipher/handshake subset; trusted signaling required
Audio Negotiated Opus RTP transport, source/clock metadata, bounded receive queues Encoded packets; application owns codec, pacing, jitter policy and playback
Video Explicit H264/VP8 capabilities, bounded frame reassembly, RTCP reports and negotiated PLI Application owns codec/packetization; no general codec or SDP renegotiation
Data channels SCTP/DCEP, ordered/unordered reliable or partial delivery, fragmentation, reset/closure Documented negotiation/resource limits apply
Compatibility Independent local Pion and Chromium; actual decoded Opus/video and protected loss recovery Consumer/provider/device E2E remains
NativeAOT Whole-library rooting, publish and executed smoke lane Linux x64 CI evidence; other native targets need their own acceptance

See the scope documents for ICE, server URIs, TURN, DTLS, SRTP, SDP, data channels, video and RTCP.

Validate locally

dotnet build WebRTC.slnx -c Release
dotnet run --project src/tests/WebRTC.ProtocolTests -c Release --no-build
dotnet run --project src/tests/WebRTC.IntegrationTests -c Release --no-build
python3 -m unittest discover -s scripts -p 'test_*.py'

Console runners exit nonzero on failure and need no test-framework package. Tests use local peers and synthetic inputs without provider keys.

Independent Pion peer — local ICE/DTLS/SRTP/SCTP/DCEP and relay checks:

docker build -f tests/interop/Pion/Dockerfile -t tryagi-webrtc-interop .
docker run --rm tryagi-webrtc-interop

Chromium — offer/answer and both DTLS roles, data-channel policies/reset, two-way decoded Opus, RTP pacing, protected packet loss/recovery and H264/VP8 rendering:

./tests/interop/Chromium/run.sh

See browser evidence and tooling. Docker is required; these checks run in an isolated network with disposable browser profiles.

NativeAOT, on a Linux x64 host with the .NET native toolchain:

dotnet publish src/tests/WebRTC.AotSmoke -c Release -r linux-x64 -p:PublishAot=true -o artifacts/aot
./artifacts/aot/WebRTC.AotSmoke

A build alone is not execution evidence. Targeted runner filters are useful for local diagnosis; passing a subset does not replace the full validation suite.

Security and provenance

Runtime source is newly authored against the standards in architecture. No SIPSorcery or Pion implementation has been imported into the runtime. Build and independent test tooling have separate licenses and dependency graphs; see source provenance and build tooling. MIT licensing does not establish security.

Read SECURITY.md for trust boundaries and private vulnerability reporting. Strong naming provides assembly identity, not publisher authentication.

Contribute

See CONTRIBUTING.md, code of conduct and changelog. Focused fixes, resource-bound regressions and independent interoperability reports are welcome.

License

MIT — tryAGI and contributors. Separately licensed test/build tooling retains its original notices.

About

MIT WebRTC transport for .NET 10: bounded ICE/STUN/TURN, DTLS/SRTP, Opus/H264/VP8 and SCTP data channels. Framework-only runtime; experimental 0.x.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages