1use smoltcp::{
2 socket::{tcp, udp},
3 wire::IpAddress,
4};
5use strate_net::IpcMessage;
6
7use crate::{
8 ipc::{reply_read, reply_write, write_data},
9 state::{NetworkStrate, TcpConnState, TcpListenerState, UdpConnState},
10};
11
12impl NetworkStrate {
13 pub(crate) fn handle_tcp_read(
14 &mut self,
15 sender: u64,
16 listener: TcpListenerState,
17 requested: usize,
18 ) -> IpcMessage {
19 if requested == 0 {
20 return reply_read(sender, &[]);
21 }
22 let socket = self.sockets.get_mut::<tcp::Socket>(listener.socket);
23 if !socket.is_open() || (!socket.is_listening() && !socket.is_active()) {
24 if listener.auto_relisten {
25 let _ = socket.listen(listener.port);
26 } else {
27 return IpcMessage::error_reply(sender, -104);
28 }
29 }
30
31 let mut data = [0u8; IpcMessage::READ_INLINE_CAPACITY];
32 if socket.can_recv() {
33 let want = requested.min(data.len());
34 match socket.recv_slice(&mut data[..want]) {
35 Ok(n) => return reply_read(sender, &data[..n]),
36 Err(_) => return IpcMessage::error_reply(sender, -5),
37 }
38 }
39
40 if socket.is_open() && !socket.may_recv() && !socket.may_send() {
41 socket.abort();
42 if listener.auto_relisten {
43 let _ = socket.listen(listener.port);
44 } else {
45 return IpcMessage::error_reply(sender, -104);
46 }
47 }
48 IpcMessage::error_reply(sender, -11)
49 }
50
51 pub(crate) fn handle_tcp_write(
52 &mut self,
53 sender: u64,
54 listener: TcpListenerState,
55 msg: &IpcMessage,
56 ) -> IpcMessage {
57 let socket = self.sockets.get_mut::<tcp::Socket>(listener.socket);
58 if !socket.is_open() || (!socket.is_listening() && !socket.is_active()) {
59 if listener.auto_relisten {
60 let _ = socket.listen(listener.port);
61 } else {
62 return IpcMessage::error_reply(sender, -104);
63 }
64 }
65
66 let data = write_data(msg);
67 if !socket.can_send() {
68 return IpcMessage::error_reply(sender, -11);
69 }
70
71 match socket.send_slice(data) {
72 Ok(n) => reply_write(sender, n),
73 Err(_) => IpcMessage::error_reply(sender, -11),
74 }
75 }
76
77 pub(crate) fn handle_tcp_conn_read(
78 &mut self,
79 sender: u64,
80 conn: TcpConnState,
81 requested: usize,
82 ) -> IpcMessage {
83 if requested == 0 {
84 return reply_read(sender, &[]);
85 }
86 let socket = self.sockets.get_mut::<tcp::Socket>(conn.socket);
87 if !socket.is_open() {
88 return IpcMessage::error_reply(sender, -104);
89 }
90 let state = socket.state();
91 if state == tcp::State::SynSent || state == tcp::State::SynReceived {
92 return IpcMessage::error_reply(sender, -115);
93 }
94
95 let mut data = [0u8; IpcMessage::READ_INLINE_CAPACITY];
96 if socket.can_recv() {
97 let want = requested.min(data.len());
98 match socket.recv_slice(&mut data[..want]) {
99 Ok(n) => reply_read(sender, &data[..n]),
100 Err(_) => IpcMessage::error_reply(sender, -5),
101 }
102 } else {
103 IpcMessage::error_reply(sender, -11)
104 }
105 }
106
107 pub(crate) fn handle_tcp_conn_write(
108 &mut self,
109 sender: u64,
110 conn: TcpConnState,
111 msg: &IpcMessage,
112 ) -> IpcMessage {
113 let socket = self.sockets.get_mut::<tcp::Socket>(conn.socket);
114 if !socket.is_open() {
115 return IpcMessage::error_reply(sender, -104);
116 }
117 let state = socket.state();
118 if state == tcp::State::SynSent || state == tcp::State::SynReceived {
119 return IpcMessage::error_reply(sender, -115);
120 }
121
122 let data = write_data(msg);
123 if !socket.can_send() {
124 return IpcMessage::error_reply(sender, -11);
125 }
126 match socket.send_slice(data) {
127 Ok(n) => reply_write(sender, n),
128 Err(_) => IpcMessage::error_reply(sender, -11),
129 }
130 }
131
132 pub(crate) fn handle_udp_bound_read(
133 &mut self,
134 sender: u64,
135 file_id: u64,
136 requested: usize,
137 ) -> IpcMessage {
138 if requested == 0 {
139 return reply_read(sender, &[]);
140 }
141 if let Some(reply) = self.drain_spilled_read(sender, file_id, requested) {
142 return reply;
143 }
144 let socket_handle = match self.udp_bound.get(&file_id) {
145 Some(state) => state.socket,
146 None => return IpcMessage::error_reply(sender, -9),
147 };
148
149 let (peer, out) = {
150 let socket = self.sockets.get_mut::<udp::Socket>(socket_handle);
151 let Ok((data, meta)) = socket.recv() else {
152 return IpcMessage::error_reply(sender, -11);
153 };
154
155 let mut out = alloc::vec![0u8; 19 + data.len()];
156 match meta.endpoint.addr {
157 IpAddress::Ipv4(src_ip) => {
158 out[0] = 4;
159 out[1..5].copy_from_slice(&src_ip.octets());
160 }
161 IpAddress::Ipv6(src_ip) => {
162 out[0] = 6;
163 out[1..17].copy_from_slice(&src_ip.octets());
164 }
165 }
166 out[17..19].copy_from_slice(&meta.endpoint.port.to_be_bytes());
167 out[19..].copy_from_slice(data);
168 (meta.endpoint, out)
169 };
170
171 if let Some(state) = self.udp_bound.get_mut(&file_id) {
172 state.last_peer = Some(peer);
173 }
174
175 self.reply_read_spilling(sender, file_id, requested, out)
176 }
177
178 pub(crate) fn handle_udp_bound_write(
179 &mut self,
180 sender: u64,
181 file_id: u64,
182 msg: &IpcMessage,
183 ) -> IpcMessage {
184 let state = match self.udp_bound.get(&file_id).copied() {
185 Some(state) => state,
186 None => return IpcMessage::error_reply(sender, -9),
187 };
188 let Some(peer) = state.last_peer else {
189 return IpcMessage::error_reply(sender, -89);
190 };
191
192 let socket = self.sockets.get_mut::<udp::Socket>(state.socket);
193 let data = write_data(msg);
194 if !socket.can_send() {
195 return IpcMessage::error_reply(sender, -11);
196 }
197 match socket.send_slice(data, peer) {
198 Ok(()) => reply_write(sender, data.len()),
199 Err(udp::SendError::BufferFull) => IpcMessage::error_reply(sender, -11),
200 Err(udp::SendError::Unaddressable) => IpcMessage::error_reply(sender, -22),
201 }
202 }
203
204 pub(crate) fn handle_udp_conn_read(
205 &mut self,
206 sender: u64,
207 file_id: u64,
208 conn: UdpConnState,
209 requested: usize,
210 ) -> IpcMessage {
211 if requested == 0 {
212 return reply_read(sender, &[]);
213 }
214 if let Some(reply) = self.drain_spilled_read(sender, file_id, requested) {
215 return reply;
216 }
217
218 let packet = {
219 let socket = self.sockets.get_mut::<udp::Socket>(conn.socket);
220 let mut packet = None;
221 while socket.can_recv() {
222 let Ok((data, meta)) = socket.recv() else {
223 break;
224 };
225 if meta.endpoint.addr == conn.remote.addr && meta.endpoint.port == conn.remote.port
226 {
227 packet = Some(data.to_vec());
228 break;
229 }
230 }
231 packet
232 };
233 if let Some(packet) = packet {
234 return self.reply_read_spilling(sender, file_id, requested, packet);
235 }
236 IpcMessage::error_reply(sender, -11)
237 }
238
239 pub(crate) fn handle_udp_conn_write(
240 &mut self,
241 sender: u64,
242 conn: UdpConnState,
243 msg: &IpcMessage,
244 ) -> IpcMessage {
245 let socket = self.sockets.get_mut::<udp::Socket>(conn.socket);
246 let data = write_data(msg);
247 if !socket.can_send() {
248 return IpcMessage::error_reply(sender, -11);
249 }
250 match socket.send_slice(data, conn.remote) {
251 Ok(()) => reply_write(sender, data.len()),
252 Err(udp::SendError::BufferFull) => IpcMessage::error_reply(sender, -11),
253 Err(udp::SendError::Unaddressable) => IpcMessage::error_reply(sender, -22),
254 }
255 }
256}