use std::net::SocketAddr;
use tokio::net::TcpStream;
#[cfg(feature = "tls")]
use std::sync::Arc;
#[cfg(feature = "tls")]
use tokio_rustls::rustls::pki_types::CertificateDer;
#[cfg(feature = "tls")]
use tokio_rustls::server::TlsStream;
pub trait Connected {
type ConnectInfo: Clone + Send + Sync + 'static;
fn connect_info(&self) -> Self::ConnectInfo;
}
#[derive(Debug, Clone)]
pub struct TcpConnectInfo {
pub local_addr: Option<SocketAddr>,
pub remote_addr: Option<SocketAddr>,
}
impl TcpConnectInfo {
pub fn local_addr(&self) -> Option<SocketAddr> {
self.local_addr
}
pub fn remote_addr(&self) -> Option<SocketAddr> {
self.remote_addr
}
}
impl Connected for TcpStream {
type ConnectInfo = TcpConnectInfo;
fn connect_info(&self) -> Self::ConnectInfo {
TcpConnectInfo {
local_addr: self.local_addr().ok(),
remote_addr: self.peer_addr().ok(),
}
}
}
impl Connected for tokio::io::DuplexStream {
type ConnectInfo = ();
fn connect_info(&self) -> Self::ConnectInfo {}
}
#[cfg(feature = "tls")]
impl<T> Connected for TlsStream<T>
where
T: Connected,
{
type ConnectInfo = TlsConnectInfo<T::ConnectInfo>;
fn connect_info(&self) -> Self::ConnectInfo {
let (inner, session) = self.get_ref();
let inner = inner.connect_info();
let certs = session
.peer_certificates()
.map(|certs| certs.to_owned().into());
TlsConnectInfo { inner, certs }
}
}
#[cfg(feature = "tls")]
#[derive(Debug, Clone)]
pub struct TlsConnectInfo<T> {
inner: T,
certs: Option<Arc<Vec<CertificateDer<'static>>>>,
}
#[cfg(feature = "tls")]
impl<T> TlsConnectInfo<T> {
pub fn get_ref(&self) -> &T {
&self.inner
}
pub fn get_mut(&mut self) -> &mut T {
&mut self.inner
}
pub fn peer_certs(&self) -> Option<Arc<Vec<CertificateDer<'static>>>> {
self.certs.clone()
}
}