1 // Copyright 2021 The Chromium OS 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
5 use std::{
6 convert::TryFrom,
7 ffi::OsString,
8 fs::remove_file,
9 io,
10 mem::size_of,
11 ops::Deref,
12 os::unix::{
13 ffi::{OsStrExt, OsStringExt},
14 io::{AsRawFd, RawFd},
15 },
16 path::{Path, PathBuf},
17 sync::Arc,
18 };
19
20 use anyhow::{anyhow, bail, Context};
21 use memoffset::offset_of;
22 use sys_util::{warn, AsRawDescriptor, FromRawDescriptor, IntoRawDescriptor, SafeDescriptor};
23 use thiserror::Error as ThisError;
24
25 use crate::{AsIoBufs, OwnedIoBuf};
26
27 use super::io_driver;
28
29 #[derive(Debug, ThisError)]
30 #[error("Failed to prepare socket fd")]
31 struct PrepareSocket;
32
sockaddr_un<P: AsRef<Path>>(path: P) -> anyhow::Result<(libc::sockaddr_un, libc::socklen_t)>33 fn sockaddr_un<P: AsRef<Path>>(path: P) -> anyhow::Result<(libc::sockaddr_un, libc::socklen_t)> {
34 let mut addr = libc::sockaddr_un {
35 sun_family: libc::AF_UNIX as libc::sa_family_t,
36 sun_path: [0; 108],
37 };
38
39 // Check if the input path is valid. Since
40 // * The pathname in sun_path should be null-terminated.
41 // * The length of the pathname, including the terminating null byte,
42 // should not exceed the size of sun_path.
43 //
44 // and our input is a `Path`, we only need to check
45 // * If the string size of `Path` should less than sizeof(sun_path)
46 // and make sure `sun_path` ends with '\0' by initialized the sun_path with zeros.
47 //
48 // Empty path name is valid since abstract socket address has sun_paht[0] = '\0'
49 let bytes = path.as_ref().as_os_str().as_bytes();
50 if bytes.len() >= addr.sun_path.len() {
51 bail!(io::Error::new(
52 io::ErrorKind::InvalidInput,
53 "Input path size should be less than the length of sun_path.",
54 ));
55 };
56
57 // Copy data from `path` to `addr.sun_path`
58 for (dst, src) in addr.sun_path.iter_mut().zip(bytes) {
59 *dst = *src as libc::c_char;
60 }
61
62 // The addrlen argument that describes the enclosing sockaddr_un structure
63 // should have a value of at least:
64 //
65 // offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path) + 1
66 //
67 // or, more simply, addrlen can be specified as sizeof(struct sockaddr_un).
68 let len = offset_of!(libc::sockaddr_un, sun_path) + bytes.len() + 1;
69 Ok((addr, len as libc::socklen_t))
70 }
71
72 /// A Unix `SOCK_SEQPACKET`.
73 #[derive(Debug)]
74 pub struct SeqPacket {
75 fd: Arc<SafeDescriptor>,
76 }
77
78 impl SeqPacket {
79 /// Open a `SOCK_SEQPACKET` connection to socket named by `path`.
connect<P: AsRef<Path>>(path: P) -> anyhow::Result<Self>80 pub async fn connect<P: AsRef<Path>>(path: P) -> anyhow::Result<Self> {
81 // Safe because this doesn't modify any memory and we check the return value.
82 let fd =
83 unsafe { libc::socket(libc::AF_UNIX, libc::SOCK_SEQPACKET | libc::SOCK_CLOEXEC, 0) };
84 if fd < 0 {
85 return Err(io::Error::last_os_error())
86 .context("failed to create SOCK_SEQPACKET socket");
87 }
88
89 // Safe because we just opened this socket and we know it is valid.
90 let fd = Arc::new(unsafe { SafeDescriptor::from_raw_descriptor(fd) });
91 io_driver::prepare(&*fd).context(PrepareSocket)?;
92
93 let (addr, len) = sockaddr_un(path).context("failed to create `sockaddr_un`")?;
94 io_driver::connect(&fd, addr, len)
95 .await
96 .context("failed to connect socket")?;
97
98 Ok(SeqPacket { fd })
99 }
100
101 /// Creates a pair of connected `SOCK_SEQPACKET` sockets.
102 ///
103 /// Both returned file descriptors have the `CLOEXEC` flag set.s
pair() -> anyhow::Result<(Self, Self)>104 pub fn pair() -> anyhow::Result<(Self, Self)> {
105 let mut fds = [0, 0];
106 // Safe because we give enough space to store all the fds and we check the return value.
107 let ret = unsafe {
108 libc::socketpair(
109 libc::AF_UNIX,
110 libc::SOCK_SEQPACKET | libc::SOCK_CLOEXEC,
111 0,
112 &mut fds[0],
113 )
114 };
115
116 if ret == 0 {
117 // Safe because we just created these sockets and we know they are valid.
118 let (s1, s2) = unsafe {
119 (
120 Arc::new(SafeDescriptor::from_raw_descriptor(fds[0])),
121 Arc::new(SafeDescriptor::from_raw_descriptor(fds[1])),
122 )
123 };
124
125 io_driver::prepare(&*s1).context(PrepareSocket)?;
126 io_driver::prepare(&*s2).context(PrepareSocket)?;
127
128 Ok((Self { fd: s1 }, Self { fd: s2 }))
129 } else {
130 Err(anyhow!(io::Error::last_os_error()))
131 }
132 }
133
134 /// Gets the number of bytes in the next packet. This blocks as if `recv` were called,
135 /// respecting the blocking and timeout settings of the underlying socket.
next_packet_size(&self) -> anyhow::Result<usize>136 pub async fn next_packet_size(&self) -> anyhow::Result<usize> {
137 io_driver::next_packet_size(&self.fd).await
138 }
139
140 /// Clone the underlying FD.
try_clone(&self) -> anyhow::Result<Self>141 pub fn try_clone(&self) -> anyhow::Result<Self> {
142 self.fd
143 .try_clone()
144 .map(|fd| Self { fd: Arc::new(fd) })
145 .map_err(From::from)
146 }
147
148 /// Writes data from `buf` to the socket.
149 ///
150 /// Returns the number of bytes written to the socket. Note that when using I/O drivers like
151 /// io_uring the data will be copied into an intermediate buffer before it is written to the
152 /// socket and so this function is best suited for sending small amounts of data. Callers that
153 /// want to avoid the intermediate buffer should use `send_iobuf` instead.
send(&self, buf: &[u8]) -> anyhow::Result<usize>154 pub async fn send(&self, buf: &[u8]) -> anyhow::Result<usize> {
155 io_driver::write(&self.fd, buf, None).await
156 }
157
158 /// Writes `buf` with the provided file descriptors to the socket.
159 ///
160 /// Returns the number of bytes written to the socket. Like with `send`, this method may copy
161 /// both the data and the fds into an intermediate buffer before writing them to the socket.
162 /// Callers that want to avoid copying should use `send_iobuf_with_fds` instead.
send_with_fds(&self, buf: &[u8], fds: &[RawFd]) -> anyhow::Result<usize>163 pub async fn send_with_fds(&self, buf: &[u8], fds: &[RawFd]) -> anyhow::Result<usize> {
164 io_driver::sendmsg(&self.fd, buf, fds).await
165 }
166
167 /// Writes data from `buf` to the socket.
168 ///
169 /// This function is like `send` but takes an owned buffer instead, avoiding the need to first
170 /// copy the data into an intermediate buffer.
send_iobuf<B: AsIoBufs + Unpin + 'static>( &self, buf: B, ) -> (anyhow::Result<usize>, B)171 pub async fn send_iobuf<B: AsIoBufs + Unpin + 'static>(
172 &self,
173 buf: B,
174 ) -> (anyhow::Result<usize>, B) {
175 io_driver::write_iobuf(&self.fd, buf, None).await
176 }
177
178 /// Writes data from `buf` with the provided file descriptors to the socket.
179 ///
180 /// Like `send_with_fds` but doesn't require copying the data into an intermediate buffer first.
181 /// Returns the number of bytes written to the socket.
send_iobuf_with_fds<B: AsIoBufs + Unpin + 'static>( &self, buf: B, fds: &[RawFd], ) -> (anyhow::Result<usize>, B)182 pub async fn send_iobuf_with_fds<B: AsIoBufs + Unpin + 'static>(
183 &self,
184 buf: B,
185 fds: &[RawFd],
186 ) -> (anyhow::Result<usize>, B) {
187 io_driver::send_iobuf_with_fds(&self.fd, buf, fds).await
188 }
189
190 /// Reads data from the socket into `buf`.
191 ///
192 /// Returns the number of bytes read from the socket. Note that when using I/O drivers like
193 /// io_uring the data will first be read into an intermediate buffer before it is copied into
194 /// `buf` and so this function is best suited for reading small amounts of data. Callers that
195 /// want to avoid the intermediate buffer should use `recv_iobuf` instead.
recv(&self, buf: &mut [u8]) -> anyhow::Result<usize>196 pub async fn recv(&self, buf: &mut [u8]) -> anyhow::Result<usize> {
197 io_driver::read(&self.fd, buf, None).await
198 }
199
200 /// Reads data from the socket into `buf` and any file descriptors into `fds`.
201 ///
202 /// Returns the number of bytes read from the socket and the number of file descriptors
203 /// received. Note that when using I/O drivers like io_uring the data will first be read into an
204 /// intermediate buffer before it is copied into `buf` and so this function is best suited for
205 /// reading small amounts of data. Callers that want to avoid the intermediate buffer should use
206 /// `recv_iobuf_with_fds` instead.
recv_with_fds( &self, buf: &mut [u8], fds: &mut [RawFd], ) -> anyhow::Result<(usize, usize)>207 pub async fn recv_with_fds(
208 &self,
209 buf: &mut [u8],
210 fds: &mut [RawFd],
211 ) -> anyhow::Result<(usize, usize)> {
212 io_driver::recvmsg(&self.fd, buf, fds).await
213 }
214
215 /// Reads data from the socket into `buf`.
216 ///
217 /// This function is like `recv` but takes an owned buffer instead, avoiding the need to first
218 /// copy the data into an intermediate buffer.
recv_iobuf<B: AsIoBufs + Unpin + 'static>( &self, buf: B, ) -> (anyhow::Result<usize>, B)219 pub async fn recv_iobuf<B: AsIoBufs + Unpin + 'static>(
220 &self,
221 buf: B,
222 ) -> (anyhow::Result<usize>, B) {
223 io_driver::read_iobuf(&self.fd, buf, None).await
224 }
225
226 /// Reads data from the socket into `buf` and any file descriptors into `fds`.
227 ///
228 /// Like `recv_with_fds` but doesn't require copying the data into an intermediate buffer first.
229 /// Returns the number of bytes read from the socket as well as the number of file descriptors
230 /// received.
recv_iobuf_with_fds<B: AsIoBufs + Unpin + 'static>( &self, buf: B, fds: &mut [RawFd], ) -> (anyhow::Result<(usize, usize)>, B)231 pub async fn recv_iobuf_with_fds<B: AsIoBufs + Unpin + 'static>(
232 &self,
233 buf: B,
234 fds: &mut [RawFd],
235 ) -> (anyhow::Result<(usize, usize)>, B) {
236 io_driver::recv_iobuf_with_fds(&self.fd, buf, fds).await
237 }
238
239 /// Reads data from the socket into a `Vec<u8>`.
recv_as_vec(&self) -> anyhow::Result<Vec<u8>>240 pub async fn recv_as_vec(&self) -> anyhow::Result<Vec<u8>> {
241 let len = self.next_packet_size().await?;
242 let (res, mut buf) = self.recv_iobuf(OwnedIoBuf::new(vec![0u8; len])).await;
243 let count = res?;
244 buf.truncate(count);
245 Ok(buf.into_inner())
246 }
247
248 /// Reads data and file descriptors from the socket.
recv_as_vec_with_fds(&self) -> anyhow::Result<(Vec<u8>, Vec<RawFd>)>249 pub async fn recv_as_vec_with_fds(&self) -> anyhow::Result<(Vec<u8>, Vec<RawFd>)> {
250 let len = self.next_packet_size().await?;
251 let mut fds = vec![0; sys_util::SCM_SOCKET_MAX_FD_COUNT];
252 let (res, mut buf) = self
253 .recv_iobuf_with_fds(OwnedIoBuf::new(vec![0u8; len]), &mut fds)
254 .await;
255 let (data_len, fd_len) = res?;
256 buf.truncate(data_len);
257 fds.truncate(fd_len);
258
259 Ok((buf.into_inner(), fds))
260 }
261 }
262
263 impl TryFrom<sys_util::net::UnixSeqpacket> for SeqPacket {
264 type Error = anyhow::Error;
265
try_from(value: sys_util::net::UnixSeqpacket) -> anyhow::Result<Self>266 fn try_from(value: sys_util::net::UnixSeqpacket) -> anyhow::Result<Self> {
267 // Safe because `value` owns the fd.
268 let fd =
269 Arc::new(unsafe { SafeDescriptor::from_raw_descriptor(value.into_raw_descriptor()) });
270 io_driver::prepare(&*fd)?;
271 Ok(Self { fd })
272 }
273 }
274
275 impl TryFrom<SeqPacket> for sys_util::net::UnixSeqpacket {
276 type Error = SeqPacket;
277
try_from(value: SeqPacket) -> Result<Self, Self::Error>278 fn try_from(value: SeqPacket) -> Result<Self, Self::Error> {
279 Arc::try_unwrap(value.fd)
280 .map(|fd| unsafe {
281 sys_util::net::UnixSeqpacket::from_raw_descriptor(fd.into_raw_descriptor())
282 })
283 .map_err(|fd| SeqPacket { fd })
284 }
285 }
286
287 impl AsRawDescriptor for SeqPacket {
as_raw_descriptor(&self) -> sys_util::RawDescriptor288 fn as_raw_descriptor(&self) -> sys_util::RawDescriptor {
289 self.fd.as_raw_descriptor()
290 }
291 }
292
293 impl AsRawFd for SeqPacket {
as_raw_fd(&self) -> RawFd294 fn as_raw_fd(&self) -> RawFd {
295 self.fd.as_raw_fd()
296 }
297 }
298
299 /// Like a `UnixListener` but for accepting `SOCK_SEQPACKET` sockets.
300 pub struct SeqPacketListener {
301 fd: Arc<SafeDescriptor>,
302 }
303
304 impl SeqPacketListener {
bind<P: AsRef<Path>>(path: P) -> anyhow::Result<Self>305 pub fn bind<P: AsRef<Path>>(path: P) -> anyhow::Result<Self> {
306 // Safe because this doesn't modify any memory and we check the return value.
307 let fd =
308 unsafe { libc::socket(libc::AF_UNIX, libc::SOCK_SEQPACKET | libc::SOCK_CLOEXEC, 0) };
309 if fd < 0 {
310 return Err(io::Error::last_os_error())
311 .context("failed to create SOCK_SEQPACKET socket");
312 }
313
314 // Safe because we just opened this socket and we know it is valid.
315 let fd = Arc::new(unsafe { SafeDescriptor::from_raw_descriptor(fd) });
316 io_driver::prepare(&*fd).context(PrepareSocket)?;
317
318 let (addr, len) = sockaddr_un(path).context("failed to create `sockaddr_un`")?;
319 // Safe connect since we handle the error and use the right length generated from
320 // `sockaddr_un`.
321 unsafe {
322 let ret = libc::bind(fd.as_raw_descriptor(), &addr as *const _ as *const _, len);
323 if ret < 0 {
324 return Err(anyhow!(io::Error::last_os_error()));
325 }
326 let ret = libc::listen(fd.as_raw_descriptor(), 128);
327 if ret < 0 {
328 return Err(anyhow!(io::Error::last_os_error()));
329 }
330 }
331
332 Ok(Self { fd })
333 }
334
335 /// Accepts a new incoming connection and returns the socket associated with that connection.
accept(&self) -> anyhow::Result<SeqPacket>336 pub async fn accept(&self) -> anyhow::Result<SeqPacket> {
337 let fd = io_driver::accept(&self.fd)
338 .await
339 .map(Arc::new)
340 .context("failed to accept connection")?;
341 io_driver::prepare(&*fd).context(PrepareSocket)?;
342 Ok(SeqPacket { fd })
343 }
344
345 /// Gets the path that this listener is bound to.
path(&self) -> anyhow::Result<PathBuf>346 pub fn path(&self) -> anyhow::Result<PathBuf> {
347 let mut addr = libc::sockaddr_un {
348 sun_family: libc::AF_UNIX as libc::sa_family_t,
349 sun_path: [0; 108],
350 };
351 let sun_path_offset = offset_of!(libc::sockaddr_un, sun_path) as libc::socklen_t;
352 let mut len = size_of::<libc::sockaddr_un>() as libc::socklen_t;
353 // Safe because the length given matches the length of the data of the given pointer, and we
354 // check the return value.
355 let ret = unsafe {
356 libc::getsockname(
357 self.fd.as_raw_descriptor(),
358 &mut addr as *mut libc::sockaddr_un as *mut libc::sockaddr,
359 &mut len,
360 )
361 };
362 if ret < 0 {
363 return Err(anyhow!(io::Error::last_os_error()));
364 }
365 if addr.sun_family != libc::AF_UNIX as libc::sa_family_t
366 || addr.sun_path[0] == 0
367 || len < 1 + sun_path_offset
368 {
369 return Err(anyhow!(io::Error::new(
370 io::ErrorKind::InvalidData,
371 "getsockname on socket returned invalid value",
372 )));
373 }
374
375 let path = OsString::from_vec(
376 addr.sun_path[..(len - sun_path_offset - 1) as usize]
377 .iter()
378 .map(|&c| c as _)
379 .collect(),
380 );
381 Ok(path.into())
382 }
383 }
384
385 impl AsRawDescriptor for SeqPacketListener {
as_raw_descriptor(&self) -> sys_util::RawDescriptor386 fn as_raw_descriptor(&self) -> sys_util::RawDescriptor {
387 self.fd.as_raw_descriptor()
388 }
389 }
390
391 impl AsRawFd for SeqPacketListener {
as_raw_fd(&self) -> RawFd392 fn as_raw_fd(&self) -> RawFd {
393 self.fd.as_raw_fd()
394 }
395 }
396
397 /// Used to attempt to clean up a `SeqPacketListener` after it is dropped.
398 pub struct UnlinkSeqPacketListener(pub SeqPacketListener);
399 impl AsRef<SeqPacketListener> for UnlinkSeqPacketListener {
as_ref(&self) -> &SeqPacketListener400 fn as_ref(&self) -> &SeqPacketListener {
401 &self.0
402 }
403 }
404
405 impl AsRawFd for UnlinkSeqPacketListener {
as_raw_fd(&self) -> RawFd406 fn as_raw_fd(&self) -> RawFd {
407 self.0.as_raw_fd()
408 }
409 }
410
411 impl Deref for UnlinkSeqPacketListener {
412 type Target = SeqPacketListener;
deref(&self) -> &Self::Target413 fn deref(&self) -> &Self::Target {
414 &self.0
415 }
416 }
417
418 impl Drop for UnlinkSeqPacketListener {
drop(&mut self)419 fn drop(&mut self) {
420 if let Ok(path) = self.0.path() {
421 if let Err(e) = remove_file(path) {
422 warn!("failed to remove socket file: {:?}", e);
423 }
424 }
425 }
426 }
427
428 #[cfg(test)]
429 mod test {
430 use super::*;
431
432 use std::{
433 env,
434 fs::File,
435 io::Write,
436 time::{Duration, Instant},
437 };
438
439 use sys_util::{AsRawDescriptor, EventFd};
440
441 use crate::{with_deadline, Executor};
442
443 #[test]
send_recv_no_fd()444 fn send_recv_no_fd() {
445 Executor::new()
446 .run_until(async {
447 let (s1, s2) = SeqPacket::pair().expect("failed to create socket pair");
448
449 let send_buf = [1u8, 1, 2, 21, 34, 55];
450 let write_count = s1
451 .send_with_fds(&send_buf, &[])
452 .await
453 .expect("failed to send data");
454
455 assert_eq!(write_count, 6);
456
457 let mut buf = [0; 6];
458 let mut files = [0; 1];
459 let (read_count, file_count) = s2
460 .recv_with_fds(&mut buf[..], &mut files)
461 .await
462 .expect("failed to recv data");
463
464 assert_eq!(read_count, 6);
465 assert_eq!(file_count, 0);
466 assert_eq!(buf, [1, 1, 2, 21, 34, 55]);
467 })
468 .unwrap();
469 }
470
471 #[test]
send_recv_iobuf_no_fd()472 fn send_recv_iobuf_no_fd() {
473 Executor::new()
474 .run_until(async {
475 let (s1, s2) = SeqPacket::pair().expect("failed to create socket pair");
476
477 let send_buf = [1u8, 1, 2, 21, 34, 55];
478 let (res, _) = s1
479 .send_iobuf_with_fds(OwnedIoBuf::new(Vec::from(send_buf)), &[])
480 .await;
481 let write_count = res.expect("failed to send data");
482 assert_eq!(write_count, 6);
483
484 let iobuf = OwnedIoBuf::new(vec![0; 6]);
485 let mut files = [0; 1];
486 let (res, iobuf) = s2.recv_iobuf_with_fds(iobuf, &mut files).await;
487 let (read_count, file_count) = res.expect("failed to recv data");
488
489 assert_eq!(read_count, 6);
490 assert_eq!(file_count, 0);
491 assert_eq!(&*iobuf, &[1, 1, 2, 21, 34, 55]);
492 })
493 .unwrap();
494 }
495
496 #[test]
send_recv_only_fd()497 fn send_recv_only_fd() {
498 Executor::new()
499 .run_until(async {
500 let (s1, s2) = SeqPacket::pair().expect("failed to create socket pair");
501
502 let evt = EventFd::new().expect("failed to create eventfd");
503 let write_count = s1
504 .send_with_fds(&[], &[evt.as_raw_descriptor()])
505 .await
506 .expect("failed to send fd");
507
508 assert_eq!(write_count, 0);
509
510 let mut files = [-1; 2];
511 let (read_count, file_count) = s2
512 .recv_with_fds(&mut [], &mut files)
513 .await
514 .expect("failed to recv fd");
515
516 assert_eq!(read_count, 0);
517 assert_eq!(file_count, 1);
518 assert!(files[0] >= 0);
519 assert_ne!(files[0], s1.as_raw_descriptor());
520 assert_ne!(files[0], s2.as_raw_descriptor());
521 assert_ne!(files[0], evt.as_raw_descriptor());
522
523 let mut file = unsafe { File::from_raw_descriptor(files[0]) };
524 file.write_all(&1203u64.to_ne_bytes())
525 .expect("failed to write to sent fd");
526
527 assert_eq!(evt.read().expect("failed to read from eventfd"), 1203);
528 })
529 .unwrap();
530 }
531
532 #[test]
send_recv_iobuf_only_fd()533 fn send_recv_iobuf_only_fd() {
534 Executor::new()
535 .run_until(async {
536 let (s1, s2) = SeqPacket::pair().expect("failed to create socket pair");
537
538 let evt = EventFd::new().expect("failed to create eventfd");
539 let (res, _) = s1
540 .send_iobuf_with_fds(OwnedIoBuf::new(vec![]), &[evt.as_raw_descriptor()])
541 .await;
542 let write_count = res.expect("failed to send fd");
543 assert_eq!(write_count, 0);
544
545 let mut files = [-1; 2];
546 let (res, _) = s2
547 .recv_iobuf_with_fds(OwnedIoBuf::new(vec![]), &mut files)
548 .await;
549 let (read_count, file_count) = res.expect("failed to recv fd");
550
551 assert_eq!(read_count, 0);
552 assert_eq!(file_count, 1);
553 assert!(files[0] >= 0);
554 assert_ne!(files[0], s1.as_raw_descriptor());
555 assert_ne!(files[0], s2.as_raw_descriptor());
556 assert_ne!(files[0], evt.as_raw_descriptor());
557
558 let mut file = unsafe { File::from_raw_descriptor(files[0]) };
559 file.write_all(&1203u64.to_ne_bytes())
560 .expect("failed to write to sent fd");
561
562 assert_eq!(evt.read().expect("failed to read from eventfd"), 1203);
563 })
564 .unwrap();
565 }
566
567 #[test]
send_recv_with_fd()568 fn send_recv_with_fd() {
569 Executor::new()
570 .run_until(async {
571 let (s1, s2) = SeqPacket::pair().expect("failed to create socket pair");
572
573 let evt = EventFd::new().expect("failed to create eventfd");
574 let write_count = s1
575 .send_with_fds(&[237], &[evt.as_raw_descriptor()])
576 .await
577 .expect("failed to send fd");
578
579 assert_eq!(write_count, 1);
580
581 let mut files = [-1; 2];
582 let mut buf = [0u8];
583 let (read_count, file_count) = s2
584 .recv_with_fds(&mut buf, &mut files)
585 .await
586 .expect("failed to recv fd");
587
588 assert_eq!(read_count, 1);
589 assert_eq!(buf[0], 237);
590 assert_eq!(file_count, 1);
591 assert!(files[0] >= 0);
592 assert_ne!(files[0], s1.as_raw_descriptor());
593 assert_ne!(files[0], s2.as_raw_descriptor());
594 assert_ne!(files[0], evt.as_raw_descriptor());
595
596 let mut file = unsafe { File::from_raw_descriptor(files[0]) };
597
598 file.write_all(&1203u64.to_ne_bytes())
599 .expect("failed to write to sent fd");
600
601 assert_eq!(evt.read().expect("failed to read from eventfd"), 1203);
602 })
603 .unwrap();
604 }
605
606 #[test]
send_recv_iobuf_with_fd()607 fn send_recv_iobuf_with_fd() {
608 Executor::new()
609 .run_until(async {
610 let (s1, s2) = SeqPacket::pair().expect("failed to create socket pair");
611
612 let evt = EventFd::new().expect("failed to create eventfd");
613 let (res, _) = s1
614 .send_iobuf_with_fds(OwnedIoBuf::new(vec![237]), &[evt.as_raw_descriptor()])
615 .await;
616 let write_count = res.expect("failed to send fd");
617
618 assert_eq!(write_count, 1);
619
620 let mut files = [-1; 2];
621 let iobuf = OwnedIoBuf::new(vec![0]);
622 let (res, iobuf) = s2.recv_iobuf_with_fds(iobuf, &mut files).await;
623 let (read_count, file_count) = res.expect("failed to recv fd");
624
625 assert_eq!(read_count, 1);
626 assert_eq!(iobuf[0], 237);
627 assert_eq!(file_count, 1);
628 assert!(files[0] >= 0);
629 assert_ne!(files[0], s1.as_raw_descriptor());
630 assert_ne!(files[0], s2.as_raw_descriptor());
631 assert_ne!(files[0], evt.as_raw_descriptor());
632
633 let mut file = unsafe { File::from_raw_descriptor(files[0]) };
634
635 file.write_all(&1203u64.to_ne_bytes())
636 .expect("failed to write to sent fd");
637
638 assert_eq!(evt.read().expect("failed to read from eventfd"), 1203);
639 })
640 .unwrap();
641 }
642
643 #[test]
sockaddr_un_zero_length_input()644 fn sockaddr_un_zero_length_input() {
645 let _res = sockaddr_un(Path::new("")).expect("sockaddr_un failed");
646 }
647
648 #[test]
sockaddr_un_long_input_err()649 fn sockaddr_un_long_input_err() {
650 let res = sockaddr_un(Path::new(&"a".repeat(108)));
651 assert!(res.is_err());
652 }
653
654 #[test]
sockaddr_un_long_input_pass()655 fn sockaddr_un_long_input_pass() {
656 let _res = sockaddr_un(Path::new(&"a".repeat(107))).expect("sockaddr_un failed");
657 }
658
659 #[test]
sockaddr_un_len_check()660 fn sockaddr_un_len_check() {
661 let (_addr, len) = sockaddr_un(Path::new(&"a".repeat(50))).expect("sockaddr_un failed");
662 assert_eq!(
663 len,
664 (offset_of!(libc::sockaddr_un, sun_path) + 50 + 1) as u32
665 );
666 }
667
668 #[test]
sockaddr_un_pass()669 fn sockaddr_un_pass() {
670 let path_size = 50;
671 let (addr, len) =
672 sockaddr_un(Path::new(&"a".repeat(path_size))).expect("sockaddr_un failed");
673 assert_eq!(
674 len,
675 (offset_of!(libc::sockaddr_un, sun_path) + path_size + 1) as u32
676 );
677 assert_eq!(addr.sun_family, libc::AF_UNIX as libc::sa_family_t);
678
679 // Check `sun_path` in returned `sockaddr_un`
680 let mut ref_sun_path = [0; 108];
681 for path in ref_sun_path.iter_mut().take(path_size) {
682 *path = 'a' as libc::c_char;
683 }
684
685 for (addr_char, ref_char) in addr.sun_path.iter().zip(ref_sun_path.iter()) {
686 assert_eq!(addr_char, ref_char);
687 }
688 }
689
690 #[test]
unix_seqpacket_path_not_exists()691 fn unix_seqpacket_path_not_exists() {
692 Executor::new()
693 .run_until(async {
694 let res = SeqPacket::connect("/path/not/exists").await;
695 assert!(res.is_err());
696 })
697 .unwrap();
698 }
699
700 #[test]
unix_seqpacket_listener_path()701 fn unix_seqpacket_listener_path() {
702 let mut socket_path = env::temp_dir();
703 socket_path.push("unix_seqpacket_listener_path");
704 let listener = UnlinkSeqPacketListener(
705 SeqPacketListener::bind(&socket_path).expect("failed to create SeqPacketListener"),
706 );
707 let listener_path = listener.path().expect("failed to get socket listener path");
708 assert_eq!(socket_path, listener_path);
709 }
710
711 #[test]
unix_seqpacket_path_exists_pass()712 fn unix_seqpacket_path_exists_pass() {
713 Executor::new()
714 .run_until(async {
715 let mut socket_path = env::temp_dir();
716 socket_path.push("path_to_socket");
717 let _listener = UnlinkSeqPacketListener(
718 SeqPacketListener::bind(&socket_path)
719 .expect("failed to create SeqPacketListener"),
720 );
721 let _res = SeqPacket::connect(socket_path.as_path())
722 .await
723 .expect("SeqPacket::connect failed");
724 })
725 .unwrap();
726 }
727
728 #[test]
unix_seqpacket_path_listener_accept()729 fn unix_seqpacket_path_listener_accept() {
730 Executor::new()
731 .run_until(async {
732 let mut socket_path = env::temp_dir();
733 socket_path.push("path_listerner_accept");
734 let listener = UnlinkSeqPacketListener(
735 SeqPacketListener::bind(&socket_path)
736 .expect("failed to create SeqPacketListener"),
737 );
738 let s1 = SeqPacket::connect(&socket_path)
739 .await
740 .expect("SeqPacket::connect failed");
741
742 let s2 = listener.accept().await.expect("SeqPacket::accept failed");
743
744 let data1 = &[0, 1, 2, 3, 4];
745 let data2 = &[10, 11, 12, 13, 14];
746 s2.send(data2).await.expect("failed to send data2");
747 s1.send(data1).await.expect("failed to send data1");
748 let recv_data = &mut [0; 5];
749 s2.recv(recv_data).await.expect("failed to recv data");
750 assert_eq!(data1, recv_data);
751 s1.recv(recv_data).await.expect("failed to recv data");
752 assert_eq!(data2, recv_data);
753 })
754 .unwrap();
755 }
756
757 #[test]
unix_seqpacket_send_recv()758 fn unix_seqpacket_send_recv() {
759 Executor::new()
760 .run_until(async {
761 let (s1, s2) = SeqPacket::pair().expect("failed to create socket pair");
762 let data1 = &[0, 1, 2, 3, 4];
763 let data2 = &[10, 11, 12, 13, 14];
764 s2.send(data2).await.expect("failed to send data2");
765 s1.send(data1).await.expect("failed to send data1");
766 let recv_data = &mut [0; 5];
767 s2.recv(recv_data).await.expect("failed to recv data");
768 assert_eq!(data1, recv_data);
769 s1.recv(recv_data).await.expect("failed to recv data");
770 assert_eq!(data2, recv_data);
771 })
772 .unwrap();
773 }
774
775 #[test]
unix_seqpacket_send_fragments()776 fn unix_seqpacket_send_fragments() {
777 Executor::new()
778 .run_until(async {
779 let (s1, s2) = SeqPacket::pair().expect("failed to create socket pair");
780 let data1 = &[0, 1, 2, 3, 4];
781 let data2 = &[10, 11, 12, 13, 14, 15, 16];
782 s1.send(data1).await.expect("failed to send data1");
783 s1.send(data2).await.expect("failed to send data2");
784
785 let recv_data = &mut [0; 32];
786 let size = s2.recv(recv_data).await.expect("failed to recv data");
787 assert_eq!(size, data1.len());
788 assert_eq!(data1, &recv_data[0..size]);
789
790 let size = s2.recv(recv_data).await.expect("failed to recv data");
791 assert_eq!(size, data2.len());
792 assert_eq!(data2, &recv_data[0..size]);
793 })
794 .unwrap();
795 }
796
797 #[test]
unix_seqpacket_next_packet_size()798 fn unix_seqpacket_next_packet_size() {
799 Executor::new()
800 .run_until(async {
801 let (s1, s2) = SeqPacket::pair().expect("failed to create socket pair");
802 let data1 = &[0, 1, 2, 3, 4];
803 s1.send(data1).await.expect("failed to send data");
804
805 assert_eq!(s2.next_packet_size().await.unwrap(), 5);
806 assert!(with_deadline(
807 Instant::now() + Duration::from_micros(1),
808 s1.next_packet_size()
809 )
810 .await
811 .is_err());
812
813 drop(s2);
814 assert_eq!(
815 s1.next_packet_size()
816 .await
817 .unwrap_err()
818 .downcast::<io::Error>()
819 .unwrap()
820 .kind(),
821 io::ErrorKind::ConnectionReset
822 );
823 })
824 .unwrap();
825 }
826
827 #[test]
unix_seqpacket_recv_as_vec()828 fn unix_seqpacket_recv_as_vec() {
829 Executor::new()
830 .run_until(async {
831 let (s1, s2) = SeqPacket::pair().expect("failed to create socket pair");
832 let data1 = &[0, 1, 2, 3, 4];
833 s1.send(data1).await.expect("failed to send data");
834
835 let recv_data = s2.recv_as_vec().await.expect("failed to recv data");
836 assert_eq!(&recv_data, &*data1);
837 })
838 .unwrap();
839 }
840 }
841