Skip to main content

starnix_core/vfs/socket/
socket_unix.rs

1// Copyright 2022 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 crate::bpf::context::EbpfRunContextImpl;
6use crate::bpf::fs::get_bpf_object;
7use crate::mm::MemoryAccessorExt;
8use crate::security;
9use crate::task::{CurrentTask, EventHandler, WaitCanceler, WaitQueue, Waiter};
10use crate::vfs::buffers::{
11    AncillaryData, InputBuffer, MessageQueue, MessageReadInfo, OutputBuffer, PasscredMode,
12    UnixControlData,
13};
14use crate::vfs::socket::{
15    AcceptQueue, DEFAULT_LISTEN_BACKLOG, SockOptValue, Socket, SocketAddress, SocketBpfState,
16    SocketDomain, SocketFile, SocketHandle, SocketMessageFlags, SocketOps, SocketPeer,
17    SocketProtocol, SocketShutdownFlags, SocketType,
18};
19use crate::vfs::{
20    AccessCheck, FdNumber, FileHandle, FileObject, FsNodeHandle, FsStr, LookupContext, Message,
21    UcredPtr,
22};
23use ebpf::{
24    BpfProgramContext, BpfValue, CbpfConfig, DataWidth, EbpfProgram, Packet, ProgramArgument, Type,
25};
26use ebpf_api::{
27    LoadBytesBase, PacketWithLoadBytes, PinnedMap, ProgramType, SOCKET_FILTER_CBPF_CONFIG,
28    SOCKET_FILTER_SK_BUF_TYPE, SocketFilterProgramContext, SocketRef,
29};
30use starnix_logging::track_stub;
31use starnix_sync::{LockDepGuard, LockDepMutex, UnixSocketInnerLock, allow_subclass};
32use starnix_syscalls::{SUCCESS, SyscallArg, SyscallResult};
33use starnix_uapi::errors::{EACCES, ECONNREFUSED, EINTR, EPERM, Errno};
34use starnix_uapi::file_mode::Access;
35use starnix_uapi::open_flags::OpenFlags;
36use starnix_uapi::user_address::{UserAddress, UserRef};
37use starnix_uapi::vfs::FdEvents;
38use starnix_uapi::{
39    __sk_buff, FIONREAD, SO_ACCEPTCONN, SO_ATTACH_BPF, SO_BROADCAST, SO_ERROR, SO_KEEPALIVE,
40    SO_LINGER, SO_NO_CHECK, SO_PASSCRED, SO_PASSSEC, SO_PEERCRED, SO_PEERSEC, SO_RCVBUF,
41    SO_REUSEADDR, SO_REUSEPORT, SO_SNDBUF, SOL_SOCKET, errno, error, gid_t, socklen_t, uapi, ucred,
42    uid_t,
43};
44use std::sync::Arc;
45use zerocopy::IntoBytes;
46
47// From unix.go in gVisor.
48const SOCKET_MIN_SIZE: usize = 4 << 10;
49const SOCKET_DEFAULT_SIZE: usize = 208 << 10;
50const SOCKET_MAX_SIZE: usize = 4 << 20;
51
52/// The data of a socket is stored in the "Inner" struct. Because both ends have separate locks,
53/// care must be taken to avoid taking both locks since there is no way to tell what order to
54/// take them in.
55///
56/// When writing, data is buffered in the "other" end of the socket's Inner.MessageQueue:
57///
58///            UnixSocket end #1          UnixSocket end #2
59///            +---------------+          +---------------+
60///            |               |          |   +-------+   |
61///   Writes -------------------------------->| Inner |------> Reads
62///            |               |          |   +-------+   |
63///            |   +-------+   |          |               |
64///   Reads <------| Inner |<-------------------------------- Writes
65///            |   +-------+   |          |               |
66///            +---------------+          +---------------+
67///
68pub struct UnixSocket {
69    inner: LockDepMutex<UnixSocketInner, UnixSocketInnerLock>,
70    waiters: WaitQueue,
71}
72
73fn downcast_socket_to_unix(socket: &Socket) -> &UnixSocket {
74    // It is a programing error if we are downcasting
75    // a different type of socket as sockets from different families
76    // should not communicate, so unwrapping here
77    // will let us know that.
78    socket.downcast_socket::<UnixSocket>().unwrap()
79}
80
81enum UnixSocketState {
82    /// The socket has not been connected.
83    Disconnected,
84
85    /// The socket has had `listen` called and can accept incoming connections.
86    Listening(AcceptQueue),
87
88    /// The socket is connected to a peer.
89    Connected(SocketHandle),
90
91    /// The socket is closed.
92    Closed,
93}
94
95struct UnixSocketInner {
96    /// The `MessageQueue` that contains messages sent to this socket.
97    messages: MessageQueue,
98
99    /// The address that this socket has been bound to, if it has been bound.
100    address: Option<SocketAddress>,
101
102    /// The `FsNode` that this socket has been bound to in the filesystem, if any.
103    ///
104    /// Retaining a strong reference while the socket is open prevents the `FsNode` (and its
105    /// `bound_socket` association) from being evicted from `FsNodeCache` when its `DirEntry` is
106    /// purged from a bounded `DirEntryCache::Lru` (e.g. on `RemoteFs`). This forms a `Socket` <->
107    /// `FsNode` cycle that only `close()` breaks, so callers must close bound sockets.
108    fs_node: Option<FsNodeHandle>,
109
110    /// Whether this end of the socket has been shut down and can no longer receive message. It is
111    /// still possible to send messages to the peer, if it exists and hasn't also been shut down.
112    is_read_shutdown: bool,
113
114    /// Whether this end of the socket has been shut down and can no longer send messages.
115    is_write_shutdown: bool,
116
117    /// Whether the peer had unread data when it was closed. In this case, reads should return
118    /// ECONNRESET instead of 0 (eof).
119    peer_closed_with_unread_data: bool,
120
121    /// See SO_LINGER.
122    linger: uapi::linger,
123
124    /// See SO_PASSCRED.
125    passcred: PasscredMode,
126
127    /// See SO_PASSSEC.
128    passsec: bool,
129
130    /// See SO_BROADCAST.
131    broadcast: bool,
132
133    /// See SO_NO_CHECK.
134    no_check: bool,
135
136    /// See SO_REUSEPORT.
137    reuseport: bool,
138
139    /// See SO_REUSEADDR.
140    reuseaddr: bool,
141
142    /// See SO_KEEPALIVE.
143    keepalive: bool,
144
145    /// See SO_ATTACH_BPF.
146    bpf_program: Option<UnixSocketFilter>,
147
148    /// Unix credentials of the peer of this socket, or of the listening socket itself, for
149    /// SO_PEERCRED.
150    credentials: Option<ucred>,
151
152    /// Socket state: a queue if this is a listening socket, or a peer if this is a connected
153    /// socket.
154    state: UnixSocketState,
155}
156
157impl UnixSocket {
158    pub fn new(_socket_type: SocketType) -> UnixSocket {
159        UnixSocket {
160            inner: UnixSocketInner {
161                messages: MessageQueue::new(SOCKET_DEFAULT_SIZE),
162                address: None,
163                fs_node: None,
164                is_read_shutdown: false,
165                is_write_shutdown: false,
166                peer_closed_with_unread_data: false,
167                linger: uapi::linger::default(),
168                passcred: PasscredMode::Disabled,
169                passsec: false,
170                broadcast: false,
171                no_check: false,
172                reuseaddr: false,
173                reuseport: false,
174                keepalive: false,
175                bpf_program: None,
176                credentials: None,
177                state: UnixSocketState::Disconnected,
178            }
179            .into(),
180            waiters: WaitQueue::default(),
181        }
182    }
183
184    /// Creates a pair of connected sockets.
185    ///
186    /// # Parameters
187    /// - `domain`: The domain of the socket (e.g., `AF_UNIX`).
188    /// - `socket_type`: The type of the socket (e.g., `SOCK_STREAM`).
189    pub fn new_pair(
190        current_task: &CurrentTask,
191        domain: SocketDomain,
192        socket_type: SocketType,
193        open_flags: OpenFlags,
194    ) -> Result<(FileHandle, FileHandle), Errno> {
195        let credentials = current_task.current_ucred();
196        let left = Socket::new(
197            current_task,
198            domain,
199            socket_type,
200            SocketProtocol::default(),
201            /* kernel_private = */ false,
202        )?;
203        let right = Socket::new(
204            current_task,
205            domain,
206            socket_type,
207            SocketProtocol::default(),
208            /* kernel_private = */ false,
209        )?;
210        downcast_socket_to_unix(&left).lock().state = UnixSocketState::Connected(right.clone());
211        downcast_socket_to_unix(&left).lock().credentials = Some(credentials.clone());
212        downcast_socket_to_unix(&right).lock().state = UnixSocketState::Connected(left.clone());
213        downcast_socket_to_unix(&right).lock().credentials = Some(credentials);
214        left.set_bpf_state(SocketBpfState::Established);
215        right.set_bpf_state(SocketBpfState::Established);
216        let left = SocketFile::from_socket(
217            current_task,
218            left,
219            open_flags,
220            /* kernel_private= */ false,
221        )?;
222        let right = SocketFile::from_socket(
223            current_task,
224            right,
225            open_flags,
226            /* kernel_private= */ false,
227        )?;
228        let left_socket = SocketFile::get_from_file(&left)?;
229        let right_socket = SocketFile::get_from_file(&right)?;
230
231        security::socket_socketpair(current_task, left_socket, right_socket)?;
232        Ok((left, right))
233    }
234
235    fn connect_stream(
236        &self,
237        socket: &SocketHandle,
238        current_task: &CurrentTask,
239        peer: &SocketHandle,
240    ) -> Result<(), Errno> {
241        // Only hold one lock at a time until we make sure the lock ordering
242        // is right: client before listener
243        match downcast_socket_to_unix(peer).lock().state {
244            UnixSocketState::Listening(_) => {}
245            _ => return error!(ECONNREFUSED),
246        }
247
248        let mut client = downcast_socket_to_unix(socket).lock();
249        match client.state {
250            UnixSocketState::Disconnected => {}
251            UnixSocketState::Connected(_) => return error!(EISCONN),
252            _ => return error!(EINVAL),
253        };
254
255        let unix_socket_peer = downcast_socket_to_unix(peer);
256        {
257            // Lock ordering is client before listener.
258            let _token = allow_subclass();
259            let mut listener = unix_socket_peer.lock();
260
261            // Must check this again because we released the listener lock for a moment
262            let queue = match &listener.state {
263                UnixSocketState::Listening(queue) => queue,
264                _ => return error!(ECONNREFUSED),
265            };
266
267            self.check_type_for_connect(socket, peer, &listener.address)?;
268
269            if queue.sockets.len() > queue.backlog {
270                return error!(EAGAIN);
271            }
272
273            let server = Socket::new(
274                current_task,
275                peer.domain,
276                peer.socket_type,
277                SocketProtocol::default(),
278                /* kernel_private = */ true,
279            )?;
280            security::unix_stream_connect(current_task, socket, peer, &server)?;
281            client.state = UnixSocketState::Connected(server.clone());
282            client.credentials = listener.credentials.clone();
283            {
284                // This allow_subclass is safe because `server` is a newly created socket
285                // that hasn't been added to any public table or returned to the user yet.
286                // It is unreachable by other threads, making lock ordering cycles impossible.
287                let _token = allow_subclass();
288                let mut server = downcast_socket_to_unix(&server).lock();
289                server.state = UnixSocketState::Connected(socket.clone());
290                server.address = listener.address.clone();
291                server.messages.set_capacity(listener.messages.capacity())?;
292                server.credentials = Some(current_task.current_ucred());
293                server.passcred = listener.passcred;
294                server.passsec = listener.passsec;
295            }
296
297            // We already checked that the socket is in Listening state...but the borrow checker cannot
298            // be convinced that it's ok to combine these checks
299            let queue = match listener.state {
300                UnixSocketState::Listening(ref mut queue) => queue,
301                _ => panic!("something changed the server socket state while I held a lock on it"),
302            };
303            queue.sockets.push_back(server);
304        }
305        unix_socket_peer.waiters.notify_fd_events(FdEvents::POLLIN);
306        Ok(())
307    }
308
309    fn connect_datagram(
310        &self,
311        socket: &SocketHandle,
312        current_task: &CurrentTask,
313        peer: &SocketHandle,
314    ) -> Result<(), Errno> {
315        {
316            let unix_socket = socket.downcast_socket::<UnixSocket>().unwrap();
317            let peer_inner = unix_socket.lock();
318            self.check_type_for_connect(socket, peer, &peer_inner.address)?;
319        }
320        security::unix_may_send(current_task, socket, peer)?;
321        let unix_socket = socket.downcast_socket::<UnixSocket>().unwrap();
322        unix_socket.lock().state = UnixSocketState::Connected(peer.clone());
323        Ok(())
324    }
325
326    pub fn check_type_for_connect(
327        &self,
328        socket: &Socket,
329        peer: &Socket,
330        peer_address: &Option<SocketAddress>,
331    ) -> Result<(), Errno> {
332        if socket.domain != peer.domain || socket.socket_type != peer.socket_type {
333            // According to ConnectWithWrongType in accept_bind_test, abstract
334            // UNIX domain sockets return ECONNREFUSED rather than EPROTOTYPE.
335            if let Some(address) = peer_address {
336                if address.is_abstract_unix() {
337                    return error!(ECONNREFUSED);
338                }
339            }
340            return error!(EPROTOTYPE);
341        }
342        Ok(())
343    }
344
345    /// Locks and returns the inner state of the Socket.
346    fn lock(&self) -> LockDepGuard<'_, UnixSocketInner> {
347        self.inner.lock()
348    }
349
350    fn is_listening(&self, _socket: &Socket) -> bool {
351        matches!(self.lock().state, UnixSocketState::Listening(_))
352    }
353
354    fn get_receive_capacity(&self) -> usize {
355        self.lock().messages.capacity()
356    }
357
358    fn set_receive_capacity(&self, requested_capacity: usize) {
359        self.lock().set_capacity(requested_capacity);
360    }
361
362    fn get_send_capacity(&self) -> usize {
363        let peer = {
364            if let Some(peer) = self.lock().peer() {
365                peer.clone()
366            } else {
367                return 0;
368            }
369        };
370        let unix_socket = downcast_socket_to_unix(&peer);
371        let capacity = unix_socket.lock().messages.capacity();
372        capacity
373    }
374
375    fn set_send_capacity(&self, requested_capacity: usize) {
376        let peer = {
377            if let Some(peer) = self.lock().peer() {
378                peer.clone()
379            } else {
380                return;
381            }
382        };
383        let unix_socket = downcast_socket_to_unix(&peer);
384        unix_socket.lock().set_capacity(requested_capacity);
385    }
386
387    fn get_linger(&self) -> uapi::linger {
388        let inner = self.lock();
389        inner.linger
390    }
391
392    fn set_linger(&self, linger: uapi::linger) {
393        let mut inner = self.lock();
394        inner.linger = linger;
395    }
396
397    fn get_passcred(&self) -> PasscredMode {
398        let inner = self.lock();
399        inner.passcred
400    }
401
402    fn set_passcred(&self, passcred: PasscredMode) {
403        let mut inner = self.lock();
404        inner.passcred = passcred;
405    }
406
407    fn get_passsec(&self) -> bool {
408        let inner = self.lock();
409        inner.passsec
410    }
411
412    fn set_passsec(&self, passsec: bool) {
413        let mut inner = self.lock();
414        inner.passsec = passsec;
415    }
416
417    fn get_broadcast(&self) -> bool {
418        let inner = self.lock();
419        inner.broadcast
420    }
421
422    fn set_broadcast(&self, broadcast: bool) {
423        let mut inner = self.lock();
424        inner.broadcast = broadcast;
425    }
426
427    fn get_no_check(&self) -> bool {
428        let inner = self.lock();
429        inner.no_check
430    }
431
432    fn set_no_check(&self, no_check: bool) {
433        let mut inner = self.lock();
434        inner.no_check = no_check;
435    }
436
437    fn get_reuseaddr(&self) -> bool {
438        let inner = self.lock();
439        inner.reuseaddr
440    }
441
442    fn set_reuseaddr(&self, reuseaddr: bool) {
443        let mut inner = self.lock();
444        inner.reuseaddr = reuseaddr;
445    }
446
447    fn get_reuseport(&self) -> bool {
448        let inner = self.lock();
449        inner.reuseport
450    }
451
452    fn set_reuseport(&self, reuseport: bool) {
453        let mut inner = self.lock();
454        inner.reuseport = reuseport;
455    }
456
457    fn get_keepalive(&self) -> bool {
458        let inner = self.lock();
459        inner.keepalive
460    }
461
462    fn set_keepalive(&self, keepalive: bool) {
463        let mut inner = self.lock();
464        inner.keepalive = keepalive;
465    }
466
467    fn set_bpf_program(&self, program: Option<UnixSocketFilter>) {
468        let mut inner = self.lock();
469        inner.bpf_program = program;
470    }
471
472    fn peer_cred(&self) -> Option<ucred> {
473        self.lock().credentials.clone()
474    }
475
476    pub fn bind_socket_to_node(
477        &self,
478        socket: &SocketHandle,
479        address: SocketAddress,
480        node: &FsNodeHandle,
481    ) -> Result<(), Errno> {
482        let unix_socket = downcast_socket_to_unix(socket);
483        let mut inner = unix_socket.lock();
484        inner.bind(address)?;
485        inner.fs_node = Some(node.clone());
486        node.set_bound_socket(socket.clone());
487        Ok(())
488    }
489
490    fn notify_shutdown(&self) {
491        self.waiters.notify_fd_events(FdEvents::POLLIN | FdEvents::POLLOUT | FdEvents::POLLHUP);
492    }
493}
494
495impl SocketOps for UnixSocket {
496    fn connect(
497        &self,
498        socket: &SocketHandle,
499        current_task: &CurrentTask,
500        peer: SocketPeer,
501    ) -> Result<(), Errno> {
502        let peer = match peer {
503            SocketPeer::Handle(handle) => handle,
504            SocketPeer::Address(SocketAddress::Unspecified) => {
505                if socket.socket_type == SocketType::Datagram {
506                    let unix_socket = socket.downcast_socket::<UnixSocket>().unwrap();
507                    unix_socket.lock().state = UnixSocketState::Disconnected;
508                    return Ok(());
509                }
510                return error!(EINVAL);
511            }
512            SocketPeer::Address(_) => return error!(EINVAL),
513        };
514        match socket.socket_type {
515            SocketType::Stream | SocketType::SeqPacket => {
516                self.connect_stream(socket, current_task, &peer)
517            }
518            SocketType::Datagram | SocketType::Raw => {
519                self.connect_datagram(socket, current_task, &peer)
520            }
521            _ => error!(EINVAL),
522        }
523    }
524
525    fn listen(&self, socket: &Socket, backlog: i32, credentials: ucred) -> Result<(), Errno> {
526        match socket.socket_type {
527            SocketType::Stream | SocketType::SeqPacket => {}
528            _ => return error!(EOPNOTSUPP),
529        }
530        let mut inner = self.lock();
531        let is_bound = inner.address.is_some();
532        let backlog = if backlog < 0 { DEFAULT_LISTEN_BACKLOG } else { backlog as usize };
533        match &mut inner.state {
534            UnixSocketState::Disconnected if is_bound => {
535                inner.state = UnixSocketState::Listening(AcceptQueue::new(backlog));
536            }
537            UnixSocketState::Listening(queue) => {
538                queue.set_backlog(backlog)?;
539            }
540            _ => return error!(EINVAL),
541        }
542        inner.credentials = Some(credentials);
543        Ok(())
544    }
545
546    fn accept(&self, socket: &Socket, _current_task: &CurrentTask) -> Result<SocketHandle, Errno> {
547        match socket.socket_type {
548            SocketType::Stream | SocketType::SeqPacket => {}
549            _ => return error!(EOPNOTSUPP),
550        }
551        let mut inner = self.lock();
552        let queue = match &mut inner.state {
553            UnixSocketState::Listening(queue) => queue,
554            _ => return error!(EINVAL),
555        };
556        queue.sockets.pop_front().ok_or_else(|| errno!(EAGAIN))
557    }
558
559    fn bind(
560        &self,
561        _socket: &Socket,
562        _current_task: &CurrentTask,
563        socket_address: SocketAddress,
564    ) -> Result<(), Errno> {
565        match socket_address {
566            SocketAddress::Unix(_) => {}
567            _ => return error!(EINVAL),
568        }
569        self.lock().bind(socket_address)
570    }
571
572    fn read(
573        &self,
574        socket: &Socket,
575        current_task: &CurrentTask,
576        data: &mut dyn OutputBuffer,
577        flags: SocketMessageFlags,
578    ) -> Result<MessageReadInfo, Errno> {
579        let mut info = MessageReadInfo::default();
580        self.read_and_append(socket, current_task, &mut info, data, flags)?;
581        Ok(info)
582    }
583
584    fn read_and_append(
585        &self,
586        socket: &Socket,
587        _current_task: &CurrentTask,
588        read_info: &mut MessageReadInfo,
589        data: &mut dyn OutputBuffer,
590        flags: SocketMessageFlags,
591    ) -> Result<bool, Errno> {
592        let bytes_read_before = read_info.bytes_read;
593        let (can_coalesce, peer) = {
594            let mut inner = self.lock();
595            let can_coalesce = inner.read_and_append(read_info, data, socket.socket_type, flags)?;
596            let peer =
597                (read_info.bytes_read > bytes_read_before).then(|| inner.peer().cloned()).flatten();
598            (can_coalesce, peer)
599        };
600        if let Some(socket) = peer {
601            if let Some(socket) = socket.downcast_socket::<UnixSocket>() {
602                socket.waiters.notify_fd_events(FdEvents::POLLOUT);
603            }
604        }
605        Ok(can_coalesce)
606    }
607
608    fn write(
609        &self,
610        socket: &Socket,
611        current_task: &CurrentTask,
612        data: &mut dyn InputBuffer,
613        dest_address: &mut Option<SocketAddress>,
614        ancillary_data: &mut Vec<AncillaryData>,
615    ) -> Result<usize, Errno> {
616        let (connected_peer, local_address, local_passcred, is_write_shutdown) = {
617            let inner = self.lock();
618            (
619                inner.peer().map(|p| p.clone()),
620                inner.address.clone(),
621                inner.passcred,
622                inner.is_write_shutdown,
623            )
624        };
625
626        if is_write_shutdown {
627            return error!(EPIPE);
628        }
629
630        let peer = match (connected_peer, dest_address, socket.socket_type) {
631            (Some(peer), None, _) => peer,
632            (Some(peer), Some(_), SocketType::SeqPacket) => peer,
633            (None, Some(_), SocketType::Stream) => return error!(EOPNOTSUPP),
634            (None, Some(_), SocketType::SeqPacket) => return error!(ENOTCONN),
635            (Some(_), Some(_), _) => return error!(EISCONN),
636            (_, Some(SocketAddress::Unix(name)), _) => {
637                resolve_unix_socket_address(current_task, name.as_ref())?
638            }
639            (_, Some(_), _) => return error!(EINVAL),
640            (None, None, _) => return error!(ENOTCONN),
641        };
642
643        let dgram_security_context = if socket.socket_type == SocketType::Datagram {
644            security::unix_may_send(current_task, socket, &peer)?;
645            // TODO: https://fxbug.dev/364568855 - Store the opaque LSM property value, and expand
646            // it to a string upon readmsg.
647            Some(security::socket_getpeersec_dgram(current_task, socket))
648        } else {
649            None
650        };
651
652        let peer_unaccepted = peer.fs_node().is_none();
653        let unix_socket = downcast_socket_to_unix(&peer);
654        let write_result = {
655            let mut peer = unix_socket.lock();
656            let default_creds =
657                (local_passcred.is_enabled() || peer.passcred.is_enabled() || peer_unaccepted)
658                    .then(|| current_task.current_ucred());
659            peer.write(
660                current_task,
661                data,
662                local_address,
663                default_creds,
664                dgram_security_context,
665                ancillary_data,
666                socket,
667            )
668        };
669
670        if let Err(ref err) = write_result {
671            if err.code == ECONNREFUSED && socket.socket_type == SocketType::Datagram {
672                let mut inner = self.lock();
673                if let UnixSocketState::Connected(ref connected_peer) = inner.state {
674                    if Arc::ptr_eq(connected_peer, &peer) {
675                        inner.state = UnixSocketState::Disconnected;
676                        self.waiters.notify_fd_events(FdEvents::POLLOUT | FdEvents::POLLHUP);
677                    }
678                }
679            }
680        }
681
682        let bytes_written = write_result?;
683        if bytes_written > 0 {
684            unix_socket.waiters.notify_fd_events(FdEvents::POLLIN);
685        }
686        Ok(bytes_written)
687    }
688
689    fn wait_async(
690        &self,
691        _socket: &Socket,
692        _current_task: &CurrentTask,
693        waiter: &Waiter,
694        events: FdEvents,
695        handler: EventHandler,
696    ) -> WaitCanceler {
697        self.waiters.wait_async_fd_events(waiter, events, handler)
698    }
699
700    fn query_events(
701        &self,
702        socket: &Socket,
703        _current_task: &CurrentTask,
704    ) -> Result<FdEvents, Errno> {
705        // Note that self.lock() must be dropped before acquiring peer.inner.lock() to avoid
706        // potential deadlocks.
707        let (
708            mut events,
709            peer,
710            local_is_read_shutdown,
711            local_is_write_shutdown,
712            is_closed,
713            is_disconnected,
714        ) = {
715            let inner = self.lock();
716
717            let mut events = FdEvents::empty();
718            let local_events = inner.messages.query_events();
719            if local_events.contains(FdEvents::POLLIN) {
720                events |= FdEvents::POLLIN;
721            }
722
723            // Listening socket gets POLLIN when there are pending connections.
724            if let UnixSocketState::Listening(queue) = &inner.state {
725                if !queue.sockets.is_empty() {
726                    events |= FdEvents::POLLIN;
727                }
728            }
729
730            (
731                events,
732                inner.peer().cloned(),
733                inner.is_read_shutdown,
734                inner.is_write_shutdown,
735                matches!(inner.state, UnixSocketState::Closed),
736                matches!(inner.state, UnixSocketState::Disconnected),
737            )
738        };
739
740        let connection_oriented = socket.socket_type.is_connection_oriented();
741
742        let mut read_dead = local_is_read_shutdown || is_closed;
743        let mut write_dead = local_is_write_shutdown || is_closed;
744        let mut force_pollout = is_closed || is_disconnected;
745        let mut force_pollhup = false;
746
747        if connection_oriented && is_disconnected {
748            force_pollhup = true;
749            write_dead = true;
750        }
751
752        if let Some(peer) = peer {
753            let unix_socket = downcast_socket_to_unix(&peer);
754            let peer_inner = unix_socket.lock();
755
756            if peer_inner.is_read_shutdown {
757                write_dead = true;
758            }
759            if matches!(peer_inner.state, UnixSocketState::Closed) {
760                read_dead = true;
761                write_dead = true;
762                force_pollout = true;
763            }
764
765            let peer_events = peer_inner.messages.query_events();
766            if peer_events.contains(FdEvents::POLLOUT) {
767                events |= FdEvents::POLLOUT;
768            }
769        }
770
771        if force_pollout {
772            events |= FdEvents::POLLOUT;
773        }
774
775        if read_dead {
776            events |= FdEvents::POLLIN | FdEvents::POLLRDHUP;
777        }
778        if (read_dead && write_dead) || force_pollhup {
779            events |= FdEvents::POLLHUP;
780        }
781
782        Ok(events)
783    }
784
785    /// Shuts down reception and/or transmission on this socket according to `how`
786    /// ([`SocketShutdownFlags`]), notifying waiters with the resulting [`FdEvents`].
787    ///
788    /// Used by the `shutdown(2)` syscall.
789    fn shutdown(&self, socket: &Socket, how: SocketShutdownFlags) -> Result<(), Errno> {
790        // Acquire and release `self.lock()` before locking `peer` below to avoid ABBA deadlocks
791        // when both endpoints call `shutdown(2)` concurrently.
792        let (peer, self_notify_events) = {
793            let mut inner = self.lock();
794            let events = inner.shutdown(how);
795            (inner.peer().cloned(), events)
796        };
797        let mut peer_notify_events = FdEvents::empty();
798        if let Some(peer) = &peer {
799            if socket.socket_type.is_connection_oriented() {
800                // For a connected `AF_UNIX` pair `(self, peer)`, the two unidirectional
801                // channels are:
802                //   - `self -> peer`: controlled by `(self.is_write_shutdown, peer.is_read_shutdown)`
803                //   - `peer -> self`: controlled by `(peer.is_write_shutdown, self.is_read_shutdown)`
804                //
805                // Transposing `READ` <-> `WRITE` on `peer` ensures that `SHUT_WR` on `self` shuts
806                // down reads on `peer` (`peer_inner.is_read_shutdown`) and `SHUT_RD` on `self`
807                // shuts down writes on `peer` (`peer_inner.is_write_shutdown`).
808                let mut peer_how = SocketShutdownFlags::empty();
809                if how.contains(SocketShutdownFlags::WRITE) {
810                    peer_how |= SocketShutdownFlags::READ;
811                }
812                if how.contains(SocketShutdownFlags::READ) {
813                    peer_how |= SocketShutdownFlags::WRITE;
814                }
815                let peer_socket = downcast_socket_to_unix(peer);
816                peer_notify_events = peer_socket.lock().shutdown(peer_how);
817            }
818        }
819        if !self_notify_events.is_empty() {
820            self.waiters.notify_fd_events(self_notify_events);
821        }
822        if !peer_notify_events.is_empty() {
823            if let Some(peer) = &peer {
824                let peer_socket = downcast_socket_to_unix(peer);
825                peer_socket.waiters.notify_fd_events(peer_notify_events);
826            }
827        }
828        Ok(())
829    }
830
831    /// Close this socket.
832    ///
833    /// Called by SocketFile when the file descriptor that is holding this
834    /// socket is closed.
835    ///
836    /// Close differs from shutdown in two ways. First, close will call
837    /// mark_peer_closed_with_unread_data if this socket has unread data,
838    /// which changes how read() behaves on that socket. Second, close
839    /// transitions the internal state of this socket to Closed and releases
840    /// any bound filesystem node, which breaks the reference cycles that exist
841    /// in the connected and bound states.
842    fn close(&self, _current_task: &CurrentTask, socket: &Socket) {
843        // Keep `_maybe_fs_node` in the tuple so that it is dropped outside of `self.lock()`.
844        let (maybe_peer, has_unread, _maybe_fs_node) = {
845            let mut inner = self.lock();
846            let maybe_peer = inner.peer().map(Arc::clone);
847            inner.is_read_shutdown = true;
848            inner.state = UnixSocketState::Closed;
849            (maybe_peer, !inner.messages.is_empty(), inner.fs_node.take())
850        };
851        self.notify_shutdown();
852        // If this is a connected socket type, also shut down the connected peer.
853        if socket.socket_type.is_connection_oriented() {
854            if let Some(peer) = maybe_peer {
855                let unix_socket = downcast_socket_to_unix(&peer);
856
857                {
858                    let mut peer_inner = unix_socket.lock();
859                    if has_unread {
860                        peer_inner.peer_closed_with_unread_data = true;
861                    }
862                    peer_inner.is_read_shutdown = true;
863                }
864                unix_socket.notify_shutdown();
865            }
866        }
867    }
868
869    /// Returns the name of this socket.
870    ///
871    /// The name is derived from the address and domain. A socket
872    /// will always have a name, even if it is not bound to an address.
873    fn getsockname(&self, socket: &Socket) -> Result<SocketAddress, Errno> {
874        let inner = self.lock();
875        if let Some(address) = &inner.address {
876            Ok(address.clone())
877        } else {
878            Ok(SocketAddress::default_for_domain(socket.domain))
879        }
880    }
881
882    /// Returns the name of the peer of this socket, if such a peer exists.
883    ///
884    /// Returns an error if the socket is not connected.
885    fn getpeername(&self, _socket: &Socket) -> Result<SocketAddress, Errno> {
886        let peer = self.lock().peer().ok_or_else(|| errno!(ENOTCONN))?.clone();
887        peer.getsockname()
888    }
889
890    fn setsockopt(
891        &self,
892        _socket: &Socket,
893        current_task: &CurrentTask,
894        level: u32,
895        optname: u32,
896        optval: SockOptValue,
897    ) -> Result<(), Errno> {
898        match level {
899            SOL_SOCKET => match optname {
900                SO_SNDBUF => {
901                    let requested_capacity: socklen_t = optval.read(current_task)?;
902                    // See StreamUnixSocketPairTest.SetSocketSendBuf for why we multiply by 2 here.
903                    self.set_send_capacity(requested_capacity as usize * 2);
904                }
905                SO_RCVBUF => {
906                    let requested_capacity: socklen_t = optval.read(current_task)?;
907                    self.set_receive_capacity(requested_capacity as usize);
908                }
909                SO_LINGER => {
910                    let mut linger: uapi::linger = optval.read(current_task)?;
911                    if linger.l_onoff != 0 {
912                        linger.l_onoff = 1;
913                    }
914                    self.set_linger(linger);
915                }
916                SO_PASSCRED => {
917                    let passcred: u32 = optval.read(current_task)?;
918                    self.set_passcred(PasscredMode::from(passcred != 0));
919                }
920                SO_PASSSEC => {
921                    let passsec: u32 = optval.read(current_task)?;
922                    self.set_passsec(passsec != 0);
923                }
924                SO_BROADCAST => {
925                    let broadcast: u32 = optval.read(current_task)?;
926                    self.set_broadcast(broadcast != 0);
927                }
928                SO_NO_CHECK => {
929                    let no_check: u32 = optval.read(current_task)?;
930                    self.set_no_check(no_check != 0);
931                }
932                SO_REUSEADDR => {
933                    let reuseaddr: u32 = optval.read(current_task)?;
934                    self.set_reuseaddr(reuseaddr != 0);
935                }
936                SO_REUSEPORT => {
937                    let reuseport: u32 = optval.read(current_task)?;
938                    self.set_reuseport(reuseport != 0);
939                }
940                SO_KEEPALIVE => {
941                    let keepalive: u32 = optval.read(current_task)?;
942                    self.set_keepalive(keepalive != 0);
943                }
944                SO_ATTACH_BPF => {
945                    let fd: FdNumber = optval.read(current_task)?;
946                    let object = get_bpf_object(current_task, fd)?;
947                    let program = object.as_program()?;
948
949                    let linked_program = program.link(ProgramType::SocketFilter)?;
950
951                    self.set_bpf_program(Some(linked_program));
952                }
953                _ => return error!(ENOPROTOOPT),
954            },
955            _ => return error!(ENOPROTOOPT),
956        }
957        Ok(())
958    }
959
960    fn getsockopt(
961        &self,
962        socket: &Socket,
963        current_task: &CurrentTask,
964        level: u32,
965        optname: u32,
966        _optlen: u32,
967    ) -> Result<Vec<u8>, Errno> {
968        match level {
969            SOL_SOCKET => match optname {
970                SO_PEERCRED => Ok(UcredPtr::into_bytes(
971                    current_task,
972                    self.peer_cred().unwrap_or(ucred { pid: 0, uid: uid_t::MAX, gid: gid_t::MAX }),
973                )
974                .map_err(|_| errno!(EINVAL))?),
975                SO_PEERSEC => match socket.socket_type {
976                    SocketType::Stream => security::socket_getpeersec_stream(current_task, socket),
977                    _ => error!(ENOPROTOOPT),
978                },
979                SO_ACCEPTCONN =>
980                {
981                    #[allow(clippy::bool_to_int_with_if)]
982                    Ok(if self.is_listening(socket) { 1u32 } else { 0u32 }.to_ne_bytes().to_vec())
983                }
984                SO_SNDBUF => Ok((self.get_send_capacity() as socklen_t).to_ne_bytes().to_vec()),
985                SO_RCVBUF => Ok((self.get_receive_capacity() as socklen_t).to_ne_bytes().to_vec()),
986                SO_LINGER => Ok(self.get_linger().as_bytes().to_vec()),
987                SO_PASSCRED => Ok((self.get_passcred().is_enabled() as u32).as_bytes().to_vec()),
988                SO_PASSSEC => Ok((self.get_passsec() as u32).as_bytes().to_vec()),
989                SO_BROADCAST => Ok((self.get_broadcast() as u32).as_bytes().to_vec()),
990                SO_NO_CHECK => Ok((self.get_no_check() as u32).as_bytes().to_vec()),
991                SO_REUSEADDR => Ok((self.get_reuseaddr() as u32).as_bytes().to_vec()),
992                SO_REUSEPORT => Ok((self.get_reuseport() as u32).as_bytes().to_vec()),
993                SO_KEEPALIVE => Ok((self.get_keepalive() as u32).as_bytes().to_vec()),
994                SO_ERROR => Ok((0u32).as_bytes().to_vec()),
995                _ => error!(ENOPROTOOPT),
996            },
997            _ => error!(ENOPROTOOPT),
998        }
999    }
1000
1001    fn ioctl(
1002        &self,
1003        socket: &Socket,
1004        _file: &FileObject,
1005        current_task: &CurrentTask,
1006        request: u32,
1007        arg: SyscallArg,
1008    ) -> Result<SyscallResult, Errno> {
1009        let user_addr = UserAddress::from(arg);
1010        match request {
1011            FIONREAD if socket.socket_type == SocketType::Stream => {
1012                let length: i32 =
1013                    self.lock().messages.len().try_into().map_err(|_| errno!(EINVAL))?;
1014                current_task.write_object(UserRef::<i32>::new(user_addr), &length)?;
1015                Ok(SUCCESS)
1016            }
1017            _ => error!(ENOTTY),
1018        }
1019    }
1020}
1021
1022impl UnixSocketInner {
1023    fn bind(&mut self, socket_address: SocketAddress) -> Result<(), Errno> {
1024        if self.address.is_some() {
1025            return error!(EINVAL);
1026        }
1027        self.address = Some(socket_address);
1028        Ok(())
1029    }
1030
1031    /// Shuts down the local endpoint directions specified by `how` ([`SocketShutdownFlags`])
1032    /// and returns the [`FdEvents`] to notify on this endpoint's wait queue.
1033    ///
1034    /// Per `shutdown(2)`:
1035    /// > "The `shutdown()` call causes all or part of a full-duplex connection on
1036    /// > the socket associated with `sockfd` to be shut down. If `how` is `SHUT_RD`,
1037    /// > further receptions will be disallowed. If `how` is `SHUT_WR`, further
1038    /// > transmissions will be disallowed. If `how` is `SHUT_RDWR`, further
1039    /// > receptions and transmissions will be disallowed."
1040    ///
1041    /// Per `poll(2)`:
1042    /// > "`POLLHUP`: Hang up (only returned in `revents`; ignored in `events`).
1043    /// > Note that when reading from a channel such as a pipe or a stream socket,
1044    /// > this event merely indicates that the peer closed its end of the channel."
1045    /// > "`POLLRDHUP` (since Linux 2.6.17): Stream socket peer closed connection,
1046    /// > or shut down writing half of connection."
1047    fn shutdown(&mut self, how: SocketShutdownFlags) -> FdEvents {
1048        let mut notify_events = FdEvents::empty();
1049        if how.contains(SocketShutdownFlags::READ) {
1050            self.is_read_shutdown = true;
1051            notify_events |= FdEvents::POLLIN | FdEvents::POLLRDHUP;
1052        }
1053        if how.contains(SocketShutdownFlags::WRITE) {
1054            self.is_write_shutdown = true;
1055            notify_events |= FdEvents::POLLOUT;
1056        }
1057        if self.is_read_shutdown && self.is_write_shutdown {
1058            notify_events |= FdEvents::POLLHUP;
1059        }
1060        notify_events
1061    }
1062
1063    fn set_capacity(&mut self, requested_capacity: usize) {
1064        let capacity = requested_capacity.clamp(SOCKET_MIN_SIZE, SOCKET_MAX_SIZE);
1065        let capacity = std::cmp::max(capacity, self.messages.len());
1066        // We have validated capacity sufficiently that set_capacity should always succeed.
1067        self.messages.set_capacity(capacity).unwrap();
1068    }
1069
1070    /// Returns the socket that is connected to this socket, if such a peer exists. Returns
1071    /// ENOTCONN otherwise.
1072    fn peer(&self) -> Option<&SocketHandle> {
1073        match &self.state {
1074            UnixSocketState::Connected(peer) => Some(peer),
1075            _ => None,
1076        }
1077    }
1078
1079    /// Reads the the contents of this socket into `InputBuffer`.
1080    ///
1081    /// Will stop reading if a message with ancillary data is encountered (after the message with
1082    /// ancillary data has been read).
1083    ///
1084    /// # Parameters
1085    /// - `data`: The `OutputBuffer` to write the data to.
1086    ///
1087    /// Returns the number of bytes that were read into the buffer, and any ancillary data that was
1088    /// read from the socket.
1089    fn read(
1090        &mut self,
1091        data: &mut dyn OutputBuffer,
1092        socket_type: SocketType,
1093        flags: SocketMessageFlags,
1094    ) -> Result<MessageReadInfo, Errno> {
1095        let (mut info, has_message) = if socket_type == SocketType::Stream {
1096            if flags.contains(SocketMessageFlags::PEEK) {
1097                self.messages.peek_stream(data, self.passcred)?
1098            } else {
1099                self.messages.read_stream_with_passcred(data, self.passcred)?
1100            }
1101        } else if flags.contains(SocketMessageFlags::PEEK) {
1102            self.messages.peek_datagram(data)?
1103        } else {
1104            self.messages.read_datagram(data)?
1105        };
1106        if !has_message {
1107            if self.peer_closed_with_unread_data {
1108                // Reset the flag
1109                self.peer_closed_with_unread_data = false;
1110                return error!(ECONNRESET);
1111            }
1112            if !self.is_read_shutdown {
1113                return error!(EAGAIN);
1114            }
1115        }
1116
1117        if self.passcred.is_enabled() {
1118            let creds = info.credentials.unwrap_or_else(UnixControlData::unknown_ucred);
1119            info.credentials = Some(creds);
1120            // Allow credentials to take priority if they are enabled, so insert at 0.
1121            info.ancillary_data.insert(0, AncillaryData::Unix(UnixControlData::Credentials(creds)));
1122        } else {
1123            info.credentials = None;
1124        }
1125
1126        // Security labels are only delivered if passsec is currently enabled on this socket.
1127        if !self.passsec {
1128            info.ancillary_data
1129                .retain(|m| !matches!(m, AncillaryData::Unix(UnixControlData::Security(..))));
1130        }
1131
1132        Ok(info)
1133    }
1134
1135    fn read_and_append(
1136        &mut self,
1137        read_info: &mut MessageReadInfo,
1138        data: &mut dyn OutputBuffer,
1139        socket_type: SocketType,
1140        flags: SocketMessageFlags,
1141    ) -> Result<bool, Errno> {
1142        if socket_type == SocketType::Stream
1143            && !self.messages.can_coalesce_with(read_info, self.passcred)
1144        {
1145            return Ok(false);
1146        }
1147        let mut info = self.read(data, socket_type, flags)?;
1148        let bytes_read = info.bytes_read;
1149        read_info.append(&mut info);
1150        if socket_type != SocketType::Stream || bytes_read == 0 {
1151            return Ok(false);
1152        }
1153        Ok(self.messages.can_coalesce_with(read_info, self.passcred))
1154    }
1155
1156    /// Writes the the contents of `InputBuffer` into this socket.
1157    ///
1158    /// # Parameters
1159    /// - `data`: The `InputBuffer` to read the data from.
1160    /// - `ancillary_data`: Any ancillary data to write to the socket. Note that the ancillary data
1161    ///                     will only be written if the entirety of the requested write completes.
1162    ///
1163    /// Returns the number of bytes that were written to the socket.
1164    fn write(
1165        &mut self,
1166        current_task: &CurrentTask,
1167        data: &mut dyn InputBuffer,
1168        address: Option<SocketAddress>,
1169        default_credentials: Option<ucred>,
1170        dgram_security_context: Option<Vec<u8>>,
1171        ancillary_data: &mut Vec<AncillaryData>,
1172        socket: &Socket,
1173    ) -> Result<usize, Errno> {
1174        if matches!(self.state, UnixSocketState::Closed) {
1175            if !socket.socket_type.is_connection_oriented() {
1176                return error!(ECONNREFUSED);
1177            } else {
1178                return error!(EPIPE);
1179            }
1180        }
1181        if self.is_read_shutdown {
1182            return error!(EPIPE);
1183        }
1184        let filter = |mut message: Message| {
1185            if let Some(context) = dgram_security_context {
1186                message
1187                    .ancillary_data
1188                    .push(AncillaryData::Unix(UnixControlData::Security(context.into())));
1189            }
1190            let Some(bpf_program) = self.bpf_program.as_ref() else {
1191                return Some(message);
1192            };
1193
1194            // TODO(https://fxbug.dev/385015056): Fill in SkBuf.
1195            let mut sk_buf = SkBuf::default();
1196
1197            let mut context = EbpfRunContextImpl::<'_>::new(current_task);
1198            let s = bpf_program.run(&mut context, &mut sk_buf);
1199            if s == 0 {
1200                None
1201            } else {
1202                message.truncate(s as usize);
1203                Some(message)
1204            }
1205        };
1206        let bytes_written = if socket.socket_type == SocketType::Stream {
1207            self.messages.write_stream_with_filter(
1208                data,
1209                address,
1210                default_credentials,
1211                ancillary_data,
1212                filter,
1213            )?
1214        } else {
1215            self.messages.write_datagram_with_filter(
1216                data,
1217                address,
1218                default_credentials,
1219                ancillary_data,
1220                filter,
1221            )?
1222        };
1223        Ok(bytes_written)
1224    }
1225}
1226
1227pub fn resolve_unix_socket_address(
1228    current_task: &CurrentTask,
1229    name: &FsStr,
1230) -> Result<SocketHandle, Errno> {
1231    if name[0] == b'\0' {
1232        current_task.running_state().abstract_socket_namespace.lookup(name)
1233    } else {
1234        let mut context = LookupContext::default();
1235        let (parent, basename) =
1236            current_task.lookup_parent_at(&mut context, FdNumber::AT_FDCWD, name)?;
1237        let name = parent.lookup_child(current_task, &mut context, basename).map_err(|errno| {
1238            if matches!(errno.code, EACCES | EPERM | EINTR) { errno } else { errno!(ECONNREFUSED) }
1239        })?;
1240        name.check_access(current_task, AccessCheck::for_internal(Access::WRITE))?;
1241        name.entry.node.bound_socket().map(|s| s.clone()).ok_or_else(|| errno!(ECONNREFUSED))
1242    }
1243}
1244
1245// Packet buffer representation used for eBPF filters.
1246#[repr(C)]
1247#[derive(Default)]
1248struct SkBuf {
1249    sk_buff: __sk_buff,
1250}
1251
1252impl Packet for &mut SkBuf {
1253    fn load(&self, _offset: i32, _width: DataWidth) -> Option<BpfValue> {
1254        // TODO(https://fxbug.dev/385015056): Implement packet access.
1255        None
1256    }
1257}
1258
1259impl<'a> PacketWithLoadBytes for &'a mut SkBuf {
1260    fn load_bytes_relative(
1261        &self,
1262        _base: LoadBytesBase,
1263        _offset: usize,
1264        _buf: ebpf::EbpfBufferPtr<'_>,
1265    ) -> i64 {
1266        track_stub!(TODO("https://fxbug.dev/385015056"), "bpf_load_bytes_relative");
1267        -1
1268    }
1269}
1270
1271impl ProgramArgument for &'_ mut SkBuf {
1272    fn get_type() -> &'static Type {
1273        &*SOCKET_FILTER_SK_BUF_TYPE
1274    }
1275}
1276
1277impl SocketRef for &'_ mut SkBuf {
1278    fn get_socket_cookie(&self) -> Option<u64> {
1279        track_stub!(TODO("https://fxbug.dev/385015056"), "bpf_get_socket_cookie");
1280        None
1281    }
1282
1283    fn get_socket_uid(&self) -> Option<uid_t> {
1284        track_stub!(TODO("https://fxbug.dev/385015056"), "bpf_get_socket_uid");
1285        None
1286    }
1287}
1288
1289struct UnixSocketEbpfContext {}
1290impl BpfProgramContext for UnixSocketEbpfContext {
1291    type RunContext<'a> = EbpfRunContextImpl<'a>;
1292    type Packet<'a> = &'a mut SkBuf;
1293    type Map = PinnedMap;
1294    const CBPF_CONFIG: &'static CbpfConfig = &SOCKET_FILTER_CBPF_CONFIG;
1295}
1296
1297ebpf_api::ebpf_program_context_type!(UnixSocketEbpfContext, SocketFilterProgramContext);
1298
1299type UnixSocketFilter = EbpfProgram<UnixSocketEbpfContext>;
1300
1301#[cfg(test)]
1302mod tests {
1303    use super::*;
1304    use crate::mm::MemoryAccessor;
1305    use crate::testing::{map_memory, spawn_kernel_and_run};
1306    use crate::vfs::{DirectoryMode, UnlinkKind};
1307    use starnix_types::user_buffer::UserBuffer;
1308    use starnix_uapi::file_mode::mode;
1309
1310    #[::fuchsia::test]
1311    async fn test_socket_send_capacity() {
1312        spawn_kernel_and_run(async |current_task| {
1313            let _kernel = current_task.kernel();
1314            let socket = Socket::new(
1315                &current_task,
1316                SocketDomain::Unix,
1317                SocketType::Stream,
1318                SocketProtocol::default(),
1319                /* kernel_private = */ false,
1320            )
1321            .expect("Failed to create socket.");
1322            socket
1323                .bind(&current_task, SocketAddress::Unix(b"\0".into()))
1324                .expect("Failed to bind socket.");
1325            socket.listen(&current_task, 10).expect("Failed to listen.");
1326            let connecting_socket = Socket::new(
1327                &current_task,
1328                SocketDomain::Unix,
1329                SocketType::Stream,
1330                SocketProtocol::default(),
1331                /* kernel_private = */ false,
1332            )
1333            .expect("Failed to connect socket.");
1334            connecting_socket
1335                .ops
1336                .connect(&connecting_socket, &current_task, SocketPeer::Handle(socket.clone()))
1337                .expect("Failed to connect socket.");
1338            assert_eq!(Ok(FdEvents::POLLIN), socket.query_events(&current_task));
1339            let server_socket = socket.accept(&current_task).unwrap();
1340
1341            let opt_size = std::mem::size_of::<socklen_t>();
1342            let user_address = map_memory(&current_task, UserAddress::default(), opt_size as u64);
1343            let send_capacity: socklen_t = 4 * 4096;
1344            current_task.write_memory(user_address, &send_capacity.to_ne_bytes()).unwrap();
1345            let user_buffer = UserBuffer { address: user_address, length: opt_size };
1346            server_socket
1347                .setsockopt(&current_task, SOL_SOCKET, SO_SNDBUF, user_buffer.into())
1348                .unwrap();
1349
1350            let opt_bytes =
1351                server_socket.getsockopt(&current_task, SOL_SOCKET, SO_SNDBUF, 0).unwrap();
1352            let retrieved_capacity = socklen_t::from_ne_bytes(opt_bytes.try_into().unwrap());
1353            // Setting SO_SNDBUF actually sets it to double the size
1354            assert_eq!(2 * send_capacity, retrieved_capacity);
1355        })
1356        .await;
1357    }
1358
1359    #[::fuchsia::test]
1360    async fn test_datagram_socket_disconnect_af_unspec() {
1361        spawn_kernel_and_run(async |current_task| {
1362            let socket1 = Socket::new(
1363                &current_task,
1364                SocketDomain::Unix,
1365                SocketType::Datagram,
1366                SocketProtocol::default(),
1367                /* kernel_private = */ false,
1368            )
1369            .expect("Failed to create socket 1.");
1370            socket1
1371                .bind(&current_task, SocketAddress::Unix(b"\0sock1".into()))
1372                .expect("Failed to bind socket 1.");
1373
1374            let socket2 = Socket::new(
1375                &current_task,
1376                SocketDomain::Unix,
1377                SocketType::Datagram,
1378                SocketProtocol::default(),
1379                /* kernel_private = */ false,
1380            )
1381            .expect("Failed to create socket 2.");
1382            socket2
1383                .bind(&current_task, SocketAddress::Unix(b"\0sock2".into()))
1384                .expect("Failed to bind socket 2.");
1385
1386            // Connect socket1 to socket2.
1387            socket1
1388                .ops
1389                .connect(&socket1, &current_task, SocketPeer::Handle(socket2.clone()))
1390                .expect("Failed to connect socket1 to socket2.");
1391
1392            // Disconnect socket1 using AF_UNSPEC.
1393            socket1
1394                .ops
1395                .connect(&socket1, &current_task, SocketPeer::Address(SocketAddress::Unspecified))
1396                .expect("Failed to disconnect socket1 with AF_UNSPEC.");
1397        })
1398        .await;
1399    }
1400
1401    #[::fuchsia::test]
1402    async fn test_bind_socket_retains_fs_node_until_close() {
1403        spawn_kernel_and_run(async |current_task| {
1404            let socket = Socket::new(
1405                &current_task,
1406                SocketDomain::Unix,
1407                SocketType::Stream,
1408                SocketProtocol::default(),
1409                /* kernel_private = */ false,
1410            )
1411            .expect("Failed to create socket.");
1412
1413            let root = current_task.fs().root();
1414            let bound_node = root
1415                .bind_socket(
1416                    &current_task,
1417                    "test_sock".into(),
1418                    socket.clone(),
1419                    SocketAddress::Unix("test_sock".into()),
1420                    mode!(IFSOCK, 0o777),
1421                )
1422                .expect("Failed to bind socket to node.");
1423            let weak_fs_node = Arc::downgrade(&bound_node.entry.node);
1424            std::mem::drop(bound_node);
1425
1426            // Unlink the directory entry so that `TmpFs`'s permanent `DirEntryCache` drops its
1427            // reference to the `DirEntry` and `FsNode`, simulating `DirEntryCache::Lru` eviction on
1428            // cached filesystems (such as `RemoteFs`).
1429            root.unlink(
1430                &current_task,
1431                "test_sock".into(),
1432                UnlinkKind::NonDirectory,
1433                DirectoryMode::AllowAny,
1434            )
1435            .expect("Failed to unlink socket.");
1436            current_task.trigger_delayed_releaser();
1437
1438            // While the socket remains open, it must retain the bound `FsNode` and its
1439            // `bound_socket` association.
1440            let fs_node =
1441                weak_fs_node.upgrade().expect("FsNode should remain alive while socket is open");
1442            assert!(fs_node.bound_socket().is_some());
1443            std::mem::drop(fs_node);
1444
1445            // Closing the socket must release its reference to the `FsNode`, breaking the
1446            // `Socket` <-> `FsNode` reference cycle so both can be freed.
1447            let weak_socket = Arc::downgrade(&socket);
1448            socket.close(&current_task);
1449            std::mem::drop(socket);
1450            current_task.trigger_delayed_releaser();
1451
1452            assert!(weak_fs_node.upgrade().is_none());
1453            assert!(weak_socket.upgrade().is_none());
1454        })
1455        .await;
1456    }
1457}