1use std::net::Ipv4Addr;
2
3use quinn::{Connection, RecvStream, SendStream};
4use tokio::io::{AsyncReadExt, AsyncWriteExt};
5use tokio::net::{TcpListener, TcpStream};
6use tracing::{error, info};
7
8use crate::common::remote;
9use crate::verbose;
10
11use super::remote::RemoteRequest;
12use super::tcp::tunnel_tcp_stream;
13use super::tunnel::{client_send_remote_request, client_send_remote_start};
14use anyhow::{anyhow, Result};
15
16pub async fn tunnel_socks_client(quic_connection: Connection, remote: RemoteRequest) -> Result<()> {
17 let local_addr = format!("{}:{}", remote.local_host, remote.local_port);
18 let listener = TcpListener::bind(&local_addr).await?;
19 info!("SOCKS5 proxy listening on {}", &local_addr);
20
21 loop {
22 let (mut local_conn, local_addr) = listener.accept().await?;
23 let connection = quic_connection.clone();
24 let remote = remote.clone();
25
26 tokio::spawn(async move {
27 let dynamic_remote = socks_handshake(&mut local_conn, &remote).await;
28 match dynamic_remote {
29 Err(e) => error!("Error handshaking with client {}: {}", local_addr, e),
30 Ok(dynamic_remote) => {
31 tokio::spawn(async move {
32 let (send, recv) = match connection.open_bi().await {
33 Ok(stream) => stream,
34 Err(e) => {
35 error!("Failed to open bi connection: {}", e);
36 return;
37 }
39 };
40 match start_client_dynamic_tunnel(local_conn, send, recv, dynamic_remote)
41 .await
42 {
43 Ok(()) => (),
44 Err(e) => {
45 error!("Failed to start dynamic remote: {}", e);
46 }
47 };
48 });
49 }
50 }
51 })
52 .await?;
53 }
54}
55
56async fn start_client_dynamic_tunnel(
57 mut socks_conn: TcpStream,
58 mut send_channel: SendStream,
59 mut recv_channel: RecvStream,
60 dynamic_remote: RemoteRequest,
61) -> Result<()> {
62 client_send_remote_request(&dynamic_remote, &mut send_channel, &mut recv_channel).await?;
63 client_send_remote_start(&mut send_channel, dynamic_remote).await?;
64
65 socks_conn
67 .write_all(&[0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0])
68 .await?;
69
70 tunnel_tcp_stream(socks_conn, send_channel, recv_channel).await?;
71
72 Ok(())
73}
74
75async fn socks_handshake(
78 conn: &mut TcpStream,
79 original_remote: &RemoteRequest,
80) -> Result<RemoteRequest> {
81 let mut buf = [0u8; 256];
83 conn.read_exact(&mut buf[..2]).await?;
84
85 if buf[0] != 0x05 {
86 eprintln!("Unsupported SOCKS version: {}", buf[0]);
87 return Err(anyhow!("Unsupported SOCKS version: {}", buf[0]));
88 }
89
90 let methods_len = buf[1] as usize;
91 conn.read_exact(&mut buf[..methods_len]).await?;
92
93 conn.write_all(&[0x05, 0x00]).await?;
95
96 conn.read_exact(&mut buf[..4]).await?;
98
99 if buf[1] != 0x01 {
100 eprintln!("Unsupported command: {}", buf[1]);
101 conn.write_all(&[0x05, 0x07]).await?; return Err(anyhow!("Unsupported SOCKS command: {}", buf[1]));
103 }
104
105 let dynamic_remote = match buf[3] {
107 0x01 => {
108 let mut addr = [0u8; 4];
110 conn.read_exact(&mut addr).await?;
111 let mut port = [0u8; 2];
112 conn.read_exact(&mut port).await?;
113 let port = u16::from_be_bytes(port);
114 let remote_address = Ipv4Addr::from(addr).to_string();
115 RemoteRequest::new(
116 original_remote.local_host,
117 original_remote.local_port,
118 remote_address,
119 port,
120 original_remote.reversed,
121 remote::Protocol::Tcp,
122 )
123 }
124 0x03 => {
125 let mut len = [0u8; 1];
127 conn.read_exact(&mut len).await?;
128 let mut domain = vec![0u8; len[0] as usize];
129 conn.read_exact(&mut domain).await?;
130 let mut port = [0u8; 2];
131 conn.read_exact(&mut port).await?;
132 let port = u16::from_be_bytes(port);
133 let domain = String::from_utf8_lossy(&domain).into_owned();
134 RemoteRequest::new(
135 original_remote.local_host,
136 original_remote.local_port,
137 domain,
138 port,
139 original_remote.reversed,
140 remote::Protocol::Tcp,
141 )
142 }
143 _ => {
144 eprintln!("Unsupported address type: {}", buf[3]);
145 conn.write_all(&[0x05, 0x08]).await?; return Err(anyhow!("Unsupported address type: {}", buf[3]));
147 }
148 };
149
150 verbose!("Creating dynamic remote: {:?}", dynamic_remote);
151
152 Ok(dynamic_remote)
153}