|
1 |
| -use std::sync::Arc; |
2 |
| - |
3 |
| -use fast_socks5::server::Socks5Socket; |
4 |
| -use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; |
| 1 | +use fast_socks5::server::Socks5ServerProtocol; |
| 2 | +use fast_socks5::ReplyError; |
| 3 | +use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite}; |
5 | 4 | use tokio::net::UdpSocket;
|
6 | 5 | use tokio::net::{TcpListener, TcpStream};
|
7 | 6 |
|
@@ -34,100 +33,68 @@ pub async fn socks5_worker() -> Result<()> {
|
34 | 33 | match listener.accept().await {
|
35 | 34 | Ok((mut _socket, _)) => {
|
36 | 35 | tokio::spawn(async {
|
37 |
| - let mut config = fast_socks5::server::BaseConfig::< |
38 |
| - TcpStream, |
39 |
| - fast_socks5::server::DenyAuthentication, |
40 |
| - RforRelaySocket, |
41 |
| - >::default() |
42 |
| - .with_command_executor(RforRelaySocket::default()); |
43 |
| - |
44 |
| - config.set_dns_resolve(false); |
45 |
| - config.set_udp_support(true); |
46 |
| - let mut socks5_socket = Socks5Socket::new(_socket, Arc::new(config)); |
47 |
| - socks5_socket |
48 |
| - .set_reply_ip(std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1))); |
49 |
| - |
50 |
| - match socks5_socket.upgrade_to_socks5().await { |
51 |
| - Ok(_) => {} |
52 |
| - Err(e) => println!("socks5 error: {}", e), |
53 |
| - } |
| 36 | + socks5_instance(_socket).await.unwrap_or_else(|e| { |
| 37 | + println!("socks5 error: {:#}", e); |
| 38 | + }); |
54 | 39 | });
|
55 | 40 | }
|
56 | 41 | Err(e) => println!("couldn't get client: {:?}", e),
|
57 | 42 | }
|
58 | 43 | }
|
59 | 44 | }
|
60 | 45 |
|
61 |
| -#[derive(Copy, Clone, Default)] |
62 |
| -pub struct RforRelaySocket; |
63 |
| - |
64 |
| -#[async_trait::async_trait] |
65 |
| -impl fast_socks5::server::CommandExecutor<TcpStream> for RforRelaySocket { |
66 |
| - async fn connect( |
67 |
| - &self, |
68 |
| - inbound: &mut TcpStream, |
69 |
| - target_addr: &fast_socks5::util::target_addr::TargetAddr, |
70 |
| - _timeout: u64, |
71 |
| - _nodelay: bool, |
72 |
| - ) -> fast_socks5::Result<()> { |
73 |
| - inbound |
74 |
| - .write(&fast_socks5::server::new_reply( |
75 |
| - &fast_socks5::ReplyError::Succeeded, |
76 |
| - std::net::SocketAddr::new(std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)), 0), |
77 |
| - )) |
78 |
| - .await |
79 |
| - .context("Can't write successful reply")?; |
80 |
| - |
81 |
| - inbound.flush().await.context("Can't flush the reply!")?; |
82 |
| - |
83 |
| - let context = match target_addr { |
84 |
| - fast_socks5::util::target_addr::TargetAddr::Ip(sock_addr) => RouteContext { |
85 |
| - src_addr: inbound.peer_addr()?, |
86 |
| - dst_addr: crate::rules::TargetAddr::Ip(sock_addr.to_owned()), |
87 |
| - inbound_proto: Some(InboundProtocol::SOCKS5), |
88 |
| - socket_type: crate::rules::SocketType::STREAM, |
89 |
| - }, |
90 |
| - fast_socks5::util::target_addr::TargetAddr::Domain(domain, port) => RouteContext { |
91 |
| - src_addr: inbound.peer_addr()?, |
92 |
| - dst_addr: crate::rules::TargetAddr::Domain( |
93 |
| - domain.to_owned(), |
94 |
| - port.to_owned(), |
95 |
| - None, |
96 |
| - ), |
97 |
| - inbound_proto: Some(InboundProtocol::SOCKS5), |
98 |
| - socket_type: crate::rules::SocketType::STREAM, |
99 |
| - }, |
100 |
| - }; |
101 |
| - transfer_tcp(inbound, context).await?; |
102 |
| - |
103 |
| - Ok(()) |
104 |
| - } |
| 46 | +async fn socks5_instance(socket: TcpStream) -> Result<()> { |
| 47 | + let (proto, cmd, target_addr) = Socks5ServerProtocol::accept_no_auth(socket).await? |
| 48 | + .read_command().await?; |
| 49 | + |
| 50 | + let empty_ip = std::net::IpAddr::V4(std::net::Ipv4Addr::new(0, 0, 0, 0)); |
| 51 | + let empty_sockaddr = std::net::SocketAddr::new(empty_ip, 0); |
| 52 | + match cmd { |
| 53 | + fast_socks5::Socks5Command::TCPConnect => { |
| 54 | + let mut inner = proto.reply_success(empty_sockaddr).await?; |
| 55 | + let src_addr = inner.peer_addr()?; |
| 56 | + |
| 57 | + let context = match target_addr { |
| 58 | + fast_socks5::util::target_addr::TargetAddr::Ip(sock_addr) => RouteContext { |
| 59 | + src_addr: src_addr, |
| 60 | + dst_addr: crate::rules::TargetAddr::Ip(sock_addr.to_owned()), |
| 61 | + inbound_proto: Some(InboundProtocol::SOCKS5), |
| 62 | + socket_type: crate::rules::SocketType::STREAM, |
| 63 | + }, |
| 64 | + fast_socks5::util::target_addr::TargetAddr::Domain(domain, port) => RouteContext { |
| 65 | + src_addr: src_addr, |
| 66 | + dst_addr: crate::rules::TargetAddr::Domain( |
| 67 | + domain.to_owned(), |
| 68 | + port.to_owned(), |
| 69 | + None, |
| 70 | + ), |
| 71 | + inbound_proto: Some(InboundProtocol::SOCKS5), |
| 72 | + socket_type: crate::rules::SocketType::STREAM, |
| 73 | + }, |
| 74 | + }; |
| 75 | + |
| 76 | + transfer_tcp(&mut inner, context.clone()).await.with_context( |
| 77 | + || format!("failed to relay {}", context), |
| 78 | + )?; |
| 79 | + } |
| 80 | + fast_socks5::Socks5Command::TCPBind => { |
| 81 | + proto.reply_error(&ReplyError::CommandNotSupported).await?; |
| 82 | + return Err(ReplyError::CommandNotSupported.into()); |
| 83 | + } |
| 84 | + fast_socks5::Socks5Command::UDPAssociate => { |
| 85 | + // Listen with UDP6 socket, so the client can connect to it with either |
| 86 | + // IPv4 or IPv6. |
| 87 | + let peer_sock = UdpSocket::bind("[::]:0").await?; |
105 | 88 |
|
106 |
| - /// Bind to a random UDP port, wait for the traffic from |
107 |
| - /// the client, and then forward the data to the remote addr. |
108 |
| - async fn udp_associate( |
109 |
| - &self, |
110 |
| - inbound: &mut TcpStream, |
111 |
| - _: Option<&fast_socks5::util::target_addr::TargetAddr>, |
112 |
| - reply_ip: std::net::IpAddr, |
113 |
| - ) -> fast_socks5::Result<()> { |
114 |
| - |
115 |
| - // Listen with UDP6 socket, so the client can connect to it with either |
116 |
| - // IPv4 or IPv6. |
117 |
| - let peer_sock = UdpSocket::bind("[::]:0").await?; |
118 |
| - |
119 |
| - // Respect the pre-populated reply IP address. |
120 |
| - inbound |
121 |
| - .write(&fast_socks5::server::new_reply( |
122 |
| - &fast_socks5::ReplyError::Succeeded, |
123 |
| - std::net::SocketAddr::new(reply_ip, peer_sock.local_addr()?.port()), |
124 |
| - )) |
125 |
| - .await |
126 |
| - .context("Can't write successful reply")?; |
127 |
| - |
128 |
| - transfer_udp(inbound, peer_sock).await?; |
129 |
| - Ok(()) |
| 89 | + let mut inner = proto.reply_success(std::net::SocketAddr::new( |
| 90 | + empty_ip, peer_sock.local_addr().unwrap().port()) |
| 91 | + ).await?; |
| 92 | + |
| 93 | + transfer_udp(&mut inner, peer_sock).await?; |
| 94 | + } |
130 | 95 | }
|
| 96 | + |
| 97 | + Ok(()) |
131 | 98 | }
|
132 | 99 |
|
133 | 100 | async fn handle_udp_request(inbound: &UdpSocket, outbound: &dyn ProxyDgram) -> Result<()> {
|
|
0 commit comments