# `XGW.SRTPSession`
[🔗](https://github.com/Lazarus404/xgw/blob/main/lib/xgw/srtp_session.ex#L1)

Encrypts and decrypts media packets for one Peer after DTLS succeeds.

## SRTP vs DTLS

**DTLS** is used once (handshake) to agree on keys. Ongoing audio/video uses
**SRTP** / **SRTCP**: a compact encryption format wrapped around RTP/RTCP so
every media packet does not pay full TLS record overhead.

XGW is the DTLS **server**, so:

* **client** write keys decrypt inbound packets from the browser
* **server** write keys encrypt outbound packets to the browser

Separate `XMediaLib.Srtp` contexts are kept per `{kind, ssrc}` for `:rtp`
and `:rtcp` so each stream can advance its own replay/ROC state.

## RFCs

* RFC 3711 -- SRTP / SRTCP encrypt and decrypt
* RFC 5764 -- DTLS-exported client/server write keys and salts

# `keys`

```elixir
@type keys() ::
  {client_key :: binary(), client_salt :: binary(), server_key :: binary(),
   server_salt :: binary()}
```

DTLS-exported SRTP keying material (RFC 5764 client/server write pairs).

Ordered as `{client_key, client_salt, server_key, server_salt}`.

# `t`

```elixir
@type t() :: %XGW.SRTPSession{
  client_key: binary() | nil,
  client_salt: binary() | nil,
  decrypt_contexts: %{optional({:rtp | :rtcp, non_neg_integer()}) =&gt; term()},
  encrypt_contexts: %{optional({:rtp | :rtcp, non_neg_integer()}) =&gt; term()},
  fail_logged: MapSet.t(),
  server_key: binary() | nil,
  server_salt: binary() | nil
}
```

Per-peer SRTP session state.

# `__struct__`
*struct* 

Per-peer SRTP encrypt/decrypt state.

## Fields

* `:client_key` / `:client_salt` - client write keys (inbound decrypt)
* `:server_key` / `:server_salt` - server write keys (outbound encrypt)
* `:decrypt_contexts` - per `{kind, ssrc}` `XMediaLib.Srtp` decrypt contexts
* `:encrypt_contexts` - per `{kind, ssrc}` `XMediaLib.Srtp` encrypt contexts
* `:fail_logged` - kinds that already logged a decrypt/encrypt failure

# `decrypt`

```elixir
@spec decrypt(t(), :rtp | :rtcp, binary()) :: {:ok, term(), t()} | {:error, t()}
```

Decrypts one RTP or RTCP SRTP packet.

Returns `{:ok, plaintext, session}` on success. Failures are dropped after one
warning log per kind (`:rtp` / `:rtcp`).

# `encrypt`

```elixir
@spec encrypt(t(), :rtp, XMediaLib.Rtp.t()) :: {:ok, binary(), t()} | {:error, t()}
@spec encrypt(t(), :rtcp, XMediaLib.Rtcp.t()) :: {:ok, binary(), t()} | {:error, t()}
```

Encrypts one plaintext RTP or RTCP packet with server write keys.

Returns `{:ok, ciphertext, session}` on success.

# `new`

```elixir
@spec new(keys()) :: t()
```

Builds a session from DTLS-exported SRTP keying material.

# `outbound`

```elixir
@spec outbound(t()) :: t()
```

Encrypt-only view for the hot-path send handle (no inbound decrypt state).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
