socks_lib/v5/
packet.rs

1use bytes::{Buf, BufMut, Bytes, BytesMut};
2
3use crate::io;
4use crate::v5::Address;
5
6/// # UDP Packet
7///
8///
9/// ```text
10///  +-----+------+------+----------+----------+----------+
11///  | RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
12///  +-----+------+------+----------+----------+----------+
13///  |  2  |  1   |  1   | Variable |    2     | Variable |
14///  +-----+------+------+----------+----------+----------+
15/// ```
16///
17#[derive(Debug)]
18pub struct UdpPacket {
19    pub frag: u8,
20    pub address: Address,
21    pub data: Bytes,
22}
23
24impl UdpPacket {
25    pub fn from_bytes<B: Buf>(buf: &mut B) -> io::Result<Self> {
26        if buf.remaining() < 2 {
27            return Err(io::Error::new(
28                io::ErrorKind::InvalidData,
29                "Insufficient data for RSV",
30            ));
31        }
32        buf.advance(2);
33
34        if buf.remaining() < 1 {
35            return Err(io::Error::new(
36                io::ErrorKind::InvalidData,
37                "Insufficient data for FRAG",
38            ));
39        }
40        let frag = buf.get_u8();
41
42        let address = Address::from_bytes(buf)?;
43
44        let data = buf.copy_to_bytes(buf.remaining());
45
46        Ok(Self {
47            frag,
48            address,
49            data,
50        })
51    }
52
53    pub fn to_bytes(&self) -> Bytes {
54        let mut bytes = BytesMut::new();
55
56        bytes.put_u8(0x00);
57        bytes.put_u8(0x00);
58
59        bytes.put_u8(self.frag);
60        bytes.extend(self.address.to_bytes());
61        bytes.extend_from_slice(&self.data);
62
63        bytes.freeze()
64    }
65
66    pub fn un_frag(address: Address, data: Bytes) -> Self {
67        Self {
68            frag: 0,
69            address,
70            data,
71        }
72    }
73}