use std::io::{Read, Write};
use std::net::TcpStream;
#[cfg(not(target_os = "windows"))]
use std::path::PathBuf;
use rustls::pki_types::CertificateDer;
use rustls_connector::{RustlsConnector as TlsConnector, RustlsConnectorConfig};
use crate::error::Error;
#[cfg(feature = "settings")]
use crate::{settings::Shared, tls::load_certificate};
#[cfg_attr(not(target_os = "windows"), path = "unix.rs")]
#[cfg_attr(target_os = "windows", path = "windows.rs")]
mod platform;
pub use platform::*;
pub trait BlockingListener: Sync + Send {
fn accept(&self) -> Result<GenericBlockingStream, Error>;
}
pub type GenericBlockingListener = Box<dyn BlockingListener>;
pub type GenericBlockingStream = Box<dyn BlockingStream>;
pub enum ConnectionSettings<'a> {
#[cfg(not(target_os = "windows"))]
UnixSocket { path: PathBuf },
TlsTcpSocket {
host: String,
port: String,
certificate: CertificateDer<'a>,
},
}
#[cfg(feature = "settings")]
impl TryFrom<Shared> for ConnectionSettings<'_> {
type Error = crate::error::Error;
fn try_from(value: Shared) -> Result<Self, Self::Error> {
#[cfg(not(target_os = "windows"))]
{
if value.use_unix_socket {
return Ok(ConnectionSettings::UnixSocket {
path: value.unix_socket_path()?,
});
}
}
let cert = load_certificate(&value.daemon_cert())?;
Ok(ConnectionSettings::TlsTcpSocket {
host: value.host,
port: value.port,
certificate: cert,
})
}
}
pub trait BlockingStream: Read + Write {}
impl BlockingStream for rustls_connector::TlsStream<TcpStream> {}
pub fn get_tls_connector(cert: CertificateDer<'_>) -> Result<TlsConnector, Error> {
let mut config = RustlsConnectorConfig::default();
config.add_parsable_certificates(vec![cert]);
let connector = config.connector_with_no_client_auth();
Ok(connector)
}