1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2022 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker
5*bb4ee6a4SAndroid Build Coastguard Worker use std::io::ErrorKind;
6*bb4ee6a4SAndroid Build Coastguard Worker use std::time::Duration;
7*bb4ee6a4SAndroid Build Coastguard Worker
8*bb4ee6a4SAndroid Build Coastguard Worker use base::AsRawDescriptor;
9*bb4ee6a4SAndroid Build Coastguard Worker use base::UnixSeqpacket;
10*bb4ee6a4SAndroid Build Coastguard Worker use base::UnixSeqpacketListener;
11*bb4ee6a4SAndroid Build Coastguard Worker use base::UnlinkUnixSeqpacketListener;
12*bb4ee6a4SAndroid Build Coastguard Worker use tempfile::tempdir;
13*bb4ee6a4SAndroid Build Coastguard Worker
14*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_path_not_exists()15*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_path_not_exists() {
16*bb4ee6a4SAndroid Build Coastguard Worker let res = UnixSeqpacket::connect("/path/not/exists");
17*bb4ee6a4SAndroid Build Coastguard Worker assert!(res.is_err());
18*bb4ee6a4SAndroid Build Coastguard Worker }
19*bb4ee6a4SAndroid Build Coastguard Worker
20*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_listener_path()21*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_listener_path() {
22*bb4ee6a4SAndroid Build Coastguard Worker let temp_dir = tempdir().expect("failed to create tempdir");
23*bb4ee6a4SAndroid Build Coastguard Worker let socket_path = temp_dir.path().join("unix_seqpacket_listener_path");
24*bb4ee6a4SAndroid Build Coastguard Worker let listener = UnlinkUnixSeqpacketListener(
25*bb4ee6a4SAndroid Build Coastguard Worker UnixSeqpacketListener::bind(&socket_path).expect("failed to create UnixSeqpacketListener"),
26*bb4ee6a4SAndroid Build Coastguard Worker );
27*bb4ee6a4SAndroid Build Coastguard Worker let listener_path = listener.path().expect("failed to get socket listener path");
28*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(socket_path, listener_path);
29*bb4ee6a4SAndroid Build Coastguard Worker }
30*bb4ee6a4SAndroid Build Coastguard Worker
31*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_listener_from_fd()32*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_listener_from_fd() {
33*bb4ee6a4SAndroid Build Coastguard Worker let temp_dir = tempdir().expect("failed to create tempdir");
34*bb4ee6a4SAndroid Build Coastguard Worker let socket_path = temp_dir.path().join("unix_seqpacket_listener_from_fd");
35*bb4ee6a4SAndroid Build Coastguard Worker let listener = UnlinkUnixSeqpacketListener(
36*bb4ee6a4SAndroid Build Coastguard Worker UnixSeqpacketListener::bind(&socket_path).expect("failed to create UnixSeqpacketListener"),
37*bb4ee6a4SAndroid Build Coastguard Worker );
38*bb4ee6a4SAndroid Build Coastguard Worker // UnixSeqpacketListener should succeed on a valid listening descriptor.
39*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: Safe because `listener` is valid and the return value is checked.
40*bb4ee6a4SAndroid Build Coastguard Worker let good_dup = UnixSeqpacketListener::bind(format!("/proc/self/fd/{}", unsafe {
41*bb4ee6a4SAndroid Build Coastguard Worker libc::dup(listener.as_raw_descriptor())
42*bb4ee6a4SAndroid Build Coastguard Worker }));
43*bb4ee6a4SAndroid Build Coastguard Worker let good_dup_path = good_dup
44*bb4ee6a4SAndroid Build Coastguard Worker .expect("failed to create dup UnixSeqpacketListener")
45*bb4ee6a4SAndroid Build Coastguard Worker .path();
46*bb4ee6a4SAndroid Build Coastguard Worker // Path of socket created by descriptor should be hidden.
47*bb4ee6a4SAndroid Build Coastguard Worker assert!(good_dup_path.is_err());
48*bb4ee6a4SAndroid Build Coastguard Worker // UnixSeqpacketListener must fail on an existing non-listener socket.
49*bb4ee6a4SAndroid Build Coastguard Worker let s1 = UnixSeqpacket::connect(socket_path.as_path()).expect("UnixSeqpacket::connect failed");
50*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: Safe because `s1` is valid and the return value is checked.
51*bb4ee6a4SAndroid Build Coastguard Worker let bad_dup = UnixSeqpacketListener::bind(format!("/proc/self/fd/{}", unsafe {
52*bb4ee6a4SAndroid Build Coastguard Worker libc::dup(s1.as_raw_descriptor())
53*bb4ee6a4SAndroid Build Coastguard Worker }));
54*bb4ee6a4SAndroid Build Coastguard Worker assert!(bad_dup.is_err());
55*bb4ee6a4SAndroid Build Coastguard Worker }
56*bb4ee6a4SAndroid Build Coastguard Worker
57*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_path_exists_pass()58*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_path_exists_pass() {
59*bb4ee6a4SAndroid Build Coastguard Worker let temp_dir = tempdir().expect("failed to create tempdir");
60*bb4ee6a4SAndroid Build Coastguard Worker let socket_path = temp_dir.path().join("path_to_socket");
61*bb4ee6a4SAndroid Build Coastguard Worker let _listener = UnlinkUnixSeqpacketListener(
62*bb4ee6a4SAndroid Build Coastguard Worker UnixSeqpacketListener::bind(&socket_path).expect("failed to create UnixSeqpacketListener"),
63*bb4ee6a4SAndroid Build Coastguard Worker );
64*bb4ee6a4SAndroid Build Coastguard Worker let _res =
65*bb4ee6a4SAndroid Build Coastguard Worker UnixSeqpacket::connect(socket_path.as_path()).expect("UnixSeqpacket::connect failed");
66*bb4ee6a4SAndroid Build Coastguard Worker }
67*bb4ee6a4SAndroid Build Coastguard Worker
68*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_path_listener_accept_with_timeout()69*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_path_listener_accept_with_timeout() {
70*bb4ee6a4SAndroid Build Coastguard Worker let temp_dir = tempdir().expect("failed to create tempdir");
71*bb4ee6a4SAndroid Build Coastguard Worker let socket_path = temp_dir.path().join("path_listerner_accept_with_timeout");
72*bb4ee6a4SAndroid Build Coastguard Worker let listener = UnlinkUnixSeqpacketListener(
73*bb4ee6a4SAndroid Build Coastguard Worker UnixSeqpacketListener::bind(&socket_path).expect("failed to create UnixSeqpacketListener"),
74*bb4ee6a4SAndroid Build Coastguard Worker );
75*bb4ee6a4SAndroid Build Coastguard Worker
76*bb4ee6a4SAndroid Build Coastguard Worker for d in [Duration::from_millis(10), Duration::ZERO] {
77*bb4ee6a4SAndroid Build Coastguard Worker let _ = listener.accept_with_timeout(d).expect_err(&format!(
78*bb4ee6a4SAndroid Build Coastguard Worker "UnixSeqpacket::accept_with_timeout {:?} connected",
79*bb4ee6a4SAndroid Build Coastguard Worker d
80*bb4ee6a4SAndroid Build Coastguard Worker ));
81*bb4ee6a4SAndroid Build Coastguard Worker
82*bb4ee6a4SAndroid Build Coastguard Worker let s1 = UnixSeqpacket::connect(socket_path.as_path())
83*bb4ee6a4SAndroid Build Coastguard Worker .unwrap_or_else(|_| panic!("UnixSeqpacket::connect {:?} failed", d));
84*bb4ee6a4SAndroid Build Coastguard Worker
85*bb4ee6a4SAndroid Build Coastguard Worker let s2 = listener
86*bb4ee6a4SAndroid Build Coastguard Worker .accept_with_timeout(d)
87*bb4ee6a4SAndroid Build Coastguard Worker .unwrap_or_else(|_| panic!("UnixSeqpacket::accept {:?} failed", d));
88*bb4ee6a4SAndroid Build Coastguard Worker
89*bb4ee6a4SAndroid Build Coastguard Worker let data1 = &[0, 1, 2, 3, 4];
90*bb4ee6a4SAndroid Build Coastguard Worker let data2 = &[10, 11, 12, 13, 14];
91*bb4ee6a4SAndroid Build Coastguard Worker s2.send(data2).expect("failed to send data2");
92*bb4ee6a4SAndroid Build Coastguard Worker s1.send(data1).expect("failed to send data1");
93*bb4ee6a4SAndroid Build Coastguard Worker let recv_data = &mut [0; 5];
94*bb4ee6a4SAndroid Build Coastguard Worker s2.recv(recv_data).expect("failed to recv data");
95*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(data1, recv_data);
96*bb4ee6a4SAndroid Build Coastguard Worker s1.recv(recv_data).expect("failed to recv data");
97*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(data2, recv_data);
98*bb4ee6a4SAndroid Build Coastguard Worker }
99*bb4ee6a4SAndroid Build Coastguard Worker }
100*bb4ee6a4SAndroid Build Coastguard Worker
101*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_path_listener_accept()102*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_path_listener_accept() {
103*bb4ee6a4SAndroid Build Coastguard Worker let temp_dir = tempdir().expect("failed to create tempdir");
104*bb4ee6a4SAndroid Build Coastguard Worker let socket_path = temp_dir.path().join("path_listerner_accept");
105*bb4ee6a4SAndroid Build Coastguard Worker let listener = UnlinkUnixSeqpacketListener(
106*bb4ee6a4SAndroid Build Coastguard Worker UnixSeqpacketListener::bind(&socket_path).expect("failed to create UnixSeqpacketListener"),
107*bb4ee6a4SAndroid Build Coastguard Worker );
108*bb4ee6a4SAndroid Build Coastguard Worker let s1 = UnixSeqpacket::connect(socket_path.as_path()).expect("UnixSeqpacket::connect failed");
109*bb4ee6a4SAndroid Build Coastguard Worker
110*bb4ee6a4SAndroid Build Coastguard Worker let s2 = listener.accept().expect("UnixSeqpacket::accept failed");
111*bb4ee6a4SAndroid Build Coastguard Worker
112*bb4ee6a4SAndroid Build Coastguard Worker let data1 = &[0, 1, 2, 3, 4];
113*bb4ee6a4SAndroid Build Coastguard Worker let data2 = &[10, 11, 12, 13, 14];
114*bb4ee6a4SAndroid Build Coastguard Worker s2.send(data2).expect("failed to send data2");
115*bb4ee6a4SAndroid Build Coastguard Worker s1.send(data1).expect("failed to send data1");
116*bb4ee6a4SAndroid Build Coastguard Worker let recv_data = &mut [0; 5];
117*bb4ee6a4SAndroid Build Coastguard Worker s2.recv(recv_data).expect("failed to recv data");
118*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(data1, recv_data);
119*bb4ee6a4SAndroid Build Coastguard Worker s1.recv(recv_data).expect("failed to recv data");
120*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(data2, recv_data);
121*bb4ee6a4SAndroid Build Coastguard Worker }
122*bb4ee6a4SAndroid Build Coastguard Worker
123*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_zero_timeout()124*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_zero_timeout() {
125*bb4ee6a4SAndroid Build Coastguard Worker let (s1, _s2) = UnixSeqpacket::pair().expect("failed to create socket pair");
126*bb4ee6a4SAndroid Build Coastguard Worker // Timeouts less than a microsecond are too small and round to zero.
127*bb4ee6a4SAndroid Build Coastguard Worker s1.set_read_timeout(Some(Duration::from_nanos(10)))
128*bb4ee6a4SAndroid Build Coastguard Worker .expect_err("successfully set zero timeout");
129*bb4ee6a4SAndroid Build Coastguard Worker }
130*bb4ee6a4SAndroid Build Coastguard Worker
131*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_read_timeout()132*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_read_timeout() {
133*bb4ee6a4SAndroid Build Coastguard Worker let (s1, _s2) = UnixSeqpacket::pair().expect("failed to create socket pair");
134*bb4ee6a4SAndroid Build Coastguard Worker s1.set_read_timeout(Some(Duration::from_millis(1)))
135*bb4ee6a4SAndroid Build Coastguard Worker .expect("failed to set read timeout for socket");
136*bb4ee6a4SAndroid Build Coastguard Worker let _ = s1.recv(&mut [0]);
137*bb4ee6a4SAndroid Build Coastguard Worker }
138*bb4ee6a4SAndroid Build Coastguard Worker
139*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_write_timeout()140*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_write_timeout() {
141*bb4ee6a4SAndroid Build Coastguard Worker let (s1, _s2) = UnixSeqpacket::pair().expect("failed to create socket pair");
142*bb4ee6a4SAndroid Build Coastguard Worker s1.set_write_timeout(Some(Duration::from_millis(1)))
143*bb4ee6a4SAndroid Build Coastguard Worker .expect("failed to set write timeout for socket");
144*bb4ee6a4SAndroid Build Coastguard Worker }
145*bb4ee6a4SAndroid Build Coastguard Worker
146*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_send_recv()147*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_send_recv() {
148*bb4ee6a4SAndroid Build Coastguard Worker let (s1, s2) = UnixSeqpacket::pair().expect("failed to create socket pair");
149*bb4ee6a4SAndroid Build Coastguard Worker let data1 = &[0, 1, 2, 3, 4];
150*bb4ee6a4SAndroid Build Coastguard Worker let data2 = &[10, 11, 12, 13, 14];
151*bb4ee6a4SAndroid Build Coastguard Worker s2.send(data2).expect("failed to send data2");
152*bb4ee6a4SAndroid Build Coastguard Worker s1.send(data1).expect("failed to send data1");
153*bb4ee6a4SAndroid Build Coastguard Worker let recv_data = &mut [0; 5];
154*bb4ee6a4SAndroid Build Coastguard Worker s2.recv(recv_data).expect("failed to recv data");
155*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(data1, recv_data);
156*bb4ee6a4SAndroid Build Coastguard Worker s1.recv(recv_data).expect("failed to recv data");
157*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(data2, recv_data);
158*bb4ee6a4SAndroid Build Coastguard Worker }
159*bb4ee6a4SAndroid Build Coastguard Worker
160*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_send_fragments()161*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_send_fragments() {
162*bb4ee6a4SAndroid Build Coastguard Worker let (s1, s2) = UnixSeqpacket::pair().expect("failed to create socket pair");
163*bb4ee6a4SAndroid Build Coastguard Worker let data1 = &[0, 1, 2, 3, 4];
164*bb4ee6a4SAndroid Build Coastguard Worker let data2 = &[10, 11, 12, 13, 14, 15, 16];
165*bb4ee6a4SAndroid Build Coastguard Worker s1.send(data1).expect("failed to send data1");
166*bb4ee6a4SAndroid Build Coastguard Worker s1.send(data2).expect("failed to send data2");
167*bb4ee6a4SAndroid Build Coastguard Worker
168*bb4ee6a4SAndroid Build Coastguard Worker let recv_data = &mut [0; 32];
169*bb4ee6a4SAndroid Build Coastguard Worker let size = s2.recv(recv_data).expect("failed to recv data");
170*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(size, data1.len());
171*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(data1, &recv_data[0..size]);
172*bb4ee6a4SAndroid Build Coastguard Worker
173*bb4ee6a4SAndroid Build Coastguard Worker let size = s2.recv(recv_data).expect("failed to recv data");
174*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(size, data2.len());
175*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(data2, &recv_data[0..size]);
176*bb4ee6a4SAndroid Build Coastguard Worker }
177*bb4ee6a4SAndroid Build Coastguard Worker
178*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_get_readable_bytes()179*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_get_readable_bytes() {
180*bb4ee6a4SAndroid Build Coastguard Worker let (s1, s2) = UnixSeqpacket::pair().expect("failed to create socket pair");
181*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(s1.get_readable_bytes().unwrap(), 0);
182*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(s2.get_readable_bytes().unwrap(), 0);
183*bb4ee6a4SAndroid Build Coastguard Worker let data1 = &[0, 1, 2, 3, 4];
184*bb4ee6a4SAndroid Build Coastguard Worker s1.send(data1).expect("failed to send data");
185*bb4ee6a4SAndroid Build Coastguard Worker
186*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(s1.get_readable_bytes().unwrap(), 0);
187*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(s2.get_readable_bytes().unwrap(), data1.len());
188*bb4ee6a4SAndroid Build Coastguard Worker
189*bb4ee6a4SAndroid Build Coastguard Worker let recv_data = &mut [0; 5];
190*bb4ee6a4SAndroid Build Coastguard Worker s2.recv(recv_data).expect("failed to recv data");
191*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(s1.get_readable_bytes().unwrap(), 0);
192*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(s2.get_readable_bytes().unwrap(), 0);
193*bb4ee6a4SAndroid Build Coastguard Worker }
194*bb4ee6a4SAndroid Build Coastguard Worker
195*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_next_packet_size()196*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_next_packet_size() {
197*bb4ee6a4SAndroid Build Coastguard Worker let (s1, s2) = UnixSeqpacket::pair().expect("failed to create socket pair");
198*bb4ee6a4SAndroid Build Coastguard Worker let data1 = &[0, 1, 2, 3, 4];
199*bb4ee6a4SAndroid Build Coastguard Worker s1.send(data1).expect("failed to send data");
200*bb4ee6a4SAndroid Build Coastguard Worker
201*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(s2.next_packet_size().unwrap(), 5);
202*bb4ee6a4SAndroid Build Coastguard Worker s1.set_read_timeout(Some(Duration::from_micros(1)))
203*bb4ee6a4SAndroid Build Coastguard Worker .expect("failed to set read timeout");
204*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
205*bb4ee6a4SAndroid Build Coastguard Worker s1.next_packet_size().unwrap_err().kind(),
206*bb4ee6a4SAndroid Build Coastguard Worker ErrorKind::WouldBlock
207*bb4ee6a4SAndroid Build Coastguard Worker );
208*bb4ee6a4SAndroid Build Coastguard Worker drop(s2);
209*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(
210*bb4ee6a4SAndroid Build Coastguard Worker s1.next_packet_size().unwrap_err().kind(),
211*bb4ee6a4SAndroid Build Coastguard Worker ErrorKind::ConnectionReset
212*bb4ee6a4SAndroid Build Coastguard Worker );
213*bb4ee6a4SAndroid Build Coastguard Worker }
214*bb4ee6a4SAndroid Build Coastguard Worker
215*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_recv_to_vec()216*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_recv_to_vec() {
217*bb4ee6a4SAndroid Build Coastguard Worker let (s1, s2) = UnixSeqpacket::pair().expect("failed to create socket pair");
218*bb4ee6a4SAndroid Build Coastguard Worker let data1 = &[0, 1, 2, 3, 4];
219*bb4ee6a4SAndroid Build Coastguard Worker s1.send(data1).expect("failed to send data");
220*bb4ee6a4SAndroid Build Coastguard Worker
221*bb4ee6a4SAndroid Build Coastguard Worker let recv_data = &mut vec![];
222*bb4ee6a4SAndroid Build Coastguard Worker s2.recv_to_vec(recv_data).expect("failed to recv data");
223*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(recv_data, &mut vec![0, 1, 2, 3, 4]);
224*bb4ee6a4SAndroid Build Coastguard Worker }
225*bb4ee6a4SAndroid Build Coastguard Worker
226*bb4ee6a4SAndroid Build Coastguard Worker #[test]
unix_seqpacket_recv_as_vec()227*bb4ee6a4SAndroid Build Coastguard Worker fn unix_seqpacket_recv_as_vec() {
228*bb4ee6a4SAndroid Build Coastguard Worker let (s1, s2) = UnixSeqpacket::pair().expect("failed to create socket pair");
229*bb4ee6a4SAndroid Build Coastguard Worker let data1 = &[0, 1, 2, 3, 4];
230*bb4ee6a4SAndroid Build Coastguard Worker s1.send(data1).expect("failed to send data");
231*bb4ee6a4SAndroid Build Coastguard Worker
232*bb4ee6a4SAndroid Build Coastguard Worker let recv_data = s2.recv_as_vec().expect("failed to recv data");
233*bb4ee6a4SAndroid Build Coastguard Worker assert_eq!(recv_data, vec![0, 1, 2, 3, 4]);
234*bb4ee6a4SAndroid Build Coastguard Worker }
235