1use std::io::{self, Result};
2use std::net::SocketAddr;
3use thiserror::Error;
4
5pub const SOCKS_VER: u8 = 0x05;
6pub const SOCKS_RSV: u8 = 0x00;
7pub const SOCKS_COMMAND_CONNECT: u8 = 0x01;
8pub const SOCKS_ADDR_IPV4: u8 = 0x01;
9pub const SOCKS_ADDR_IPV6: u8 = 0x04;
10pub const SOCKS_ADDR_DOMAINNAME: u8 = 0x03;
11
12pub enum Addr {
13 SocketAddr(SocketAddr),
14 HostnamePort(String),
15}
16#[derive(Debug)]
17pub enum AuthMethod {
18 NoAuth,
19 UserPass(Option<(String, String)>),
20 NoAvailable,
21}
22impl AuthMethod {
23 pub fn to_code(&self) -> u8 {
24 use AuthMethod::*;
25 match self {
26 NoAuth => 0x00,
27 UserPass(_) => 0x02,
28 NoAvailable => 0xFF,
29 }
30 }
31 pub fn from_code(code: u8) -> Result<AuthMethod> {
32 use AuthMethod::*;
33 match code {
34 0x00 => Ok(NoAuth),
35 0x02 => Ok(UserPass(None)),
36 0xFF => Ok(NoAvailable),
37 _ => Err(io::Error::new(
38 io::ErrorKind::ConnectionRefused,
39 format!("unsupported authenticate method {:#04X?}", code),
40 )),
41 }
42 }
43}
44#[derive(Error, Debug)]
45pub enum SocksError {
46 #[error("succeeded")]
47 SUCCESS = 0x00,
48 #[error("general SOCKS server failure")]
49 FAIL = 0x01,
50 #[error("connection not allowed by ruleset")]
51 DENY = 0x02,
52 #[error("Network unreachable")]
53 NETWORK = 0x03,
54 #[error("Host unreachable")]
55 HOST = 0x04,
56 #[error("Connection refused")]
57 CONNECTION = 0x05,
58 #[error("TTL expired")]
59 TTL = 0x06,
60 #[error("Command not supported")]
61 COMMAND = 0x07,
62 #[error("Address type not supported")]
63 ADDRESS = 0x08,
64 #[error("unkown error")]
65 OTHOR,
66}
67
68impl Into<io::Error> for SocksError {
69 fn into(self) -> io::Error {
70 io::Error::new(io::ErrorKind::ConnectionAborted, self)
71 }
72}
73
74impl From<u8> for SocksError {
75 fn from(code: u8) -> Self {
76 use SocksError::*;
77 match code {
78 0x01 => FAIL,
79 0x02 => DENY,
80 0x03 => NETWORK,
81 0x04 => HOST,
82 0x05 => CONNECTION,
83 0x06 => TTL,
84 0x07 => COMMAND,
85 0x08 => ADDRESS,
86 _ => OTHOR,
87 }
88 }
89}
90
91pub struct Buffer<'a> {
92 buffer: &'a mut [u8],
93 pos: usize,
94}
95impl<'a> Buffer<'a> {
96 #[inline]
97 pub fn from(buffer: &mut [u8]) -> Buffer {
98 Buffer { buffer, pos: 0 }
99 }
100 #[inline]
101 pub fn content(self) -> &'a [u8] {
102 &self.buffer[..self.pos]
103 }
104 #[inline]
105 pub fn push(&mut self, byte: u8) {
106 self.buffer[self.pos] = byte;
107 self.pos += 1;
108 }
109 #[inline]
110 pub fn extend(&mut self, slice: &[u8]) {
111 let end = self.pos + slice.len();
112 self.buffer[self.pos..end].clone_from_slice(slice);
113 self.pos = end;
114 }
115}
116
117macro_rules! impl_deref {
118 ($x:tt,$y:ty) => {
119 struct $x($y);
120 impl Deref for $x {
121 type Target = $y;
122 fn deref(&self) -> &Self::Target {
123 &self.0
124 }
125 }
126 impl DerefMut for $x {
127 fn deref_mut(&mut self) -> &mut Self::Target {
128 &mut self.0
129 }
130 }
131 };
132}