1#[allow(dead_code)]
2use std::{
3 error::Error,
4 fmt,
5 net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs},
6};
7use tokio::{
8 io::{AsyncReadExt, AsyncRead, AsyncWrite},
9 };
11
12pub const VERSION5: u8 = 0x05;
14pub const RESERVED: u8 = 0x00;
15
16pub enum Command {
18 Connect = 0x01,
19 Bind = 0x02,
20 UdpAssosiate = 0x3,
21}
22impl Command {
23 pub fn from(byte: usize) -> Option<Command> {
24 match byte {
25 1 => Some(Command::Connect),
26 2 => Some(Command::Bind),
27 3 => Some(Command::UdpAssosiate),
28 _ => None,
29 }
30 }
31}
32
33#[derive(PartialEq)]
35pub enum AddrType {
36 V4 = 0x01,
37 Domain = 0x03,
38 V6 = 0x04,
39}
40impl AddrType {
41 pub fn from(byte: usize) -> Option<AddrType> {
42 match byte {
43 1 => Some(AddrType::V4),
44 3 => Some(AddrType::Domain),
45 4 => Some(AddrType::V6),
46 _ => None,
47 }
48 }
49
50 pub async fn get_socket_addrs<S: AsyncRead + AsyncWrite + Unpin>(
51 socket: &mut S,
52 ) -> Result<Vec<SocketAddr>, Box<dyn Error>> {
53 let mut addr_type = [0u8; 1];
55 socket.read(&mut addr_type).await?;
56 let addr_type = AddrType::from(addr_type[0] as usize);
57 if let None = addr_type {
58 Err(Response::AddrTypeNotSupported)?;
59 }
60 let addr_type = addr_type.unwrap();
61
62 let addr;
64 if let AddrType::Domain = addr_type {
65 let mut dlen = [0u8; 1];
66 socket.read_exact(&mut dlen).await?;
67 let mut domain = vec![0u8; dlen[0] as usize];
68 socket.read_exact(&mut domain).await?;
69 addr = domain;
70 } else if let AddrType::V4 = addr_type {
71 let mut v4 = [0u8; 4];
72 socket.read_exact(&mut v4).await?;
73 addr = Vec::from(v4);
74 } else {
75 let mut v6 = [0u8; 16];
76 socket.read_exact(&mut v6).await?;
77 addr = Vec::from(v6);
78 }
79
80 let mut port = [0u8; 2];
82 socket.read_exact(&mut port).await?;
83 let port = (u16::from(port[0]) << 8) | u16::from(port[1]);
84
85 match addr_type {
87 AddrType::V6 => {
88 let new_addr = (0..8)
89 .map(|x| (u16::from(addr[(x * 2)]) << 8) | u16::from(addr[(x * 2) + 1]))
90 .collect::<Vec<u16>>();
91 Ok(vec![SocketAddr::from(SocketAddrV6::new(
92 Ipv6Addr::new(
93 new_addr[0],
94 new_addr[1],
95 new_addr[2],
96 new_addr[3],
97 new_addr[4],
98 new_addr[5],
99 new_addr[6],
100 new_addr[7],
101 ),
102 port,
103 0,
104 0,
105 ))])
106 }
107 AddrType::V4 => Ok(vec![SocketAddr::from(SocketAddrV4::new(
108 Ipv4Addr::new(addr[0], addr[1], addr[2], addr[3]),
109 port,
110 ))]),
111 AddrType::Domain => {
112 let mut domain = String::from_utf8_lossy(&addr[..]).to_string();
113 domain.push_str(&":");
114 domain.push_str(&port.to_string());
115 Ok(domain.to_socket_addrs()?.collect())
116 }
117 }
118 }
119}
120
121#[allow(dead_code)]
123#[derive(Debug)]
124pub enum Response {
125 Success = 0x00,
126 Failure = 0x01,
127 RuleFailure = 0x02,
128 NetworkUnreachable = 0x03,
129 HostUnreachable = 0x04,
130 ConnectionRefused = 0x05,
131 TtlExpired = 0x06,
132 CommandNotSupported = 0x07,
133 AddrTypeNotSupported = 0x08,
134}
135impl Error for Response {}
136impl fmt::Display for Response {
137 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
138 write!(f, "Error: {}", self)
139 }
140}
141
142#[derive(PartialEq)]
144pub enum AuthMethod {
145 NoAuth = 0x00,
146 UserPass = 0x02,
147 NoMethods = 0xFF,
148}
149impl AuthMethod {
150 fn from(byte: u8) -> AuthMethod {
151 if byte == (AuthMethod::NoAuth as u8) {
152 AuthMethod::NoAuth
153 } else if byte == (AuthMethod::UserPass as u8) {
154 AuthMethod::UserPass
155 } else {
156 AuthMethod::NoMethods
157 }
158 }
159 pub async fn get_available_methods<S: AsyncRead + AsyncWrite + Unpin>(
160 methods_count: u8,
161 socket: &mut S,
162 ) -> Result<Vec<AuthMethod>, Box<dyn Error>> {
163 let mut methods: Vec<AuthMethod> = Vec::with_capacity(methods_count as usize);
164 for _ in 0..methods_count {
165 let mut method = [0u8; 1];
166 socket.read_exact(&mut method).await?;
167 methods.push(AuthMethod::from(method[0]));
168 }
169 Ok(methods)
170 }
171}