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

source

#[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)

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

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

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.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.