# `XGW.Stun.TCP`
[🔗](https://github.com/Lazarus404/xgw/blob/main/lib/xgw/stun/tcp.ex#L1)

Frames STUN messages for transport over TCP (RFC 8489).

## Why TCP framing exists

On UDP, each datagram is already one STUN message. On TCP, bytes stream
without message boundaries, so each STUN PDU is prefixed with a 16-bit
big-endian length. ICE-TCP (RFC 6544) uses this framing when UDP is blocked
and peers fall back to TCP candidates.

Helpers: `frame/1` for encode, `recv/2` / `send/2` for socket I/O.

## RFCs

* RFC 8489 -- STUN-over-TCP framing (16-bit length prefix)
* RFC 6544 -- ICE-TCP usage of that framing

# `frame`

```elixir
@spec frame(binary()) :: binary()
```

Prefixes a STUN wire with its 16-bit big-endian length.

## Examples

    iex> XGW.Stun.TCP.frame(<<1, 2, 3>>)
    <<0, 3, 1, 2, 3>>

# `recv`

```elixir
@spec recv(:gen_tcp.socket(), timeout()) :: {:ok, binary()} | {:error, term()}
```

Reads one framed STUN message from `sock`. Returns `{:ok, wire}` or `{:error, reason}`.

# `send`

```elixir
@spec send(:gen_tcp.socket(), binary()) :: :ok | {:error, term()}
```

Sends one framed STUN message on `sock`.

---

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