ombrac_client/endpoint/socks/
mod.rs

1mod v5;
2
3use std::error::Error;
4use std::net::SocketAddr;
5use std::sync::Arc;
6
7use ombrac::request::Address;
8use ombrac::Provider;
9use ombrac_macros::{error, info, try_or_return};
10use tokio::io::{AsyncRead, AsyncWrite};
11use tokio::net::{TcpListener, TcpStream};
12
13use crate::Client;
14
15pub struct Server {}
16
17pub enum Request {
18    TcpConnect(TcpStream, Address),
19}
20
21impl Server {
22    pub async fn listen<T, S>(addr: SocketAddr, ombrac: Client<T>) -> Result<(), Box<dyn Error>>
23    where
24        T: Provider<Item = S> + Send + Sync + 'static,
25        S: AsyncRead + AsyncWrite + Unpin + Send + Sync + 'static,
26    {
27        use ombrac::io::util::copy_bidirectional;
28
29        let ombrac = Arc::new(ombrac);
30        let listener = TcpListener::bind(addr).await?;
31
32        info!("SOCKS server listening on {}", listener.local_addr()?);
33
34        while let Ok((stream, _addr)) = listener.accept().await {
35            let ombrac = ombrac.clone();
36
37            tokio::spawn(async move {
38                let request = try_or_return!(Self::handler_v5(stream).await);
39
40                match request {
41                    Request::TcpConnect(mut inbound, addr) => {
42                        let mut retries = 0;
43                        let mut outbound = loop {
44                            match ombrac.tcp_connect(addr.clone()).await {
45                                Ok(conn) => break conn,
46                                Err(error) => {
47                                    if retries >= 2 {
48                                        error!("{error}");
49                                        return;
50                                    }
51                                    retries += 1;
52                                }
53                            }
54                        };
55
56                        let bytes =
57                            try_or_return!(copy_bidirectional(&mut inbound, &mut outbound).await);
58
59                        info!(
60                            "TCP Connect {:?} Send {}, Receive {}",
61                            addr, bytes.0, bytes.1
62                        );
63                    }
64                };
65            });
66        }
67
68        Ok(())
69    }
70}