Tls module

Tls_Stream

structSource

A TLS connection over any Io.Reader / Io.Writer pair (a TCP stream's, a pipe's, an Http Link's). The handshake is a plain blocking call on the calling fiber: it waits through the Io calls under it, so Io.with_deadline limits it and Io.cancel ends it. After it, the stream is read and written like any other, through reader_of and writer_of, or directly with read, write_some and write. The example in the module's docs connects, writes and reads.

One stream belongs to one scheduler thread. One fiber may read while another writes (every call into the TLS library is short and not interrupted by a switch to another fiber of the stream); two fibers reading, or two writing, take turns call by call, so their data interleaves.

A stream is allocated by tls_connect or tls_accept and freed by close, which must be called once and after which the stream is not used. The fields are the module's own state, not an interface: use the procedures.

Fields

reader: Io.Reader
writer: Io.Writer
ssl: *void
fiber_context: #Context
The running fiber's context, saved before every call into the library, so the callbacks the library makes (which are #c_call) can run Jai code and park the fiber.
lock: Io.Fiber_Mutex
Calls into the library take turns. A fiber never waits for the network while it holds this: the receive callback asks the library to retry and the fiber waits outside, and the send callback only appends to out.
out: [..] u8
What the library has produced and the connection has not taken yet, in order. Appended to under lock by the send callback; flush writes it out under flush_lock, so the bytes of two flushes never interleave. The library is never parked in a send: that is what lets both ends of a connection write a lot at once and still read each other.
flush_lock: Io.Fiber_Mutex
flusher_running: bool
A fiber started by flush_later is sending out (it counts as a user of the stream).
io_error: Io.Io_Error
What the Io call under the running library call returned, when it failed.
broken: Io.Io_Error
Set once the connection is unusable (an Io call failed in the middle of a record, a record did not decrypt, the peer cut the connection short): what every later call returns.
failure: Tls_Error
The error behind broken, for last_error.
can_wait: bool
The underlying reader says when it is readable: the library is never made to wait for input inside a callback (it returns "want read" and the fiber waits outside), so a fiber waiting for data does not block a writer of the same stream.
ready: bool
ahead: [] u8
Bytes read from the connection and not yet handed to the library. The library asks for one record at a time (at most 16 KiB), and each ask used to cost a wait and a read on the connection; reading more at once and serving the library from here costs one pair for several records. The buffer lives from a read to the moment the library has taken all of it, so a quiet connection holds none; ahead_size is how much the next read takes (it grows while reads come back full, and starts again at the size of a record after a short one).
ahead_start: s64
ahead_end: s64
ahead_size: s64
established: bool
peer_closed: bool
closing: bool
users: s64
Calls in progress; the stream is freed after close when the last one has left.
key_log_proc: Tls_Key_Log_Proc
The client's key log, from its config.
key_log_data: *void
peer_name_count: u8
The server name a client asked for (SNI), on a server stream.
peer_name_bytes: [255] u8

See also