1use crate::sync::SpinLock;
4use crate::vfs::{File, FsError, InodeMetadata};
5use alloc::vec;
6use lazy_static::lazy_static;
7use smoltcp::iface::{Interface, SocketHandle as SmoltcpHandle, SocketSet};
8use smoltcp::socket::{tcp, udp};
9use smoltcp::wire::{IpAddress, IpEndpoint, Ipv4Address};
10
11#[derive(Clone, Copy)]
12pub enum SocketHandle {
13 Tcp(SmoltcpHandle),
14 Udp(SmoltcpHandle),
15}
16
17use alloc::collections::BTreeMap;
18use alloc::sync::Arc;
19
20lazy_static! {
21 pub static ref SOCKET_SET: SpinLock<SocketSet<'static>> = SpinLock::new(SocketSet::new(vec![]));
22 pub static ref FD_SOCKET_MAP: SpinLock<BTreeMap<(usize, usize), SocketHandle>> = SpinLock::new(BTreeMap::new());
24 pub static ref GLOBAL_INTERFACE: SpinLock<Option<Interface>> = SpinLock::new(None);
26}
27
28use crate::uapi::fcntl::OpenFlags;
29use crate::uapi::socket::SocketOptions;
30
31pub struct SocketFile {
32 handle: SpinLock<SocketHandle>,
33 local_endpoint: SpinLock<Option<IpEndpoint>>,
34 remote_endpoint: SpinLock<Option<IpEndpoint>>,
35 shutdown_rd: SpinLock<bool>,
36 shutdown_wr: SpinLock<bool>,
37 flags: SpinLock<OpenFlags>,
38 options: SpinLock<SocketOptions>,
39}
40
41impl SocketFile {
42 pub fn new(handle: SocketHandle) -> Self {
43 Self {
44 handle: SpinLock::new(handle),
45 local_endpoint: SpinLock::new(None),
46 remote_endpoint: SpinLock::new(None),
47 shutdown_rd: SpinLock::new(false),
48 shutdown_wr: SpinLock::new(false),
49 flags: SpinLock::new(OpenFlags::empty()),
50 options: SpinLock::new(SocketOptions::default()),
51 }
52 }
53
54 pub fn new_with_flags(handle: SocketHandle, flags: OpenFlags) -> Self {
55 Self {
56 handle: SpinLock::new(handle),
57 local_endpoint: SpinLock::new(None),
58 remote_endpoint: SpinLock::new(None),
59 shutdown_rd: SpinLock::new(false),
60 shutdown_wr: SpinLock::new(false),
61 flags: SpinLock::new(flags),
62 options: SpinLock::new(SocketOptions::default()),
63 }
64 }
65
66 pub fn get_socket_options(&self) -> SocketOptions {
67 *self.options.lock()
68 }
69
70 pub fn set_socket_options(&self, opts: SocketOptions) {
71 *self.options.lock() = opts;
72 }
73
74 pub fn handle(&self) -> SocketHandle {
75 *self.handle.lock()
76 }
77
78 pub fn set_handle(&self, new_handle: SocketHandle) {
79 *self.handle.lock() = new_handle;
80 }
81
82 pub fn set_local_endpoint(&self, endpoint: IpEndpoint) {
83 *self.local_endpoint.lock() = Some(endpoint);
84 }
85
86 pub fn get_local_endpoint(&self) -> Option<IpEndpoint> {
87 *self.local_endpoint.lock()
88 }
89
90 pub fn set_remote_endpoint(&self, endpoint: IpEndpoint) {
91 *self.remote_endpoint.lock() = Some(endpoint);
92 }
93
94 pub fn get_remote_endpoint(&self) -> Option<IpEndpoint> {
95 *self.remote_endpoint.lock()
96 }
97
98 pub fn shutdown_read(&self) {
99 *self.shutdown_rd.lock() = true;
100 }
101
102 pub fn shutdown_write(&self) {
103 *self.shutdown_wr.lock() = true;
104 }
105
106 pub fn is_shutdown_read(&self) -> bool {
107 *self.shutdown_rd.lock()
108 }
109
110 pub fn is_shutdown_write(&self) -> bool {
111 *self.shutdown_wr.lock()
112 }
113}
114
115impl Drop for SocketFile {
116 fn drop(&mut self) {
117 let mut sockets = SOCKET_SET.lock();
118 match *self.handle.lock() {
119 SocketHandle::Tcp(h) => {
120 sockets.remove(h);
121 }
122 SocketHandle::Udp(h) => {
123 sockets.remove(h);
124 }
125 }
126 }
127}
128
129pub fn register_socket_fd(tid: usize, fd: usize, handle: SocketHandle) {
131 FD_SOCKET_MAP.lock().insert((tid, fd), handle);
132}
133
134pub fn unregister_socket_fd(tid: usize, fd: usize) {
136 FD_SOCKET_MAP.lock().remove(&(tid, fd));
137}
138
139pub fn get_socket_handle(tid: usize, fd: usize) -> Option<SocketHandle> {
141 FD_SOCKET_MAP.lock().get(&(tid, fd)).copied()
142}
143
144pub fn update_socket_handle(tid: usize, fd: usize, handle: SocketHandle) {
146 FD_SOCKET_MAP.lock().insert((tid, fd), handle);
147}
148
149pub fn set_socket_local_endpoint(
151 file: &Arc<dyn crate::vfs::File>,
152 endpoint: IpEndpoint,
153) -> Result<(), ()> {
154 let any = file.as_any();
155 if let Some(socket_file) = any.downcast_ref::<SocketFile>() {
156 socket_file.set_local_endpoint(endpoint);
157 Ok(())
158 } else {
159 Err(())
160 }
161}
162
163pub fn get_socket_local_endpoint(file: &Arc<dyn crate::vfs::File>) -> Option<IpEndpoint> {
165 let any = file.as_any();
166 any.downcast_ref::<SocketFile>()
167 .and_then(|socket_file| socket_file.get_local_endpoint())
168}
169
170pub fn set_socket_remote_endpoint(
172 file: &Arc<dyn crate::vfs::File>,
173 endpoint: IpEndpoint,
174) -> Result<(), ()> {
175 let any = file.as_any();
176 if let Some(socket_file) = any.downcast_ref::<SocketFile>() {
177 socket_file.set_remote_endpoint(endpoint);
178 Ok(())
179 } else {
180 Err(())
181 }
182}
183
184pub fn get_socket_remote_endpoint(file: &Arc<dyn crate::vfs::File>) -> Option<IpEndpoint> {
186 let any = file.as_any();
187 any.downcast_ref::<SocketFile>()
188 .and_then(|socket_file| socket_file.get_remote_endpoint())
189}
190
191pub fn socket_shutdown_read(file: &Arc<dyn crate::vfs::File>) {
193 if let Some(socket_file) = file.as_any().downcast_ref::<SocketFile>() {
194 socket_file.shutdown_read();
195 }
196}
197
198pub fn socket_shutdown_write(file: &Arc<dyn crate::vfs::File>) {
200 if let Some(socket_file) = file.as_any().downcast_ref::<SocketFile>() {
201 socket_file.shutdown_write();
202 }
203}
204
205pub fn update_socket_file_handle(
207 file: &Arc<dyn crate::vfs::File>,
208 new_handle: SocketHandle,
209) -> Result<(), ()> {
210 let any = file.as_any();
211 if let Some(socket_file) = any.downcast_ref::<SocketFile>() {
212 socket_file.set_handle(new_handle);
213 Ok(())
214 } else {
215 Err(())
216 }
217}
218
219pub fn socket_sendto(
221 handle: SocketHandle,
222 buf: &[u8],
223 endpoint: IpEndpoint,
224) -> Result<usize, FsError> {
225 let mut sockets = SOCKET_SET.lock();
226 match handle {
227 SocketHandle::Tcp(_) => Err(FsError::NotSupported), SocketHandle::Udp(h) => {
229 let socket = sockets.get_mut::<udp::Socket>(h);
230 socket
231 .send_slice(buf, endpoint)
232 .map_err(|_| FsError::WouldBlock)?;
233 Ok(buf.len())
234 }
235 }
236}
237
238impl File for SocketFile {
239 fn readable(&self) -> bool {
240 let sockets = SOCKET_SET.lock();
241 match *self.handle.lock() {
242 SocketHandle::Tcp(h) => {
243 let socket = sockets.get::<tcp::Socket>(h);
244 socket.can_recv()
245 }
246 SocketHandle::Udp(h) => {
247 let socket = sockets.get::<udp::Socket>(h);
248 socket.can_recv()
249 }
250 }
251 }
252 fn writable(&self) -> bool {
253 let sockets = SOCKET_SET.lock();
254 match *self.handle.lock() {
255 SocketHandle::Tcp(h) => {
256 let socket = sockets.get::<tcp::Socket>(h);
257 socket.can_send()
258 }
259 SocketHandle::Udp(h) => {
260 let socket = sockets.get::<udp::Socket>(h);
261 socket.can_send()
262 }
263 }
264 }
265
266 fn read(&self, buf: &mut [u8]) -> Result<usize, FsError> {
267 if self.is_shutdown_read() {
268 return Ok(0); }
270
271 let mut sockets = SOCKET_SET.lock();
272 let result = match *self.handle.lock() {
273 SocketHandle::Tcp(h) => {
274 let socket = sockets.get_mut::<tcp::Socket>(h);
275 socket.recv_slice(buf).map_err(|_| FsError::WouldBlock)
276 }
277 SocketHandle::Udp(h) => {
278 let socket = sockets.get_mut::<udp::Socket>(h);
279 socket
280 .recv_slice(buf)
281 .map(|(n, _)| n)
282 .map_err(|_| FsError::WouldBlock)
283 }
284 };
285 if result.is_ok() {
286 crate::kernel::syscall::io::wake_poll_waiters();
287 }
288 result
289 }
290
291 fn write(&self, buf: &[u8]) -> Result<usize, FsError> {
292 if self.is_shutdown_write() {
293 return Err(FsError::BrokenPipe);
294 }
295
296 let mut sockets = SOCKET_SET.lock();
297 let result = match *self.handle.lock() {
298 SocketHandle::Tcp(h) => {
299 let socket = sockets.get_mut::<tcp::Socket>(h);
300 socket.send_slice(buf).map_err(|_| FsError::WouldBlock)
301 }
302 SocketHandle::Udp(h) => {
303 let endpoint = match self.get_remote_endpoint() {
304 Some(ep) => ep,
305 None => return Err(FsError::NotConnected),
306 };
307 let socket = sockets.get_mut::<udp::Socket>(h);
308 socket
309 .send_slice(buf, endpoint)
310 .map_err(|_| FsError::WouldBlock)?;
311 Ok(buf.len())
312 }
313 };
314 if result.is_ok() {
315 crate::kernel::syscall::io::wake_poll_waiters();
316 }
317 result
318 }
319
320 fn metadata(&self) -> Result<InodeMetadata, FsError> {
321 Err(FsError::NotSupported)
322 }
323
324 fn as_any(&self) -> &dyn core::any::Any {
325 self
326 }
327
328 fn flags(&self) -> OpenFlags {
329 *self.flags.lock()
330 }
331
332 fn set_status_flags(&self, new_flags: OpenFlags) -> Result<(), FsError> {
333 *self.flags.lock() = new_flags;
334 Ok(())
335 }
336
337 fn recvfrom(&self, buf: &mut [u8]) -> Result<(usize, Option<alloc::vec::Vec<u8>>), FsError> {
338 if self.is_shutdown_read() {
339 return Ok((0, None));
340 }
341
342 let mut sockets = SOCKET_SET.lock();
343 match *self.handle.lock() {
344 SocketHandle::Tcp(h) => {
345 let socket = sockets.get_mut::<tcp::Socket>(h);
346 let n = socket.recv_slice(buf).map_err(|_| FsError::WouldBlock)?;
347 let remote = socket.remote_endpoint().map(|ep| {
348 let mut addr_buf = alloc::vec![0u8; 16];
349 let _ = write_sockaddr_in_to_buf(&mut addr_buf, ep);
350 addr_buf
351 });
352 Ok((n, remote))
353 }
354 SocketHandle::Udp(h) => {
355 let socket = sockets.get_mut::<udp::Socket>(h);
356 let (n, metadata) = socket.recv_slice(buf).map_err(|_| FsError::WouldBlock)?;
357 let mut addr_buf = alloc::vec![0u8; 16];
358 let _ = write_sockaddr_in_to_buf(&mut addr_buf, metadata.endpoint);
359 Ok((n, Some(addr_buf)))
360 }
361 }
362 }
363}
364
365pub fn create_tcp_socket() -> Result<SocketHandle, ()> {
366 let mut rx_vec = alloc::vec::Vec::new();
368 rx_vec.try_reserve(4096).map_err(|_| ())?;
369 rx_vec.resize(4096, 0);
370
371 let mut tx_vec = alloc::vec::Vec::new();
372 tx_vec.try_reserve(4096).map_err(|_| ())?;
373 tx_vec.resize(4096, 0);
374
375 let rx_buffer = tcp::SocketBuffer::new(rx_vec);
376 let tx_buffer = tcp::SocketBuffer::new(tx_vec);
377 let socket = tcp::Socket::new(rx_buffer, tx_buffer);
378 let handle = SOCKET_SET.lock().add(socket);
379 Ok(SocketHandle::Tcp(handle))
380}
381
382pub fn create_udp_socket() -> Result<SocketHandle, ()> {
383 let mut rx_meta_vec = alloc::vec::Vec::new();
385 rx_meta_vec.try_reserve(4).map_err(|_| ())?;
386 rx_meta_vec.resize(4, udp::PacketMetadata::EMPTY);
387
388 let mut tx_meta_vec = alloc::vec::Vec::new();
389 tx_meta_vec.try_reserve(4).map_err(|_| ())?;
390 tx_meta_vec.resize(4, udp::PacketMetadata::EMPTY);
391
392 let mut rx_data_vec = alloc::vec::Vec::new();
394 rx_data_vec.try_reserve(4096).map_err(|_| ())?;
395 rx_data_vec.resize(4096, 0);
396
397 let mut tx_data_vec = alloc::vec::Vec::new();
398 tx_data_vec.try_reserve(4096).map_err(|_| ())?;
399 tx_data_vec.resize(4096, 0);
400
401 let rx_buffer = udp::PacketBuffer::new(rx_meta_vec, rx_data_vec);
402 let tx_buffer = udp::PacketBuffer::new(tx_meta_vec, tx_data_vec);
403 let socket = udp::Socket::new(rx_buffer, tx_buffer);
404 let handle = SOCKET_SET.lock().add(socket);
405 Ok(SocketHandle::Udp(handle))
406}
407
408const AF_INET: u16 = 2;
409const SOCKADDR_IN_SIZE: usize = 16;
410
411pub fn parse_sockaddr_in(addr: *const u8, addrlen: u32) -> Result<IpEndpoint, ()> {
413 if (addrlen as usize) < SOCKADDR_IN_SIZE {
414 return Err(());
415 }
416
417 unsafe {
418 let family = core::ptr::read_unaligned(addr as *const u16);
419 if family != AF_INET {
420 return Err(());
421 }
422
423 let port = u16::from_be(core::ptr::read_unaligned(addr.add(2) as *const u16));
424 let ip_bytes = core::slice::from_raw_parts(addr.add(4), 4);
425 let ip = Ipv4Address::from_octets([ip_bytes[0], ip_bytes[1], ip_bytes[2], ip_bytes[3]]);
426
427 Ok(IpEndpoint::new(IpAddress::Ipv4(ip), port))
428 }
429}
430
431fn write_sockaddr_in_to_buf(buf: &mut [u8], endpoint: IpEndpoint) -> Result<(), ()> {
433 if buf.len() < SOCKADDR_IN_SIZE {
434 return Err(());
435 }
436
437 buf[0..2].copy_from_slice(&AF_INET.to_ne_bytes());
439
440 buf[2..4].copy_from_slice(&endpoint.port.to_be_bytes());
442
443 match endpoint.addr {
445 IpAddress::Ipv4(ipv4) => {
446 buf[4..8].copy_from_slice(&ipv4.octets());
447 }
448 #[cfg(feature = "proto-ipv6")]
449 IpAddress::Ipv6(_) => {
450 return Err(()); }
452 _ => {
453 return Err(()); }
455 }
456
457 buf[8..16].fill(0);
459
460 Ok(())
461}
462
463pub fn write_sockaddr_in(addr: *mut u8, addrlen: *mut u32, endpoint: IpEndpoint) -> Result<(), ()> {
465 if addr.is_null() || addrlen.is_null() {
466 return Ok(());
467 }
468
469 unsafe {
470 let len = *addrlen as usize;
471 if len < SOCKADDR_IN_SIZE {
472 return Err(());
473 }
474
475 let buf = core::slice::from_raw_parts_mut(addr, SOCKADDR_IN_SIZE);
476 write_sockaddr_in_to_buf(buf, endpoint)?;
477
478 *addrlen = SOCKADDR_IN_SIZE as u32;
479 }
480
481 Ok(())
482}
483
484pub fn init_global_interface(iface: Interface) {
486 *GLOBAL_INTERFACE.lock() = Some(iface);
487}
488
489pub fn tcp_connect(handle: SmoltcpHandle, remote: IpEndpoint, local: IpEndpoint) -> Result<(), ()> {
491 let mut iface_guard = GLOBAL_INTERFACE.lock();
492 let iface = iface_guard.as_mut().ok_or(())?;
493
494 let mut sockets = SOCKET_SET.lock();
495 let socket = sockets.get_mut::<tcp::Socket>(handle);
496
497 socket
498 .connect(iface.context(), remote, local)
499 .map_err(|_| ())
500}