diff --git a/src/main.rs b/src/main.rs index fde3ec7..1903762 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,47 +1,11 @@ -use std::sync::Arc; -use std::fmt; -use tokio::io; -use tokio::net::{TcpListener, TcpStream}; -use tokio::sync::Mutex; +mod netutils; + use anywho::Error; +use netutils::{Backend, proxy, proxy_connection}; +use std::sync::Arc; -#[derive(Clone, Debug)] -struct Backend { - address: String, -} - -impl fmt::Display for Backend { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.address) - } -} - -impl Backend { - fn new(address: String) -> Self { - Backend { address } - } -} - -async fn proxy_connection(client_stream: TcpStream, backend: &Backend) -> Result<(), io::Error> { - let log_error = |e| { eprintln!("error: something went wrong {}", e); e }; - - println!("info: connecting to backend {}", backend); - let backend_stream = TcpStream::connect(&backend.address).await.map_err(log_error)?; - println!("info: the bluetooth device is connected successfully {}", backend); - - let (mut client_read, mut client_write) = client_stream.into_split(); - let (mut backend_read, mut backend_write) = backend_stream.into_split(); - - let client_to_backend = io::copy(&mut client_read, &mut backend_write); - let backend_to_client = io::copy(&mut backend_read, &mut client_write); - - let _ = tokio::select! { - res_a = client_to_backend => res_a.map_err(log_error)?, - res_b = backend_to_client => res_b.map_err(log_error)?, - }; - - Ok(()) -} +use tokio::net::TcpListener; +use tokio::sync::Mutex; #[tokio::main] async fn main() -> Result<(), Error> { @@ -80,4 +44,4 @@ async fn main() -> Result<(), Error> { } }); } -} \ No newline at end of file +} diff --git a/src/netutils.rs b/src/netutils.rs new file mode 100644 index 0000000..1914e08 --- /dev/null +++ b/src/netutils.rs @@ -0,0 +1,77 @@ +use std::fmt; +use tokio::io; +use tokio::net::{TcpListener, TcpStream}; + +use std::error::Error; + +#[derive(Clone, Debug)] +pub struct Backend { + address: String, +} + +impl Backend { + pub fn new(address: String) -> Self { + Backend { address } + } +} + +impl fmt::Display for Backend { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.address) + } +} + +pub async fn proxy(client_addr: String, server_addr: String) -> Result<(), Box> { + let listener = TcpListener::bind(client_addr.clone()).await?; + println!("Opened {client_addr} -> {server_addr}"); + loop { + let server_addr = server_addr.clone(); + let (client, _) = listener.accept().await?; + tokio::spawn(async move { + let server = TcpStream::connect(server_addr).await.unwrap(); + + let (mut read_client, mut write_client) = client.into_split(); + let (mut read_server, mut write_server) = server.into_split(); + + let forward_to_server = + tokio::spawn(async move { io::copy(&mut read_client, &mut write_server).await }); + + let forward_to_client = + tokio::spawn(async move { io::copy(&mut read_server, &mut write_client).await }); + + let _ = tokio::join!(forward_to_server, forward_to_client); + }); + } +} + +pub async fn proxy_connection( + client_stream: TcpStream, + backend: &Backend, +) -> Result<(), io::Error> { + let log_error = |e| { + eprintln!("error: something went wrong {}", e); + e + }; + + println!("info: connecting to backend {}", backend); + let backend_stream = TcpStream::connect(&backend.address) + .await + .map_err(log_error)?; + println!( + "info: the bluetooth device is connected successfully {}", + backend + ); + + let (mut client_read, mut client_write) = client_stream.into_split(); + let (mut backend_read, mut backend_write) = backend_stream.into_split(); + + let client_to_backend = io::copy(&mut client_read, &mut backend_write); + let backend_to_client = io::copy(&mut backend_read, &mut client_write); + + let _ = tokio::select! { + res_a = client_to_backend => res_a.map_err(log_error)?, + res_b = backend_to_client => res_b.map_err(log_error)?, + }; + + Ok(()) +}