Skip to main content

ts_netstack_smoltcp_socket/
raw.rs

1use core::{
2    fmt::{Debug, Formatter},
3    num::NonZeroUsize,
4};
5
6use bytes::Bytes;
7use netcore::{
8    DisplayExt, HasChannel, Response, raw,
9    smoltcp::{
10        iface::SocketHandle,
11        wire::{IpProtocol, IpVersion},
12    },
13};
14
15/// A raw IP socket.
16///
17/// This socket type intercepts all traffic for its protocol number, even if there are
18/// protocol-specific sockets connected or listening.
19pub struct RawSocket {
20    handle: SocketHandle,
21    ip_protocol: IpProtocol,
22    ip_version: IpVersion,
23    sender: netcore::Channel,
24}
25
26impl Debug for RawSocket {
27    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
28        f.debug_struct("UdpSocket")
29            .field("handle", &self.handle.as_display_debug())
30            .field("version", &self.ip_version)
31            .field("proto", &self.ip_protocol)
32            .finish()
33    }
34}
35
36impl RawSocket {
37    pub(crate) fn new(
38        sender: netcore::Channel,
39        handle: SocketHandle,
40        ip_protocol: IpProtocol,
41        ip_version: IpVersion,
42    ) -> Self {
43        Self {
44            handle,
45            ip_protocol,
46            ip_version,
47            sender,
48        }
49    }
50
51    /// Send the raw packet contained in `buf` over the network.
52    pub fn send_blocking(&self, buf: &[u8]) -> Result<(), netcore::Error> {
53        self.request_blocking(raw::Command::Send {
54            buf: Bytes::copy_from_slice(buf),
55        })?
56        .to_ok()
57    }
58
59    /// Send the raw packet contained in `buf` over the network.
60    pub async fn send(&self, buf: &[u8]) -> Result<(), netcore::Error> {
61        self.request(raw::Command::Send {
62            buf: Bytes::copy_from_slice(buf),
63        })
64        .await?
65        .to_ok()
66    }
67
68    /// Receive a raw packet into `buf` from the network.
69    pub fn recv_blocking(&self, buf: &mut [u8]) -> Result<usize, netcore::Error> {
70        let len = NonZeroUsize::new(buf.len()).ok_or(netcore::Error::zero_buffer())?;
71        let resp = self.request_blocking(raw::Command::Recv { max_len: Some(len) })?;
72
73        self._recv(buf, resp)
74    }
75
76    /// Receive a raw packet into `buf` from the network.
77    pub async fn recv(&self, buf: &mut [u8]) -> Result<usize, netcore::Error> {
78        let len = NonZeroUsize::new(buf.len()).ok_or(netcore::Error::zero_buffer())?;
79        let resp = self
80            .request(raw::Command::Recv { max_len: Some(len) })
81            .await?;
82
83        self._recv(buf, resp)
84    }
85
86    /// Receive a raw packet into `buf` from the network.
87    pub fn recv_bytes_blocking(&self) -> Result<Bytes, netcore::Error> {
88        let resp = self.request_blocking(raw::Command::Recv { max_len: None })?;
89        self._recv_bytes(resp)
90    }
91
92    /// Receive a raw packet into `buf` from the network.
93    pub async fn recv_bytes(&self) -> Result<Bytes, netcore::Error> {
94        let resp = self.request(raw::Command::Recv { max_len: None }).await?;
95        self._recv_bytes(resp)
96    }
97
98    fn _recv(&self, buf: &mut [u8], resp: Response) -> Result<usize, netcore::Error> {
99        let ret_buf = self._recv_bytes(resp)?;
100
101        let len = buf.len().min(ret_buf.len());
102        buf[..len].copy_from_slice(&ret_buf[..len]);
103
104        Ok(len)
105    }
106
107    fn _recv_bytes(&self, resp: Response) -> Result<Bytes, netcore::Error> {
108        netcore::try_response_as!(resp, raw::Response::Recv { buf, truncated });
109
110        if let Some(truncated) = truncated {
111            tracing::warn!(truncated, "packet was truncated");
112        }
113
114        Ok(buf)
115    }
116
117    socket_requestor_impl!();
118}
119
120impl Drop for RawSocket {
121    fn drop(&mut self) {
122        if let Err(e) = self
123            .sender
124            .request_nonblocking(Some(self.handle), raw::Command::Close)
125        {
126            tracing::warn!(err = %e, "possible socket leak");
127        }
128    }
129}