socks5_impl/protocol/
mod.rs1mod address;
2mod command;
3pub mod handshake;
4mod proxy_parameters;
5mod reply;
6mod request;
7mod response;
8mod udp;
9
10pub use self::{
11 address::{Address, AddressType},
12 command::Command,
13 handshake::{
14 AuthMethod,
15 password_method::{self, UserKey},
16 },
17 proxy_parameters::{ProxyParameters, ProxyType},
18 reply::Reply,
19 request::Request,
20 response::Response,
21 udp::UdpHeader,
22};
23pub use bytes::BufMut;
24
25#[cfg(feature = "tokio")]
26use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt};
27
28#[repr(u8)]
30#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
31pub enum Version {
32 V4 = 4,
33 #[default]
34 V5 = 5,
35}
36
37impl TryFrom<u8> for Version {
38 type Error = std::io::Error;
39
40 fn try_from(value: u8) -> std::io::Result<Self> {
41 match value {
42 4 => Ok(Version::V4),
43 5 => Ok(Version::V5),
44 _ => Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "invalid version")),
45 }
46 }
47}
48
49impl From<Version> for u8 {
50 fn from(v: Version) -> Self {
51 v as u8
52 }
53}
54
55impl std::fmt::Display for Version {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 let v: u8 = (*self).into();
58 write!(f, "{v}")
59 }
60}
61
62pub trait StreamOperation {
63 fn retrieve_from_stream<R>(stream: &mut R) -> std::io::Result<Self>
64 where
65 R: std::io::Read,
66 Self: Sized;
67
68 fn write_to_stream<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
69 let len = self.len();
70 let mut buf = bytes::BytesMut::with_capacity(len);
71 self.write_to_buf(&mut buf);
72 w.write_all(&buf)
73 }
74
75 fn write_to_buf<B: bytes::BufMut>(&self, buf: &mut B);
76
77 fn len(&self) -> usize;
78
79 fn is_empty(&self) -> bool {
80 self.len() == 0
81 }
82}
83
84#[cfg(feature = "tokio")]
85#[async_trait::async_trait]
86pub trait AsyncStreamOperation: StreamOperation {
87 async fn retrieve_from_async_stream<R>(r: &mut R) -> std::io::Result<Self>
88 where
89 R: AsyncRead + Unpin + Send + ?Sized,
90 Self: Sized;
91
92 async fn write_to_async_stream<W>(&self, w: &mut W) -> std::io::Result<()>
93 where
94 W: AsyncWrite + Unpin + Send + ?Sized,
95 {
96 let mut buf = bytes::BytesMut::with_capacity(self.len());
97 self.write_to_buf(&mut buf);
98 w.write_all(&buf).await
99 }
100}