hyper_util/client/legacy/connect/proxy/socks/
mod.rs
1mod v5;
2pub use v5::{SocksV5, SocksV5Error};
3
4mod v4;
5pub use v4::{SocksV4, SocksV4Error};
6
7use bytes::BytesMut;
8
9use hyper::rt::Read;
10
11#[derive(Debug)]
12pub enum SocksError<C> {
13 Inner(C),
14 Io(std::io::Error),
15
16 DnsFailure,
17 MissingHost,
18 MissingPort,
19
20 V4(SocksV4Error),
21 V5(SocksV5Error),
22
23 Parsing(ParsingError),
24 Serialize(SerializeError),
25}
26
27#[derive(Debug)]
28pub enum ParsingError {
29 Incomplete,
30 WouldOverflow,
31 Other,
32}
33
34#[derive(Debug)]
35pub enum SerializeError {
36 WouldOverflow,
37}
38
39async fn read_message<T, M, C>(mut conn: &mut T, buf: &mut BytesMut) -> Result<M, SocksError<C>>
40where
41 T: Read + Unpin,
42 M: for<'a> TryFrom<&'a mut BytesMut, Error = ParsingError>,
43{
44 let mut tmp = [0; 513];
45
46 loop {
47 let n = crate::rt::read(&mut conn, &mut tmp).await?;
48 buf.extend_from_slice(&tmp[..n]);
49
50 match M::try_from(buf) {
51 Err(ParsingError::Incomplete) => {
52 if n == 0 {
53 if buf.spare_capacity_mut().len() == 0 {
54 return Err(SocksError::Parsing(ParsingError::WouldOverflow));
55 } else {
56 return Err(std::io::Error::new(
57 std::io::ErrorKind::UnexpectedEof,
58 "unexpected eof",
59 )
60 .into());
61 }
62 }
63 }
64 Err(err) => return Err(err.into()),
65 Ok(res) => return Ok(res),
66 }
67 }
68}
69
70impl<C> std::fmt::Display for SocksError<C> {
71 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72 f.write_str("SOCKS error: ")?;
73
74 match self {
75 Self::Inner(_) => f.write_str("failed to create underlying connection"),
76 Self::Io(_) => f.write_str("io error during SOCKS handshake"),
77
78 Self::DnsFailure => f.write_str("could not resolve to acceptable address type"),
79 Self::MissingHost => f.write_str("missing destination host"),
80 Self::MissingPort => f.write_str("missing destination port"),
81
82 Self::Parsing(_) => f.write_str("failed parsing server response"),
83 Self::Serialize(_) => f.write_str("failed serialize request"),
84
85 Self::V4(e) => e.fmt(f),
86 Self::V5(e) => e.fmt(f),
87 }
88 }
89}
90
91impl<C: std::fmt::Debug + std::fmt::Display> std::error::Error for SocksError<C> {}
92
93impl<C> From<std::io::Error> for SocksError<C> {
94 fn from(err: std::io::Error) -> Self {
95 Self::Io(err)
96 }
97}
98
99impl<C> From<ParsingError> for SocksError<C> {
100 fn from(err: ParsingError) -> Self {
101 Self::Parsing(err)
102 }
103}
104
105impl<C> From<SerializeError> for SocksError<C> {
106 fn from(err: SerializeError) -> Self {
107 Self::Serialize(err)
108 }
109}
110
111impl<C> From<SocksV4Error> for SocksError<C> {
112 fn from(err: SocksV4Error) -> Self {
113 Self::V4(err)
114 }
115}
116
117impl<C> From<SocksV5Error> for SocksError<C> {
118 fn from(err: SocksV5Error) -> Self {
119 Self::V5(err)
120 }
121}