xref: /freebsd/tests/sys/kern/socket_splice.c (revision 5a5c2279813012882e59aa7bb51d50c5baba3b1e)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2024 Stormshield
5  */
6 
7 #include <sys/capsicum.h>
8 #include <sys/event.h>
9 #include <sys/filio.h>
10 #include <sys/socket.h>
11 #include <sys/wait.h>
12 
13 #include <netinet/in.h>
14 #include <netinet/tcp.h>
15 
16 #include <errno.h>
17 #include <poll.h>
18 #include <pthread.h>
19 #include <signal.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <time.h>
24 
25 #include <atf-c.h>
26 
27 static void
28 checked_close(int fd)
29 {
30 	int error;
31 
32 	error = close(fd);
33 	ATF_REQUIRE_MSG(error == 0, "close failed: %s", strerror(errno));
34 }
35 
36 static int
37 fionread(int fd)
38 {
39 	int data, error;
40 
41 	data = 0;
42 	error = ioctl(fd, FIONREAD, &data);
43 	ATF_REQUIRE_MSG(error == 0, "ioctl failed: %s", strerror(errno));
44 	ATF_REQUIRE(data >= 0);
45 	return (data);
46 }
47 
48 static void
49 noblocking(int fd)
50 {
51 	int flags, error;
52 
53 	flags = fcntl(fd, F_GETFL);
54 	ATF_REQUIRE_MSG(flags != -1, "fcntl failed: %s", strerror(errno));
55 	flags |= O_NONBLOCK;
56 	error = fcntl(fd, F_SETFL, flags);
57 	ATF_REQUIRE_MSG(error == 0, "fcntl failed: %s", strerror(errno));
58 }
59 
60 /*
61  * Create a pair of connected TCP sockets, returned via the "out" array.
62  */
63 static void
64 tcp_socketpair(int out[2], int domain)
65 {
66 	struct sockaddr_in sin;
67 	struct sockaddr_in6 sin6;
68 	struct sockaddr *sinp;
69 	int error, sd[2];
70 
71 	sd[0] = socket(domain, SOCK_STREAM, 0);
72 	ATF_REQUIRE_MSG(sd[0] >= 0, "socket failed: %s", strerror(errno));
73 	sd[1] = socket(domain, SOCK_STREAM, 0);
74 	ATF_REQUIRE_MSG(sd[1] >= 0, "socket failed: %s", strerror(errno));
75 
76 	error = setsockopt(sd[0], IPPROTO_TCP, TCP_NODELAY, &(int){ 1 },
77 	    sizeof(int));
78 	ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno));
79 	error = setsockopt(sd[1], IPPROTO_TCP, TCP_NODELAY, &(int){ 1 },
80 	    sizeof(int));
81 	ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno));
82 
83 	if (domain == PF_INET) {
84 		memset(&sin, 0, sizeof(sin));
85 		sin.sin_family = AF_INET;
86 		sin.sin_len = sizeof(sin);
87 		sin.sin_addr.s_addr = htonl(INADDR_ANY);
88 		sin.sin_port = htons(0);
89 		sinp = (struct sockaddr *)&sin;
90 	} else {
91 		ATF_REQUIRE(domain == PF_INET6);
92 		memset(&sin6, 0, sizeof(sin6));
93 		sin6.sin6_family = AF_INET6;
94 		sin6.sin6_len = sizeof(sin6);
95 		sin6.sin6_addr = in6addr_any;
96 		sin6.sin6_port = htons(0);
97 		sinp = (struct sockaddr *)&sin6;
98 	}
99 
100 	error = bind(sd[0], sinp, sinp->sa_len);
101 	ATF_REQUIRE_MSG(error == 0, "bind failed: %s", strerror(errno));
102 	error = listen(sd[0], 1);
103 	ATF_REQUIRE_MSG(error == 0, "listen failed: %s", strerror(errno));
104 
105 	error = getsockname(sd[0], sinp, &(socklen_t){ sinp->sa_len });
106 	ATF_REQUIRE_MSG(error == 0, "getsockname failed: %s", strerror(errno));
107 
108 	error = connect(sd[1], sinp, sinp->sa_len);
109 	ATF_REQUIRE_MSG(error == 0, "connect failed: %s", strerror(errno));
110 	out[0] = accept(sd[0], NULL, NULL);
111 	ATF_REQUIRE_MSG(out[0] >= 0, "accept failed: %s", strerror(errno));
112 	checked_close(sd[0]);
113 	out[1] = sd[1];
114 }
115 
116 static void
117 tcp4_socketpair(int out[2])
118 {
119 	tcp_socketpair(out, PF_INET);
120 }
121 
122 static void
123 tcp6_socketpair(int out[2])
124 {
125 	tcp_socketpair(out, PF_INET6);
126 }
127 
128 static off_t
129 nspliced(int sd)
130 {
131 	off_t n;
132 	socklen_t len;
133 	int error;
134 
135 	len = sizeof(n);
136 	error = getsockopt(sd, SOL_SOCKET, SO_SPLICE, &n, &len);
137 	ATF_REQUIRE_MSG(error == 0, "getsockopt failed: %s", strerror(errno));
138 	ATF_REQUIRE_MSG(len == sizeof(n), "unexpected length: %d", len);
139 	return (n);
140 }
141 
142 /*
143  * Use a macro so that ATF_REQUIRE_MSG prints a useful line number.
144  */
145 #define check_nspliced(sd, n) do {					\
146 	off_t sofar;							\
147 									\
148 	sofar = nspliced(sd);						\
149 	ATF_REQUIRE_MSG(sofar == (off_t)n, "spliced %jd bytes, expected %jd", \
150 	    (intmax_t)sofar, (intmax_t)n);				\
151 } while (0)
152 
153 static void
154 splice_init(struct splice *sp, int fd, off_t max, struct timeval *tv)
155 {
156 	memset(sp, 0, sizeof(*sp));
157 	sp->sp_fd = fd;
158 	sp->sp_max = max;
159 	if (tv != NULL)
160 		sp->sp_idle = *tv;
161 	else
162 		sp->sp_idle.tv_sec = sp->sp_idle.tv_usec = 0;
163 }
164 
165 static void
166 unsplice(int fd)
167 {
168 	struct splice sp;
169 	int error;
170 
171 	splice_init(&sp, -1, 0, NULL);
172 	error = setsockopt(fd, SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
173 	ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno));
174 }
175 
176 static void
177 unsplice_pair(int fd1, int fd2)
178 {
179 	unsplice(fd1);
180 	unsplice(fd2);
181 }
182 
183 static void
184 splice_pair(int fd1, int fd2, off_t max, struct timeval *tv)
185 {
186 	struct splice sp;
187 	int error;
188 
189 	splice_init(&sp, fd1, max, tv);
190 	error = setsockopt(fd2, SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
191 	ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno));
192 
193 	splice_init(&sp, fd2, max, tv);
194 	error = setsockopt(fd1, SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
195 	ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno));
196 }
197 
198 /*
199  * A structure representing a spliced pair of connections.  left[1] is
200  * bidirectionally spliced with right[0].
201  */
202 struct splice_conn {
203 	int left[2];
204 	int right[2];
205 };
206 
207 /*
208  * Initialize a splice connection with the given maximum number of bytes to
209  * splice and the given idle timeout.  For now we're forced to use TCP socket,
210  * but at some point it would be nice (and simpler) to use pairs of PF_LOCAL
211  * sockets.
212  */
213 static void
214 splice_conn_init_limits(struct splice_conn *sc, off_t max, struct timeval *tv)
215 {
216 	memset(sc, 0, sizeof(*sc));
217 	tcp4_socketpair(sc->left);
218 	tcp4_socketpair(sc->right);
219 	splice_pair(sc->left[1], sc->right[0], max, tv);
220 }
221 
222 static void
223 splice_conn_init(struct splice_conn *sc)
224 {
225 	splice_conn_init_limits(sc, 0, NULL);
226 }
227 
228 static void
229 splice_conn_check_empty(struct splice_conn *sc)
230 {
231 	int data;
232 
233 	data = fionread(sc->left[0]);
234 	ATF_REQUIRE_MSG(data == 0, "unexpected data on left[0]: %d", data);
235 	data = fionread(sc->left[1]);
236 	ATF_REQUIRE_MSG(data == 0, "unexpected data on left[1]: %d", data);
237 	data = fionread(sc->right[0]);
238 	ATF_REQUIRE_MSG(data == 0, "unexpected data on right[0]: %d", data);
239 	data = fionread(sc->right[1]);
240 	ATF_REQUIRE_MSG(data == 0, "unexpected data on right[1]: %d", data);
241 }
242 
243 static void
244 splice_conn_fini(struct splice_conn *sc)
245 {
246 	checked_close(sc->left[0]);
247 	checked_close(sc->left[1]);
248 	checked_close(sc->right[0]);
249 	checked_close(sc->right[1]);
250 }
251 
252 static void
253 splice_conn_noblocking(struct splice_conn *sc)
254 {
255 	noblocking(sc->left[0]);
256 	noblocking(sc->left[1]);
257 	noblocking(sc->right[0]);
258 	noblocking(sc->right[1]);
259 }
260 
261 /* Pass a byte through a pair of spliced connections. */
262 ATF_TC_WITHOUT_HEAD(splice_basic);
263 ATF_TC_BODY(splice_basic, tc)
264 {
265 	struct splice_conn sc;
266 	ssize_t n;
267 	char c;
268 
269 	splice_conn_init(&sc);
270 
271 	check_nspliced(sc.left[1], 0);
272 	check_nspliced(sc.right[0], 0);
273 
274 	/* Left-to-right. */
275 	c = 'M';
276 	n = write(sc.left[0], &c, 1);
277 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
278 	n = read(sc.right[1], &c, 1);
279 	ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno));
280 	ATF_REQUIRE_MSG(c == 'M', "unexpected character: %c", c);
281 	check_nspliced(sc.left[1], 1);
282 	check_nspliced(sc.right[0], 0);
283 
284 	/* Right-to-left. */
285 	c = 'J';
286 	n = write(sc.right[1], &c, 1);
287 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
288 	n = read(sc.left[0], &c, 1);
289 	ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno));
290 	ATF_REQUIRE_MSG(c == 'J', "unexpected character: %c", c);
291 	check_nspliced(sc.left[1], 1);
292 	check_nspliced(sc.right[0], 1);
293 
294 	/* Unsplice and verify that the byte counts haven't changed. */
295 	unsplice(sc.left[1]);
296 	unsplice(sc.right[0]);
297 	check_nspliced(sc.left[1], 1);
298 	check_nspliced(sc.right[0], 1);
299 
300 	splice_conn_fini(&sc);
301 }
302 
303 static void
304 remove_rights(int fd, const cap_rights_t *toremove)
305 {
306 	cap_rights_t rights;
307 	int error;
308 
309 	error = cap_rights_get(fd, &rights);
310 	ATF_REQUIRE_MSG(error == 0, "cap_rights_get failed: %s",
311 	    strerror(errno));
312 	cap_rights_remove(&rights, toremove);
313 	error = cap_rights_limit(fd, &rights);
314 	ATF_REQUIRE_MSG(error == 0, "cap_rights_limit failed: %s",
315 	    strerror(errno));
316 }
317 
318 /*
319  * Verify that splicing fails when the socket is missing the necessary rights.
320  */
321 ATF_TC_WITHOUT_HEAD(splice_capsicum);
322 ATF_TC_BODY(splice_capsicum, tc)
323 {
324 	struct splice sp;
325 	cap_rights_t rights;
326 	off_t n;
327 	int error, left[2], right[2];
328 
329 	tcp4_socketpair(left);
330 	tcp4_socketpair(right);
331 
332 	/*
333 	 * Make sure that we splice a socket that's missing recv rights.
334 	 */
335 	remove_rights(left[1], cap_rights_init(&rights, CAP_RECV));
336 	splice_init(&sp, right[0], 0, NULL);
337 	error = setsockopt(left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
338 	ATF_REQUIRE_ERRNO(ENOTCAPABLE, error == -1);
339 
340 	/* Make sure we can still splice left[1] in the other direction. */
341 	splice_init(&sp, left[1], 0, NULL);
342 	error = setsockopt(right[0], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
343 	ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno));
344 	splice_init(&sp, -1, 0, NULL);
345 	error = setsockopt(right[0], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
346 	ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno));
347 
348 	/*
349 	 * Now remove send rights from left[1] and verify that splicing is no
350 	 * longer possible.
351 	 */
352 	remove_rights(left[1], cap_rights_init(&rights, CAP_SEND));
353 	splice_init(&sp, left[1], 0, NULL);
354 	error = setsockopt(right[0], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
355 	ATF_REQUIRE_ERRNO(ENOTCAPABLE, error == -1);
356 
357 	/*
358 	 * It's still ok to query the SO_SPLICE state though.
359 	 */
360 	n = -1;
361 	error = getsockopt(left[1], SOL_SOCKET, SO_SPLICE, &n,
362 	    &(socklen_t){ sizeof(n) });
363 	ATF_REQUIRE_MSG(error == 0, "getsockopt failed: %s", strerror(errno));
364 	ATF_REQUIRE(n == 0);
365 
366 	/*
367 	 * Make sure that we can unsplice a spliced pair without any rights
368 	 * other than CAP_SETSOCKOPT.
369 	 */
370 	splice_pair(left[0], right[1], 0, NULL);
371 	error = cap_rights_limit(left[0],
372 	    cap_rights_init(&rights, CAP_SETSOCKOPT));
373 	ATF_REQUIRE_MSG(error == 0, "cap_rights_limit failed: %s",
374 	    strerror(errno));
375 	unsplice(left[0]);
376 
377 	checked_close(left[0]);
378 	checked_close(left[1]);
379 	checked_close(right[0]);
380 	checked_close(right[1]);
381 }
382 
383 /*
384  * Check various error cases in splice configuration.
385  */
386 ATF_TC_WITHOUT_HEAD(splice_error);
387 ATF_TC_BODY(splice_error, tc)
388 {
389 	struct splice_conn sc;
390 	struct splice sp;
391 	char path[PATH_MAX];
392 	int error, fd, sd, usd[2];
393 
394 	memset(&sc, 0, sizeof(sc));
395 	tcp4_socketpair(sc.left);
396 	tcp4_socketpair(sc.right);
397 
398 	/* A negative byte limit is invalid. */
399 	splice_init(&sp, sc.right[0], -3, NULL);
400 	error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
401 	ATF_REQUIRE_ERRNO(EINVAL, error == -1);
402 
403 	/* Can't unsplice a never-spliced socket. */
404 	splice_init(&sp, -1, 0, NULL);
405 	error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
406 	ATF_REQUIRE_ERRNO(ENOTCONN, error == -1);
407 
408 	/* Can't double-unsplice a socket. */
409 	splice_init(&sp, sc.right[0], 0, NULL);
410 	error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
411 	ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno));
412 	unsplice(sc.left[1]);
413 	splice_init(&sp, -1, 0, NULL);
414 	error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
415 	ATF_REQUIRE_ERRNO(ENOTCONN, error == -1);
416 
417 	/* Can't splice a spliced socket */
418 	splice_init(&sp, sc.right[0], 0, NULL);
419 	error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
420 	ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno));
421 	splice_init(&sp, sc.right[1], 0, NULL);
422 	error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
423 	ATF_REQUIRE_ERRNO(EBUSY, error == -1);
424 	splice_init(&sp, sc.right[0], 0, NULL);
425 	error = setsockopt(sc.left[0], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
426 	ATF_REQUIRE_ERRNO(EBUSY, error == -1);
427 	splice_init(&sp, -1, 0, NULL);
428 	error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
429 
430 	/* Can't splice to a non-socket. */
431 	snprintf(path, sizeof(path), "/tmp/splice_error.XXXXXX");
432 	fd = mkstemp(path);
433 	ATF_REQUIRE_MSG(fd >= 0, "mkstemp failed: %s", strerror(errno));
434 	splice_init(&sp, fd, 0, NULL);
435 	error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
436 	ATF_REQUIRE_ERRNO(ENOTSOCK, error == -1);
437 
438 	/* Can't splice to an invalid fd. */
439 	checked_close(fd);
440 	splice_init(&sp, fd, 0, NULL);
441 	error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
442 	ATF_REQUIRE_ERRNO(EBADF, error == -1);
443 
444 	/* Can't splice a unix stream socket. */
445 	error = socketpair(AF_UNIX, SOCK_STREAM, 0, usd);
446 	ATF_REQUIRE_MSG(error == 0, "socketpair failed: %s", strerror(errno));
447 	splice_init(&sp, usd[0], 0, NULL);
448 	error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
449 	ATF_REQUIRE_ERRNO(EPROTONOSUPPORT, error == -1);
450 	error = setsockopt(usd[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
451 	ATF_REQUIRE_ERRNO(EPROTONOSUPPORT, error == -1);
452 	checked_close(usd[0]);
453 	checked_close(usd[1]);
454 
455 	/* Can't splice an unconnected TCP socket. */
456 	sd = socket(PF_INET, SOCK_STREAM, 0);
457 	ATF_REQUIRE_MSG(sd >= 0, "socket failed: %s", strerror(errno));
458 	splice_init(&sp, sd, 0, NULL);
459 	error = setsockopt(sc.left[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
460 	ATF_REQUIRE_ERRNO(ENOTCONN, error == -1);
461 	splice_init(&sp, sc.right[0], 0, NULL);
462 	error = setsockopt(sd, SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
463 	ATF_REQUIRE_ERRNO(ENOTCONN, error == -1);
464 
465 	splice_conn_fini(&sc);
466 }
467 
468 /*
469  * Make sure that kevent() doesn't report read I/O events on spliced sockets.
470  */
471 ATF_TC_WITHOUT_HEAD(splice_kevent);
472 ATF_TC_BODY(splice_kevent, tc)
473 {
474 	struct splice_conn sc;
475 	struct kevent kev;
476 	struct timespec ts;
477 	ssize_t n;
478 	int error, nev, kq;
479 	uint8_t b;
480 
481 	splice_conn_init(&sc);
482 
483 	kq = kqueue();
484 	ATF_REQUIRE_MSG(kq >= 0, "kqueue failed: %s", strerror(errno));
485 
486 	EV_SET(&kev, sc.left[1], EVFILT_READ, EV_ADD, 0, 0, NULL);
487 	error = kevent(kq, &kev, 1, NULL, 0, NULL);
488 	ATF_REQUIRE_MSG(error == 0, "kevent failed: %s", strerror(errno));
489 
490 	memset(&ts, 0, sizeof(ts));
491 	nev = kevent(kq, NULL, 0, &kev, 1, &ts);
492 	ATF_REQUIRE_MSG(nev >= 0, "kevent failed: %s", strerror(errno));
493 	ATF_REQUIRE(nev == 0);
494 
495 	b = 'M';
496 	n = write(sc.left[0], &b, 1);
497 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
498 	n = read(sc.right[1], &b, 1);
499 	ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno));
500 	ATF_REQUIRE(b == 'M');
501 
502 	nev = kevent(kq, NULL, 0, &kev, 1, &ts);
503 	ATF_REQUIRE_MSG(nev >= 0, "kevent failed: %s", strerror(errno));
504 	ATF_REQUIRE(nev == 0);
505 
506 	b = 'J';
507 	n = write(sc.right[1], &b, 1);
508 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
509 	n = read(sc.left[0], &b, 1);
510 	ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno));
511 	ATF_REQUIRE(b == 'J');
512 
513 	splice_conn_fini(&sc);
514 	checked_close(kq);
515 }
516 
517 /*
518  * Verify that a splice byte limit is applied.
519  */
520 ATF_TC_WITHOUT_HEAD(splice_limit_bytes);
521 ATF_TC_BODY(splice_limit_bytes, tc)
522 {
523 	struct splice_conn sc;
524 	ssize_t n;
525 	uint8_t b, buf[128];
526 
527 	splice_conn_init_limits(&sc, sizeof(buf) + 1, NULL);
528 
529 	memset(buf, 'A', sizeof(buf));
530 	for (size_t total = sizeof(buf); total > 0; total -= n) {
531 		n = write(sc.left[0], buf, total);
532 		ATF_REQUIRE_MSG(n > 0, "write failed: %s", strerror(errno));
533 	}
534 	for (size_t total = sizeof(buf); total > 0; total -= n) {
535 		n = read(sc.right[1], buf, sizeof(buf));
536 		ATF_REQUIRE_MSG(n > 0, "read failed: %s", strerror(errno));
537 	}
538 
539 	check_nspliced(sc.left[1], sizeof(buf));
540 	check_nspliced(sc.right[0], 0);
541 
542 	/* Trigger an unsplice by writing the last byte. */
543 	b = 'B';
544 	n = write(sc.left[0], &b, 1);
545 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
546 	n = read(sc.right[1], &b, 1);
547 	ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno));
548 	ATF_REQUIRE(b == 'B');
549 
550 	/*
551 	 * The next byte should appear on the other side of the connection
552 	 * rather than the splice.
553 	 */
554 	b = 'C';
555 	n = write(sc.left[0], &b, 1);
556 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
557 	n = read(sc.left[1], &b, 1);
558 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
559 	ATF_REQUIRE(b == 'C');
560 
561 	splice_conn_check_empty(&sc);
562 
563 	splice_conn_fini(&sc);
564 }
565 
566 /*
567  * Verify that a splice timeout limit is applied.
568  */
569 ATF_TC_WITHOUT_HEAD(splice_limit_timeout);
570 ATF_TC_BODY(splice_limit_timeout, tc)
571 {
572 	struct splice_conn sc;
573 	ssize_t n;
574 	int error;
575 	uint8_t b, buf[128];
576 
577 	splice_conn_init_limits(&sc, 0,
578 	    &(struct timeval){ .tv_sec = 0, .tv_usec = 500000 /* 500ms */ });
579 
580 	/* Write some data through the splice. */
581 	memset(buf, 'A', sizeof(buf));
582 	for (size_t total = sizeof(buf); total > 0; total -= n) {
583 		n = write(sc.left[0], buf, total);
584 		ATF_REQUIRE_MSG(n > 0, "write failed: %s", strerror(errno));
585 	}
586 	for (size_t total = sizeof(buf); total > 0; total -= n) {
587 		n = read(sc.right[1], buf, sizeof(buf));
588 		ATF_REQUIRE_MSG(n > 0, "read failed: %s", strerror(errno));
589 	}
590 
591 	check_nspliced(sc.left[1], sizeof(buf));
592 	check_nspliced(sc.right[0], 0);
593 
594 	/* Wait for the splice to time out. */
595 	error = usleep(550000);
596 	ATF_REQUIRE_MSG(error == 0, "usleep failed: %s", strerror(errno));
597 
598 	/*
599 	 * The next byte should appear on the other side of the connection
600 	 * rather than the splice.
601 	 */
602 	b = 'C';
603 	n = write(sc.left[0], &b, 1);
604 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
605 	n = read(sc.left[1], &b, 1);
606 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
607 	ATF_REQUIRE(b == 'C');
608 
609 	splice_conn_fini(&sc);
610 }
611 
612 /*
613  * Make sure that listen() fails on spliced sockets, and that SO_SPLICE can't be
614  * used with listening sockets.
615  */
616 ATF_TC_WITHOUT_HEAD(splice_listen);
617 ATF_TC_BODY(splice_listen, tc)
618 {
619 	struct splice sp;
620 	struct splice_conn sc;
621 	int error, sd[3];
622 
623 	/*
624 	 * These should fail regardless since the sockets are connected, but it
625 	 * doesn't hurt to check.
626 	 */
627 	splice_conn_init(&sc);
628 	error = listen(sc.left[1], 1);
629 	ATF_REQUIRE_ERRNO(EINVAL, error == -1);
630 	error = listen(sc.right[0], 1);
631 	ATF_REQUIRE_ERRNO(EINVAL, error == -1);
632 	splice_conn_fini(&sc);
633 
634 	tcp4_socketpair(sd);
635 	sd[2] = socket(PF_INET, SOCK_STREAM, 0);
636 	ATF_REQUIRE_MSG(sd[2] >= 0, "socket failed: %s", strerror(errno));
637 	error = listen(sd[2], 1);
638 	ATF_REQUIRE_MSG(error == 0, "listen failed: %s", strerror(errno));
639 
640 	/*
641 	 * Make sure a listening socket can't be spliced in either direction.
642 	 */
643 	splice_init(&sp, sd[2], 0, NULL);
644 	error = setsockopt(sd[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
645 	ATF_REQUIRE_ERRNO(EINVAL, error == -1);
646 	splice_init(&sp, sd[1], 0, NULL);
647 	error = setsockopt(sd[2], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
648 	ATF_REQUIRE_ERRNO(EINVAL, error == -1);
649 
650 	/*
651 	 * Make sure we can't try to unsplice a listening socket.
652 	 */
653 	splice_init(&sp, -1, 0, NULL);
654 	error = setsockopt(sd[2], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
655 	ATF_REQUIRE_ERRNO(EINVAL, error == -1);
656 
657 	checked_close(sd[0]);
658 	checked_close(sd[1]);
659 	checked_close(sd[2]);
660 }
661 
662 static void
663 sigalarm(int sig __unused)
664 {
665 }
666 
667 /*
668  * Our SO_SPLICE implementation doesn't do anything to prevent loops.  We should
669  * however make sure that they are interruptible.
670  */
671 ATF_TC_WITHOUT_HEAD(splice_loop);
672 ATF_TC_BODY(splice_loop, tc)
673 {
674 	ssize_t n;
675 	int sd[2], status;
676 	pid_t child;
677 	char c;
678 
679 	tcp_socketpair(sd, PF_INET);
680 	splice_pair(sd[0], sd[1], 0, NULL);
681 
682 	/*
683 	 * Let the child process trigger an infinite loop.  It should still be
684 	 * possible to kill the child with a signal, causing the connection to
685 	 * be dropped and ending the loop.
686 	 */
687 	child = fork();
688 	ATF_REQUIRE_MSG(child >= 0, "fork failed: %s", strerror(errno));
689 	if (child == 0) {
690 		alarm(2);
691 		c = 42;
692 		n = write(sd[0], &c, 1);
693 		if (n != 1)
694 			_exit(2);
695 		c = 24;
696 		n = write(sd[1], &c, 1);
697 		if (n != 1)
698 			_exit(3);
699 
700 		for (;;) {
701 			/* Wait for SIGALARM. */
702 			sleep(100);
703 		}
704 
705 		_exit(0);
706 	} else {
707 		checked_close(sd[0]);
708 		checked_close(sd[1]);
709 
710 		child = waitpid(child, &status, 0);
711 		ATF_REQUIRE_MSG(child >= 0,
712 		    "waitpid failed: %s", strerror(errno));
713 		ATF_REQUIRE(WIFSIGNALED(status));
714 		ATF_REQUIRE(WTERMSIG(status) == SIGALRM);
715 	}
716 }
717 
718 /*
719  * Simple I/O test.
720  */
721 ATF_TC_WITHOUT_HEAD(splice_nonblock);
722 ATF_TC_BODY(splice_nonblock, tc)
723 {
724 	struct splice_conn sc;
725 	char buf[200];
726 	size_t sofar;
727 	ssize_t n;
728 
729 	splice_conn_init(&sc);
730 	splice_conn_noblocking(&sc);
731 
732 	memset(buf, 'A', sizeof(buf));
733 	for (sofar = 0;;) {
734 		n = write(sc.left[0], buf, sizeof(buf));
735 		if (n < 0) {
736 			ATF_REQUIRE_ERRNO(EAGAIN, n == -1);
737 			break;
738 		}
739 		sofar += n;
740 	}
741 
742 	while (sofar > 0) {
743 		n = read(sc.right[1], buf, sizeof(buf));
744 		if (n < 0) {
745 			ATF_REQUIRE_ERRNO(EAGAIN, n == -1);
746 			usleep(100);
747 		} else {
748 			for (size_t i = 0; i < (size_t)n; i++)
749 				ATF_REQUIRE(buf[i] == 'A');
750 			sofar -= n;
751 		}
752 	}
753 
754 	splice_conn_fini(&sc);
755 }
756 
757 ATF_TC_WITHOUT_HEAD(splice_resplice);
758 ATF_TC_BODY(splice_resplice, tc)
759 {
760 	struct splice_conn sc;
761 	ssize_t n;
762 	char c;
763 
764 	splice_conn_init(&sc);
765 
766 	/* Left-to-right. */
767 	c = 'M';
768 	n = write(sc.left[0], &c, 1);
769 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
770 	n = read(sc.right[1], &c, 1);
771 	ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno));
772 	ATF_REQUIRE_MSG(c == 'M', "unexpected character: %c", c);
773 	check_nspliced(sc.left[1], 1);
774 	check_nspliced(sc.right[0], 0);
775 
776 	/* Right-to-left. */
777 	c = 'J';
778 	n = write(sc.right[1], &c, 1);
779 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
780 	n = read(sc.left[0], &c, 1);
781 	ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno));
782 	ATF_REQUIRE_MSG(c == 'J', "unexpected character: %c", c);
783 	check_nspliced(sc.left[1], 1);
784 	check_nspliced(sc.right[0], 1);
785 
786 	/* Unsplice and verify that the byte counts haven't changed. */
787 	unsplice(sc.left[1]);
788 	unsplice(sc.right[0]);
789 	check_nspliced(sc.left[1], 1);
790 	check_nspliced(sc.right[0], 1);
791 
792 	/* Splice again, check that byte counts are reset. */
793 	splice_pair(sc.left[1], sc.right[0], 0, NULL);
794 	check_nspliced(sc.left[1], 0);
795 	check_nspliced(sc.right[0], 0);
796 
797 	/* Left-to-right. */
798 	c = 'M';
799 	n = write(sc.left[0], &c, 1);
800 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
801 	n = read(sc.right[1], &c, 1);
802 	ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno));
803 	ATF_REQUIRE_MSG(c == 'M', "unexpected character: %c", c);
804 	check_nspliced(sc.left[1], 1);
805 	check_nspliced(sc.right[0], 0);
806 
807 	/* Right-to-left. */
808 	c = 'J';
809 	n = write(sc.right[1], &c, 1);
810 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
811 	n = read(sc.left[0], &c, 1);
812 	ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno));
813 	ATF_REQUIRE_MSG(c == 'J', "unexpected character: %c", c);
814 	check_nspliced(sc.left[1], 1);
815 	check_nspliced(sc.right[0], 1);
816 
817 	splice_conn_fini(&sc);
818 }
819 
820 struct xfer_args {
821 	pthread_barrier_t *barrier;
822 	uint32_t bytes;
823 	int fd;
824 };
825 
826 static void *
827 xfer(void *arg)
828 {
829 	struct xfer_args *xfer;
830 	uint8_t *buf;
831 	size_t sz;
832 	ssize_t n;
833 	uint32_t resid;
834 	int error;
835 
836 	xfer = arg;
837 
838 	error = fcntl(xfer->fd, F_SETFL, O_NONBLOCK);
839 	ATF_REQUIRE_MSG(error == 0, "fcntl failed: %s", strerror(errno));
840 
841 	sz = MIN(xfer->bytes, 1024 * 1024);
842 	buf = malloc(sz);
843 	ATF_REQUIRE(buf != NULL);
844 	arc4random_buf(buf, sz);
845 
846 	pthread_barrier_wait(xfer->barrier);
847 
848 	for (resid = xfer->bytes; xfer->bytes > 0 || resid > 0;) {
849 		n = write(xfer->fd, buf, MIN(sz, xfer->bytes));
850 		if (n < 0) {
851 			ATF_REQUIRE_ERRNO(EAGAIN, n == -1);
852 			usleep(1000);
853 		} else {
854 			ATF_REQUIRE(xfer->bytes >= (size_t)n);
855 			xfer->bytes -= n;
856 		}
857 
858 		n = read(xfer->fd, buf, sz);
859 		if (n < 0) {
860 			ATF_REQUIRE_ERRNO(EAGAIN, n == -1);
861 			usleep(1000);
862 		} else {
863 			ATF_REQUIRE(resid >= (size_t)n);
864 			resid -= n;
865 		}
866 	}
867 
868 	free(buf);
869 	return (NULL);
870 }
871 
872 /*
873  * Use two threads to transfer data between two spliced connections.
874  */
875 ATF_TC_WITHOUT_HEAD(splice_throughput);
876 ATF_TC_BODY(splice_throughput, tc)
877 {
878 	struct xfer_args xfers[2];
879 	pthread_t thread[2];
880 	pthread_barrier_t barrier;
881 	struct splice_conn sc;
882 	uint32_t bytes;
883 	int error;
884 
885 	/* Transfer an amount between 1B and 1GB. */
886 	bytes = arc4random_uniform(1024 * 1024 * 1024) + 1;
887 	splice_conn_init(&sc);
888 
889 	error = pthread_barrier_init(&barrier, NULL, 2);
890 	ATF_REQUIRE(error == 0);
891 	xfers[0] = (struct xfer_args){
892 	    .barrier = &barrier,
893 	    .bytes = bytes,
894 	    .fd = sc.left[0]
895 	};
896 	xfers[1] = (struct xfer_args){
897 	    .barrier = &barrier,
898 	    .bytes = bytes,
899 	    .fd = sc.right[1]
900 	};
901 
902 	error = pthread_create(&thread[0], NULL, xfer, &xfers[0]);
903 	ATF_REQUIRE_MSG(error == 0,
904 	    "pthread_create failed: %s", strerror(errno));
905 	error = pthread_create(&thread[1], NULL, xfer, &xfers[1]);
906 	ATF_REQUIRE_MSG(error == 0,
907 	    "pthread_create failed: %s", strerror(errno));
908 
909 	error = pthread_join(thread[0], NULL);
910 	ATF_REQUIRE_MSG(error == 0,
911 	    "pthread_join failed: %s", strerror(errno));
912 	error = pthread_join(thread[1], NULL);
913 	ATF_REQUIRE_MSG(error == 0,
914 	    "pthread_join failed: %s", strerror(errno));
915 
916 	error = pthread_barrier_destroy(&barrier);
917 	ATF_REQUIRE(error == 0);
918 	splice_conn_fini(&sc);
919 }
920 
921 /*
922  * Make sure it's possible to splice v4 and v6 sockets together.
923  */
924 ATF_TC_WITHOUT_HEAD(splice_v4v6);
925 ATF_TC_BODY(splice_v4v6, tc)
926 {
927 	struct splice sp;
928 	ssize_t n;
929 	int sd4[2], sd6[2];
930 	int error;
931 	uint8_t b;
932 
933 	tcp4_socketpair(sd4);
934 	tcp6_socketpair(sd6);
935 
936 	splice_init(&sp, sd6[0], 0, NULL);
937 	error = setsockopt(sd4[1], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
938 	ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno));
939 
940 	splice_init(&sp, sd4[1], 0, NULL);
941 	error = setsockopt(sd6[0], SOL_SOCKET, SO_SPLICE, &sp, sizeof(sp));
942 	ATF_REQUIRE_MSG(error == 0, "setsockopt failed: %s", strerror(errno));
943 
944 	b = 'M';
945 	n = write(sd4[0], &b, 1);
946 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
947 	n = read(sd6[1], &b, 1);
948 	ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno));
949 	ATF_REQUIRE(b == 'M');
950 
951 	b = 'J';
952 	n = write(sd6[1], &b, 1);
953 	ATF_REQUIRE_MSG(n == 1, "write failed: %s", strerror(errno));
954 	n = read(sd4[0], &b, 1);
955 	ATF_REQUIRE_MSG(n == 1, "read failed: %s", strerror(errno));
956 	ATF_REQUIRE(b == 'J');
957 
958 	checked_close(sd4[0]);
959 	checked_close(sd4[1]);
960 	checked_close(sd6[0]);
961 	checked_close(sd6[1]);
962 }
963 
964 ATF_TP_ADD_TCS(tp)
965 {
966 	ATF_TP_ADD_TC(tp, splice_basic);
967 	ATF_TP_ADD_TC(tp, splice_capsicum);
968 	ATF_TP_ADD_TC(tp, splice_error);
969 	ATF_TP_ADD_TC(tp, splice_kevent);
970 	ATF_TP_ADD_TC(tp, splice_limit_bytes);
971 	ATF_TP_ADD_TC(tp, splice_limit_timeout);
972 	ATF_TP_ADD_TC(tp, splice_listen);
973 	ATF_TP_ADD_TC(tp, splice_loop);
974 	ATF_TP_ADD_TC(tp, splice_nonblock);
975 	ATF_TP_ADD_TC(tp, splice_resplice);
976 	ATF_TP_ADD_TC(tp, splice_throughput);
977 	ATF_TP_ADD_TC(tp, splice_v4v6);
978 	return (atf_no_error());
979 }
980