use crate::servers::protocol::tls::determine_upstream_name; use crate::servers::Proxy; use log::{debug, error, info, trace, warn}; use std::error::Error; use std::sync::Arc; use tokio::net::{TcpListener, TcpStream}; pub(crate) async fn proxy(config: Arc) -> Result<(), Box> { let listener = TcpListener::bind(config.listen).await?; let config = config.clone(); loop { let thread_proxy = config.clone(); match listener.accept().await { Err(err) => { error!("Failed to accept connection: {}", err); return Err(Box::new(err)); } Ok((stream, _)) => { tokio::spawn(async move { match accept(stream, thread_proxy).await { Ok(_) => {} Err(err) => { error!("Relay thread returned an error: {}", err); } }; }); } } } } async fn accept(inbound: TcpStream, proxy: Arc) -> Result<(), Box> { info!("New connection from {:?}", inbound.peer_addr()?); let upstream_name = match proxy.tls { false => proxy.default_action.clone(), true => determine_upstream_name(&inbound, &proxy).await?, }; debug!("Upstream: {}", upstream_name); let upstream = match proxy.upstream.get(&upstream_name) { Some(upstream) => upstream, None => { warn!( "No upstream named {:?} on server {:?}", proxy.default_action, proxy.name ); proxy.upstream.get(&proxy.default_action).unwrap() } }; upstream.process(inbound).await }