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