1use crate::{
2 Address, AddressType, AsyncStreamOperation, StreamOperation, UserKey,
3 error::{Error, Result},
4 protocol::{AuthMethod, Command, Reply, Version},
5};
6use std::{
7 fmt::Debug,
8 io::Cursor,
9 net::{SocketAddr, ToSocketAddrs},
10 time::Duration,
11};
12use tokio::{
13 io::{AsyncReadExt, AsyncWriteExt, BufStream},
14 net::{TcpStream, UdpSocket},
15};
16
17#[async_trait::async_trait]
18pub trait Socks5Reader: AsyncReadExt + Unpin {
19 async fn read_version(&mut self) -> Result<()> {
20 let value = Version::try_from(self.read_u8().await?)?;
21 match value {
22 Version::V4 => Err(Error::WrongVersion),
23 Version::V5 => Ok(()),
24 }
25 }
26
27 async fn read_method(&mut self) -> Result<AuthMethod> {
28 let value = AuthMethod::from(self.read_u8().await?);
29 match value {
30 AuthMethod::NoAuth | AuthMethod::UserPass => Ok(value),
31 _ => Err(Error::InvalidAuthMethod(value)),
32 }
33 }
34
35 async fn read_command(&mut self) -> Result<Command> {
36 let value = self.read_u8().await?;
37 Ok(Command::try_from(value)?)
38 }
39
40 async fn read_atyp(&mut self) -> Result<AddressType> {
41 let value = self.read_u8().await?;
42 Ok(AddressType::try_from(value)?)
43 }
44
45 async fn read_reserved(&mut self) -> Result<()> {
46 let value = self.read_u8().await?;
47 match value {
48 0x00 => Ok(()),
49 _ => Err(Error::InvalidReserved(value)),
50 }
51 }
52
53 async fn read_fragment_id(&mut self) -> Result<()> {
54 let value = self.read_u8().await?;
55 if value == 0x00 {
56 Ok(())
57 } else {
58 Err(Error::InvalidFragmentId(value))
59 }
60 }
61
62 async fn read_reply(&mut self) -> Result<()> {
63 let value = self.read_u8().await?;
64 match Reply::try_from(value)? {
65 Reply::Succeeded => Ok(()),
66 reply => Err(format!("{reply}").into()),
67 }
68 }
69
70 async fn read_address(&mut self) -> Result<Address> {
71 Ok(Address::retrieve_from_async_stream(self).await?)
72 }
73
74 async fn read_string(&mut self) -> Result<String> {
75 let len = self.read_u8().await? as usize;
76 let mut str = vec![0; len];
77 self.read_exact(&mut str).await?;
78 let str = String::from_utf8(str)?;
79 Ok(str)
80 }
81
82 async fn read_auth_version(&mut self) -> Result<()> {
83 let value = self.read_u8().await?;
84 if value != 0x01 {
85 return Err(Error::InvalidAuthSubnegotiation(value));
86 }
87 Ok(())
88 }
89
90 async fn read_auth_status(&mut self) -> Result<()> {
91 let value = self.read_u8().await?;
92 if value != 0x00 {
93 return Err(Error::InvalidAuthStatus(value));
94 }
95 Ok(())
96 }
97
98 async fn read_selection_msg(&mut self) -> Result<AuthMethod> {
99 self.read_version().await?;
100 self.read_method().await
101 }
102
103 async fn read_final(&mut self) -> Result<Address> {
104 self.read_version().await?;
105 self.read_reply().await?;
106 self.read_reserved().await?;
107 let addr = self.read_address().await?;
108 Ok(addr)
109 }
110}
111
112#[async_trait::async_trait]
113impl<T: AsyncReadExt + Unpin> Socks5Reader for T {}
114
115#[async_trait::async_trait]
116pub trait Socks5Writer: AsyncWriteExt + Unpin {
117 async fn write_version(&mut self) -> Result<()> {
118 self.write_u8(0x05).await?;
119 Ok(())
120 }
121
122 async fn write_method(&mut self, method: AuthMethod) -> Result<()> {
123 self.write_u8(u8::from(method)).await?;
124 Ok(())
125 }
126
127 async fn write_command(&mut self, command: Command) -> Result<()> {
128 self.write_u8(u8::from(command)).await?;
129 Ok(())
130 }
131
132 async fn write_atyp(&mut self, atyp: AddressType) -> Result<()> {
133 self.write_u8(u8::from(atyp)).await?;
134 Ok(())
135 }
136
137 async fn write_reserved(&mut self) -> Result<()> {
138 self.write_u8(0x00).await?;
139 Ok(())
140 }
141
142 async fn write_fragment_id(&mut self, id: u8) -> Result<()> {
143 self.write_u8(id).await?;
144 Ok(())
145 }
146
147 async fn write_address(&mut self, address: &Address) -> Result<()> {
148 address.write_to_async_stream(self).await?;
149 Ok(())
150 }
151
152 async fn write_string(&mut self, string: &str) -> Result<()> {
153 let bytes = string.as_bytes();
154 if bytes.len() > 255 {
155 return Err("Too long string".into());
156 }
157 self.write_u8(bytes.len() as u8).await?;
158 self.write_all(bytes).await?;
159 Ok(())
160 }
161
162 async fn write_auth_version(&mut self) -> Result<()> {
163 self.write_u8(0x01).await?;
164 Ok(())
165 }
166
167 async fn write_methods(&mut self, methods: &[AuthMethod]) -> Result<()> {
168 let method_count = u8::try_from(methods.len()).map_err(|_| "Too many authentication methods")?;
169 self.write_u8(method_count).await?;
170 for method in methods {
171 self.write_method(*method).await?;
172 }
173 Ok(())
174 }
175
176 async fn write_selection_msg(&mut self, methods: &[AuthMethod]) -> Result<()> {
177 self.write_version().await?;
178 self.write_methods(methods).await?;
179 self.flush().await?;
180 Ok(())
181 }
182
183 async fn write_final(&mut self, command: Command, addr: &Address) -> Result<()> {
184 self.write_version().await?;
185 self.write_command(command).await?;
186 self.write_reserved().await?;
187 self.write_address(addr).await?;
188 self.flush().await?;
189 Ok(())
190 }
191}
192
193#[async_trait::async_trait]
194impl<T: AsyncWriteExt + Unpin> Socks5Writer for T {}
195
196async fn username_password_auth<S>(stream: &mut S, auth: &UserKey) -> Result<()>
197where
198 S: Socks5Writer + Socks5Reader + Send,
199{
200 stream.write_auth_version().await?;
201 stream.write_string(&auth.username).await?;
202 stream.write_string(&auth.password).await?;
203 stream.flush().await?;
204
205 stream.read_auth_version().await?;
206 stream.read_auth_status().await
207}
208
209async fn init<S, A>(stream: &mut S, command: Command, addr: A, auth: Option<UserKey>) -> Result<Address>
210where
211 S: Socks5Writer + Socks5Reader + Send,
212 A: Into<Address>,
213{
214 let addr: Address = addr.into();
215
216 let mut methods = Vec::with_capacity(2);
217 methods.push(AuthMethod::NoAuth);
218 if auth.is_some() {
219 methods.push(AuthMethod::UserPass);
220 }
221 stream.write_selection_msg(&methods).await?;
222 stream.flush().await?;
223
224 let method: AuthMethod = stream.read_selection_msg().await?;
225 match method {
226 AuthMethod::NoAuth => {}
227 AuthMethod::UserPass if auth.is_some() => {
228 username_password_auth(stream, auth.as_ref().unwrap()).await?;
229 }
230 _ => return Err(Error::InvalidAuthMethod(method)),
231 }
232
233 stream.write_final(command, &addr).await?;
234 stream.read_final().await
235}
236
237pub async fn connect<S, A>(socket: &mut S, addr: A, auth: Option<UserKey>) -> Result<Address>
256where
257 S: AsyncWriteExt + AsyncReadExt + Send + Unpin,
258 A: Into<Address>,
259{
260 init(socket, Command::Connect, addr, auth).await
261}
262
263#[derive(Debug)]
283pub struct SocksListener<S> {
284 stream: S,
285 proxy_addr: Address,
286}
287
288impl<S> SocksListener<S>
289where
290 S: AsyncWriteExt + AsyncReadExt + Send + Unpin,
291{
292 pub async fn bind<A>(mut stream: S, addr: A, auth: Option<UserKey>) -> Result<Self>
296 where
297 A: Into<Address>,
298 {
299 let addr = init(&mut stream, Command::Bind, addr, auth).await?;
300 Ok(Self { stream, proxy_addr: addr })
301 }
302
303 pub fn proxy_addr(&self) -> &Address {
304 &self.proxy_addr
305 }
306
307 pub async fn accept(mut self) -> Result<(S, Address)> {
308 let addr = self.stream.read_final().await?;
309 Ok((self.stream, addr))
310 }
311}
312
313#[derive(Debug)]
315pub struct SocksDatagram<S> {
316 socket: UdpSocket,
317 proxy_addr: Address,
318 stream: S,
319}
320
321impl<S> SocksDatagram<S>
322where
323 S: AsyncWriteExt + AsyncReadExt + Send + Unpin,
324{
325 pub async fn udp_associate(mut stream: S, socket: UdpSocket, auth: Option<UserKey>) -> Result<Self> {
329 let addr = if socket.local_addr()?.is_ipv4() { "0.0.0.0:0" } else { "[::]:0" };
330 let addr = addr.parse::<SocketAddr>()?;
331 let proxy_addr = init(&mut stream, Command::UdpAssociate, addr, auth).await?;
332 let addr = proxy_addr.to_socket_addrs()?.next().ok_or("InvalidAddress")?;
333 socket.connect(addr).await?;
334 Ok(Self {
335 socket,
336 proxy_addr,
337 stream,
338 })
339 }
340
341 pub fn proxy_addr(&self) -> &Address {
343 &self.proxy_addr
344 }
345
346 pub fn get_ref(&self) -> &UdpSocket {
348 &self.socket
349 }
350
351 pub fn get_mut(&mut self) -> &mut UdpSocket {
353 &mut self.socket
354 }
355
356 pub fn into_inner(self) -> (S, UdpSocket) {
358 (self.stream, self.socket)
359 }
360
361 pub async fn build_socks5_udp_datagram(buf: &[u8], addr: &Address) -> Result<Vec<u8>> {
371 let bytes_size = Self::get_buf_size(addr.len(), buf.len());
372 let bytes = Vec::with_capacity(bytes_size);
373
374 let mut cursor = Cursor::new(bytes);
375 cursor.write_reserved().await?;
376 cursor.write_reserved().await?;
377 cursor.write_fragment_id(0x00).await?;
378 cursor.write_address(addr).await?;
379 cursor.write_all(buf).await?;
380
381 let bytes = cursor.into_inner();
382 Ok(bytes)
383 }
384
385 pub async fn send_to<A>(&self, buf: &[u8], addr: A) -> Result<usize>
387 where
388 A: Into<Address>,
389 {
390 let addr: Address = addr.into();
391 let bytes = Self::build_socks5_udp_datagram(buf, &addr).await?;
392 Ok(self.socket.send(&bytes).await?)
393 }
394
395 async fn parse_socks5_udp_response(bytes: &mut [u8], buf: &mut Vec<u8>) -> Result<(usize, Address)> {
397 let len = bytes.len();
398 let mut cursor = Cursor::new(bytes);
399 cursor.read_reserved().await?;
400 cursor.read_reserved().await?;
401 cursor.read_fragment_id().await?;
402 let addr = cursor.read_address().await?;
403 let header_len = cursor.position() as usize;
404 buf.resize(len - header_len, 0);
405 _ = cursor.read_exact(buf).await?;
406 Ok((len - header_len, addr))
407 }
408
409 pub async fn recv_from(&self, timeout: Duration, buf: &mut Vec<u8>) -> Result<(usize, Address)> {
411 const UDP_MTU: usize = 1500;
412 let bytes_size = UDP_MTU;
414 let mut bytes = vec![0; bytes_size];
415 let len = tokio::time::timeout(timeout, self.socket.recv(&mut bytes)).await??;
416 bytes.truncate(len);
417 let (read, addr) = Self::parse_socks5_udp_response(&mut bytes, buf).await?;
418 Ok((read, addr))
419 }
420
421 fn get_buf_size(addr_size: usize, buf_len: usize) -> usize {
422 2 + 1 + addr_size + buf_len
424 }
425}
426
427pub type GuardTcpStream = BufStream<TcpStream>;
428pub type SocksUdpClient = SocksDatagram<GuardTcpStream>;
429
430#[async_trait::async_trait]
431pub trait UdpClientTrait {
432 async fn send_to<A>(&mut self, buf: &[u8], addr: A) -> Result<usize>
433 where
434 A: Into<Address> + Send + Unpin;
435
436 async fn recv_from(&mut self, timeout: Duration, buf: &mut Vec<u8>) -> Result<(usize, Address)>;
437}
438
439#[async_trait::async_trait]
440impl UdpClientTrait for SocksUdpClient {
441 async fn send_to<A>(&mut self, buf: &[u8], addr: A) -> Result<usize, Error>
442 where
443 A: Into<Address> + Send + Unpin,
444 {
445 SocksDatagram::send_to(self, buf, addr).await
446 }
447
448 async fn recv_from(&mut self, timeout: Duration, buf: &mut Vec<u8>) -> Result<(usize, Address), Error> {
449 SocksDatagram::recv_from(self, timeout, buf).await
450 }
451}
452
453pub async fn create_udp_client<A: Into<SocketAddr>>(proxy_addr: A, auth: Option<UserKey>) -> Result<SocksUdpClient> {
454 let proxy_addr = proxy_addr.into();
455 let client_addr = if proxy_addr.is_ipv4() { "0.0.0.0:0" } else { "[::]:0" };
456 let proxy = TcpStream::connect(proxy_addr).await?;
457 let proxy = BufStream::new(proxy);
458 let client = UdpSocket::bind(client_addr).await?;
459 SocksDatagram::udp_associate(proxy, client, auth).await
460}
461
462pub struct ClientWrapper<C> {
463 client: C,
464}
465
466impl ClientWrapper<SocksUdpClient> {
467 pub async fn transfer_data<A2: Into<Address>>(&self, server_addr: A2, data: &[u8], timeout: Duration) -> Result<Vec<u8>> {
468 let _len = self.send_to(data, server_addr).await?;
469 let mut buf = Vec::with_capacity(data.len());
470 let (_len, _) = self.recv(timeout, &mut buf).await?;
471 Ok(buf)
472 }
473
474 pub async fn send_to<A2: Into<Address>>(&self, data: &[u8], server_addr: A2) -> Result<usize> {
475 self.client.send_to(data, server_addr).await
476 }
477
478 pub async fn recv(&self, timeout: Duration, buf: &mut Vec<u8>) -> Result<(usize, Address)> {
479 self.client.recv_from(timeout, buf).await
480 }
481
482 pub async fn datagram<A1: Into<SocketAddr>>(proxy_addr: A1, auth: Option<UserKey>) -> Result<Self> {
483 let client = create_udp_client(proxy_addr, auth).await?;
484 Ok(Self { client })
485 }
486}
487
488#[cfg(test)]
489mod tests {
490 use crate::{Address, UserKey};
491 use crate::{
492 Error, Result,
493 client::{self, SocksListener, SocksUdpClient, UdpClientTrait},
494 };
495 use std::{
496 net::{SocketAddr, ToSocketAddrs},
497 sync::Arc,
498 time::Duration,
499 };
500 use tokio::{
501 io::{AsyncReadExt, AsyncWriteExt, BufStream},
502 net::{TcpStream, UdpSocket},
503 };
504
505 const PROXY_ADDR: &str = "127.0.0.1:1080";
506 const PROXY_AUTH_ADDR: &str = "127.0.0.1:1081";
507 const DATA: &[u8] = b"Hello, world!";
508
509 async fn connect(addr: &str, auth: Option<UserKey>) {
510 let socket = TcpStream::connect(addr).await.unwrap();
511 let mut socket = BufStream::new(socket);
512 client::connect(&mut socket, Address::from(("baidu.com", 80)), auth).await.unwrap();
513 }
514
515 #[ignore]
516 #[tokio::test]
517 async fn connect_auth() {
518 connect(PROXY_AUTH_ADDR, Some(UserKey::new("hyper", "proxy"))).await;
519 }
520
521 #[ignore]
522 #[tokio::test]
523 async fn connect_no_auth() {
524 connect(PROXY_ADDR, None).await;
525 }
526
527 #[ignore]
528 #[should_panic = "InvalidAuthMethod(NoAcceptableMethods)"]
529 #[tokio::test]
530 async fn connect_no_auth_panic() {
531 connect(PROXY_AUTH_ADDR, None).await;
532 }
533
534 #[ignore]
535 #[tokio::test]
536 async fn bind() {
537 let run_block = async {
538 let server_addr = Address::from(("127.0.0.1", 8000));
539
540 let client = TcpStream::connect(PROXY_ADDR).await?;
541 let client = BufStream::new(client);
542 let client = SocksListener::bind(client, server_addr, None).await?;
543
544 let server_addr = client.proxy_addr.to_socket_addrs()?.next().ok_or("Invalid address")?;
545 let mut server = TcpStream::connect(&server_addr).await?;
546
547 let (mut client, _) = client.accept().await?;
548
549 server.write_all(DATA).await?;
550
551 let mut buf = [0; DATA.len()];
552 client.read_exact(&mut buf).await?;
553 assert_eq!(buf, DATA);
554 Ok::<_, Error>(())
555 };
556 if let Err(e) = run_block.await {
557 println!("{e:?}");
558 }
559 }
560
561 type TestHalves = (Arc<SocksUdpClient>, Arc<SocksUdpClient>);
562
563 #[async_trait::async_trait]
564 impl UdpClientTrait for TestHalves {
565 async fn send_to<A>(&mut self, buf: &[u8], addr: A) -> Result<usize, Error>
566 where
567 A: Into<Address> + Send,
568 {
569 self.1.send_to(buf, addr).await
570 }
571
572 async fn recv_from(&mut self, timeout: Duration, buf: &mut Vec<u8>) -> Result<(usize, Address), Error> {
573 self.0.recv_from(timeout, buf).await
574 }
575 }
576
577 const SERVER_ADDR: &str = "127.0.0.1:23456";
578
579 struct UdpTest<C> {
580 client: C,
581 server: UdpSocket,
582 server_addr: Address,
583 }
584
585 impl<C: UdpClientTrait> UdpTest<C> {
586 async fn test(mut self) {
587 let mut buf = vec![0; DATA.len()];
588 self.client.send_to(DATA, self.server_addr).await.unwrap();
589 let (len, addr) = self.server.recv_from(&mut buf).await.unwrap();
590 assert_eq!(len, buf.len());
591 assert_eq!(buf.as_slice(), DATA);
592
593 let mut buf = vec![0; DATA.len()];
594 self.server.send_to(DATA, addr).await.unwrap();
595 let timeout = Duration::from_secs(5);
596 let (len, _) = self.client.recv_from(timeout, &mut buf).await.unwrap();
597 assert_eq!(len, buf.len());
598 assert_eq!(buf.as_slice(), DATA);
599 }
600 }
601
602 impl UdpTest<SocksUdpClient> {
603 async fn datagram() -> Self {
604 let addr = PROXY_ADDR.parse::<SocketAddr>().unwrap();
605 let client = client::create_udp_client(addr, None).await.unwrap();
606
607 let server_addr: SocketAddr = SERVER_ADDR.parse().unwrap();
608 let server = UdpSocket::bind(server_addr).await.unwrap();
609 let server_addr = Address::from(server_addr);
610
611 Self {
612 client,
613 server,
614 server_addr,
615 }
616 }
617 }
618
619 impl UdpTest<TestHalves> {
620 async fn halves() -> Self {
621 let this = UdpTest::<SocksUdpClient>::datagram().await;
622 let client = Arc::new(this.client);
623 Self {
624 client: (client.clone(), client),
625 server: this.server,
626 server_addr: this.server_addr,
627 }
628 }
629 }
630
631 #[ignore]
632 #[tokio::test]
633 async fn udp_datagram_halves() {
634 UdpTest::halves().await.test().await
635 }
636}