io_proxy/socks/v5/
message.rs1use core::fmt;
6
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub enum Socks5Reply {
10 Succeeded,
12 GeneralFailure,
14 ConnectionNotAllowed,
16 NetworkUnreachable,
18 HostUnreachable,
20 ConnectionRefused,
22 TtlExpired,
24 CommandNotSupported,
26 AddressTypeNotSupported,
28}
29
30impl Socks5Reply {
31 pub fn from_u8(byte: u8) -> Option<Socks5Reply> {
34 let reply = match byte {
35 0x00 => Socks5Reply::Succeeded,
36 0x01 => Socks5Reply::GeneralFailure,
37 0x02 => Socks5Reply::ConnectionNotAllowed,
38 0x03 => Socks5Reply::NetworkUnreachable,
39 0x04 => Socks5Reply::HostUnreachable,
40 0x05 => Socks5Reply::ConnectionRefused,
41 0x06 => Socks5Reply::TtlExpired,
42 0x07 => Socks5Reply::CommandNotSupported,
43 0x08 => Socks5Reply::AddressTypeNotSupported,
44 _ => return None,
45 };
46 Some(reply)
47 }
48}
49
50impl fmt::Display for Socks5Reply {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 let msg = match self {
53 Socks5Reply::Succeeded => "succeeded",
54 Socks5Reply::GeneralFailure => "general SOCKS server failure",
55 Socks5Reply::ConnectionNotAllowed => "connection not allowed by ruleset",
56 Socks5Reply::NetworkUnreachable => "network unreachable",
57 Socks5Reply::HostUnreachable => "host unreachable",
58 Socks5Reply::ConnectionRefused => "connection refused",
59 Socks5Reply::TtlExpired => "TTL expired",
60 Socks5Reply::CommandNotSupported => "command not supported",
61 Socks5Reply::AddressTypeNotSupported => "address type not supported",
62 };
63 f.write_str(msg)
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn from_u8_covers_rfc_range() {
73 assert_eq!(Socks5Reply::from_u8(0x00), Some(Socks5Reply::Succeeded));
74 assert_eq!(
75 Socks5Reply::from_u8(0x08),
76 Some(Socks5Reply::AddressTypeNotSupported)
77 );
78 assert_eq!(Socks5Reply::from_u8(0x09), None);
79 assert_eq!(Socks5Reply::from_u8(0xFF), None);
80 }
81}