Skip to main content

starnix_core/vfs/socket/
socket.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use super::{
6    NetlinkFamily, QipcrtrSocket, SocketAddress, SocketBpfState, SocketDomain, SocketFile,
7    SocketMessageFlags, SocketProtocol, SocketShutdownFlags, SocketType, UnixSocket, VsockSocket,
8    ZxioBackedSocket, new_netlink_socket,
9};
10use crate::mm::MemoryAccessorExt;
11use crate::security;
12use crate::syscalls::time::TimeValPtr;
13use crate::task::{CurrentTask, EventHandler, WaitCanceler, Waiter};
14use crate::vfs::buffers::{AncillaryData, InputBuffer, MessageReadInfo, OutputBuffer};
15use crate::vfs::{DowncastedFile, FileHandle, FileObject, FsNodeHandle};
16use starnix_logging::track_stub;
17use starnix_sync::{LockDepMutex, SocketStateLock};
18use starnix_syscalls::{SyscallArg, SyscallResult};
19use starnix_types::time::{duration_from_timeval, timeval_from_duration};
20use starnix_types::user_buffer::UserBuffer;
21use starnix_uapi::as_any::AsAny;
22use starnix_uapi::auth::CAP_NET_RAW;
23use starnix_uapi::errors::{ENOTTY, Errno};
24use starnix_uapi::user_address::MappingMultiArchUserRef;
25use starnix_uapi::vfs::FdEvents;
26use starnix_uapi::{
27    SO_DOMAIN, SO_PROTOCOL, SO_RCVTIMEO, SO_SNDTIMEO, SO_TYPE, SOL_SOCKET, errno, error, uapi,
28};
29use std::collections::VecDeque;
30use std::sync::Arc;
31use std::sync::atomic::Ordering;
32use zerocopy::FromBytes;
33
34pub const DEFAULT_LISTEN_BACKLOG: usize = 1024;
35
36/// TODO(https://fxbug.dev/477273398"): These come from Android, and are currently stubbed out.
37const SO_ANDROID_DROP_REASON: u32 = 0xAD01D01;
38const ANDROID_DROP_REASON_NONE: u64 = 0;
39
40pub trait SocketOps: Send + Sync + AsAny {
41    /// Returns the domain, type and protocol of the socket. This is only used for socket that are
42    /// build without previous knowledge of this information, and can be ignored if all sockets are
43    /// build with it.
44    fn get_socket_info(&self) -> Result<(SocketDomain, SocketType, SocketProtocol), Errno> {
45        // This should not be used by most socket type that are created with their domain, type and
46        // protocol.
47        error!(EINVAL)
48    }
49
50    /// Connect the `socket` to the listening `peer`. On success
51    /// a new socket is created and added to the accept queue.
52    fn connect(
53        &self,
54        socket: &SocketHandle,
55        current_task: &CurrentTask,
56        peer: SocketPeer,
57    ) -> Result<(), Errno>;
58
59    /// Start listening at the bound address for `connect` calls.
60    fn listen(&self, socket: &Socket, backlog: i32, credentials: uapi::ucred) -> Result<(), Errno>;
61
62    /// Returns the eariest socket on the accept queue of this
63    /// listening socket. Returns EAGAIN if the queue is empty.
64    fn accept(&self, socket: &Socket, current_task: &CurrentTask) -> Result<SocketHandle, Errno>;
65
66    /// Binds this socket to a `socket_address`.
67    ///
68    /// Returns an error if the socket could not be bound.
69    fn bind(
70        &self,
71        socket: &Socket,
72        current_task: &CurrentTask,
73        socket_address: SocketAddress,
74    ) -> Result<(), Errno>;
75
76    /// Reads the specified number of bytes from the socket, if possible.
77    ///
78    /// # Parameters
79    /// - `task`: The task to which the user buffers belong (i.e., the task to which the read bytes
80    ///           are written.
81    /// - `data`: The buffers to write the read data into.
82    ///
83    /// Returns the number of bytes that were written to the user buffers, as well as any ancillary
84    /// data associated with the read messages.
85    fn read(
86        &self,
87        socket: &Socket,
88        current_task: &CurrentTask,
89        data: &mut dyn OutputBuffer,
90        flags: SocketMessageFlags,
91    ) -> Result<MessageReadInfo, Errno>;
92
93    /// Writes the data in the provided user buffers to this socket.
94    ///
95    /// # Parameters
96    /// - `task`: The task to which the user buffers belong, used to read the memory.
97    /// - `data`: The data to write to the socket.
98    /// - `ancillary_data`: Optional ancillary data (a.k.a., control message) to write.
99    ///
100    /// Advances the iterator to indicate how much was actually written.
101    fn write(
102        &self,
103        socket: &Socket,
104        current_task: &CurrentTask,
105        data: &mut dyn InputBuffer,
106        dest_address: &mut Option<SocketAddress>,
107        ancillary_data: &mut Vec<AncillaryData>,
108    ) -> Result<usize, Errno>;
109
110    /// Queues an asynchronous wait for the specified `events`
111    /// on the `waiter`. Note that no wait occurs until a
112    /// wait functions is called on the `waiter`.
113    ///
114    /// # Parameters
115    /// - `waiter`: The Waiter that can be waited on, for example by
116    ///             calling Waiter::wait_until.
117    /// - `events`: The events that will trigger the waiter to wake up.
118    /// - `handler`: A handler that will be called on wake-up.
119    /// Returns a WaitCanceler that can be used to cancel the wait.
120    fn wait_async(
121        &self,
122        socket: &Socket,
123        current_task: &CurrentTask,
124        waiter: &Waiter,
125        events: FdEvents,
126        handler: EventHandler,
127    ) -> WaitCanceler;
128
129    /// Return the events that are currently active on the `socket`.
130    fn query_events(&self, socket: &Socket, current_task: &CurrentTask) -> Result<FdEvents, Errno>;
131
132    /// Shuts down this socket according to how, preventing any future reads and/or writes.
133    ///
134    /// Used by the shutdown syscalls.
135    fn shutdown(&self, socket: &Socket, how: SocketShutdownFlags) -> Result<(), Errno>;
136
137    /// Close this socket.
138    ///
139    /// Called by SocketFile when the file descriptor that is holding this
140    /// socket is closed.
141    ///
142    /// Close differs from shutdown in two ways. First, close will call
143    /// mark_peer_closed_with_unread_data if this socket has unread data,
144    /// which changes how read() behaves on that socket. Second, close
145    /// transitions the internal state of this socket to Closed, which breaks
146    /// the reference cycle that exists in the connected state.
147    fn close(&self, current_task: &CurrentTask, socket: &Socket);
148
149    /// Returns the name of this socket.
150    ///
151    /// The name is derived from the address and domain. A socket
152    /// will always have a name, even if it is not bound to an address.
153    fn getsockname(&self, socket: &Socket) -> Result<SocketAddress, Errno>;
154
155    /// Returns the name of the peer of this socket, if such a peer exists.
156    ///
157    /// Returns an error if the socket is not connected.
158    fn getpeername(&self, socket: &Socket) -> Result<SocketAddress, Errno>;
159
160    /// Sets socket-specific options.
161    fn setsockopt(
162        &self,
163        _socket: &Socket,
164        _current_task: &CurrentTask,
165        _level: u32,
166        _optname: u32,
167        _optval: SockOptValue,
168    ) -> Result<(), Errno> {
169        error!(ENOPROTOOPT)
170    }
171
172    /// Retrieves socket-specific options.
173    fn getsockopt(
174        &self,
175        _socket: &Socket,
176        _current_task: &CurrentTask,
177        _level: u32,
178        _optname: u32,
179        _optlen: u32,
180    ) -> Result<Vec<u8>, Errno> {
181        error!(ENOPROTOOPT)
182    }
183
184    /// Implements ioctl.
185    fn ioctl(
186        &self,
187        _socket: &Socket,
188        _file: &FileObject,
189        _current_task: &CurrentTask,
190        _request: u32,
191        _arg: SyscallArg,
192    ) -> Result<SyscallResult, Errno> {
193        error!(ENOTTY)
194    }
195
196    /// Return a handle that allows access to this file descritor through the zxio protocols.
197    ///
198    /// If None is returned, the file will be proxied.
199    fn to_handle(
200        &self,
201        _socket: &Socket,
202        _current_task: &CurrentTask,
203    ) -> Result<Option<zx::NullableHandle>, Errno> {
204        Ok(None)
205    }
206}
207
208/// A `Socket` represents one endpoint of a bidirectional communication channel.
209pub struct Socket {
210    pub(super) ops: Box<dyn SocketOps>,
211
212    /// The domain of this socket.
213    pub domain: SocketDomain,
214
215    /// The type of this socket.
216    pub socket_type: SocketType,
217
218    /// The protocol of this socket.
219    pub protocol: SocketProtocol,
220
221    state: LockDepMutex<SocketState, SocketStateLock>,
222
223    /// Security module state associated with this socket. Note that the socket's security label is
224    /// applied to the associated `fs_node`.
225    pub security: security::SocketState,
226}
227
228#[derive(Default)]
229struct SocketState {
230    /// The value of SO_RCVTIMEO.
231    receive_timeout: Option<zx::MonotonicDuration>,
232
233    /// The value for SO_SNDTIMEO.
234    send_timeout: Option<zx::MonotonicDuration>,
235
236    /// Reference to the [`crate::vfs::FsNode`] to which this `Socket` is attached.
237    /// `None` until the `Socket` is wrapped into a [`crate::vfs::FileObject`] (e.g. while it is
238    /// still held in a listen queue).
239    fs_node: Option<FsNodeHandle>,
240
241    /// Socket state passed to eBPF programs in `bpf_sock.state` field.
242    /// TODO(https://fxbug.dev/549754529): State tracking logic is incomplete
243    /// for TCP sockets. It tracks only some states correctly.
244    bpf_state: SocketBpfState,
245}
246
247pub type SocketHandle = Arc<Socket>;
248
249#[derive(Clone)]
250pub enum SocketPeer {
251    Handle(SocketHandle),
252    Address(SocketAddress),
253}
254
255// `resolve_protocol()` returns the protocol that should be used for a new
256// socket. `socket()` allows `protocol` parameter to be set 0, in which case the
257// protocol defaults to TCP or UDP depending on the specified `socket_type`.
258fn resolve_protocol(
259    domain: SocketDomain,
260    socket_type: SocketType,
261    protocol: SocketProtocol,
262) -> SocketProtocol {
263    if domain.is_inet() && protocol.as_raw() == 0 {
264        match socket_type {
265            SocketType::Stream => SocketProtocol::TCP,
266            SocketType::Datagram => SocketProtocol::UDP,
267            _ => protocol,
268        }
269    } else {
270        protocol
271    }
272}
273
274fn create_socket_ops(
275    current_task: &CurrentTask,
276    domain: SocketDomain,
277    socket_type: SocketType,
278    protocol: SocketProtocol,
279) -> Result<Box<dyn SocketOps>, Errno> {
280    match domain {
281        SocketDomain::Unix => Ok(Box::new(UnixSocket::new(socket_type))),
282        SocketDomain::Vsock => Ok(Box::new(VsockSocket::new(socket_type))),
283        SocketDomain::Inet | SocketDomain::Inet6 => {
284            // Follow Linux, and require CAP_NET_RAW to create raw sockets.
285            // See https://man7.org/linux/man-pages/man7/raw.7.html.
286            if socket_type == SocketType::Raw {
287                security::check_task_capable(current_task, CAP_NET_RAW)?;
288            }
289            Ok(Box::new(ZxioBackedSocket::new(current_task, domain, socket_type, protocol)?))
290        }
291        SocketDomain::Netlink => {
292            let netlink_family = NetlinkFamily::from_raw(protocol.as_raw());
293            new_netlink_socket(current_task.kernel(), socket_type, netlink_family)
294        }
295        SocketDomain::Packet => {
296            // Follow Linux, and require CAP_NET_RAW to create packet sockets.
297            // See https://man7.org/linux/man-pages/man7/packet.7.html.
298            security::check_task_capable(current_task, CAP_NET_RAW)?;
299            Ok(Box::new(ZxioBackedSocket::new(current_task, domain, socket_type, protocol)?))
300        }
301        SocketDomain::Key => {
302            track_stub!(
303                TODO("https://fxbug.dev/323365389"),
304                "Returning a UnixSocket instead of a KeySocket"
305            );
306            Ok(Box::new(UnixSocket::new(SocketType::Datagram)))
307        }
308        SocketDomain::Qipcrtr => Ok(Box::new(QipcrtrSocket::new(socket_type))),
309    }
310}
311
312#[derive(Debug)]
313pub enum SockOptValue {
314    Value(Vec<u8>),
315    User(UserBuffer),
316}
317
318impl From<Vec<u8>> for SockOptValue {
319    fn from(buffer: Vec<u8>) -> Self {
320        Self::Value(buffer)
321    }
322}
323
324impl From<UserBuffer> for SockOptValue {
325    fn from(buffer: UserBuffer) -> Self {
326        Self::User(buffer)
327    }
328}
329
330impl SockOptValue {
331    pub fn len(&self) -> usize {
332        match self {
333            Self::Value(buffer) => buffer.len(),
334            Self::User(user_buffer) => user_buffer.length,
335        }
336    }
337
338    pub fn read<T: FromBytes>(&self, current_task: &CurrentTask) -> Result<T, Errno> {
339        match self {
340            Self::Value(buffer) => {
341                T::read_from_prefix(&buffer).map_err(|_| errno!(EINVAL)).map(|(v, _)| v)
342            }
343            Self::User(user_buffer) => {
344                current_task.read_object::<T>(user_buffer.clone().try_into()?)
345            }
346        }
347    }
348
349    pub fn read_bytes(
350        &self,
351        current_task: &CurrentTask,
352        max_bytes: usize,
353    ) -> Result<Vec<u8>, Errno> {
354        match self {
355            Self::Value(buffer) => {
356                let bytes = std::cmp::min(max_bytes, buffer.len());
357                Ok(buffer[..bytes].to_owned())
358            }
359            Self::User(user_buffer) => {
360                let bytes = std::cmp::min(max_bytes, user_buffer.length);
361                current_task
362                    .read_buffer(&UserBuffer { address: user_buffer.address, length: bytes })
363            }
364        }
365    }
366
367    pub fn to_vec(self, current_task: &CurrentTask) -> Result<Vec<u8>, Errno> {
368        match self {
369            Self::Value(buffer) => Ok(buffer),
370            Self::User(user_buffer) => current_task.read_buffer(&user_buffer),
371        }
372    }
373}
374
375// Trait used to provide `read_from_sockopt_value` for `MappingMultiArchUserRef`.
376pub trait ReadFromSockOptValue {
377    type Result;
378    fn read_from_sockopt_value(
379        current_task: &CurrentTask,
380        buffer: &SockOptValue,
381    ) -> Result<Self::Result, Errno>;
382}
383
384impl<T, T64, T32> ReadFromSockOptValue for MappingMultiArchUserRef<T, T64, T32>
385where
386    T64: FromBytes + TryInto<T>,
387    T32: FromBytes + TryInto<T>,
388{
389    type Result = T;
390    fn read_from_sockopt_value(
391        current_task: &CurrentTask,
392        buffer: &SockOptValue,
393    ) -> Result<T, Errno> {
394        match buffer {
395            SockOptValue::Value(buffer) => {
396                Self::read_from_prefix(current_task, &buffer).map_err(|_| errno!(EINVAL))
397            }
398            SockOptValue::User(user_buffer) => {
399                let user_ref = Self::new_with_ref(current_task, user_buffer.clone())?;
400                current_task.read_multi_arch_object(user_ref)
401            }
402        }
403    }
404}
405
406impl Socket {
407    /// Creates a new unbound socket.
408    ///
409    /// # Parameters
410    /// - `domain`: The domain of the socket (e.g., `AF_UNIX`).
411    pub fn new(
412        current_task: &CurrentTask,
413        domain: SocketDomain,
414        socket_type: SocketType,
415        protocol: SocketProtocol,
416        kernel_private: bool,
417    ) -> Result<SocketHandle, Errno> {
418        let protocol = resolve_protocol(domain, socket_type, protocol);
419        // Checking access in `Socket::new()` prevents creating socket handles when not allowed,
420        // while skipping the "create" permission check for accepted sockets created with
421        // `Socket::new_with_ops()` and `Socket::new_with_ops_and_info()`.
422        security::check_socket_create_access(
423            current_task,
424            domain,
425            socket_type,
426            protocol,
427            kernel_private,
428        )?;
429        let ops = create_socket_ops(current_task, domain, socket_type, protocol)?;
430        Ok(Self::new_with_ops_and_info(ops, domain, socket_type, protocol))
431    }
432
433    pub fn new_with_ops(ops: Box<dyn SocketOps>) -> Result<SocketHandle, Errno> {
434        let (domain, socket_type, protocol) = ops.get_socket_info()?;
435        Ok(Self::new_with_ops_and_info(ops, domain, socket_type, protocol))
436    }
437
438    pub fn new_with_ops_and_info(
439        ops: Box<dyn SocketOps>,
440        domain: SocketDomain,
441        socket_type: SocketType,
442        protocol: SocketProtocol,
443    ) -> SocketHandle {
444        Arc::new(Socket {
445            ops,
446            domain,
447            socket_type,
448            protocol,
449            state: Default::default(),
450            security: security::SocketState::default(),
451        })
452    }
453
454    pub(super) fn set_fs_node(&self, node: &FsNodeHandle) {
455        let mut locked_state = self.state.lock();
456        assert!(locked_state.fs_node.is_none());
457        locked_state.fs_node = Some(node.clone());
458    }
459
460    /// Returns the Socket that this FileHandle refers to. If this file is not a socket file,
461    /// returns ENOTSOCK.
462    pub fn get_from_file(file: &FileHandle) -> Result<&SocketHandle, Errno> {
463        let socket_file = file.downcast_file::<SocketFile>().ok_or_else(|| errno!(ENOTSOCK))?;
464        Ok(&socket_file.socket)
465    }
466
467    pub fn downcast_socket<T>(&self) -> Option<&T>
468    where
469        T: 'static,
470    {
471        let ops = &*self.ops;
472        ops.as_any().downcast_ref::<T>()
473    }
474
475    pub fn getsockname(&self) -> Result<SocketAddress, Errno> {
476        self.ops.getsockname(self)
477    }
478
479    pub fn getpeername(&self) -> Result<SocketAddress, Errno> {
480        self.ops.getpeername(self)
481    }
482
483    pub fn setsockopt(
484        &self,
485        current_task: &CurrentTask,
486        level: u32,
487        optname: u32,
488        optval: SockOptValue,
489    ) -> Result<(), Errno> {
490        let read_timeval = || {
491            let timeval = TimeValPtr::read_from_sockopt_value(current_task, &optval)?;
492            let duration = duration_from_timeval(timeval)?;
493            Ok(if duration == zx::MonotonicDuration::default() { None } else { Some(duration) })
494        };
495
496        security::check_socket_setsockopt_access(current_task, self, level, optname)?;
497        match (level, optname) {
498            (SOL_SOCKET, SO_RCVTIMEO) => self.state.lock().receive_timeout = read_timeval()?,
499            (SOL_SOCKET, SO_SNDTIMEO) => self.state.lock().send_timeout = read_timeval()?,
500            _ => self.ops.setsockopt(self, current_task, level, optname, optval)?,
501        }
502        Ok(())
503    }
504
505    pub fn getsockopt(
506        &self,
507        current_task: &CurrentTask,
508        level: u32,
509        optname: u32,
510        optlen: u32,
511    ) -> Result<Vec<u8>, Errno> {
512        security::check_socket_getsockopt_access(current_task, self, level, optname)?;
513        let value = match level {
514            SOL_SOCKET => match optname {
515                SO_TYPE => self.socket_type.as_raw().to_ne_bytes().to_vec(),
516                SO_DOMAIN => {
517                    let domain = self.domain.as_raw() as u32;
518                    domain.to_ne_bytes().to_vec()
519                }
520                SO_PROTOCOL => self.protocol.as_raw().to_ne_bytes().to_vec(),
521                SO_RCVTIMEO => {
522                    let duration = self.receive_timeout().unwrap_or_default();
523                    TimeValPtr::into_bytes(current_task, timeval_from_duration(duration))
524                        .map_err(|_| errno!(EINVAL))?
525                }
526                SO_SNDTIMEO => {
527                    let duration = self.send_timeout().unwrap_or_default();
528                    TimeValPtr::into_bytes(current_task, timeval_from_duration(duration))
529                        .map_err(|_| errno!(EINVAL))?
530                }
531                SO_ANDROID_DROP_REASON => {
532                    track_stub!(
533                        TODO("https://fxbug.dev/477273398"),
534                        "Faking SO_ANDROID_DROP_REASON"
535                    );
536                    ANDROID_DROP_REASON_NONE.to_ne_bytes().to_vec()
537                }
538                _ => self.ops.getsockopt(self, current_task, level, optname, optlen)?,
539            },
540            _ => self.ops.getsockopt(self, current_task, level, optname, optlen)?,
541        };
542        Ok(value)
543    }
544
545    pub fn receive_timeout(&self) -> Option<zx::MonotonicDuration> {
546        self.state.lock().receive_timeout
547    }
548
549    pub fn send_timeout(&self) -> Option<zx::MonotonicDuration> {
550        self.state.lock().send_timeout
551    }
552
553    pub fn ioctl(
554        &self,
555        file: &FileObject,
556        current_task: &CurrentTask,
557        request: u32,
558        arg: SyscallArg,
559    ) -> Result<SyscallResult, Errno> {
560        let res = super::netlink_ioctl::netlink_ioctl(current_task, request, arg);
561        match &res {
562            Err(e) if e.code == ENOTTY => {}
563            _ => return res,
564        }
565        self.ops.ioctl(self, file, current_task, request, arg)
566    }
567
568    pub fn bind(
569        &self,
570        current_task: &CurrentTask,
571        socket_address: SocketAddress,
572    ) -> Result<(), Errno> {
573        self.ops.bind(self, current_task, socket_address)
574    }
575
576    pub fn listen(&self, current_task: &CurrentTask, backlog: i32) -> Result<(), Errno> {
577        security::check_socket_listen_access(current_task, self, backlog)?;
578        let max_connections =
579            current_task.kernel().system_limits.socket.max_connections.load(Ordering::Relaxed);
580        let backlog = std::cmp::min(backlog, max_connections);
581        let credentials = current_task.current_ucred();
582        self.ops.listen(self, backlog, credentials)?;
583        self.state.lock().bpf_state = SocketBpfState::Listen;
584        Ok(())
585    }
586
587    pub fn accept(&self, current_task: &CurrentTask) -> Result<SocketHandle, Errno> {
588        let new_socket = self.ops.accept(self, current_task)?;
589        new_socket.state.lock().bpf_state = SocketBpfState::Established;
590        Ok(new_socket)
591    }
592
593    pub fn read(
594        &self,
595        current_task: &CurrentTask,
596        data: &mut dyn OutputBuffer,
597        flags: SocketMessageFlags,
598    ) -> Result<MessageReadInfo, Errno> {
599        security::check_socket_recvmsg_access(current_task, self)?;
600        self.ops.read(self, current_task, data, flags)
601    }
602
603    pub fn write(
604        &self,
605        current_task: &CurrentTask,
606        data: &mut dyn InputBuffer,
607        dest_address: &mut Option<SocketAddress>,
608        ancillary_data: &mut Vec<AncillaryData>,
609    ) -> Result<usize, Errno> {
610        security::check_socket_sendmsg_access(current_task, self)?;
611        self.ops.write(self, current_task, data, dest_address, ancillary_data)
612    }
613
614    pub fn wait_async(
615        &self,
616        current_task: &CurrentTask,
617        waiter: &Waiter,
618        events: FdEvents,
619        handler: EventHandler,
620    ) -> WaitCanceler {
621        self.ops.wait_async(self, current_task, waiter, events, handler)
622    }
623
624    pub fn query_events(&self, current_task: &CurrentTask) -> Result<FdEvents, Errno> {
625        self.ops.query_events(self, current_task)
626    }
627
628    pub fn shutdown(
629        &self,
630        current_task: &CurrentTask,
631        how: SocketShutdownFlags,
632    ) -> Result<(), Errno> {
633        security::check_socket_shutdown_access(current_task, self, how)?;
634        self.ops.shutdown(self, how)
635    }
636
637    pub fn close(&self, current_task: &CurrentTask) {
638        self.state.lock().bpf_state = SocketBpfState::Close;
639        self.ops.close(current_task, self)
640    }
641
642    pub fn to_handle(
643        &self,
644        _file: &FileObject,
645        current_task: &CurrentTask,
646    ) -> Result<Option<zx::NullableHandle>, Errno> {
647        self.ops.to_handle(self, current_task)
648    }
649
650    /// Returns the [`crate::vfs::FsNode`] unique to this `Socket`.
651    // TODO: https://fxbug.dev/414583985 - Create `FsNode` at `Socket` creation and make this
652    // infallible.
653    pub fn fs_node(&self) -> Option<FsNodeHandle> {
654        self.state.lock().fs_node.clone()
655    }
656
657    pub fn bpf_state(&self) -> SocketBpfState {
658        self.state.lock().bpf_state
659    }
660
661    pub fn set_bpf_state(&self, state: SocketBpfState) {
662        self.state.lock().bpf_state = state;
663    }
664}
665
666impl DowncastedFile<'_, SocketFile> {
667    pub fn connect(self, current_task: &CurrentTask, peer: SocketPeer) -> Result<(), Errno> {
668        security::check_socket_connect_access(current_task, self, &peer)?;
669        let res = self.socket.ops.connect(&self.socket, current_task, peer);
670        if res.is_ok() || res == error!(EINPROGRESS) {
671            self.socket.state.lock().bpf_state = SocketBpfState::Established;
672        }
673        res
674    }
675}
676
677pub struct AcceptQueue {
678    pub sockets: VecDeque<SocketHandle>,
679    pub backlog: usize,
680}
681
682impl AcceptQueue {
683    pub fn new(backlog: usize) -> AcceptQueue {
684        AcceptQueue { sockets: VecDeque::with_capacity(backlog), backlog }
685    }
686
687    pub fn set_backlog(&mut self, backlog: usize) -> Result<(), Errno> {
688        if self.sockets.len() > backlog {
689            return error!(EINVAL);
690        }
691        self.backlog = backlog;
692        Ok(())
693    }
694}
695
696#[cfg(test)]
697mod tests {
698    use super::*;
699    use crate::testing::{map_memory, spawn_kernel_and_run};
700    use crate::vfs::{UnixControlData, VecInputBuffer, VecOutputBuffer};
701    use starnix_uapi::SO_PASSCRED;
702    use starnix_uapi::user_address::{UserAddress, UserRef};
703
704    #[fuchsia::test]
705    async fn test_dgram_socket() {
706        spawn_kernel_and_run(async |current_task| {
707            let bind_address = SocketAddress::Unix(b"dgram_test".into());
708            let rec_dgram = Socket::new(
709                &current_task,
710                SocketDomain::Unix,
711                SocketType::Datagram,
712                SocketProtocol::default(),
713                /* kernel_private = */ false,
714            )
715            .expect("Failed to create socket.");
716            let passcred: u32 = 1;
717            let opt_size = std::mem::size_of::<u32>();
718            let user_address = map_memory(&current_task, UserAddress::default(), opt_size as u64);
719            let opt_ref = UserRef::<u32>::new(user_address);
720            current_task.write_object(opt_ref, &passcred).unwrap();
721            let opt_buf = UserBuffer { address: user_address, length: opt_size };
722            rec_dgram.setsockopt(&current_task, SOL_SOCKET, SO_PASSCRED, opt_buf.into()).unwrap();
723
724            rec_dgram.bind(&current_task, bind_address).expect("failed to bind datagram socket");
725
726            let xfer_value: u64 = 1234567819;
727            let xfer_bytes = xfer_value.to_ne_bytes();
728
729            let send = Socket::new(
730                &current_task,
731                SocketDomain::Unix,
732                SocketType::Datagram,
733                SocketProtocol::default(),
734                /* kernel_private = */ false,
735            )
736            .expect("Failed to connect socket.");
737            send.ops.connect(&send, &current_task, SocketPeer::Handle(rec_dgram.clone())).unwrap();
738            let mut source_iter = VecInputBuffer::new(&xfer_bytes);
739            send.write(&current_task, &mut source_iter, &mut None, &mut vec![]).unwrap();
740            assert_eq!(source_iter.available(), 0);
741            // Previously, this would cause the test to fail,
742            // because rec_dgram was shut down.
743            send.close(&current_task);
744
745            let mut rec_buffer = VecOutputBuffer::new(8);
746            let read_info = rec_dgram
747                .read(&current_task, &mut rec_buffer, SocketMessageFlags::empty())
748                .unwrap();
749            assert_eq!(read_info.bytes_read, xfer_bytes.len());
750            assert_eq!(rec_buffer.data(), xfer_bytes);
751            assert_eq!(1, read_info.ancillary_data.len());
752            assert_eq!(
753                read_info.ancillary_data[0],
754                AncillaryData::Unix(UnixControlData::Credentials(uapi::ucred {
755                    pid: current_task.get_pid(),
756                    uid: 0,
757                    gid: 0
758                }))
759            );
760
761            rec_dgram.close(&current_task);
762        })
763        .await;
764    }
765}