use std::io;
use crate::client::session::TlsContext;
use crate::cluster::metadata::UntranslatedEndpoint;
#[derive(Clone)] pub(crate) enum TlsProvider {
GlobalContext(TlsContext),
}
impl TlsProvider {
pub(crate) fn new_with_global_context(context: TlsContext) -> Self {
Self::GlobalContext(context)
}
pub(crate) fn make_tls_config(
&self,
#[expect(unused)] endpoint: &UntranslatedEndpoint,
) -> Option<TlsConfig> {
match self {
TlsProvider::GlobalContext(context) => {
#[cfg_attr(
not(any(feature = "openssl-010", feature = "rustls-023")),
// TODO: make this expect() once MSRV is 1.92+.
allow(unreachable_code)
)]
Some(TlsConfig::new_with_global_context(context.clone()))
}
}
}
}
#[derive(Clone)]
pub(crate) struct TlsConfig {
context: TlsContext,
}
pub(crate) enum Tls {
#[cfg(feature = "openssl-010")]
OpenSsl010(openssl::ssl::Ssl),
#[cfg(feature = "rustls-023")]
Rustls023 {
connector: tokio_rustls::TlsConnector,
},
}
#[derive(Debug, thiserror::Error)]
#[error(transparent)]
#[non_exhaustive]
pub enum TlsError {
#[cfg(feature = "openssl-010")]
OpenSsl010(#[from] openssl::error::ErrorStack),
#[cfg(feature = "rustls-023")]
InvalidName(#[from] rustls::pki_types::InvalidDnsNameError),
#[cfg(feature = "rustls-023")]
PemParse(#[from] rustls::pki_types::pem::Error),
#[cfg(feature = "rustls-023")]
Rustls023(#[from] rustls::Error),
}
impl From<TlsError> for io::Error {
fn from(value: TlsError) -> Self {
match value {
#[cfg(feature = "openssl-010")]
TlsError::OpenSsl010(e) => e.into(),
#[cfg(feature = "rustls-023")]
TlsError::InvalidName(e) => io::Error::other(e),
#[cfg(feature = "rustls-023")]
TlsError::PemParse(e) => io::Error::other(e),
#[cfg(feature = "rustls-023")]
TlsError::Rustls023(e) => io::Error::other(e),
}
}
}
impl TlsConfig {
pub(crate) fn new_with_global_context(context: TlsContext) -> Self {
Self { context }
}
pub(crate) fn new_tls(&self) -> Result<Tls, TlsError> {
match self.context {
#[cfg(feature = "openssl-010")]
TlsContext::OpenSsl010(ref context) => {
#[allow(unused_mut)]
let mut ssl = openssl::ssl::Ssl::new(context)?;
ssl.set_connect_state();
Ok(Tls::OpenSsl010(ssl))
}
#[cfg(feature = "rustls-023")]
TlsContext::Rustls023(ref config) => {
let connector = tokio_rustls::TlsConnector::from(config.clone());
Ok(Tls::Rustls023 { connector })
}
}
}
}