socks5_proxy/
utils.rs

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}