ts_netstack_smoltcp_socket/
raw.rs1use 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
15pub 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 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 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 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 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 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 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}