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