socken5/
downstream.rs

1use tokio::io::AsyncWriteExt;
2use async_trait::async_trait;
3
4use crate::error::Result;
5use crate::{AsyncWrite, VERSION, Method, Reply, Addr};
6
7/// ```text
8/// +----+--------+
9/// |VER | METHOD |
10/// +----+--------+
11/// | 1  |   1    |
12/// +----+--------+
13/// ```
14#[derive(Debug)]
15pub struct Handshake(pub Method);
16
17#[async_trait]
18impl AsyncWrite for Handshake {
19    async fn write<W>(&self, buf: &mut W) -> Result<()>
20        where
21            W: AsyncWriteExt + Unpin + Send
22    {
23        buf.write_u8(VERSION).await?;
24        buf.write_u8(u8::from(self.0)).await?;
25        Ok(())
26    }
27}
28
29/// ```text
30/// +----+-----+-------+------+----------+----------+
31/// |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
32/// +----+-----+-------+------+----------+----------+
33/// | 1  |  1  | X'00' |  1   | Variable |    2     |
34/// +----+-----+-------+------+----------+----------+
35/// ```
36#[derive(Debug)]
37pub struct CommandResponse {
38    pub reply: Reply,
39    pub addr: Addr,
40    pub port: u16,
41}
42
43#[async_trait]
44impl AsyncWrite for CommandResponse {
45    async fn write<W>(&self, buf: &mut W) -> Result<()>
46        where
47            W: AsyncWriteExt + Unpin + Send
48    {
49        buf.write_u8(VERSION).await?;
50        buf.write_u8(u8::from(self.reply)).await?;
51        buf.write_u8(0x00).await?;
52
53        match &self.addr {
54            Addr::V4(ip) => {
55                buf.write_u8(0x01).await?;
56                buf.write(&ip.octets()).await?;
57            }
58            Addr::Domain(domain) => {
59                buf.write_u8(0x03).await?;
60                buf.write_u8(u8::try_from(domain.len())?).await?;
61                buf.write(domain.as_bytes()).await?;
62            }
63            Addr::V6(ip) => {
64                buf.write_u8(0x04).await?;
65                buf.write(&ip.octets()).await?;
66            }
67        }
68
69        buf.write_u16(self.port).await?;
70        Ok(())
71    }
72}
73
74/// ```text
75/// +----+--------+
76/// |VER | STATUS |
77/// +----+--------+
78/// | 1  |   1    |
79/// +----+--------+
80/// ```
81#[derive(Debug)]
82pub struct AuthResponse(pub u8);
83
84#[async_trait]
85impl AsyncWrite for AuthResponse {
86    async fn write<W>(&self, buf: &mut W) -> Result<()>
87        where
88            W: AsyncWriteExt + Unpin + Send
89    {
90        buf.write_u8(0x01).await?;
91        buf.write_u8(self.0).await?;
92        Ok(())
93    }
94}