use std::os::fd::AsRawFd as _;
use std::sync::Arc;
use crate::error::{last_error, Error, Result};
use crate::ffi::Ssl;
use crate::stream::{attach_socket_bio, drive_handshake, TlsStream};
use crate::ServerConfig;
#[derive(Clone, Debug)]
pub struct TlsAcceptor {
cfg: Arc<ServerConfig>,
}
impl TlsAcceptor {
pub fn new(cfg: impl Into<Arc<ServerConfig>>) -> Self {
Self { cfg: cfg.into() }
}
pub async fn accept(&self, tcp: tokio::net::TcpStream) -> Result<TlsStream> {
let mut ssl = new_ssl(&self.cfg)?;
unsafe {
attach_socket_bio(&mut ssl, tcp.as_raw_fd())?;
aws_lc_sys::SSL_set_accept_state(ssl.as_ptr());
}
unsafe {
drive_handshake(&mut ssl, &tcp).await?;
}
let mut stream = TlsStream::from_parts(ssl, tcp, self.cfg.ktls_disabled);
stream.try_auto_install_ktls()?;
Ok(stream)
}
}
fn new_ssl(cfg: &ServerConfig) -> Result<Ssl> {
let raw = unsafe { aws_lc_sys::SSL_new(cfg.ctx_ptr()) };
unsafe { Ssl::from_raw(raw) }.ok_or_else(|| Error::Init(format!("SSL_new: {}", last_error())))
}