use anyhow::Result; use tokio::io::copy_bidirectional; use tokio::net::{TcpListener, TcpStream}; use crate::state::{ServerState, SharedServerState}; pub async fn run_proxy( listen_addr: String, server_addr: String, motd_server_addr: String, state: SharedServerState, ) -> Result<()> { println!("Listening on {}", listen_addr); println!("Server backend: {}", server_addr); println!("MOTD backend: {}", motd_server_addr); let listener = TcpListener::bind(&listen_addr).await?; while let Ok((mut inbound, client_addr)) = listener.accept().await { let server_addr = server_addr.clone(); let motd_server_addr = motd_server_addr.clone(); let state = state.clone(); tokio::spawn(async move { let current_state = state.get().await; let backend = match current_state { ServerState::Running { .. } => { println!("Client {} -> server (Running)", client_addr); server_addr } _ => { println!("Client {} -> MOTD (state: {:?})", client_addr, current_state); motd_server_addr } }; match TcpStream::connect(&backend).await { Ok(mut outbound) => { if let Err(e) = copy_bidirectional(&mut inbound, &mut outbound).await { eprintln!("Failed to transfer; error={}", e); } } Err(e) => { eprintln!("Failed to connect to backend {}; error={}", backend, e); } } }); } Ok(()) }