eggress_protocol_socks/
error.rs1#[derive(Debug, thiserror::Error)]
3pub enum Socks5Error {
4 #[error("IO error: {0}")]
5 Io(#[from] std::io::Error),
6
7 #[error("unsupported SOCKS version: {0}")]
8 UnsupportedVersion(u8),
9
10 #[error("unsupported command: {0}")]
11 UnsupportedCommand(u8),
12
13 #[error("unsupported address type: {0}")]
14 UnsupportedAddressType(u8),
15
16 #[error("unsupported authentication method: {0}")]
17 UnsupportedAuthMethod(u8),
18
19 #[error("authentication failed")]
20 AuthFailed,
21
22 #[error("credentials too long (max 255 bytes)")]
23 CredentialsTooLong,
24
25 #[error("connection refused by SOCKS server")]
26 ConnectionRefused,
27
28 #[error("connection failed: {0}")]
29 ConnectionFailed(String),
30
31 #[error("malformed message: {0}")]
32 MalformedMessage(String),
33
34 #[error("method negotiation failed")]
35 MethodNegotiationFailed,
36
37 #[error("unexpected end of stream")]
38 UnexpectedEof,
39
40 #[error("address too long")]
41 AddressTooLong,
42
43 #[error("non-zero reserved byte: {0}")]
44 InvalidReservedByte(u8),
45
46 #[error("domain exceeds SOCKS5 255-byte limit: {0}")]
47 DomainTooLong(usize),
48}
49
50impl From<Socks5Error> for std::io::Error {
51 fn from(e: Socks5Error) -> Self {
52 match e {
53 Socks5Error::Io(io_err) => io_err,
54 other => std::io::Error::other(other),
55 }
56 }
57}
58
59impl Socks5Error {
60 pub fn display_hex(&self) -> String {
62 match self {
63 Socks5Error::UnsupportedVersion(v) => {
64 format!("unsupported SOCKS version: {v:#04x}")
65 }
66 Socks5Error::UnsupportedCommand(c) => {
67 format!("unsupported command: {c:#04x}")
68 }
69 Socks5Error::UnsupportedAddressType(a) => {
70 format!("unsupported address type: {a:#04x}")
71 }
72 Socks5Error::UnsupportedAuthMethod(m) => {
73 format!("unsupported authentication method: {m:#04x}")
74 }
75 _ => self.to_string(),
76 }
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn test_error_display() {
86 assert_eq!(
88 Socks5Error::UnsupportedVersion(0x04).to_string(),
89 "unsupported SOCKS version: 4"
90 );
91 assert_eq!(
92 Socks5Error::UnsupportedCommand(0x02).to_string(),
93 "unsupported command: 2"
94 );
95 assert_eq!(
96 Socks5Error::UnsupportedAddressType(0x05).to_string(),
97 "unsupported address type: 5"
98 );
99 assert_eq!(
100 Socks5Error::UnsupportedAuthMethod(0x03).to_string(),
101 "unsupported authentication method: 3"
102 );
103 assert_eq!(Socks5Error::AuthFailed.to_string(), "authentication failed");
104 assert_eq!(
105 Socks5Error::CredentialsTooLong.to_string(),
106 "credentials too long (max 255 bytes)"
107 );
108 assert_eq!(
109 Socks5Error::ConnectionRefused.to_string(),
110 "connection refused by SOCKS server"
111 );
112 assert_eq!(
113 Socks5Error::ConnectionFailed("timeout".to_string()).to_string(),
114 "connection failed: timeout"
115 );
116 assert_eq!(
117 Socks5Error::MalformedMessage("bad".to_string()).to_string(),
118 "malformed message: bad"
119 );
120 assert_eq!(
121 Socks5Error::MethodNegotiationFailed.to_string(),
122 "method negotiation failed"
123 );
124 assert_eq!(
125 Socks5Error::UnexpectedEof.to_string(),
126 "unexpected end of stream"
127 );
128 assert_eq!(Socks5Error::AddressTooLong.to_string(), "address too long");
129 assert_eq!(
130 Socks5Error::InvalidReservedByte(0x01).to_string(),
131 "non-zero reserved byte: 1"
132 );
133 assert_eq!(
134 Socks5Error::DomainTooLong(256).to_string(),
135 "domain exceeds SOCKS5 255-byte limit: 256"
136 );
137 }
138
139 #[test]
140 fn test_error_display_hex() {
141 assert_eq!(
143 Socks5Error::UnsupportedVersion(0x04).display_hex(),
144 "unsupported SOCKS version: 0x04"
145 );
146 assert_eq!(
147 Socks5Error::UnsupportedCommand(0x02).display_hex(),
148 "unsupported command: 0x02"
149 );
150 assert_eq!(
151 Socks5Error::UnsupportedAddressType(0x05).display_hex(),
152 "unsupported address type: 0x05"
153 );
154 assert_eq!(
155 Socks5Error::UnsupportedAuthMethod(0x03).display_hex(),
156 "unsupported authentication method: 0x03"
157 );
158 assert_eq!(
160 Socks5Error::AuthFailed.display_hex(),
161 "authentication failed"
162 );
163 }
164}