socks5_proto/
response.rs

1use crate::{address::AddressError, Address, Error, ProtocolError, Reply};
2use bytes::{BufMut, BytesMut};
3use std::io::Error as IoError;
4use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
5
6/// SOCKS5 response
7///
8/// ```plain
9/// +-----+-----+-------+------+----------+----------+
10/// | VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
11/// +-----+-----+-------+------+----------+----------+
12/// |  1  |  1  | X'00' |  1   | Variable |    2     |
13/// +-----+-----+-------+------+----------+----------+
14/// ```
15#[derive(Clone, Debug)]
16pub struct Response {
17    pub reply: Reply,
18    pub address: Address,
19}
20
21impl Response {
22    pub const fn new(reply: Reply, address: Address) -> Self {
23        Self { reply, address }
24    }
25
26    pub async fn read_from<R>(r: &mut R) -> Result<Self, Error>
27    where
28        R: AsyncRead + Unpin,
29    {
30        let ver = r.read_u8().await?;
31
32        if ver != crate::SOCKS_VERSION {
33            return Err(Error::Protocol(ProtocolError::ProtocolVersion {
34                version: ver,
35            }));
36        }
37
38        let rep = r.read_u8().await?;
39        let rep = Reply::try_from(rep).map_err(|rep| ProtocolError::InvalidReply {
40            version: ver,
41            reply: rep,
42        })?;
43
44        let _ = r.read_u8().await?;
45
46        let addr = Address::read_from(r).await.map_err(|err| match err {
47            AddressError::Io(err) => Error::Io(err),
48            AddressError::InvalidType(code) => {
49                Error::Protocol(ProtocolError::InvalidAddressTypeInResponse {
50                    version: ver,
51                    reply: rep,
52                    address_type: code,
53                })
54            }
55        })?;
56
57        Ok(Self::new(rep, addr))
58    }
59
60    pub async fn write_to<W>(&self, w: &mut W) -> Result<(), IoError>
61    where
62        W: AsyncWrite + Unpin,
63    {
64        let mut buf = BytesMut::with_capacity(self.serialized_len());
65        self.write_to_buf(&mut buf);
66        w.write_all(&buf).await?;
67
68        Ok(())
69    }
70
71    pub fn write_to_buf<B: BufMut>(&self, buf: &mut B) {
72        buf.put_u8(crate::SOCKS_VERSION);
73        buf.put_u8(u8::from(self.reply));
74        buf.put_u8(0x00);
75        self.address.write_to_buf(buf);
76    }
77
78    pub fn serialized_len(&self) -> usize {
79        1 + 1 + 1 + self.address.serialized_len()
80    }
81}