Tls module

Tls_Stream

structextensionexperimentalSource

A TLS connection over any Io.Reader and Io.Writer pair. Read and write it with read, write_some and write, or through reader_of and writer_of.

One stream belongs to one scheduler thread. One fiber may read while another writes; two fibers reading, or two writing, take turns call by call, so their data interleaves.

tls_connect or tls_accept allocates it and close frees it, once. The fields are the module's own state: 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