saluki_io/net/unix/
linux.rs1use std::io;
2
3use bytes::BufMut;
4use socket2::{MaybeUninitSlice, MsgHdrMut, SockAddr, SockAddrStorage, SockRef};
5
6use super::ancillary::{ControlMessage, SocketCredentialsAncillaryData};
7use crate::net::addr::{ConnectionAddress, ProcessCredentials};
8
9pub fn enable_uds_socket_credentials<'sock, S>(socket: &'sock S) -> io::Result<()>
15where
16 SockRef<'sock>: From<&'sock S>,
17{
18 let sock_ref = SockRef::from(socket);
19 sock_ref.set_passcred(true)
20}
21
22pub(super) fn uds_recvmsg<'sock, S, B: BufMut>(socket: &'sock S, buf: &mut B) -> io::Result<(usize, ConnectionAddress)>
23where
24 SockRef<'sock>: From<&'sock S>,
25{
26 let sock_ref = SockRef::from(socket);
27
28 let sock_storage = SockAddrStorage::zeroed();
34 let sock_storage_len = sock_storage.size_of();
35 let mut sock_addr = unsafe { SockAddr::new(sock_storage, sock_storage_len) };
36
37 let mut ancillary_data = SocketCredentialsAncillaryData::new();
38
39 let data_buf = unsafe { MaybeUninitSlice::new(buf.chunk_mut().as_uninit_slice_mut()) };
40 let mut data_bufs = [data_buf];
41
42 let mut msg_hdr = MsgHdrMut::new()
43 .with_addr(&mut sock_addr)
44 .with_buffers(&mut data_bufs)
45 .with_control(ancillary_data.as_mut_uninit());
46
47 let n = sock_ref.recvmsg(&mut msg_hdr, libc::MSG_CMSG_CLOEXEC)?;
48
49 let control_len = msg_hdr.control_len();
51
52 let maybe_process_creds = if control_len > 0 {
53 unsafe {
54 ancillary_data.set_len(control_len);
55 let messages = ancillary_data.messages();
56 messages
57 .map(|m| match m {
58 ControlMessage::Credentials(creds) => ProcessCredentials {
59 pid: creds.pid,
60 uid: creds.uid,
61 gid: creds.gid,
62 },
63 })
64 .next()
65 }
66 } else {
67 None
68 };
69
70 let conn_addr = ConnectionAddress::ProcessLike(maybe_process_creds);
71
72 unsafe {
74 buf.advance_mut(n);
75 }
76
77 Ok((n, conn_addr))
78}