use super::super::std::{collections::*, immutable::*};
use {
rustls::{server::*, sign::*},
std::sync::*,
};
#[derive(Clone, Debug)]
pub enum SniResolver {
BySNI(FastHashMap<ImmutableString, SniResolverTarget>),
Single(SniResolverTarget),
}
impl ResolvesServerCert for SniResolver {
fn resolve(&self, client_hello: ClientHello) -> Option<Arc<CertifiedKey>> {
match self {
Self::BySNI(targets) => match client_hello.server_name() {
Some(sni) => match targets.get(sni) {
Some(target) => {
tracing::trace!("SNI: {}", sni);
target.resolve(client_hello)
}
None => {
tracing::warn!("unknown SNI: {}", sni);
None
}
},
None => {
tracing::trace!("no SNI");
None
}
},
Self::Single(target) => {
tracing::trace!("single");
target.resolve(client_hello)
}
}
}
}
#[derive(Clone, Debug)]
pub enum SniResolverTarget {
Key(Arc<CertifiedKey>),
Delegate(Arc<dyn ResolvesServerCert>),
}
impl ResolvesServerCert for SniResolverTarget {
fn resolve(&self, client_hello: ClientHello) -> Option<Arc<rustls::sign::CertifiedKey>> {
match self {
Self::Key(certified_key) => {
tracing::trace!("key");
Some(certified_key.clone())
}
Self::Delegate(delegate) => {
tracing::trace!("delegate");
delegate.resolve(client_hello)
}
}
}
}