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, SocketDomain, SocketFile, SocketMessageFlags,
7    SocketProtocol, SocketShutdownFlags, SocketType, UnixSocket, VsockSocket, ZxioBackedSocket,
8    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
242pub type SocketHandle = Arc<Socket>;
243
244#[derive(Clone)]
245pub enum SocketPeer {
246    Handle(SocketHandle),
247    Address(SocketAddress),
248}
249
250// `resolve_protocol()` returns the protocol that should be used for a new
251// socket. `socket()` allows `protocol` parameter to be set 0, in which case the
252// protocol defaults to TCP or UDP depending on the specified `socket_type`.
253fn resolve_protocol(
254    domain: SocketDomain,
255    socket_type: SocketType,
256    protocol: SocketProtocol,
257) -> SocketProtocol {
258    if domain.is_inet() && protocol.as_raw() == 0 {
259        match socket_type {
260            SocketType::Stream => SocketProtocol::TCP,
261            SocketType::Datagram => SocketProtocol::UDP,
262            _ => protocol,
263        }
264    } else {
265        protocol
266    }
267}
268
269fn create_socket_ops(
270    current_task: &CurrentTask,
271    domain: SocketDomain,
272    socket_type: SocketType,
273    protocol: SocketProtocol,
274) -> Result<Box<dyn SocketOps>, Errno> {
275    match domain {
276        SocketDomain::Unix => Ok(Box::new(UnixSocket::new(socket_type))),
277        SocketDomain::Vsock => Ok(Box::new(VsockSocket::new(socket_type))),
278        SocketDomain::Inet | SocketDomain::Inet6 => {
279            // Follow Linux, and require CAP_NET_RAW to create raw sockets.
280            // See https://man7.org/linux/man-pages/man7/raw.7.html.
281            if socket_type == SocketType::Raw {
282                security::check_task_capable(current_task, CAP_NET_RAW)?;
283            }
284            Ok(Box::new(ZxioBackedSocket::new(current_task, domain, socket_type, protocol)?))
285        }
286        SocketDomain::Netlink => {
287            let netlink_family = NetlinkFamily::from_raw(protocol.as_raw());
288            new_netlink_socket(current_task.kernel(), socket_type, netlink_family)
289        }
290        SocketDomain::Packet => {
291            // Follow Linux, and require CAP_NET_RAW to create packet sockets.
292            // See https://man7.org/linux/man-pages/man7/packet.7.html.
293            security::check_task_capable(current_task, CAP_NET_RAW)?;
294            Ok(Box::new(ZxioBackedSocket::new(current_task, domain, socket_type, protocol)?))
295        }
296        SocketDomain::Key => {
297            track_stub!(
298                TODO("https://fxbug.dev/323365389"),
299                "Returning a UnixSocket instead of a KeySocket"
300            );
301            Ok(Box::new(UnixSocket::new(SocketType::Datagram)))
302        }
303        SocketDomain::Qipcrtr => Ok(Box::new(QipcrtrSocket::new(socket_type))),
304    }
305}
306
307#[derive(Debug)]
308pub enum SockOptValue {
309    Value(Vec<u8>),
310    User(UserBuffer),
311}
312
313impl From<Vec<u8>> for SockOptValue {
314    fn from(buffer: Vec<u8>) -> Self {
315        Self::Value(buffer)
316    }
317}
318
319impl From<UserBuffer> for SockOptValue {
320    fn from(buffer: UserBuffer) -> Self {
321        Self::User(buffer)
322    }
323}
324
325impl SockOptValue {
326    pub fn len(&self) -> usize {
327        match self {
328            Self::Value(buffer) => buffer.len(),
329            Self::User(user_buffer) => user_buffer.length,
330        }
331    }
332
333    pub fn read<T: FromBytes>(&self, current_task: &CurrentTask) -> Result<T, Errno> {
334        match self {
335            Self::Value(buffer) => {
336                T::read_from_prefix(&buffer).map_err(|_| errno!(EINVAL)).map(|(v, _)| v)
337            }
338            Self::User(user_buffer) => {
339                current_task.read_object::<T>(user_buffer.clone().try_into()?)
340            }
341        }
342    }
343
344    pub fn read_bytes(
345        &self,
346        current_task: &CurrentTask,
347        max_bytes: usize,
348    ) -> Result<Vec<u8>, Errno> {
349        match self {
350            Self::Value(buffer) => {
351                let bytes = std::cmp::min(max_bytes, buffer.len());
352                Ok(buffer[..bytes].to_owned())
353            }
354            Self::User(user_buffer) => {
355                let bytes = std::cmp::min(max_bytes, user_buffer.length);
356                current_task
357                    .read_buffer(&UserBuffer { address: user_buffer.address, length: bytes })
358            }
359        }
360    }
361
362    pub fn to_vec(self, current_task: &CurrentTask) -> Result<Vec<u8>, Errno> {
363        match self {
364            Self::Value(buffer) => Ok(buffer),
365            Self::User(user_buffer) => current_task.read_buffer(&user_buffer),
366        }
367    }
368}
369
370// Trait used to provide `read_from_sockopt_value` for `MappingMultiArchUserRef`.
371pub trait ReadFromSockOptValue {
372    type Result;
373    fn read_from_sockopt_value(
374        current_task: &CurrentTask,
375        buffer: &SockOptValue,
376    ) -> Result<Self::Result, Errno>;
377}
378
379impl<T, T64, T32> ReadFromSockOptValue for MappingMultiArchUserRef<T, T64, T32>
380where
381    T64: FromBytes + TryInto<T>,
382    T32: FromBytes + TryInto<T>,
383{
384    type Result = T;
385    fn read_from_sockopt_value(
386        current_task: &CurrentTask,
387        buffer: &SockOptValue,
388    ) -> Result<T, Errno> {
389        match buffer {
390            SockOptValue::Value(buffer) => {
391                Self::read_from_prefix(current_task, &buffer).map_err(|_| errno!(EINVAL))
392            }
393            SockOptValue::User(user_buffer) => {
394                let user_ref = Self::new_with_ref(current_task, user_buffer.clone())?;
395                current_task.read_multi_arch_object(user_ref)
396            }
397        }
398    }
399}
400
401impl Socket {
402    /// Creates a new unbound socket.
403    ///
404    /// # Parameters
405    /// - `domain`: The domain of the socket (e.g., `AF_UNIX`).
406    pub fn new(
407        current_task: &CurrentTask,
408        domain: SocketDomain,
409        socket_type: SocketType,
410        protocol: SocketProtocol,
411        kernel_private: bool,
412    ) -> Result<SocketHandle, Errno> {
413        let protocol = resolve_protocol(domain, socket_type, protocol);
414        // Checking access in `Socket::new()` prevents creating socket handles when not allowed,
415        // while skipping the "create" permission check for accepted sockets created with
416        // `Socket::new_with_ops()` and `Socket::new_with_ops_and_info()`.
417        security::check_socket_create_access(
418            current_task,
419            domain,
420            socket_type,
421            protocol,
422            kernel_private,
423        )?;
424        let ops = create_socket_ops(current_task, domain, socket_type, protocol)?;
425        Ok(Self::new_with_ops_and_info(ops, domain, socket_type, protocol))
426    }
427
428    pub fn new_with_ops(ops: Box<dyn SocketOps>) -> Result<SocketHandle, Errno> {
429        let (domain, socket_type, protocol) = ops.get_socket_info()?;
430        Ok(Self::new_with_ops_and_info(ops, domain, socket_type, protocol))
431    }
432
433    pub fn new_with_ops_and_info(
434        ops: Box<dyn SocketOps>,
435        domain: SocketDomain,
436        socket_type: SocketType,
437        protocol: SocketProtocol,
438    ) -> SocketHandle {
439        Arc::new(Socket {
440            ops,
441            domain,
442            socket_type,
443            protocol,
444            state: Default::default(),
445            security: security::SocketState::default(),
446        })
447    }
448
449    pub(super) fn set_fs_node(&self, node: &FsNodeHandle) {
450        let mut locked_state = self.state.lock();
451        assert!(locked_state.fs_node.is_none());
452        locked_state.fs_node = Some(node.clone());
453    }
454
455    /// Returns the Socket that this FileHandle refers to. If this file is not a socket file,
456    /// returns ENOTSOCK.
457    pub fn get_from_file(file: &FileHandle) -> Result<&SocketHandle, Errno> {
458        let socket_file = file.downcast_file::<SocketFile>().ok_or_else(|| errno!(ENOTSOCK))?;
459        Ok(&socket_file.socket)
460    }
461
462    pub fn downcast_socket<T>(&self) -> Option<&T>
463    where
464        T: 'static,
465    {
466        let ops = &*self.ops;
467        ops.as_any().downcast_ref::<T>()
468    }
469
470    pub fn getsockname(&self) -> Result<SocketAddress, Errno> {
471        self.ops.getsockname(self)
472    }
473
474    pub fn getpeername(&self) -> Result<SocketAddress, Errno> {
475        self.ops.getpeername(self)
476    }
477
478    pub fn setsockopt(
479        &self,
480        current_task: &CurrentTask,
481        level: u32,
482        optname: u32,
483        optval: SockOptValue,
484    ) -> Result<(), Errno> {
485        let read_timeval = || {
486            let timeval = TimeValPtr::read_from_sockopt_value(current_task, &optval)?;
487            let duration = duration_from_timeval(timeval)?;
488            Ok(if duration == zx::MonotonicDuration::default() { None } else { Some(duration) })
489        };
490
491        security::check_socket_setsockopt_access(current_task, self, level, optname)?;
492        match (level, optname) {
493            (SOL_SOCKET, SO_RCVTIMEO) => self.state.lock().receive_timeout = read_timeval()?,
494            (SOL_SOCKET, SO_SNDTIMEO) => self.state.lock().send_timeout = read_timeval()?,
495            _ => self.ops.setsockopt(self, current_task, level, optname, optval)?,
496        }
497        Ok(())
498    }
499
500    pub fn getsockopt(
501        &self,
502        current_task: &CurrentTask,
503        level: u32,
504        optname: u32,
505        optlen: u32,
506    ) -> Result<Vec<u8>, Errno> {
507        security::check_socket_getsockopt_access(current_task, self, level, optname)?;
508        let value = match level {
509            SOL_SOCKET => match optname {
510                SO_TYPE => self.socket_type.as_raw().to_ne_bytes().to_vec(),
511                SO_DOMAIN => {
512                    let domain = self.domain.as_raw() as u32;
513                    domain.to_ne_bytes().to_vec()
514                }
515                SO_PROTOCOL => self.protocol.as_raw().to_ne_bytes().to_vec(),
516                SO_RCVTIMEO => {
517                    let duration = self.receive_timeout().unwrap_or_default();
518                    TimeValPtr::into_bytes(current_task, timeval_from_duration(duration))
519                        .map_err(|_| errno!(EINVAL))?
520                }
521                SO_SNDTIMEO => {
522                    let duration = self.send_timeout().unwrap_or_default();
523                    TimeValPtr::into_bytes(current_task, timeval_from_duration(duration))
524                        .map_err(|_| errno!(EINVAL))?
525                }
526                SO_ANDROID_DROP_REASON => {
527                    track_stub!(
528                        TODO("https://fxbug.dev/477273398"),
529                        "Faking SO_ANDROID_DROP_REASON"
530                    );
531                    ANDROID_DROP_REASON_NONE.to_ne_bytes().to_vec()
532                }
533                _ => self.ops.getsockopt(self, current_task, level, optname, optlen)?,
534            },
535            _ => self.ops.getsockopt(self, current_task, level, optname, optlen)?,
536        };
537        Ok(value)
538    }
539
540    pub fn receive_timeout(&self) -> Option<zx::MonotonicDuration> {
541        self.state.lock().receive_timeout
542    }
543
544    pub fn send_timeout(&self) -> Option<zx::MonotonicDuration> {
545        self.state.lock().send_timeout
546    }
547
548    pub fn ioctl(
549        &self,
550        file: &FileObject,
551        current_task: &CurrentTask,
552        request: u32,
553        arg: SyscallArg,
554    ) -> Result<SyscallResult, Errno> {
555        let res = super::netlink_ioctl::netlink_ioctl(current_task, request, arg);
556        match &res {
557            Err(e) if e.code == ENOTTY => {}
558            _ => return res,
559        }
560        self.ops.ioctl(self, file, current_task, request, arg)
561    }
562
563    pub fn bind(
564        &self,
565        current_task: &CurrentTask,
566        socket_address: SocketAddress,
567    ) -> Result<(), Errno> {
568        self.ops.bind(self, current_task, socket_address)
569    }
570
571    pub fn listen(&self, current_task: &CurrentTask, backlog: i32) -> Result<(), Errno> {
572        security::check_socket_listen_access(current_task, self, backlog)?;
573        let max_connections =
574            current_task.kernel().system_limits.socket.max_connections.load(Ordering::Relaxed);
575        let backlog = std::cmp::min(backlog, max_connections);
576        let credentials = current_task.current_ucred();
577        self.ops.listen(self, backlog, credentials)
578    }
579
580    pub fn accept(&self, current_task: &CurrentTask) -> Result<SocketHandle, Errno> {
581        self.ops.accept(self, current_task)
582    }
583
584    pub fn read(
585        &self,
586        current_task: &CurrentTask,
587        data: &mut dyn OutputBuffer,
588        flags: SocketMessageFlags,
589    ) -> Result<MessageReadInfo, Errno> {
590        security::check_socket_recvmsg_access(current_task, self)?;
591        self.ops.read(self, current_task, data, flags)
592    }
593
594    pub fn write(
595        &self,
596        current_task: &CurrentTask,
597        data: &mut dyn InputBuffer,
598        dest_address: &mut Option<SocketAddress>,
599        ancillary_data: &mut Vec<AncillaryData>,
600    ) -> Result<usize, Errno> {
601        security::check_socket_sendmsg_access(current_task, self)?;
602        self.ops.write(self, current_task, data, dest_address, ancillary_data)
603    }
604
605    pub fn wait_async(
606        &self,
607        current_task: &CurrentTask,
608        waiter: &Waiter,
609        events: FdEvents,
610        handler: EventHandler,
611    ) -> WaitCanceler {
612        self.ops.wait_async(self, current_task, waiter, events, handler)
613    }
614
615    pub fn query_events(&self, current_task: &CurrentTask) -> Result<FdEvents, Errno> {
616        self.ops.query_events(self, current_task)
617    }
618
619    pub fn shutdown(
620        &self,
621        current_task: &CurrentTask,
622        how: SocketShutdownFlags,
623    ) -> Result<(), Errno> {
624        security::check_socket_shutdown_access(current_task, self, how)?;
625        self.ops.shutdown(self, how)
626    }
627
628    pub fn close(&self, current_task: &CurrentTask) {
629        self.ops.close(current_task, self)
630    }
631
632    pub fn to_handle(
633        &self,
634        _file: &FileObject,
635        current_task: &CurrentTask,
636    ) -> Result<Option<zx::NullableHandle>, Errno> {
637        self.ops.to_handle(self, current_task)
638    }
639
640    /// Returns the [`crate::vfs::FsNode`] unique to this `Socket`.
641    // TODO: https://fxbug.dev/414583985 - Create `FsNode` at `Socket` creation and make this
642    // infallible.
643    pub fn fs_node(&self) -> Option<FsNodeHandle> {
644        self.state.lock().fs_node.clone()
645    }
646}
647
648impl DowncastedFile<'_, SocketFile> {
649    pub fn connect(self, current_task: &CurrentTask, peer: SocketPeer) -> Result<(), Errno> {
650        security::check_socket_connect_access(current_task, self, &peer)?;
651        self.socket.ops.connect(&self.socket, current_task, peer)
652    }
653}
654
655pub struct AcceptQueue {
656    pub sockets: VecDeque<SocketHandle>,
657    pub backlog: usize,
658}
659
660impl AcceptQueue {
661    pub fn new(backlog: usize) -> AcceptQueue {
662        AcceptQueue { sockets: VecDeque::with_capacity(backlog), backlog }
663    }
664
665    pub fn set_backlog(&mut self, backlog: usize) -> Result<(), Errno> {
666        if self.sockets.len() > backlog {
667            return error!(EINVAL);
668        }
669        self.backlog = backlog;
670        Ok(())
671    }
672}
673
674#[cfg(test)]
675mod tests {
676    use super::*;
677    use crate::testing::{map_memory, spawn_kernel_and_run};
678    use crate::vfs::{UnixControlData, VecInputBuffer, VecOutputBuffer};
679    use starnix_uapi::SO_PASSCRED;
680    use starnix_uapi::user_address::{UserAddress, UserRef};
681
682    #[fuchsia::test]
683    async fn test_dgram_socket() {
684        spawn_kernel_and_run(async |current_task| {
685            let bind_address = SocketAddress::Unix(b"dgram_test".into());
686            let rec_dgram = Socket::new(
687                &current_task,
688                SocketDomain::Unix,
689                SocketType::Datagram,
690                SocketProtocol::default(),
691                /* kernel_private = */ false,
692            )
693            .expect("Failed to create socket.");
694            let passcred: u32 = 1;
695            let opt_size = std::mem::size_of::<u32>();
696            let user_address = map_memory(&current_task, UserAddress::default(), opt_size as u64);
697            let opt_ref = UserRef::<u32>::new(user_address);
698            current_task.write_object(opt_ref, &passcred).unwrap();
699            let opt_buf = UserBuffer { address: user_address, length: opt_size };
700            rec_dgram.setsockopt(&current_task, SOL_SOCKET, SO_PASSCRED, opt_buf.into()).unwrap();
701
702            rec_dgram.bind(&current_task, bind_address).expect("failed to bind datagram socket");
703
704            let xfer_value: u64 = 1234567819;
705            let xfer_bytes = xfer_value.to_ne_bytes();
706
707            let send = Socket::new(
708                &current_task,
709                SocketDomain::Unix,
710                SocketType::Datagram,
711                SocketProtocol::default(),
712                /* kernel_private = */ false,
713            )
714            .expect("Failed to connect socket.");
715            send.ops.connect(&send, &current_task, SocketPeer::Handle(rec_dgram.clone())).unwrap();
716            let mut source_iter = VecInputBuffer::new(&xfer_bytes);
717            send.write(&current_task, &mut source_iter, &mut None, &mut vec![]).unwrap();
718            assert_eq!(source_iter.available(), 0);
719            // Previously, this would cause the test to fail,
720            // because rec_dgram was shut down.
721            send.close(&current_task);
722
723            let mut rec_buffer = VecOutputBuffer::new(8);
724            let read_info = rec_dgram
725                .read(&current_task, &mut rec_buffer, SocketMessageFlags::empty())
726                .unwrap();
727            assert_eq!(read_info.bytes_read, xfer_bytes.len());
728            assert_eq!(rec_buffer.data(), xfer_bytes);
729            assert_eq!(1, read_info.ancillary_data.len());
730            assert_eq!(
731                read_info.ancillary_data[0],
732                AncillaryData::Unix(UnixControlData::Credentials(uapi::ucred {
733                    pid: current_task.get_pid(),
734                    uid: 0,
735                    gid: 0
736                }))
737            );
738
739            rec_dgram.close(&current_task);
740        })
741        .await;
742    }
743}