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

Accepts ICE-TCP connections and delivers framed STUN to `XGW.Listener`.

## ICE-TCP in brief

Some networks block UDP entirely. WebRTC can then try **TCP candidates**
(RFC 6544). The Listener optionally opens a passive TCP listen socket; this
module accepts connections and reads length-prefixed STUN frames
(`XGW.Stun.TCP`), notifying the Listener with:

* `{:xgw_internal, :tcp_accept, sock}`
* framed STUN / closed messages for the established socket

## RFCs

* RFC 6544 -- ICE-TCP (passive TCP candidates)
* RFC 8489 -- STUN-over-TCP length-prefixed framing

# `listen`

```elixir
@spec listen({:inet.ip_address(), :inet.port_number()}) ::
  {:ok, :gen_tcp.socket()} | {:error, term()}
```

Listens for ICE-TCP on `{ip, port}` via xirsys TCP transport.

# `read_stun`

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

Reads one RFC 4571-framed STUN message from `sock`.

# `send_stun`

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

Sends one RFC 4571-framed STUN message on `sock`.

# `start_acceptor`

```elixir
@spec start_acceptor(pid(), :gen_tcp.socket()) :: :no_return
```

Runs the accept loop (does not return) until the listen socket dies.

---

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