SIP signaling and RTP transport for WaveKat voice pipelines, on a from-scratch SIP engine (no external SIP stack). Same pattern as wavekat-vad and wavekat-turn.
[!WARNING] Early development. API will change between minor versions.
What this crate is
A small, focused SIP/RTP toolkit for building softphones, voice bots, and recording bridges in Rust. It owns the wire-level concerns —
- SIP signaling: REGISTER (digest auth + keepalive), outbound and inbound
calls (
Caller/IncomingCall), in-dialog hold/resume, DTMF (RFC 4733 + INFO fallback), and RFC 4028 session timers. - SDP: offer/answer for Opus (preferred, with in-band FEC) and G.711 (PCMU + PCMA) fallback; answers and mid-call re-offers pin the negotiated codec. Negotiation only — encode/decode stays with the consumer.
- RTP: header parser, a debug-friendly receive loop, and a codec-agnostic send loop.
— and stays out of the audio device, codec, and call-orchestration layers so it remains light and embeddable.
Quick Start
Register an account against your SIP server:
use CancellationToken;
use ;
# async
Place an outbound call and hang up:
use Arc;
use ;
# async #
Answer inbound calls from the endpoint's incoming stream:
# use Arc;
# use SipEndpoint;
# async #
TLS
SIP over TLS (Transport::Tls, RFC 3261 §26.2) is behind the tls
feature, off by default:
Set transport: Transport::Tls on the account. Unless an explicit
port is set, the account resolves against port 5061 and, when a
server isn't an IP literal, locates it via _sips._tcp SRV records
(RFC 3263 §4.1) rather than _sip._tcp. Certificate verification checks
the account's domain — never the host an SRV lookup happened to
return — per RFC 5922 §7.3; verifying the resolved target instead would
let whoever answers the DNS query pick which name the certificate has
to match.
tls_policy selects how a server certificate is trusted. There are
exactly two variants, and deliberately no third one that skips
verification:
TlsPolicy::SystemRoots(the default) — validate against the operating system's trust store.TlsPolicy::Pinned { sha256 }— trust exactly one certificate, by the SHA-256 of its DER encoding. This is the variant for the legitimate case people usually want a bypass for: a self-signed certificate on an on-premise server. It stays narrow on purpose — it trusts one certificate, not every certificate a peer might present.
There is no Insecure or skip_verify option, and there will not be
one. It is the setting people reach for to make a certificate error
message go away, and once it's on, the connection has all the ceremony
of TLS and none of the security, permanently, with nothing on screen
saying so. A rejected certificate always drops the connection; the way
back in is Pinned, made with the actual fingerprint in hand — not a
flag that silences the check.
A failed connection carries an UntrustedCertificate (fingerprint +
typed CertFailure reason) that untrusted_certificate can pull out
of the returned error, so your own UI can offer to pin what it just
saw:
use CancellationToken;
use ;
# async
Status
| Module | State |
|---|---|
account |
Stable — runtime SIP account type. |
endpoint |
Working — shared SIP endpoint + transport + routing. |
registrar |
Working — REGISTER + auth + keepalive + unregister. |
resolve |
Working — RFC 3263 (subset) SRV + A/AAAA fallback. |
caller |
Working — outbound dial, hold/resume, DTMF, hangup. |
callee |
Working — inbound INVITE accept/reject. |
sdp |
Working — Opus + G.711 offer/answer (negotiation only). |
rtp |
Working — header parser, receive loop, send loop. |
tls_error |
Working — typed CertFailure / UntrustedCertificate reporting for TLS. |
Architecture
PSTN / SIP trunk
│
▼
wavekat-sip (in-house transport, transactions, dialogs)
│
├─ account ──── credentials + endpoint config
├─ endpoint ─── UDP transport + transaction/dialog engine + routing
├─ registrar ── REGISTER / digest auth / keepalive
├─ caller ───── outbound INVITE / hold / DTMF / hangup
├─ callee ───── inbound INVITE accept / reject
├─ sdp ──────── offer/answer for telephony codecs
└─ rtp ──────── RTP header parse / receive / send
│
▼
your app ──► audio device I/O, codec, recording, AI pipeline
About WaveKat
wavekat-sip is part of WaveKat, an open-source ecosystem of Rust crates for building real-time voice pipelines. It handles SIP signaling and RTP transport, alongside sibling crates for voice activity detection, turn detection, speech-to-text, and text-to-speech.
See wavekat.com for the full project.
Stars
License
Licensed under Apache 2.0.
Copyright 2026 WaveKat.
Acknowledgements
rsip— SIP message types.