socks5_impl/protocol/
mod.rs

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