# rtsp-runtime
Sans-IO **RTSP 1.0** ([RFC 2326](https://www.rfc-editor.org/rfc/rfc2326)) session
engine — a driveable client **and** server, the piece the Rust ecosystem leaves
out.
Message parse/serialize is delegated to the mature [`rtsp-types`] and
[`sdp-types`] codecs, and authentication (Basic/Digest/Bearer) to the shared
[`broadcast-auth`](../broadcast-auth) crate (which itself wraps [`http-auth`]
for Basic/Digest) — extracted so RTSP and HTTP clients (e.g. `multimux`'s
HTTP input adapters) share one auth implementation instead of duplicating
it. What lives here is the part nothing else provides:
- **Session state machines** — [`ClientSession`] and [`ServerSession`], per
RFC 2326 Appendix A (`Init → Ready → Playing/Recording`), with
illegal-method-in-state rejection (the client returns `Err`; the server
returns `455 Method Not Valid In This State`).
- **CSeq correlation** — outbound requests carry an incrementing `CSeq`;
inbound responses are matched back to the pending request.
- **`Transport` negotiation** — a typed, round-trippable `Transport` header
(§12.39): UDP unicast/multicast and TCP-interleaved.
- **Interleaved RTP/RTCP framing** — `InterleavedFrame` and a streaming
demultiplexer for the `$`-channel muxing of §10.12 (complete frames + partial
tail).
- **Auth** — Basic + Digest (RFC 7617 / 7616), plus Bearer (RFC 6750),
wired into request signing via `broadcast-auth`, including transparent
`401` retry and `stale=true` nonce refresh, for the authenticated RTSP
that IP cameras require.
All **sans-IO**: feed inbound bytes, get outbound bytes and typed events back —
no sockets in the core. Drive `ClientSession` with the request builders and
`handle_data`; drive `ServerSession` with `handle_request`.
- **Async socket adapter** (feature `tokio`) — `AsyncRtspClient` /
`AsyncRtspServer` are `tokio_util::codec::Framed` adapters over the sans-IO
engine: the codec reassembles fragmented reads (one deadline per whole frame,
64 KiB header / 2 MiB message caps), and Digest `401` challenges are answered
transparently. Every awaited IO is bounded by `RtspTimeouts` (connect /
handshake / read_idle / write), and `recv_interleaved` sends the
`GET_PARAMETER` keepalive at half the `Session` timeout. Both are generic over
the stream type, so the same driver logic runs over plain TCP and TLS.
- **`rtsps://` over TLS** (feature `tls`) — the adapter wraps the stream in a
`tokio-rustls` session before the RTSP exchange (`AsyncRtspClient::connect_tls`
/ `AsyncRtspServer::accept_tls`), for `rtsps://` on default port **322**. The
client trusts the `webpki-roots` bundle by default, or a custom
`rustls::ClientConfig` for a self-signed camera cert.
[`ClientSession`]: https://docs.rs/rtsp-runtime/latest/rtsp_runtime/client/struct.ClientSession.html
[`ServerSession`]: https://docs.rs/rtsp-runtime/latest/rtsp_runtime/server/struct.ServerSession.html
```toml
[dependencies]
rtsp-runtime = "0.7" # sans-IO core
rtsp-runtime = { version = "0.7", features = ["tokio"] } # + real sockets
rtsp-runtime = { version = "0.7", features = ["tls"] } # + rtsps:// (TLS)
```
## Status
The sans-IO core — client + server state machines, `Transport` negotiation,
interleaved framing, and Basic/Digest auth — is implemented and tested against
the RFC 2326 fixtures (see [issue #521](https://github.com/fishloa/rust-broadcast/issues/521)).
The `tokio` socket adapter (and `tls` for `rtsps://`) is implemented on top of
the same core, with real-loopback integration tests covering a full
OPTIONS→DESCRIBE→SETUP→PLAY→TEARDOWN session, fragmented interleaved media,
transparent Digest auth, and an end-to-end TLS handshake with a self-signed
cert.
## License
MIT OR Apache-2.0.
[`rtsp-types`]: https://crates.io/crates/rtsp-types
[`sdp-types`]: https://crates.io/crates/sdp-types
[`http-auth`]: https://crates.io/crates/http-auth
## Header parsing and `rtsp-types` gaps
`Transport` (RFC 2326 §12.39) and `Session` (§12.37) are parsed and serialized by this crate
(`transport`, `session_header`, one shared RFC 2326 §15.1 lexer), not by `rtsp-types` 0.1.3,
which is exact-case, does not trim whitespace, drops case-variant parameters and rejects a
quoted `ssrc` / malformed `timeout`. The probe table, for a future upstream issue, is in
[`docs/transport-header.md`](docs/transport-header.md#rtsp-types-gaps-rtsp-types-013-material-for-an-upstream-issue).