TCPConnection[optional TCP: TCPBackend ref]¶
The TCP connection: all connection state and I/O, including SSL. A
TCPConnectionActor owns one and delegates to it.
Create it with one of the four constructors -- client, server,
ssl_client, ssl_server -- using TCPConnection.none() as the field
initializer before that. An open plaintext connection can be upgraded to TLS
with start_tls. See the package documentation for the full lifecycle.
Constructors¶
client¶
Create a client-side plaintext connection. An optional connection_timeout
bounds the TCP Happy Eyeballs phase. If the timeout fires before
_on_connected, the connection fails with ConnectionFailedTimeout.
new ref client(
auth: TCPConnectAuth val,
host: String val,
port: String val,
from: String val,
enclosing: TCPConnectionActor[TCP] ref,
ler: ClientLifecycleEventReceiver[TCP] ref,
read_buffer_size: ReadBufferSize = call,
ip_version: IPVersion = reference,
connection_timeout: (ConnectionTimeout | None val) = reference)
: TCPConnection[TCP] ref^
Parameters¶
- auth: TCPConnectAuth val
- host: String val
- port: String val
- from: String val
- enclosing: TCPConnectionActor[TCP] ref
- ler: ClientLifecycleEventReceiver[TCP] ref
- read_buffer_size: ReadBufferSize = call
- ip_version: IPVersion = reference
- connection_timeout: (ConnectionTimeout | None val) = reference
Returns¶
- TCPConnection[TCP] ref^
server¶
Create a server-side plaintext connection from an accepted socket fd'.
new ref server(
auth: TCPServerAuth val,
fd': U32 val,
enclosing: TCPConnectionActor[TCP] ref,
ler: ServerLifecycleEventReceiver[TCP] ref,
read_buffer_size: ReadBufferSize = call)
: TCPConnection[TCP] ref^
Parameters¶
- auth: TCPServerAuth val
- fd': U32 val
- enclosing: TCPConnectionActor[TCP] ref
- ler: ServerLifecycleEventReceiver[TCP] ref
- read_buffer_size: ReadBufferSize = call
Returns¶
- TCPConnection[TCP] ref^
ssl_client¶
Create a client-side SSL connection. The SSL session is created from the
provided SSLContext. If session creation fails, the connection reports
failure asynchronously via _on_connection_failure(ConnectionFailedSSL).
An optional connection_timeout bounds the connect-to-ready phase
(TCP Happy Eyeballs + TLS handshake). If the timeout fires before
_on_connected, the connection fails with ConnectionFailedTimeout.
new ref ssl_client(
auth: TCPConnectAuth val,
ssl_ctx: SSLContext val,
host: String val,
port: String val,
from: String val,
enclosing: TCPConnectionActor[TCP] ref,
ler: ClientLifecycleEventReceiver[TCP] ref,
read_buffer_size: ReadBufferSize = call,
ip_version: IPVersion = reference,
connection_timeout: (ConnectionTimeout | None val) = reference)
: TCPConnection[TCP] ref^
Parameters¶
- auth: TCPConnectAuth val
- ssl_ctx: SSLContext val
- host: String val
- port: String val
- from: String val
- enclosing: TCPConnectionActor[TCP] ref
- ler: ClientLifecycleEventReceiver[TCP] ref
- read_buffer_size: ReadBufferSize = call
- ip_version: IPVersion = reference
- connection_timeout: (ConnectionTimeout | None val) = reference
Returns¶
- TCPConnection[TCP] ref^
ssl_server¶
Create a server-side SSL connection. The SSL session is created from the provided SSLContext. If session creation fails, the connection reports failure asynchronously via _on_start_failure(StartFailedSSL) and closes the fd.
new ref ssl_server(
auth: TCPServerAuth val,
ssl_ctx: SSLContext val,
fd': U32 val,
enclosing: TCPConnectionActor[TCP] ref,
ler: ServerLifecycleEventReceiver[TCP] ref,
read_buffer_size: ReadBufferSize = call)
: TCPConnection[TCP] ref^
Parameters¶
- auth: TCPServerAuth val
- ssl_ctx: SSLContext val
- fd': U32 val
- enclosing: TCPConnectionActor[TCP] ref
- ler: ServerLifecycleEventReceiver[TCP] ref
- read_buffer_size: ReadBufferSize = call
Returns¶
- TCPConnection[TCP] ref^
none¶
Returns¶
- TCPConnection[TCP] ref^
Public Functions¶
keepalive¶
Sets the TCP keepalive timeout to approximately secs seconds. Exact
timing is OS dependent. If secs is zero, TCP keepalive is disabled. TCP
keepalive is disabled by default. This can only be set on a connected
socket.
Parameters¶
- secs: U32 val
Returns¶
- None val
set_nodelay¶
Turn Nagle on/off. Defaults to on (Nagle enabled, nodelay off). When
enabled (state = true), small writes are sent immediately without
waiting to coalesce — useful for latency-sensitive protocols. When
disabled (state = false), the OS may buffer small writes.
Returns 0 on success, or a non-zero errno on failure. Only meaningful on a connected socket — returns non-zero if the connection is not open.
Parameters¶
- state: Bool val
Returns¶
- U32 val
get_so_rcvbuf¶
Get the OS receive buffer size for this socket.
Returns a 2-tuple: (errno, value). On success, errno is 0 and value is the buffer size in bytes. On failure, errno is non-zero and value should be ignored. Only meaningful on a connected socket — returns (1, 0) if the connection is not open.
Returns¶
set_so_rcvbuf¶
Set the OS receive buffer size for this socket. The OS may round the requested size up to a minimum or clamp it to a maximum.
Returns 0 on success, or a non-zero errno on failure. Only meaningful on a connected socket — returns non-zero if the connection is not open.
Parameters¶
- bufsize: U32 val
Returns¶
- U32 val
get_so_sndbuf¶
Get the OS send buffer size for this socket.
Returns a 2-tuple: (errno, value). On success, errno is 0 and value is the buffer size in bytes. On failure, errno is non-zero and value should be ignored. Only meaningful on a connected socket — returns (1, 0) if the connection is not open.
Returns¶
set_so_sndbuf¶
Set the OS send buffer size for this socket. The OS may round the requested size up to a minimum or clamp it to a maximum.
Returns 0 on success, or a non-zero errno on failure. Only meaningful on a connected socket — returns non-zero if the connection is not open.
Parameters¶
- bufsize: U32 val
Returns¶
- U32 val
getsockopt¶
General interface to getsockopt(2) for accessing any socket option.
The option_max_size argument is the maximum number of bytes the caller
expects the kernel to return. This method allocates a buffer of that size
before calling getsockopt(2).
Returns a 2-tuple: on success, (0, data) where data is the bytes
returned by the kernel, sized to the actual length the kernel wrote. On
failure, (errno, undefined) — the second element must be ignored. Only
meaningful on a connected socket — returns (1, empty) if the connection
is not open.
For commonly-tuned options, prefer the dedicated convenience methods
(set_nodelay, get_so_rcvbuf, etc.). Do not change the socket's
non-blocking mode — lori's event-driven I/O requires non-blocking
sockets.
fun box getsockopt(
level: I32 val,
option_name: I32 val,
option_max_size: USize val = 4)
: (U32 val , Array[U8 val] iso^)
Parameters¶
Returns¶
getsockopt_u32¶
Wrapper for getsockopt(2) where the kernel returns a C uint32_t.
Returns a 2-tuple: on success, (0, value). On failure,
(errno, undefined) — the second element must be ignored. Only
meaningful on a connected socket — returns (1, 0) if the connection
is not open.
For commonly-tuned options, prefer the dedicated convenience methods
(get_so_rcvbuf, get_so_sndbuf, etc.). Do not change the socket's
non-blocking mode — lori's event-driven I/O requires non-blocking
sockets.
Parameters¶
Returns¶
setsockopt¶
General interface to setsockopt(2) for setting any socket option.
The caller is responsible for the correct size, byte contents, and
byte order of the option array for the requested level and
option_name.
Returns 0 on success, or the value of errno on failure. Only
meaningful on a connected socket — returns non-zero if the connection
is not open.
For commonly-tuned options, prefer the dedicated convenience methods
(set_nodelay, set_so_rcvbuf, etc.). Do not change the socket's
non-blocking mode — lori's event-driven I/O requires non-blocking
sockets.
Parameters¶
Returns¶
- U32 val
setsockopt_u32¶
Wrapper for setsockopt(2) where the kernel expects a C uint32_t.
Returns 0 on success, or the value of errno on failure. Only
meaningful on a connected socket — returns non-zero if the connection
is not open.
For commonly-tuned options, prefer the dedicated convenience methods
(set_nodelay, set_so_rcvbuf, etc.). Do not change the socket's
non-blocking mode — lori's event-driven I/O requires non-blocking
sockets.
Parameters¶
Returns¶
- U32 val
idle_timeout¶
Set or disable the idle timeout. Idle timeout is disabled by default.
When duration is an IdleTimeout, the timer fires when no successful
send or receive occurs for that duration, delivering
_on_idle_timeout() to the lifecycle event receiver. When duration
is None, the idle timeout is disabled.
The timer re-arms after each firing while the connection is open.
Both hard_close() and close() cancel it.
Can be called before the connection is established — the value is stored and the timer starts when the connection is ready.
This is independent of TCP keepalive (keepalive()). TCP keepalive
is a transport-level probe that detects dead peers. Idle timeout is
application-level inactivity detection — it fires whether or not the
peer is alive.
If the idle timer's ASIO event subscription fails asynchronously
(e.g. ENOMEM from kevent/epoll_ctl), the timer is cancelled and
_on_idle_timer_failure() is dispatched to the lifecycle event
receiver.
Parameters¶
- duration: (IdleTimeout | None val)
Returns¶
- None val
set_timer¶
Create a one-shot timer that fires _on_timer() after the configured
duration. Returns a TimerToken on success, or a SetTimerError on
failure.
Unlike idle_timeout(), this timer has no I/O-reset behavior — it fires
unconditionally after the duration elapses, regardless of send/receive
activity. There is no automatic re-arming; call set_timer() again from
_on_timer() for repetition.
Only one user timer can be active at a time. Setting a timer while one is
already active returns SetTimerAlreadyActive — call cancel_timer()
first. This prevents silent token invalidation.
Requires the connection to be application-level connected: the connection
must be open and the initial SSL handshake (if any) must have completed.
TLS upgrades via start_tls() do not block timer creation.
The timer survives close() (graceful shutdown) but is cancelled by
hard_close().
User timers have two error paths. This method returns a
SetTimerError synchronously when preconditions prevent the timer
from being created (see the return type). When creation succeeds but
the ASIO event subscription later fails (e.g. ENOMEM from
kevent/epoll_ctl), _on_timer_failure() is dispatched to the
lifecycle event receiver.
Parameters¶
- duration: TimerDuration
Returns¶
- (TimerToken val | SetTimerError)
cancel_timer¶
Cancel an active timer. No-op if the token doesn't match the active timer (already fired, already cancelled, wrong token). Safe to call with stale tokens.
No connection state check — timers can be cancelled during graceful
shutdown (_Closing) since they remain active until hard_close().
Parameters¶
- token: TimerToken val
Returns¶
- None val
set_read_buffer_minimum¶
Set the shrink-back floor for the read buffer to exactly new_min bytes.
When the read buffer is empty and larger than the minimum, it shrinks back
to this size automatically. If the current buffer allocation is smaller
than new_min, the buffer is grown to match.
Returns ReadBufferResizeBelowBufferSize if new_min is less than the
current buffer-until value.
fun ref set_read_buffer_minimum(
new_min: ReadBufferSize)
: (ReadBufferResized val | ReadBufferResizeBelowBufferSize val)
Parameters¶
- new_min: ReadBufferSize
Returns¶
- (ReadBufferResized val | ReadBufferResizeBelowBufferSize val)
resize_read_buffer¶
Force the read buffer to exactly size' bytes, reallocating if different.
If size' is below the current minimum, the minimum is lowered to match.
Returns ReadBufferResizeBelowBufferSize if size' is less than the
current buffer-until value, or ReadBufferResizeBelowUsed if size' is
less than the amount of unprocessed data currently in the buffer.
Parameters¶
- size': ReadBufferSize
Returns¶
local_address¶
Return the local IP address. If this TCPConnection is closed then the address returned is invalid.
Returns¶
- NetAddress val
remote_address¶
Return the remote IP address. If this TCPConnection is closed then the address returned is invalid.
Returns¶
- NetAddress val
mute¶
Temporarily suspend reading off this TCPConnection until such time as
unmute is called.
When called from _on_received, no further data is delivered. Whatever the
connection has read but not yet delivered is held, and unmute delivers it
before anything read off the socket afterward. This holds for plaintext and
SSL connections alike.
Held data only survives to an unmute. Closing a muted connection drops it,
because close on a muted connection hard closes and dispose always does.
Returns¶
- None val
unmute¶
Start reading off this TCPConnection again after having been muted.
Reading resumes on a later turn, not during this call. Data held since the
mute is delivered before anything read off the socket afterward.
Returns¶
- None val
buffer_until¶
Set the number of bytes to buffer before delivering data via
_on_received. When qty is Streaming, all available data is delivered
as it arrives.
Returns BufferSizeAboveMinimum if qty exceeds the current read
buffer minimum. Raise the buffer minimum first, then set buffer_until.
Parameters¶
- qty: (BufferSize | Streaming val)
Returns¶
close¶
Gracefully close the connection. Data already handed to an accepted
send() is delivered before the connection closes.
On a muted connection this is a hard close instead: it shuts down at once
and drops undelivered data — both held reads and queued writes (the writes
fail with _on_send_failed).
Closing before the connection is established abandons the attempt and
delivers _on_connection_failure.
Returns¶
- None val
hard_close¶
When an error happens, do a non-graceful close.
Returns¶
- None val
is_closed¶
Returns whether the connection is closed or closing.
Returns¶
- Bool val
is_writeable¶
Returns whether the socket can currently send.
Returns¶
- Bool val
start_tls¶
Initiate a TLS handshake on an established plaintext connection. Returns
None when the handshake has been started, or a StartTLSError if the
upgrade cannot proceed (the connection is unchanged in that case).
Preconditions: the connection must be open, not already TLS, not muted, have no unprocessed data in the read buffer, and have no pending writes. The read buffer check prevents a man-in-the-middle from injecting pre-TLS data that the application would process as post-TLS (CVE-2021-23222).
On success, _on_tls_ready() fires when the handshake completes. During
the handshake, send() returns SendErrorNotConnected. If the handshake
fails, _on_tls_failure fires followed by _on_closed().
The host parameter is used for SNI (Server Name Indication) on client
connections. Pass an empty string for server connections or when SNI is
not needed.
Parameters¶
- ssl_ctx: SSLContext val
- host: String val = ""
Returns¶
- (None val | StartTLSError)
send¶
Send data on this connection. Accepts a single buffer (ByteSeq) or
multiple buffers (ByteSeqIter). When multiple buffers are provided,
they are sent in a single syscall — avoiding both per-buffer
syscall overhead and the cost of copying into a contiguous buffer.
Returns SendAccepted on success, or a SendError explaining the
failure. On success _on_send_accepted(token, data) has already fired,
from inside this call and before the bytes were written. That token gets
exactly one further callback: _on_sent(token) once the data has been
handed to the OS (written to the kernel send buffer, not received by the
peer), or _on_send_failed(token) if the connection is lost or
hard-closed before the bytes are written. A graceful close() sends
what's still queued, so those sends fire _on_sent, not
_on_send_failed. Closing the connection from any callback that runs
inside this call does not change the return: the send stays accepted.
Both callbacks can run before this returns, so anything the calling code updates after the call -- a counter, a map, a flag -- is not updated yet when they fire.
Parameters¶
- data: (ByteSeq | ByteSeqIter val)
Returns¶
read_again¶
Returns¶
- None val