use std::convert::TryFrom;
use async_trait::async_trait;
use rustls::pki_types::ServerName;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::net::{TcpListener, TcpStream};
use tokio_rustls::TlsAcceptor;
use crate::error::Error;
use crate::network::tls::{get_tls_connector, get_tls_listener};
use crate::settings::Shared;
pub fn socket_cleanup(_settings: &Shared) -> Result<(), Error> {
Ok(())
}
pub struct TlsTcpListener {
tcp_listener: TcpListener,
tls_acceptor: TlsAcceptor,
}
#[async_trait]
pub trait Listener: Sync + Send {
async fn accept<'a>(&'a self) -> Result<GenericStream, Error>;
}
#[async_trait]
impl Listener for TlsTcpListener {
async fn accept<'a>(&'a self) -> Result<GenericStream, Error> {
let (stream, _) = self.tcp_listener.accept().await?;
Ok(Box::new(self.tls_acceptor.accept(stream).await?))
}
}
pub trait Stream: AsyncRead + AsyncWrite + Unpin + Send {}
impl Stream for tokio_rustls::server::TlsStream<TcpStream> {}
impl Stream for tokio_rustls::client::TlsStream<TcpStream> {}
pub type GenericListener = Box<dyn Listener>;
pub type GenericStream = Box<dyn Stream>;
pub async fn get_client_stream(settings: &Shared) -> Result<GenericStream, Error> {
let address = format!("{}:{}", settings.host, settings.port);
let tcp_stream = TcpStream::connect(&address).await.map_err(|_| {
Error::Connection(format!(
"Failed to connect to the daemon on {address}. Did you start it?"
))
})?;
let tls_connector = get_tls_connector(settings)
.await
.map_err(|err| Error::Connection(format!("Failed to initialize tls connector {err}.")))?;
let stream = tls_connector
.connect(ServerName::try_from("pueue.local").unwrap(), tcp_stream)
.await
.map_err(|err| Error::Connection(format!("Failed to initialize tls {err}.")))?;
Ok(Box::new(stream))
}
pub async fn get_listener(settings: &Shared) -> Result<GenericListener, Error> {
let address = format!("{}:{}", settings.host, settings.port);
let tcp_listener = TcpListener::bind(&address).await.map_err(|err| {
Error::Connection(format!("Failed to listen on address {address}. {err}"))
})?;
let tls_acceptor = get_tls_listener(settings)?;
let tls_listener = TlsTcpListener {
tcp_listener,
tls_acceptor,
};
Ok(Box::new(tls_listener))
}