TLS (:ssl) implementation of Aerospike.Cluster.NodeTransport.
The only real difference between this transport and
Aerospike.Transport.Tcp is how the socket is opened: connect/3
performs a plain TCP handshake and immediately upgrades the socket via
:ssl.connect/3 with the caller-supplied verification / cert / key
opts. Once the TLS handshake completes the connection handle is an
Aerospike.Transport.Tcp{} struct whose socket_mod is :ssl rather
than :gen_tcp, so every post-connect operation — framing, auth,
compression, telemetry, stream framing — is shared with the plaintext
path. The other callbacks (command/4, command_stream/4, info/2,
stream_open/4, stream_read/2, stream_close/1, close/1,
login/2) therefore delegate straight to Aerospike.Transport.Tcp.
Callers select TLS by setting transport: Aerospike.Transport.Tls on
Aerospike.start_link/1. Three deployment shapes are supported:
- Standard TLS — server certificate verified against a CA bundle,
no client cert. Set
:tls_cacertfileand:tls_name. - mTLS — client presents a cert and key in addition to verifying
the server. Set
:tls_certfile/:tls_keyfilealongside the CA bundle. - PKI — the server accepts the client cert as auth;
:user/:passwordmay be omitted. Same opt shape as mTLS; auth is a server-side configuration concern, not a transport one.
connect/3 options
Every option lives in the opts keyword list. Keys that Transport.Tcp
also accepts (:connect_timeout_ms, :info_timeout, :node_name,
:user, :password, :session_token, TCP tuning knobs) flow through
unchanged — the TCP handshake uses them before the TLS upgrade, and the
login RPC runs on top of the upgraded socket if credentials are set.
TLS-specific keys:
:tls_name— string compared against the server certificate's subject / SAN. When set, enables Server Name Indication (SNI) and hostname verification. When absent, falls back to thehostargument passed toconnect/3; callers that connect by IP must set:tls_nameexplicitly because OTP's default:verify_peerrejects an IP as a host name.:tls_cacertfile— path to a PEM-encoded CA bundle used to verify the server certificate. Required when:tls_verifyis:verify_peer(the default).:tls_certfile/:tls_keyfile— PEM-encoded client certificate and private key. Required for mTLS and PKI; omitted for standard one-way TLS.:tls_verify—:verify_peer(default) or:verify_none. The latter is test-only and logs a:warningat connect time.:tls_opts— extra keyword list passed through to:ssl.connect/3verbatim after the plan-level keys above have been translated. Use for rarely-tuned knobs (cipher suites, depth, CRL files) that the plan does not expose as first-class options.
Security notes
OTP does not verify hostnames by default even with :verify_peer —
the caller must supply :server_name_indication and a :customize_hostname_check
configuration. This module builds both from :tls_name so a caller
who sets the CA bundle and the expected name automatically gets
hostname verification. Callers who need stricter verification (CRL,
OCSP, pinning) pass extra opts through :tls_opts.
Summary
Functions
Closes the TLS socket.
Sends one pre-encoded command frame over TLS and returns one decoded response body.
Sends one pre-encoded command frame over TLS and reads a bounded multi-frame response.
Opens a TCP connection, upgrades it with TLS, and returns a transport handle.
Sends one or more info commands over TLS and returns the decoded response map.
Runs the admin-protocol login or authenticate handshake over TLS.
Closes a TLS stream handle.
Sends a streaming TLS request and returns a stream handle for incremental reads.
Reads the next frame from a TLS stream.
Types
@type connect_option() :: Aerospike.Transport.Tcp.connect_option() | {:tls_name, String.t() | nil} | {:tls_cacertfile, Path.t() | nil} | {:tls_certfile, Path.t() | nil} | {:tls_keyfile, Path.t() | nil} | {:tls_verify, :verify_peer | :verify_none} | {:tls_opts, keyword()}
TLS connection option accepted by connect/3.
Includes the plaintext TCP options documented by
Aerospike.Transport.Tcp plus TLS verification and certificate keys.
@type connect_opts() :: [connect_option()]
Keyword list accepted by connect/3.
Functions
@spec close(Aerospike.Transport.Tcp.conn()) :: :ok
Closes the TLS socket.
@spec command( Aerospike.Transport.Tcp.conn(), iodata(), non_neg_integer(), Aerospike.Transport.Tcp.command_opts() ) :: {:ok, binary()} | {:error, Aerospike.Error.t()}
Sends one pre-encoded command frame over TLS and returns one decoded response body.
Accepts :use_compression, :message_type, and :attempt in opts.
@spec command_stream( Aerospike.Transport.Tcp.conn(), iodata(), non_neg_integer(), Aerospike.Transport.Tcp.command_opts() ) :: {:ok, binary()} | {:error, Aerospike.Error.t()}
Sends one pre-encoded command frame over TLS and reads a bounded multi-frame response.
Accepts the same options as command/4.
@spec connect(String.t(), :inet.port_number(), connect_opts()) :: {:ok, Aerospike.Transport.Tcp.conn()} | {:error, Aerospike.Error.t()}
Opens a TCP connection, upgrades it with TLS, and returns a transport handle.
TLS-specific options are documented in the module docs. After the handshake,
command framing and optional auth use Aerospike.Transport.Tcp. See
connect_option/0 for supported keys.
@spec info(Aerospike.Transport.Tcp.conn(), [String.t()]) :: {:ok, %{required(String.t()) => String.t()}} | {:error, Aerospike.Error.t()}
Sends one or more info commands over TLS and returns the decoded response map.
@spec login( Aerospike.Transport.Tcp.conn(), Aerospike.Cluster.NodeTransport.login_opts() ) :: {:ok, Aerospike.Cluster.NodeTransport.login_reply()} | {:error, Aerospike.Error.t()}
Runs the admin-protocol login or authenticate handshake over TLS.
See Aerospike.Cluster.NodeTransport.login_opts/0 for supported keys.
@spec stream_close(Aerospike.Transport.Tcp.stream()) :: :ok
Closes a TLS stream handle.
@spec stream_open( Aerospike.Transport.Tcp.conn(), iodata(), non_neg_integer(), Aerospike.Transport.Tcp.stream_opts() ) :: {:ok, Aerospike.Transport.Tcp.stream()} | {:error, Aerospike.Error.t()}
Sends a streaming TLS request and returns a stream handle for incremental reads.
Accepts :use_compression and :attempt in opts.
@spec stream_read(Aerospike.Transport.Tcp.stream(), non_neg_integer()) :: {:ok, binary()} | :done | {:error, Aerospike.Error.t()}
Reads the next frame from a TLS stream.