socks5_impl/protocol/
reply.rs1#[repr(u8)]
2#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Default)]
3pub enum Reply {
4 #[default]
5 Succeeded = 0x00,
6 GeneralFailure = 0x01,
7 ConnectionNotAllowed = 0x02,
8 NetworkUnreachable = 0x03,
9 HostUnreachable = 0x04,
10 ConnectionRefused = 0x05,
11 TtlExpired = 0x06,
12 CommandNotSupported = 0x07,
13 AddressTypeNotSupported = 0x08,
14}
15
16impl TryFrom<u8> for Reply {
17 type Error = std::io::Error;
18
19 fn try_from(code: u8) -> Result<Self, Self::Error> {
20 let err = format!("Unsupported reply code {0:#x}", code);
21 match code {
22 0x00 => Ok(Reply::Succeeded),
23 0x01 => Ok(Reply::GeneralFailure),
24 0x02 => Ok(Reply::ConnectionNotAllowed),
25 0x03 => Ok(Reply::NetworkUnreachable),
26 0x04 => Ok(Reply::HostUnreachable),
27 0x05 => Ok(Reply::ConnectionRefused),
28 0x06 => Ok(Reply::TtlExpired),
29 0x07 => Ok(Reply::CommandNotSupported),
30 0x08 => Ok(Reply::AddressTypeNotSupported),
31 _ => Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, err)),
32 }
33 }
34}
35
36impl From<Reply> for u8 {
37 fn from(reply: Reply) -> Self {
38 match reply {
39 Reply::Succeeded => 0x00,
40 Reply::GeneralFailure => 0x01,
41 Reply::ConnectionNotAllowed => 0x02,
42 Reply::NetworkUnreachable => 0x03,
43 Reply::HostUnreachable => 0x04,
44 Reply::ConnectionRefused => 0x05,
45 Reply::TtlExpired => 0x06,
46 Reply::CommandNotSupported => 0x07,
47 Reply::AddressTypeNotSupported => 0x08,
48 }
49 }
50}
51
52impl std::fmt::Display for Reply {
53 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54 let s = match self {
55 Reply::Succeeded => "Reply::Succeeded",
56 Reply::GeneralFailure => "Reply::GeneralFailure",
57 Reply::ConnectionNotAllowed => "Reply::ConnectionNotAllowed",
58 Reply::NetworkUnreachable => "Reply::NetworkUnreachable",
59 Reply::HostUnreachable => "Reply::HostUnreachable",
60 Reply::ConnectionRefused => "Reply::ConnectionRefused",
61 Reply::TtlExpired => "Reply::TtlExpired",
62 Reply::CommandNotSupported => "Reply::CommandNotSupported",
63 Reply::AddressTypeNotSupported => "Reply::AddressTypeNotSupported",
64 };
65 write!(f, "{}", s)
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn reply_try_from() {
75 assert_eq!(Reply::try_from(0x00).unwrap(), Reply::Succeeded);
76 assert_eq!(Reply::try_from(0x01).unwrap(), Reply::GeneralFailure);
77 assert_eq!(Reply::try_from(0x02).unwrap(), Reply::ConnectionNotAllowed);
78 assert_eq!(Reply::try_from(0x03).unwrap(), Reply::NetworkUnreachable);
79 assert_eq!(Reply::try_from(0x04).unwrap(), Reply::HostUnreachable);
80 assert_eq!(Reply::try_from(0x05).unwrap(), Reply::ConnectionRefused);
81 assert_eq!(Reply::try_from(0x06).unwrap(), Reply::TtlExpired);
82 assert_eq!(Reply::try_from(0x07).unwrap(), Reply::CommandNotSupported);
83 assert_eq!(Reply::try_from(0x08).unwrap(), Reply::AddressTypeNotSupported);
84 assert!(Reply::try_from(0x09).is_err());
85 }
86
87 #[test]
88 fn reply_from() {
89 assert_eq!(u8::from(Reply::Succeeded), 0x00);
90 assert_eq!(u8::from(Reply::GeneralFailure), 0x01);
91 assert_eq!(u8::from(Reply::ConnectionNotAllowed), 0x02);
92 assert_eq!(u8::from(Reply::NetworkUnreachable), 0x03);
93 assert_eq!(u8::from(Reply::HostUnreachable), 0x04);
94 assert_eq!(u8::from(Reply::ConnectionRefused), 0x05);
95 assert_eq!(u8::from(Reply::TtlExpired), 0x06);
96 assert_eq!(u8::from(Reply::CommandNotSupported), 0x07);
97 assert_eq!(u8::from(Reply::AddressTypeNotSupported), 0x08);
98 }
99}