1use tokio::io::AsyncWriteExt;
2use async_trait::async_trait;
3
4use crate::error::Result;
5use crate::{AsyncWrite, VERSION, Method, Reply, Addr};
6
7#[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#[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#[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}