OTP :ssl-compatible client facade for the implemented ex_ssl feature subset.
This experimental client supports TLS 1.3 and explicit bounded TLS 1.2, binary raw sockets, passive and
active-once delivery, application ownership transfer, authenticated ALPN,
bounded streaming writes, and mandatory peer verification. These restricted
defaults differ from OTP. Unsupported options return explicit
{:error, {:options, reason}} errors.
STARTTLS callers must own a passive binary/raw TCP socket, fully consume and
validate the application's upgrade response, and reject any buffered plaintext.
Supply server_name_indication as the certificate reference DNS name, or use
ex_ssl: [reference_identity: {:ip, address} | {:dns_id, name}] to verify a
separate IP/DNS identity independently of SNI and the TCP destination. Once
upgrade is attempted, an owned socket is closed on failure; plaintext must
never resume. A socket belonging to another process is left untouched.
Summary
Functions
Permanently abandons application writes while retaining response reads.
Closes the connection. Closing an already closed handle succeeds.
Returns the supported non-secret connection metadata.
Transfers application ownership while the TLS process retains the TCP socket.
Enables bounded response reads during an application send.
Returns the authenticated ALPN selection, if the server negotiated one.
Returns the authenticated server leaf certificate as DER.
Returns the live TCP peer address and port.
Receives available bytes for length 0, or exactly length bytes. Timeout retains buffered data.
Writes iodata as one ordered logical write. Concurrent writes return :busy.
Changes supported delivery, send, and mutable TCP options after validation.
Returns the live local TCP address and port.
Functions
@spec abandon_send(SSL.Socket.t()) :: :ok | {:error, term()}
Permanently abandons application writes while retaining response reads.
Only the controlling owner may call this on an established connection. An
admitted send settles as {:error, :write_abandoned}; unsent plaintext is discarded and
future sends are rejected. A bounded already-protected application output job may
still finish its original transport write under its original finite deadline.
The job may include an automatic KeyUpdate followed by one application record. It is
never re-encrypted or replayed. Reads keep their existing byte bounds; inbound
protocol traffic that requires output while this record is pending fails closed.
Call close/1 after consuming the response, or to abort the pending record.
Ordinary sender death continues to fail the connection closed unless the owner
explicitly abandons writes before the sender dies.
@spec close(SSL.Socket.t()) :: :ok | {:error, term()}
Closes the connection. Closing an already closed handle succeeds.
@spec connect(:gen_tcp.socket(), list()) :: {:ok, SSL.Socket.t()} | {:error, term()}
@spec connect(term(), term(), term()) :: {:ok, SSL.Socket.t()} | {:error, term()}
@spec connect(term(), :inet.port_number(), list(), timeout()) :: {:ok, SSL.Socket.t()} | {:error, term()}
@spec connection_information(SSL.Socket.t()) :: {:ok, keyword()} | {:error, term()}
Returns the supported non-secret connection metadata.
@spec connection_information(SSL.Socket.t(), term()) :: {:ok, keyword()} | {:error, term()}
@spec controlling_process(SSL.Socket.t(), pid()) :: :ok | {:error, term()}
Transfers application ownership while the TLS process retains the TCP socket.
@spec enable_duplex_reads(SSL.Socket.t()) :: :ok | {:error, term()}
Enables bounded response reads during an application send.
This owner-only, idempotent operation applies to an established open socket. It requires a finite send timeout and rejects later infinite-timeout sends. Reads may progress while one already-protected application output job is pending. Handshake, control and shutdown output barriers remain in place; inbound protocol traffic requiring output on a busy writer fails closed. Normal sender death still fails the connection closed.
@spec negotiated_protocol(SSL.Socket.t()) :: {:ok, binary()} | {:error, term()}
Returns the authenticated ALPN selection, if the server negotiated one.
@spec peercert(SSL.Socket.t()) :: {:ok, binary()} | {:error, term()}
Returns the authenticated server leaf certificate as DER.
@spec peername(SSL.Socket.t()) :: {:ok, {:inet.ip_address(), :inet.port_number()}} | {:error, term()}
Returns the live TCP peer address and port.
@spec recv(SSL.Socket.t(), non_neg_integer(), timeout()) :: {:ok, binary()} | {:error, term()}
Receives available bytes for length 0, or exactly length bytes. Timeout retains buffered data.
@spec send(SSL.Socket.t(), iodata()) :: :ok | {:error, term()}
Writes iodata as one ordered logical write. Concurrent writes return :busy.
@spec setopts(SSL.Socket.t(), list()) :: :ok | {:error, term()}
Changes supported delivery, send, and mutable TCP options after validation.
@spec sockname(SSL.Socket.t()) :: {:ok, {:inet.ip_address(), :inet.port_number()}} | {:error, term()}
Returns the live local TCP address and port.