Struct rustls_ffi::acceptor::rustls_acceptor
source · pub struct rustls_acceptor { /* private fields */ }
Expand description
A buffer and parser for ClientHello bytes.
This allows reading ClientHello before choosing a rustls_server_config.
It’s useful when the server config will be based on parameters in the ClientHello: server name indication (SNI), ALPN protocols, signature schemes, and cipher suites.
In particular, if a server wants to do some potentially expensive work to load a certificate for a given hostname, rustls_acceptor allows doing that asynchronously, as opposed to rustls_server_config_builder_set_hello_callback(), which doesn’t work well for asynchronous I/O.
The general flow is:
- rustls_acceptor_new()
- Loop:
- Read bytes from the network it with rustls_acceptor_read_tls().
- If successful, parse those bytes with rustls_acceptor_accept().
- If that returns RUSTLS_RESULT_ACCEPTOR_NOT_READY, continue.
- Otherwise, break.
- If rustls_acceptor_accept() returned RUSTLS_RESULT_OK:
- Examine the resulting rustls_accepted.
- Create or select a rustls_server_config.
- Call rustls_accepted_into_connection().
- Otherwise, there was a problem with the ClientHello data and the connection should be rejected.
Implementations§
source§impl rustls_acceptor
impl rustls_acceptor
source#[no_mangle]pub extern "C" fn rustls_acceptor_new() -> *mut rustls_acceptor
#[no_mangle]pub extern "C" fn rustls_acceptor_new() -> *mut rustls_acceptor
Create and return a new rustls_acceptor.
Caller owns the pointed-to memory and must eventually free it with
rustls_acceptor_free()
.
source#[no_mangle]pub extern "C" fn rustls_acceptor_free(acceptor: *mut rustls_acceptor)
#[no_mangle]pub extern "C" fn rustls_acceptor_free(acceptor: *mut rustls_acceptor)
Free a rustls_acceptor.
Parameters:
acceptor: The rustls_acceptor to free.
Calling with NULL is fine. Must not be called twice with the same value.
source#[no_mangle]pub extern "C" fn rustls_acceptor_read_tls(
acceptor: *mut rustls_acceptor,
callback: rustls_read_callback,
userdata: *mut c_void,
out_n: *mut size_t,
) -> rustls_io_result
#[no_mangle]pub extern "C" fn rustls_acceptor_read_tls(
acceptor: *mut rustls_acceptor,
callback: rustls_read_callback,
userdata: *mut c_void,
out_n: *mut size_t,
) -> rustls_io_result
Read some TLS bytes from the network into internal buffers.
The actual network I/O is performed by callback
, which you provide.
Rustls will invoke your callback with a suitable buffer to store the
read bytes into. You don’t have to fill it up, just fill with as many
bytes as you get in one syscall.
Parameters:
acceptor: The rustls_acceptor to read bytes into.
callback: A function that will perform the actual network I/O.
Must be valid to call with the given userdata parameter until
this function call returns.
userdata: An opaque parameter to be passed directly to callback
.
Note: this is distinct from the userdata
parameter set with
rustls_connection_set_userdata
.
out_n: An output parameter. This will be passed through to callback
,
which should use it to store the number of bytes written.
Returns:
- 0: Success. You should call
rustls_acceptor_accept()
next. - Any non-zero value: error.
This function passes through return values from callback
. Typically
callback
should return an errno value. See rustls_read_callback()
for
more details.
source#[no_mangle]pub extern "C" fn rustls_acceptor_accept(
acceptor: *mut rustls_acceptor,
out_accepted: *mut *mut rustls_accepted,
out_alert: *mut *mut rustls_accepted_alert,
) -> rustls_result
#[no_mangle]pub extern "C" fn rustls_acceptor_accept(
acceptor: *mut rustls_acceptor,
out_accepted: *mut *mut rustls_accepted,
out_alert: *mut *mut rustls_accepted_alert,
) -> rustls_result
Parse all TLS bytes read so far.
If those bytes make up a ClientHello, create a rustls_accepted from them.
Parameters:
acceptor: The rustls_acceptor to access. out_accepted: An output parameter. The pointed-to pointer will be set to a new rustls_accepted only when the function returns RUSTLS_RESULT_OK. The memory is owned by the caller and must eventually be freed out_alert: An output parameter. The pointed-to pointer will be set to a new rustls_accepted_alert only when the function returns a non-OK result. The memory is owned by the caller and must eventually be freed with rustls_accepted_alert_free. The caller should call rustls_accepted_alert_write_tls to write the alert bytes to the TLS connection before freeing the rustls_accepted_alert.
At most one of out_accepted or out_alert will be set.
Returns:
- RUSTLS_RESULT_OK: a ClientHello has successfully been parsed. A pointer to a newly allocated rustls_accepted has been written to *out_accepted.
- RUSTLS_RESULT_ACCEPTOR_NOT_READY: a full ClientHello has not yet been read. Read more TLS bytes to continue.
- Any other rustls_result: the TLS bytes read so far cannot be parsed as a ClientHello, and reading additional bytes won’t help.
Memory and lifetimes:
After this method returns RUSTLS_RESULT_OK, acceptor
is
still allocated and valid. It needs to be freed regardless of success
or failure of this function.
Calling rustls_acceptor_accept()
multiple times on the same
rustls_acceptor
is acceptable from a memory perspective but pointless
from a protocol perspective.