async_proxies/proxies/socks4/
no_ident.rs1use crate::proxy::AsyncProxy;
2use crate::proxies::socks4::general::{Command, ErrorKind};
3use async_trait::async_trait;
4
5use tokio::io::{AsyncReadExt, AsyncWriteExt};
6use tokio::net::TcpStream;
7use tokio::time::timeout;
8
9use std::net::SocketAddr;
10use std::net::SocketAddrV4;
11use std::time::Duration;
12
13pub struct Socks4NoIdent;
14
15pub struct Timeouts {
16 connection_timeout: Duration,
17 write_timeout: Duration,
18 read_timeout: Duration
19}
20
21pub struct ConnParams {
22 socks_addr: SocketAddr,
24 dest_addr: SocketAddrV4,
26 command: Command,
28 timeouts: Timeouts
29}
30
31impl Timeouts {
32 pub fn new(connection_timeout: Duration,
33 write_timeout: Duration,
34 read_timeout: Duration)
35 -> Timeouts
36 {
37 Timeouts { connection_timeout, write_timeout, read_timeout }
38 }
39}
40
41impl ConnParams {
42 pub fn new(socks_addr: SocketAddr, dest_addr: SocketAddrV4,
43 command: Command, timeouts: Timeouts)
44 -> ConnParams
45 {
46 ConnParams { socks_addr, dest_addr, command, timeouts }
47 }
48}
49
50#[async_trait]
51impl AsyncProxy for Socks4NoIdent {
52 type OutputStream = TcpStream;
53 type ErrorKind = ErrorKind;
54 type ConnParams = ConnParams;
55
56 async fn connect(&mut self, params: Self::ConnParams)
57 -> Result<Self::OutputStream, Self::ErrorKind>
58 {
59 let future = TcpStream::connect(params.socks_addr);
61 let future = timeout(params.timeouts.connection_timeout, future);
62 let stream = future.await
67 .map_err(|_| ErrorKind::OperationTimeoutReached)?
68 .map_err(|_| ErrorKind::ConnectionFailed)?;
69
70 const BUFFER_LEN: usize = 1 + 1 + 2 + 4 + 1;
78 let mut buffer = Vec::with_capacity(BUFFER_LEN);
79
80 buffer.push(4);
82 buffer.push(params.command as u8);
84
85 let port_in_bytes = params.dest_addr.port().to_be_bytes();
86 buffer.extend_from_slice(&port_in_bytes[..]);
88
89 let ipaddr_in_bytes = params.dest_addr.ip().octets();
90 buffer.extend_from_slice(&ipaddr_in_bytes[..]);
92
93 buffer.push(0);
95
96 let future = self.write_buffer(&buffer[..], stream);
97 let future = timeout(params.timeouts.write_timeout, future);
98 let mut stream = future.await
99 .map_err(|_| ErrorKind::OperationTimeoutReached)??;
100
101 let future = stream.read(&mut buffer[..]);
102 let future = timeout(params.timeouts.read_timeout, future);
103 let read_bytes = future.await
104 .map_err(|_| ErrorKind::OperationTimeoutReached)?
105 .map_err(|e| ErrorKind::RawStreamIOFailed(e))?;
106
107 if read_bytes < 2 {
108 return Err(ErrorKind::GotBadBuffer)
109 }
110
111 match buffer[1] {
112 0x5a => Ok(stream),
113 0x5b => Err(ErrorKind::RequestDenied),
114 0x5c => Err(ErrorKind::IdentIsUnavailable),
115 0x5d => Err(ErrorKind::BadIdent),
116 _ => Err(ErrorKind::GotBadBuffer)
117 }
118 }
119
120 async fn write_buffer(&mut self, buffer: &[u8], mut stream: Self::OutputStream)
121 -> Result<Self::OutputStream, Self::ErrorKind>
122 {
123 match stream.write_all(buffer).await {
124 Ok(_) => Ok(stream),
125 Err(e) => Err(ErrorKind::RawStreamIOFailed(e))
126 }
127
128 }
134
135 async fn read_buffer(&mut self, buffer: &mut [u8], mut stream: Self::OutputStream)
136 -> Result<Self::OutputStream, Self::ErrorKind>
137 {
138 match stream.read(buffer).await {
139 Ok(_) => Ok(stream),
140 Err(e) => Err(ErrorKind::RawStreamIOFailed(e))
141 }
142 }
143
144 async fn drop_stream(&mut self, _: Self::OutputStream)
145 -> Result<(), Self::ErrorKind>
146 {
147 Ok(())
148 }
149}