# `SmolNet.Inet6.Tcp`
[🔗](https://github.com/ausimian/smolnet/blob/0.7.1/lib/smol_net/inet6/tcp.ex#L1)

IPv6 TCP callback and shared adapter for Erlang `:gen_tcp` and `:inet`.

Select this callback with the `:tcp_module` option and pass the target stack
with the `:smolnet_stack` option. Each returned OTP socket is backed by one
temporary `:gen_statem` child of that stack's inet supervisor.

This module is the IPv6 callback and shared socket implementation. Use
`SmolNet.Inet.Tcp` as the callback for IPv4. File descriptors and
packet modes other than raw, line, 1, 2, and 4 fail explicitly.

Either module can also be `:ssl`'s transport, as its `cb_info`:
`{SmolNet.Inet6.Tcp, :tcp, :tcp_closed, :tcp_error}`, or `SmolNet.Inet.Tcp`
for IPv4, with `:smolnet_stack` among the socket options. See the
`:gen_tcp` guide.

# `socket_term`

```elixir
@type socket_term() :: {:&quot;$inet&quot;, SmolNet.Inet.Tcp | SmolNet.Inet6.Tcp, pid()}
```

# `accept`

```elixir
@spec accept(socket_term()) :: {:ok, socket_term()} | {:error, atom()}
```

# `accept`

```elixir
@spec accept(socket_term(), timeout()) :: {:ok, socket_term()} | {:error, atom()}
```

# `cancel_monitor`

```elixir
@spec cancel_monitor(reference()) :: boolean()
```

Cancels a monitor that the calling process started with `monitor/1`;
`:inet.cancel_monitor/1` calls this for a SmolNet socket's monitor.

Returns `true` if the monitor was removed, in which case no DOWN message
for it arrives, or `false` if it was not found, typically because it has
already triggered and its DOWN message is in the caller's mailbox.

# `child_spec`

```elixir
@spec child_spec(map()) :: Supervisor.child_spec()
```

# `close`

```elixir
@spec close(socket_term()) :: :ok
```

# `connect`

```elixir
@spec connect(:inet.ip6_address(), :inet.port_number(), list()) ::
  {:ok, socket_term()} | {:error, atom()}
@spec connect(map(), list(), timeout()) :: {:ok, socket_term()} | {:error, atom()}
```

# `connect`

```elixir
@spec connect(term(), term(), list(), timeout()) ::
  {:ok, socket_term()} | {:error, atom()}
```

# `controlling_process`

```elixir
@spec controlling_process(socket_term(), pid()) :: :ok | {:error, atom()}
```

# `family`

```elixir
@spec family() :: :inet6
```

# `fdopen`

```elixir
@spec fdopen(term(), list()) :: {:error, :enotsup}
```

# `getaddr`

```elixir
@spec getaddr(term()) :: {:ok, :inet.ip6_address()} | {:error, atom()}
```

# `getaddr`

```elixir
@spec getaddr(term(), term()) :: {:ok, :inet.ip6_address()} | {:error, atom()}
```

# `getaddrs`

```elixir
@spec getaddrs(term()) :: {:ok, [:inet.ip6_address()]} | {:error, atom()}
```

# `getaddrs`

```elixir
@spec getaddrs(term(), term()) :: {:ok, [:inet.ip6_address()]} | {:error, atom()}
```

# `getopts`

```elixir
@spec getopts(socket_term(), list()) :: {:ok, list()} | {:error, atom()}
```

# `getserv`

```elixir
@spec getserv(term()) :: {:ok, :inet.port_number()} | {:error, atom()}
```

# `getstat`

```elixir
@spec getstat(socket_term(), list()) :: {:ok, list()} | {:error, atom()}
```

# `info`

```elixir
@spec info(socket_term()) :: map() | {:error, atom()}
```

# `listen`

```elixir
@spec listen(:inet.port_number(), list()) :: {:ok, socket_term()} | {:error, atom()}
```

# `mask`

```elixir
@spec mask(tuple(), tuple()) :: tuple()
```

# `monitor`

```elixir
@spec monitor(socket_term()) :: reference()
```

Starts a monitor of `socket` for the calling process; `:inet.monitor/1`
calls this for a SmolNet socket.

When the socket closes, the caller gets
`{:DOWN, ref, :socket, socket, :closed}`, as for an OTP `socket`-backed
`:gen_tcp` socket, or `{:DOWN, ref, :socket, socket, :nosock}` at once if
`socket` was already closed. Any process may monitor a socket, and each
call creates a separate monitor. See `cancel_monitor/1`.

A SmolNet socket closes when `close/1` is called, when its owner exits,
when a send timeout closes it (`send_timeout_close`), on a connection
error, or when its stack stops. A peer's FIN alone does not close it,
since the socket can still send.

# `parse_address`

```elixir
@spec parse_address(charlist()) :: {:ok, :inet.ip6_address()} | {:error, atom()}
```

# `peername`

```elixir
@spec peername(socket_term()) ::
  {:ok, {:inet.ip6_address(), :inet.port_number()}} | {:error, atom()}
```

# `port`

```elixir
@spec port(socket_term()) :: {:ok, :inet.port_number()} | {:error, atom()}
```

Returns the local port of `socket`, as `:inet.port/1` does.

`:ssl` calls this on a transport given through `cb_info`.

# `recv`

```elixir
@spec recv(socket_term(), non_neg_integer()) :: {:ok, term()} | {:error, atom()}
```

# `recv`

```elixir
@spec recv(socket_term(), non_neg_integer(), timeout()) ::
  {:ok, term()} | {:error, atom()}
```

# `send`

```elixir
@spec send(socket_term(), iodata()) :: :ok | {:error, term()}
```

# `send`

```elixir
@spec send(socket_term(), iodata(), list()) :: :ok | {:error, term()}
```

# `setopts`

```elixir
@spec setopts(socket_term(), list()) :: :ok | {:error, atom()}
```

# `shutdown`

```elixir
@spec shutdown(socket_term(), :read | :write | :read_write) :: :ok | {:error, atom()}
```

# `socket_to_list`

```elixir
@spec socket_to_list(socket_term()) :: charlist()
```

# `sockname`

```elixir
@spec sockname(socket_term()) ::
  {:ok, {:inet.ip6_address(), :inet.port_number()}} | {:error, atom()}
```

# `start_link`

```elixir
@spec start_link(map()) :: :gen_statem.start_ret()
```

# `translate_ip`

```elixir
@spec translate_ip(term()) :: term()
```

# `unrecv`

```elixir
@spec unrecv(socket_term(), iodata()) :: :ok | {:error, atom()}
```

---

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