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