use super::socket::{BtpConfig, BtpSocket};
use std::future::Future;
use std::net::SocketAddr;
use tokio::net::{TcpListener, TcpStream};
#[cfg(feature = "tls")]
use std::sync::Arc;
type Error = Box<dyn std::error::Error + Send + Sync>;
pub trait AsListener {
fn accept(&self) -> impl Future<Output = Result<(TcpStream, SocketAddr), std::io::Error>>;
}
pub struct BtpListener<Listener: AsListener> {
pub listener: Listener,
pub btp_conf: BtpConfig,
#[cfg(feature = "tls")]
pub tls_conf: Arc<rustls::ServerConfig>,
}
impl AsListener for TcpListener {
fn accept(&self) -> impl Future<Output = Result<(TcpStream, SocketAddr), std::io::Error>> {
return self.accept();
}
}
#[cfg(not(feature = "tls"))]
mod _impl {
use super::*;
impl<L: AsListener> BtpListener<L> {
pub async fn from(listener: L, btp_conf: BtpConfig) -> Self {
BtpListener { listener, btp_conf }
}
pub async fn accept(&self) -> Result<BtpSocket<TcpStream, std::net::SocketAddr>, Error> {
let (socket, peer) = self.listener.accept().await?;
let me = BtpConfig {
ver: self.btp_conf.ver,
addr: self.btp_conf.addr,
};
Ok(BtpSocket::from(socket, me, peer))
}
}
}
#[cfg(feature = "tls")]
mod _impl {
use crate::VERSION;
use super::*;
use rustls::ServerConfig;
use std::sync::Arc;
use tokio_rustls::{TlsAcceptor, server::TlsStream};
impl<L: AsListener> BtpListener<L> {
pub async fn from(listener: L, btp_conf: BtpConfig, tls_conf: Arc<ServerConfig>) -> Self {
BtpListener {
listener,
btp_conf,
tls_conf,
}
}
pub async fn accept(
&self,
) -> Result<BtpSocket<TlsStream<TcpStream>, std::net::SocketAddr>, Error> {
let acceptor = TlsAcceptor::from(self.tls_conf.clone());
let (socket, peer) = self.listener.accept().await?;
let tls_stream = acceptor.accept(socket).await?;
let conf = BtpConfig {
ver: VERSION,
addr: peer,
};
Ok(BtpSocket::from(tls_stream, conf, peer))
}
}
}