X-Git-Url: https://git.r.bdr.sh/rbdr/olden-mail/blobdiff_plain/768227f7aa31e2930e1ff2641c24fbf06fc339fe..573aaf2a8ccdb6c8c917b2d88a39c9c8103f64ef:/src/proxy.rs diff --git a/src/proxy.rs b/src/proxy.rs index c6954a0..2798df3 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -1,7 +1,7 @@ //! # Proxy Module //! //! This module has the actual proxy functionality, exposed through -//! `ProxyServer`. The proxy consists of a local unencrypted TCP stream +//! `Server`. The proxy consists of a local unencrypted TCP stream //! and a remote TLS stream. Messages are passed between them via two //! threads. //! @@ -9,24 +9,24 @@ //! - **Client to Server Thread**: Forwards data from client -> TLS server //! - **Serveer to Client Thread**: Forwards data from TLS server -> client //! -//! Finally, the ProxyServer may be shutdown by calling `.shutdown()`, +//! Finally, the `Server` may be shutdown by calling `.shutdown()`, //! this will stop new connections and wait for it to finish. //! //! # Example //! //! ``` //! use std::sync::Arc; -//! use crate::configuration::ProxyConfiguration; -//! use crate::proxy::ProxyServer; +//! use crate::configuration::Proxy; +//! use crate::proxy::Server; //! -//! let config = Arc::new(ProxyConfiguration { +//! let config = Arc::new(Proxy { //! protocol: "IMAP".to_string(), //! local_port: 143, //! remote_domain: "imap.example.com".to_string(), //! remote_port: 993, //! }); //! -//! let mut server = ProxyServer::new(config); +//! let mut server = Server::new(config); //! // The server runs in a background thread. To shut down gracefully: //! server.shutdown(); //! ``` @@ -41,41 +41,42 @@ use std::sync::{ use std::thread::{sleep, spawn, JoinHandle}; use std::time::Duration; -use crate::configuration::ProxyConfiguration; +use crate::configuration::Proxy; +use crate::middleware::MIDDLEWARE; /// A proxy server that listens for plaintext connections and forwards them /// via TLS. /// -/// Creating a new `ProxyServer` spawns a dedicated thread that: +/// Creating a new `Server` spawns a dedicated thread that: /// - Binds to a local port (non-blocking mode). /// - Spawns additional threads for each incoming client connection. /// - Manages connection-lifetime until it receives a shutdown signal. -pub struct ProxyServer { +pub struct Server { running: Arc, thread_handle: Option>, } -impl ProxyServer { - /// Creates a new `ProxyServer` for the given `ProxyConfiguration` and +impl Server { + /// Creates a new `Server` for the given `Proxy` configuration and /// immediately starts it. /// /// # Arguments /// - /// * `configuration` - Shared (Arc) `ProxyConfiguration` + /// * `configuration` - Shared (Arc) `Proxy` /// /// # Returns /// - /// A `ProxyServer` instance that will keep running until its `.shutdown()` + /// A `Server` instance that will keep running until its `.shutdown()` /// method is called, or an error occurs. - pub fn new(configuration: Arc) -> Self { + pub fn new(configuration: Arc) -> Self { let running = Arc::new(AtomicBool::new(true)); let running_clone = Arc::clone(&running); let thread_handle = spawn(move || { - run_proxy(configuration, running_clone); + run_proxy(&configuration, &running_clone); }); - ProxyServer { + Server { running, thread_handle: Some(thread_handle), } @@ -93,7 +94,7 @@ impl ProxyServer { /// The main loop that listens for incoming (plaintext) connections on /// `configuration.bind_address:configuration.local_port`. -fn run_proxy(configuration: Arc, running: Arc) { +fn run_proxy(configuration: &Arc, running: &Arc) { let listener = match TcpListener::bind(format!( "{}:{}", configuration.bind_address, configuration.local_port @@ -119,9 +120,9 @@ fn run_proxy(configuration: Arc, running: Arc) { Ok((stream, addr)) => { info!("New {} connection from {}", configuration.protocol, addr); - let configuration_clone = Arc::clone(&configuration); + let configuration_clone = Arc::clone(configuration); let handle = spawn(move || { - handle_client(stream, configuration_clone); + handle_client(stream, &configuration_clone); }); active_threads.push(handle); } @@ -152,7 +153,7 @@ fn run_proxy(configuration: Arc, running: Arc) { } /// Handles a single client connection by bridging it (plaintext) to a TLS connection. -fn handle_client(client_stream: TcpStream, configuration: Arc) { +fn handle_client(client_stream: TcpStream, configuration: &Arc) { if let Err(e) = client_stream.set_nonblocking(true) { error!("Failed to set client stream to nonblocking: {}", e); return; @@ -213,7 +214,6 @@ fn handle_client(client_stream: TcpStream, configuration: Arc"); let bytes_read = match client_reader.read(&mut buffer) { Ok(0) => break, Ok(n) => n, @@ -227,7 +227,13 @@ fn handle_client(client_stream: TcpStream, configuration: Arc match tls_guard.read(&mut buffer) {