xref: /freebsd/tests/sys/kern/unix_seqpacket_test.c (revision 7937bfbc0ca53fe7cdd0d54414f9296e273a518e)
1 /*-
2  *
3  * Copyright (c) 2024 Gleb Smirnoff <glebius@FreeBSD.org>
4  * Copyright (c) 2014 Spectra Logic Corporation. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <pthread.h>
32 #include <signal.h>
33 #include <stdlib.h>
34 #include <sys/socket.h>
35 #include <sys/sysctl.h>
36 #include <sys/un.h>
37 
38 #include <stdio.h>
39 
40 #include <atf-c.h>
41 
42 /*
43  * Helper functions
44  */
45 
46 #define MIN(x, y)	((x) < (y) ? (x) : (y))
47 #define MAX(x, y)	((x) > (y) ? (x) : (y))
48 
49 static void
50 do_socketpair(int *sv)
51 {
52 	int s;
53 
54 	s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv);
55 	ATF_REQUIRE_EQ(0, s);
56 	ATF_REQUIRE(sv[0] >= 0);
57 	ATF_REQUIRE(sv[1] >= 0);
58 	ATF_REQUIRE(sv[0] != sv[1]);
59 }
60 
61 static void
62 do_socketpair_nonblocking(int *sv)
63 {
64 	int s;
65 
66 	s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv);
67 	ATF_REQUIRE_EQ(0, s);
68 	ATF_REQUIRE(sv[0] >= 0);
69 	ATF_REQUIRE(sv[1] >= 0);
70 	ATF_REQUIRE(sv[0] != sv[1]);
71 	ATF_REQUIRE(-1 != fcntl(sv[0], F_SETFL, O_NONBLOCK));
72 	ATF_REQUIRE(-1 != fcntl(sv[1], F_SETFL, O_NONBLOCK));
73 }
74 
75 /*
76  * Returns a bound and listening socket.
77  * @return	const char* The path to the socket
78  */
79 static const struct sockaddr_un *
80 mk_listening_socket(int *sv)
81 {
82 	/* ATF's isolation mechanisms will guarantee uniqueness of this file */
83 	static const struct sockaddr_un sun = {
84 		.sun_family = AF_LOCAL,
85 		.sun_len = sizeof(sun),
86 		.sun_path = "sock",
87 	};
88 	int s, r, l;
89 
90 	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
91 	ATF_REQUIRE(s >= 0);
92 
93 	r = bind(s, (struct sockaddr *)&sun, sizeof(sun));
94 	l = listen(s, -1);
95 	ATF_CHECK_EQ(0, r);
96 	ATF_CHECK_EQ(0, l);
97 
98 	if (sv != NULL)
99 		*sv = s;
100 
101 	return (&sun);
102 }
103 
104 /*
105  * Returns a pair of sockets made the hard way: bind, listen, connect & accept
106  * @return	const char* The path to the socket
107  */
108 static const struct sockaddr_un *
109 mk_pair_of_sockets(int *sv)
110 {
111 	const struct sockaddr_un *sun;
112 	int s, s2, err, s1;
113 
114 	sun = mk_listening_socket(&s);
115 
116 	/* Create the other socket */
117 	s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
118 	ATF_REQUIRE(s2 >= 0);
119 	err = connect(s2, (struct sockaddr *)sun, sizeof(*sun));
120 	if (err != 0) {
121 		perror("connect");
122 		atf_tc_fail("connect(2) failed");
123 	}
124 
125 	/* Accept it */
126 	s1 = accept(s, NULL, NULL);
127 	if (s1 == -1) {
128 		perror("accept");
129 		atf_tc_fail("accept(2) failed");
130 	}
131 
132 	sv[0] = s1;
133 	sv[1] = s2;
134 
135 	close(s);
136 
137 	return (sun);
138 }
139 
140 static volatile sig_atomic_t got_sigpipe = 0;
141 static void
142 shutdown_send_sigpipe_handler(int __unused x)
143 {
144 	got_sigpipe = 1;
145 }
146 
147 /*
148  * Parameterized test function bodies
149  */
150 static void
151 test_eagain(int sndbufsize, int rcvbufsize)
152 {
153 	int i;
154 	int sv[2];
155 	const size_t totalsize = (sndbufsize + rcvbufsize) * 2;
156 	const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4;
157 	const int numpkts = totalsize / pktsize;
158 	char sndbuf[pktsize];
159 	ssize_t ssize;
160 
161 	/* setup the socket pair */
162 	do_socketpair_nonblocking(sv);
163 	/* Setup the buffers */
164 	ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
165 	    sizeof(sndbufsize)));
166 	ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
167 	    sizeof(rcvbufsize)));
168 
169 	bzero(sndbuf, pktsize);
170 	/* Send data until we get EAGAIN */
171 	for(i=0; i < numpkts; i++) {
172 		ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
173 		if (ssize == -1) {
174 			if (errno == EAGAIN) {
175 				close(sv[0]);
176 				close(sv[1]);
177 				atf_tc_pass();
178 			}
179 			else {
180 				perror("send");
181 				atf_tc_fail("send returned < 0 but not EAGAIN");
182 			}
183 		}
184 	}
185 	atf_tc_fail("Never got EAGAIN");
186 }
187 
188 static void
189 test_sendrecv_symmetric_buffers(int bufsize, int blocking) {
190 	int s;
191 	int sv[2];
192 	const ssize_t pktsize = bufsize / 2;
193 	char sndbuf[pktsize];
194 	char recv_buf[pktsize];
195 	ssize_t ssize, rsize;
196 
197 	/* setup the socket pair */
198 	if (blocking)
199 		do_socketpair(sv);
200 	else
201 		do_socketpair_nonblocking(sv);
202 
203 	/* Setup the buffers */
204 	s = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize));
205 	ATF_REQUIRE_EQ(0, s);
206 	s = setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize));
207 	ATF_REQUIRE_EQ(0, s);
208 
209 	/* Fill the send buffer */
210 	bzero(sndbuf, pktsize);
211 
212 	/* send and receive the packet */
213 	ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
214 	if (ssize < 0) {
215 		perror("send");
216 		atf_tc_fail("send returned < 0");
217 	}
218 	ATF_CHECK_EQ_MSG(pktsize, ssize, "expected %zd=send(...) but got %zd",
219 	    pktsize, ssize);
220 
221 	rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL);
222 	if (rsize < 0) {
223 		perror("recv");
224 		atf_tc_fail("recv returned < 0");
225 	}
226 	ATF_CHECK_EQ_MSG(pktsize, rsize, "expected %zd=send(...) but got %zd",
227 	    pktsize, rsize);
228 	close(sv[0]);
229 	close(sv[1]);
230 }
231 
232 static void
233 test_pipe_simulator(int sndbufsize, int rcvbufsize)
234 {
235 	int num_sent, num_received;
236 	int sv[2];
237 	const ssize_t pktsize = MIN(sndbufsize, rcvbufsize) / 4;
238 	int numpkts;
239 	char sndbuf[pktsize];
240 	char rcvbuf[pktsize];
241 	char comparebuf[pktsize];
242 	ssize_t ssize, rsize;
243 	bool currently_sending = true;
244 
245 	/* setup the socket pair */
246 	do_socketpair_nonblocking(sv);
247 	/* Setup the buffers */
248 	ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
249 	    sizeof(sndbufsize)));
250 	ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
251 	    sizeof(rcvbufsize)));
252 
253 	/* Send a total amount of data comfortably greater than the buffers */
254 	numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize;
255 	for (num_sent=0, num_received=0;
256 	     num_sent < numpkts || num_received < numpkts; ) {
257 		if (currently_sending && num_sent < numpkts) {
258 			/* The simulated sending process */
259 			/* fill the buffer */
260 			memset(sndbuf, num_sent, pktsize);
261 			ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
262 			if (ssize < 0) {
263 				if (errno == EAGAIN)
264 					currently_sending = false;
265 				else {
266 					perror("send");
267 					atf_tc_fail("send failed");
268 				}
269 			} else  {
270 				ATF_CHECK_EQ_MSG(pktsize, ssize,
271 				    "expected %zd=send(...) but got %zd",
272 				    pktsize, ssize);
273 				num_sent++;
274 			}
275 		} else {
276 			/* The simulated receiving process */
277 			rsize = recv(sv[1], rcvbuf, pktsize, MSG_WAITALL);
278 			if (rsize < 0) {
279 				if (errno == EAGAIN) {
280 					currently_sending = true;
281 					ATF_REQUIRE_MSG(num_sent < numpkts,
282 					    "Packets were lost!");
283 				}
284 				else {
285 					perror("recv");
286 					atf_tc_fail("recv failed");
287 				}
288 			} else  {
289 				ATF_CHECK_EQ_MSG(pktsize, rsize,
290 				    "expected %zd=recv(...) but got %zd",
291 				    pktsize, rsize);
292 				memset(comparebuf, num_received, pktsize);
293 				ATF_CHECK_EQ_MSG(0, memcmp(comparebuf, rcvbuf,
294 				    			   pktsize),
295 				    "Received data miscompare");
296 				num_received++;
297 			}
298 		}
299 	}
300 	close(sv[0]);
301 	close(sv[1]);
302 }
303 
304 typedef struct {
305 	ssize_t	pktsize;
306 	int	numpkts;
307 	int	so;
308 } test_pipe_thread_data_t;
309 
310 static void*
311 test_pipe_writer(void* args)
312 {
313 	test_pipe_thread_data_t* td = args;
314 	char sndbuf[td->pktsize];
315 	ssize_t ssize;
316 	int i;
317 
318 	for(i=0; i < td->numpkts; i++) {
319 			memset(sndbuf, i, td->pktsize);
320 			ssize = send(td->so, sndbuf, td->pktsize, MSG_EOR);
321 			if (ssize < 0) {
322 				perror("send");
323 				atf_tc_fail("send returned < 0");
324 			}
325 			ATF_CHECK_EQ_MSG(td->pktsize, ssize,
326 			    		 "expected %zd=send(...) but got %zd",
327 			    		  td->pktsize, ssize);
328 	}
329 	return (0);
330 }
331 
332 static void*
333 test_pipe_reader(void* args)
334 {
335 	test_pipe_thread_data_t* td = args;
336 	char rcvbuf[td->pktsize];
337 	char comparebuf[td->pktsize];
338 	ssize_t rsize;
339 	int i, d;
340 
341 	for(i=0; i < td->numpkts; i++) {
342 		memset(comparebuf, i, td->pktsize);
343 		rsize = recv(td->so, rcvbuf, td->pktsize, MSG_WAITALL);
344 		if (rsize < 0) {
345 			perror("recv");
346 			atf_tc_fail("recv returned < 0");
347 		}
348 		ATF_CHECK_EQ_MSG(td->pktsize, rsize,
349 		    		 "expected %zd=send(...) but got %zd",
350 				 td->pktsize, rsize);
351 		d = memcmp(comparebuf, rcvbuf, td->pktsize);
352 		ATF_CHECK_EQ_MSG(0, d,
353 		    		 "Received data miscompare on packet %d", i);
354 	}
355 	return (0);
356 }
357 
358 
359 static void
360 test_pipe(int sndbufsize, int rcvbufsize)
361 {
362 	test_pipe_thread_data_t writer_data, reader_data;
363 	pthread_t writer, reader;
364 	int sv[2];
365 	const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4;
366 	int numpkts;
367 
368 	/* setup the socket pair */
369 	do_socketpair(sv);
370 	/* Setup the buffers */
371 	ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
372 	    sizeof(sndbufsize)));
373 	ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
374 	    sizeof(rcvbufsize)));
375 
376 	/* Send a total amount of data comfortably greater than the buffers */
377 	numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize;
378 
379 	/* Start the child threads */
380 	writer_data.pktsize = pktsize;
381 	writer_data.numpkts = numpkts;
382 	writer_data.so = sv[0];
383 	reader_data.pktsize = pktsize;
384 	reader_data.numpkts = numpkts;
385 	reader_data.so = sv[1];
386 	ATF_REQUIRE_EQ(0, pthread_create(&writer, NULL, test_pipe_writer,
387 	    				 (void*)&writer_data));
388 	/*
389 	 * Give the writer time to start writing, and hopefully block, before
390 	 * starting the reader.  This increases the likelihood of the test case
391 	 * failing due to PR kern/185812
392 	 */
393 	usleep(1000);
394 	ATF_REQUIRE_EQ(0, pthread_create(&reader, NULL, test_pipe_reader,
395 	    				 (void*)&reader_data));
396 
397 	/* Join the children */
398 	ATF_REQUIRE_EQ(0, pthread_join(writer, NULL));
399 	ATF_REQUIRE_EQ(0, pthread_join(reader, NULL));
400 	close(sv[0]);
401 	close(sv[1]);
402 }
403 
404 
405 /*
406  * Test Cases
407  */
408 
409 /* Create a SEQPACKET socket */
410 ATF_TC_WITHOUT_HEAD(create_socket);
411 ATF_TC_BODY(create_socket, tc)
412 {
413 	int s;
414 
415 	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
416 	ATF_REQUIRE(s >= 0);
417 	close(s);
418 }
419 
420 /* Create SEQPACKET sockets using socketpair(2) */
421 ATF_TC_WITHOUT_HEAD(create_socketpair);
422 ATF_TC_BODY(create_socketpair, tc)
423 {
424 	int sv[2];
425 	int s;
426 
427 	s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv);
428 	ATF_CHECK_EQ(0, s);
429 	ATF_CHECK(sv[0] >= 0);
430 	ATF_CHECK(sv[1] >= 0);
431 	ATF_CHECK(sv[0] != sv[1]);
432 	close(sv[0]);
433 	close(sv[1]);
434 }
435 
436 /* Call listen(2) without first calling bind(2).  It should fail */
437 ATF_TC_WITHOUT_HEAD(listen_unbound);
438 ATF_TC_BODY(listen_unbound, tc)
439 {
440 	int s, r;
441 
442 	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
443 	ATF_REQUIRE(s > 0);
444 	r = listen(s, -1);
445 	/* expect listen to fail since we haven't called bind(2) */
446 	ATF_CHECK(r != 0);
447 	close(s);
448 }
449 
450 /* Bind the socket to a file */
451 ATF_TC_WITHOUT_HEAD(bind);
452 ATF_TC_BODY(bind, tc)
453 {
454 	struct sockaddr_un sun;
455 	/* ATF's isolation mechanisms will guarantee uniqueness of this file */
456 	const char *path = "sock";
457 	int s, r;
458 
459 	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
460 	ATF_REQUIRE(s >= 0);
461 
462 	bzero(&sun, sizeof(sun));
463 	sun.sun_family = AF_LOCAL;
464 	sun.sun_len = sizeof(sun);
465 	strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
466 	r = bind(s, (struct sockaddr *)&sun, sizeof(sun));
467 	ATF_CHECK_EQ(0, r);
468 	close(s);
469 }
470 
471 /* listen(2) a socket that is already bound(2) should succeed */
472 ATF_TC_WITHOUT_HEAD(listen_bound);
473 ATF_TC_BODY(listen_bound, tc)
474 {
475 	int s;
476 
477 	(void)mk_listening_socket(&s);
478 	close(s);
479 }
480 
481 /* connect(2) can make a connection */
482 ATF_TC_WITHOUT_HEAD(connect);
483 ATF_TC_BODY(connect, tc)
484 {
485 	const struct sockaddr_un *sun;
486 	int s, err, s2;
487 
488 	sun = mk_listening_socket(&s);
489 
490 	/* Create the other socket */
491 	s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
492 	ATF_REQUIRE(s2 >= 0);
493 	err = connect(s2, (struct sockaddr *)sun, sizeof(*sun));
494 	if (err != 0) {
495 		perror("connect");
496 		atf_tc_fail("connect(2) failed");
497 	}
498 	close(s);
499 	close(s2);
500 }
501 
502 /*
503  * An undocumented feature that we probably want to preserve: sending to
504  * a socket that isn't yet accepted lands data on the socket.  It can be
505  * read after accept(2).
506  */
507 ATF_TC_WITHOUT_HEAD(send_before_accept);
508 ATF_TC_BODY(send_before_accept, tc)
509 {
510 	const char buf[] = "hello";
511 	char repl[sizeof(buf)];
512 	const struct sockaddr_un *sun;
513 	int l, s, a;
514 
515 	sun = mk_listening_socket(&l);
516 
517 	ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0);
518 	ATF_REQUIRE(connect(s, (struct sockaddr *)sun, sizeof(*sun)) == 0);
519 	ATF_REQUIRE(send(s, &buf, sizeof(buf), 0) == sizeof(buf));
520 	ATF_REQUIRE((a = accept(l, NULL, NULL)) != 1);
521 	ATF_REQUIRE(recv(a, &repl, sizeof(repl), 0) == sizeof(buf));
522 	ATF_REQUIRE(strcmp(buf, repl) == 0);
523 	close(l);
524 	close(s);
525 	close(a);
526 }
527 
528 /*
529  * Test that close(2) of the peer ends in EPIPE when we try to send(2).
530  * Test both normal case as well as a peer that was not accept(2)-ed.
531  */
532 static bool sigpipe_received = false;
533 static void
534 sigpipe_handler(int signo __unused)
535 {
536 	sigpipe_received = true;
537 }
538 
539 ATF_TC_WITHOUT_HEAD(send_to_closed);
540 ATF_TC_BODY(send_to_closed, tc)
541 {
542 	struct sigaction sa = {
543 		.sa_handler = sigpipe_handler,
544 	};
545 	const struct sockaddr_un *sun;
546 	int l, s, a;
547 
548 	ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
549 	ATF_REQUIRE(sigaction(SIGPIPE, &sa, NULL) == 0);
550 
551 	sun = mk_listening_socket(&l);
552 
553 	ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0);
554 	ATF_REQUIRE(connect(s, (struct sockaddr *)sun, sizeof(*sun)) == 0);
555 	ATF_REQUIRE((a = accept(l, NULL, NULL)) != 1);
556 	close(a);
557 	ATF_REQUIRE(send(s, &s, sizeof(s), 0) == -1);
558 	ATF_REQUIRE(errno == EPIPE);
559 	ATF_REQUIRE(sigpipe_received == true);
560 	close(s);
561 
562 	ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0);
563 	ATF_REQUIRE(connect(s, (struct sockaddr *)sun, sizeof(*sun)) == 0);
564 	close(l);
565 	sigpipe_received = false;
566 	ATF_REQUIRE(send(s, &s, sizeof(s), 0) == -1);
567 	ATF_REQUIRE(errno == EPIPE);
568 	ATF_REQUIRE(sigpipe_received == true);
569 	close(s);
570 
571 	sa.sa_handler = SIG_DFL;
572 	ATF_REQUIRE(sigaction(SIGPIPE, &sa, NULL) == 0);
573 }
574 
575 /* Implied connect is unix/dgram only feature. Fails on stream or seqpacket. */
576 ATF_TC_WITHOUT_HEAD(implied_connect);
577 ATF_TC_BODY(implied_connect, tc)
578 {
579 	const struct sockaddr_un *sun;
580 	int l, s;
581 
582 	sun = mk_listening_socket(&l);
583 
584 	ATF_REQUIRE((s = socket(PF_LOCAL, SOCK_SEQPACKET, 0)) > 0);
585 	ATF_REQUIRE(sendto(s, &s, sizeof(s), 0, (struct sockaddr *)sun,
586 	    sizeof(*sun)) == -1);
587 	ATF_REQUIRE(errno == ENOTCONN);
588 	close(l);
589 	close(s);
590 }
591 
592 /* accept(2) can receive a connection */
593 ATF_TC_WITHOUT_HEAD(accept);
594 ATF_TC_BODY(accept, tc)
595 {
596 	int sv[2];
597 
598 	mk_pair_of_sockets(sv);
599 	close(sv[0]);
600 	close(sv[1]);
601 }
602 
603 
604 /* Set O_NONBLOCK on the socket */
605 ATF_TC_WITHOUT_HEAD(fcntl_nonblock);
606 ATF_TC_BODY(fcntl_nonblock, tc)
607 {
608 	int s;
609 
610 	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
611 	ATF_REQUIRE(s >= 0);
612 	if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) {
613 		perror("fcntl");
614 		atf_tc_fail("fcntl failed");
615 	}
616 	close(s);
617 }
618 
619 /* Resize the send and receive buffers */
620 ATF_TC_WITHOUT_HEAD(resize_buffers);
621 ATF_TC_BODY(resize_buffers, tc)
622 {
623 	int s;
624 	int sndbuf = 12345;
625 	int rcvbuf = 23456;
626 	int xs, xr;
627 	socklen_t sl = sizeof(xs);
628 
629 	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
630 	ATF_REQUIRE(s >= 0);
631 
632 	printf("                       Socket Buffer Sizes\n");
633 	printf("                              | SNDBUF  | RCVBUF  |\n");
634 	ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl));
635 	ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl));
636 	printf("Default                       | %7d | %7d |\n", xs, xr);
637 
638 	if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) != 0){
639 		perror("setsockopt");
640 		atf_tc_fail("setsockopt(SO_SNDBUF) failed");
641 	}
642 	ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl));
643 	ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl));
644 	printf("After changing SNDBUF         | %7d | %7d |\n", xs, xr);
645 
646 	if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) != 0){
647 		perror("setsockopt");
648 		atf_tc_fail("setsockopt(SO_RCVBUF) failed");
649 	}
650 	ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl));
651 	ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl));
652 	printf("After changing RCVBUF         | %7d | %7d |\n", xs, xr);
653 	close(s);
654 }
655 
656 /*
657  * Resize the send and receive buffers of a connected socketpair
658  * Print some useful debugging info too
659  */
660 ATF_TC_WITHOUT_HEAD(resize_connected_buffers);
661 ATF_TC_BODY(resize_connected_buffers, tc)
662 {
663 	int sv[2];
664 	int sndbuf = 12345;
665 	int rcvbuf = 23456;
666 	int err;
667 	int ls, lr, rs, rr;
668 	socklen_t sl = sizeof(ls);
669 
670 	/* setup the socket pair */
671 	do_socketpair(sv);
672 
673 	printf("                       Socket Buffer Sizes\n");
674 	printf("                              | Left Socket       | Right Socket      |\n");
675 	printf("                              | SNDBUF  | RCVBUF  | SNDBUF  | RCVBUF  |\n");
676 	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl));
677 	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl));
678 	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl));
679 	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl));
680 	printf("Default                       | %7d | %7d | %7d | %7d |\n",
681 	    ls, lr, rs, rr);
682 
683 	/* Update one side's send buffer */
684 	err = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
685 	if (err != 0){
686 		perror("setsockopt");
687 		atf_tc_fail("setsockopt(SO_SNDBUF) failed");
688 	}
689 
690 	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl));
691 	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl));
692 	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl));
693 	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl));
694 	printf("After changing Left's SNDBUF  | %7d | %7d | %7d | %7d |\n",
695 	    ls, lr, rs, rr);
696 
697 	/* Update the same side's receive buffer */
698 	err = setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
699 	if (err != 0){
700 		perror("setsockopt");
701 		atf_tc_fail("setsockopt(SO_RCVBUF) failed");
702 	}
703 
704 	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl));
705 	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl));
706 	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl));
707 	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl));
708 	printf("After changing Left's RCVBUF  | %7d | %7d | %7d | %7d |\n",
709 	    ls, lr, rs, rr);
710 	close(sv[0]);
711 	close(sv[1]);
712 }
713 
714 
715 /* send(2) and recv(2) a single short record */
716 ATF_TC_WITHOUT_HEAD(send_recv);
717 ATF_TC_BODY(send_recv, tc)
718 {
719 	int sv[2];
720 	const int bufsize = 64;
721 	const char *data = "data";
722 	char recv_buf[bufsize];
723 	ssize_t datalen;
724 	ssize_t ssize, rsize;
725 
726 	/* setup the socket pair */
727 	do_socketpair(sv);
728 
729 	/* send and receive a small packet */
730 	datalen = strlen(data) + 1;	/* +1 for the null */
731 	ssize = send(sv[0], data, datalen, MSG_EOR);
732 	if (ssize < 0) {
733 		perror("send");
734 		atf_tc_fail("send returned < 0");
735 	}
736 	ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
737 	    datalen, ssize);
738 
739 	rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
740 	ATF_CHECK_EQ(datalen, rsize);
741 	close(sv[0]);
742 	close(sv[1]);
743 }
744 
745 /* sendto(2) and recvfrom(2) a single short record
746  * According to The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
747  * Edition, sendto(2) is exactly the same as send(2) on a connection-mode socket
748  *
749  * According to the same spec, not all protocols are required to provide the
750  * source addres in recvfrom(2).
751  */
752 ATF_TC_WITHOUT_HEAD(sendto_recvfrom);
753 ATF_TC_BODY(sendto_recvfrom, tc)
754 {
755 #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS
756 	const sockaddr_un *sun;
757 #endif
758 	struct sockaddr_storage from;
759 	int sv[2];
760 	const int bufsize = 64;
761 	const char *data = "data";
762 	char recv_buf[bufsize];
763 	ssize_t datalen;
764 	ssize_t ssize, rsize;
765 	socklen_t fromlen;
766 
767 	/* setup the socket pair */
768 #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS
769 	sun =
770 #endif
771 		mk_pair_of_sockets(sv);
772 
773 	/* send and receive a small packet */
774 	datalen = strlen(data) + 1;	/* +1 for the null */
775 	ssize = sendto(sv[0], data, datalen, MSG_EOR, NULL, 0);
776 	if (ssize < 0) {
777 		perror("send");
778 		atf_tc_fail("send returned < 0");
779 	}
780 	ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
781 	    datalen, ssize);
782 
783 	fromlen = sizeof(from);
784 	rsize = recvfrom(sv[1], recv_buf, bufsize, MSG_WAITALL,
785 	    (struct sockaddr*)&from, &fromlen);
786 	if (ssize < 0) {
787 		perror("recvfrom");
788 		atf_tc_fail("recvfrom returned < 0");
789 	}
790 	ATF_CHECK_EQ(datalen, rsize);
791 
792 #ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS
793 	/*
794 	 * FreeBSD does not currently provide the source address for SEQ_PACKET
795 	 * AF_UNIX sockets, and POSIX does not require it, so these two checks
796 	 * are disabled.  If FreeBSD gains that feature in the future, then
797 	 * these checks may be reenabled
798 	 */
799 	ATF_CHECK_EQ(PF_LOCAL, from.ss_family);
800 	ATF_CHECK_STREQ(sun->sun_path, ((struct sockaddr_un*)&from)->sun_path);
801 #endif
802 	close(sv[0]);
803 	close(sv[1]);
804 }
805 
806 /*
807  * send(2) and recv(2) a single short record with sockets created the
808  * traditional way, involving bind, listen, connect, and accept
809  */
810 ATF_TC_WITHOUT_HEAD(send_recv_with_connect);
811 ATF_TC_BODY(send_recv_with_connect, tc)
812 {
813 	int sv[2];
814 	const int bufsize = 64;
815 	const char *data = "data";
816 	char recv_buf[bufsize];
817 	ssize_t datalen;
818 	ssize_t ssize, rsize;
819 
820 	mk_pair_of_sockets(sv);
821 
822 	/* send and receive a small packet */
823 	datalen = strlen(data) + 1;	/* +1 for the null */
824 	ssize = send(sv[0], data, datalen, MSG_EOR);
825 	if (ssize < 0) {
826 		perror("send");
827 		atf_tc_fail("send returned < 0");
828 	}
829 	ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
830 	    datalen, ssize);
831 
832 	rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
833 	ATF_CHECK_EQ(datalen, rsize);
834 	close(sv[0]);
835 	close(sv[1]);
836 }
837 
838 /* send(2) should fail on a shutdown socket */
839 ATF_TC_WITHOUT_HEAD(shutdown_send);
840 ATF_TC_BODY(shutdown_send, tc)
841 {
842 	const struct sockaddr_un *sun;
843 	const char *data = "data";
844 	ssize_t datalen, ssize;
845 	int s, err, s2;
846 
847 	sun = mk_listening_socket(&s);
848 
849 	/* Create the other socket */
850 	s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
851 	ATF_REQUIRE(s2 >= 0);
852 	err = connect(s2, (struct sockaddr *)sun, sizeof(*sun));
853 	if (err != 0) {
854 		perror("connect");
855 		atf_tc_fail("connect(2) failed");
856 	}
857 
858 	ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR));
859 	datalen = strlen(data) + 1;	/* +1 for the null */
860 	/* USE MSG_NOSIGNAL so we don't get SIGPIPE */
861 	ssize = send(s2, data, datalen, MSG_EOR | MSG_NOSIGNAL);
862 	ATF_CHECK_EQ(EPIPE, errno);
863 	ATF_CHECK_EQ(-1, ssize);
864 	close(s);
865 	close(s2);
866 }
867 
868 /* send(2) should cause SIGPIPE on a shutdown socket */
869 ATF_TC_WITHOUT_HEAD(shutdown_send_sigpipe);
870 ATF_TC_BODY(shutdown_send_sigpipe, tc)
871 {
872 	const struct sockaddr_un *sun;
873 	const char *data = "data";
874 	ssize_t datalen;
875 	int s, err, s2;
876 
877 	sun = mk_listening_socket(&s);
878 
879 	/* Create the other socket */
880 	s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
881 	ATF_REQUIRE(s2 >= 0);
882 	err = connect(s2, (struct sockaddr *)sun, sizeof(*sun));
883 	if (err != 0) {
884 		perror("connect");
885 		atf_tc_fail("connect(2) failed");
886 	}
887 
888 	ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR));
889 	ATF_REQUIRE(SIG_ERR != signal(SIGPIPE, shutdown_send_sigpipe_handler));
890 	datalen = strlen(data) + 1;	/* +1 for the null */
891 	(void)send(s2, data, datalen, MSG_EOR);
892 	ATF_CHECK_EQ(1, got_sigpipe);
893 	close(s);
894 	close(s2);
895 }
896 
897 /* nonblocking send(2) and recv(2) a single short record */
898 ATF_TC_WITHOUT_HEAD(send_recv_nonblocking);
899 ATF_TC_BODY(send_recv_nonblocking, tc)
900 {
901 	int sv[2];
902 	const int bufsize = 64;
903 	const char *data = "data";
904 	char recv_buf[bufsize];
905 	ssize_t datalen;
906 	ssize_t ssize, rsize;
907 
908 	/* setup the socket pair */
909 	do_socketpair_nonblocking(sv);
910 
911 	/* Verify that there is nothing to receive */
912 	rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
913 	ATF_CHECK_EQ(EAGAIN, errno);
914 	ATF_CHECK_EQ(-1, rsize);
915 
916 	/* send and receive a small packet */
917 	datalen = strlen(data) + 1;	/* +1 for the null */
918 	ssize = send(sv[0], data, datalen, MSG_EOR);
919 	if (ssize < 0) {
920 		perror("send");
921 		atf_tc_fail("send returned < 0");
922 	}
923 	ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
924 	    datalen, ssize);
925 
926 	rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
927 	ATF_CHECK_EQ(datalen, rsize);
928 	close(sv[0]);
929 	close(sv[1]);
930 }
931 
932 /*
933  * We should get EAGAIN if we try to send a message larger than the socket
934  * buffer, with nonblocking sockets.  Test with several different sockbuf sizes
935  */
936 ATF_TC_WITHOUT_HEAD(eagain_8k_8k);
937 ATF_TC_BODY(eagain_8k_8k, tc)
938 {
939 	test_eagain(8192, 8192);
940 }
941 ATF_TC_WITHOUT_HEAD(eagain_8k_128k);
942 ATF_TC_BODY(eagain_8k_128k, tc)
943 {
944 	test_eagain(8192, 131072);
945 }
946 ATF_TC_WITHOUT_HEAD(eagain_128k_8k);
947 ATF_TC_BODY(eagain_128k_8k, tc)
948 {
949 	test_eagain(131072, 8192);
950 }
951 ATF_TC_WITHOUT_HEAD(eagain_128k_128k);
952 ATF_TC_BODY(eagain_128k_128k, tc)
953 {
954 	test_eagain(131072, 131072);
955 }
956 
957 
958 /*
959  * nonblocking send(2) and recv(2) of several records, which should collectively
960  * fill up the send buffer but not the receive buffer
961  */
962 ATF_TC_WITHOUT_HEAD(rcvbuf_oversized);
963 ATF_TC_BODY(rcvbuf_oversized, tc)
964 {
965 	int i;
966 	int sv[2];
967 	const ssize_t pktsize = 1024;
968 	const int sndbufsize = 8192;
969 	const int rcvbufsize = 131072;
970 	const size_t geometric_mean_bufsize = 32768;
971 	const int numpkts = geometric_mean_bufsize / pktsize;
972 	char sndbuf[pktsize];
973 	char recv_buf[pktsize];
974 	ssize_t ssize, rsize;
975 
976 	/* setup the socket pair */
977 	do_socketpair_nonblocking(sv);
978 	ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
979 	    sizeof(sndbufsize)));
980 	ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
981 	    sizeof(rcvbufsize)));
982 
983 	/*
984 	 * Send and receive packets that are collectively greater than the send
985 	 * buffer, but less than the receive buffer
986 	 */
987 	for (i=0; i < numpkts; i++) {
988 		/* Fill the buffer */
989 		memset(sndbuf, i, pktsize);
990 
991 		/* send the packet */
992 		ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
993 		if (ssize < 0) {
994 			perror("send");
995 			atf_tc_fail("send returned < 0");
996 		}
997 		ATF_CHECK_EQ_MSG(pktsize, ssize,
998 		    "expected %zd=send(...) but got %zd", pktsize, ssize);
999 
1000 		/* Receive it */
1001 
1002 		rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL);
1003 		if (rsize < 0) {
1004 			perror("recv");
1005 			atf_tc_fail("recv returned < 0");
1006 		}
1007 		ATF_CHECK_EQ_MSG(pktsize, rsize,
1008 		    "expected %zd=send(...) but got %zd", pktsize, rsize);
1009 
1010 		/* Verify the contents */
1011 		ATF_CHECK_EQ_MSG(0, memcmp(sndbuf, recv_buf, pktsize),
1012 		    "Received data miscompare");
1013 	}
1014 
1015 	/* Trying to receive again should return EAGAIN */
1016 	rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL);
1017 	ATF_CHECK_EQ(EAGAIN, errno);
1018 	ATF_CHECK_EQ(-1, rsize);
1019 	close(sv[0]);
1020 	close(sv[1]);
1021 }
1022 
1023 /*
1024  * Simulate the behavior of a blocking pipe.  The sender will send until his
1025  * buffer fills up, then we'll simulate a scheduler switch that will allow the
1026  * receiver to read until his buffer empties.  Repeat the process until the
1027  * transfer is complete.
1028  * Repeat the test with multiple send and receive buffer sizes
1029  */
1030 ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_8k);
1031 ATF_TC_BODY(pipe_simulator_8k_8k, tc)
1032 {
1033 	test_pipe_simulator(8192, 8192);
1034 }
1035 
1036 ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_128k);
1037 ATF_TC_BODY(pipe_simulator_8k_128k, tc)
1038 {
1039 	test_pipe_simulator(8192, 131072);
1040 }
1041 
1042 ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_8k);
1043 ATF_TC_BODY(pipe_simulator_128k_8k, tc)
1044 {
1045 	test_pipe_simulator(131072, 8192);
1046 }
1047 
1048 ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_128k);
1049 ATF_TC_BODY(pipe_simulator_128k_128k, tc)
1050 {
1051 	test_pipe_simulator(131072, 131072);
1052 }
1053 
1054 /*
1055  * Test blocking I/O by passing data between two threads.  The total amount of
1056  * data will be >> buffer size to force blocking.  Repeat the test with multiple
1057  * send and receive buffer sizes
1058  */
1059 ATF_TC_WITHOUT_HEAD(pipe_8k_8k);
1060 ATF_TC_BODY(pipe_8k_8k, tc)
1061 {
1062 	test_pipe(8192, 8192);
1063 }
1064 
1065 ATF_TC_WITHOUT_HEAD(pipe_8k_128k);
1066 ATF_TC_BODY(pipe_8k_128k, tc)
1067 {
1068 	test_pipe(8192, 131072);
1069 }
1070 
1071 ATF_TC_WITHOUT_HEAD(pipe_128k_8k);
1072 ATF_TC_BODY(pipe_128k_8k, tc)
1073 {
1074 	test_pipe(131072, 8192);
1075 }
1076 
1077 ATF_TC_WITHOUT_HEAD(pipe_128k_128k);
1078 ATF_TC_BODY(pipe_128k_128k, tc)
1079 {
1080 	test_pipe(131072, 131072);
1081 }
1082 
1083 
1084 /*
1085  * Test single-packet I/O with and without blocking, with symmetric buffers of
1086  * various sizes
1087  */
1088 ATF_TC_WITHOUT_HEAD(sendrecv_8k);
1089 ATF_TC_BODY(sendrecv_8k, tc)
1090 {
1091 	test_sendrecv_symmetric_buffers(8 * 1024, true);
1092 }
1093 ATF_TC_WITHOUT_HEAD(sendrecv_16k);
1094 ATF_TC_BODY(sendrecv_16k, tc)
1095 {
1096 	test_sendrecv_symmetric_buffers(16 * 1024, true);
1097 }
1098 ATF_TC_WITHOUT_HEAD(sendrecv_32k);
1099 ATF_TC_BODY(sendrecv_32k, tc)
1100 {
1101 	test_sendrecv_symmetric_buffers(32 * 1024, true);
1102 }
1103 ATF_TC_WITHOUT_HEAD(sendrecv_64k);
1104 ATF_TC_BODY(sendrecv_64k, tc)
1105 {
1106 	test_sendrecv_symmetric_buffers(64 * 1024, true);
1107 }
1108 ATF_TC_WITHOUT_HEAD(sendrecv_128k);
1109 ATF_TC_BODY(sendrecv_128k, tc)
1110 {
1111 	test_sendrecv_symmetric_buffers(128 * 1024, true);
1112 }
1113 ATF_TC_WITHOUT_HEAD(sendrecv_8k_nonblocking);
1114 ATF_TC_BODY(sendrecv_8k_nonblocking, tc)
1115 {
1116 	test_sendrecv_symmetric_buffers(8 * 1024, false);
1117 }
1118 ATF_TC_WITHOUT_HEAD(sendrecv_16k_nonblocking);
1119 ATF_TC_BODY(sendrecv_16k_nonblocking, tc)
1120 {
1121 	test_sendrecv_symmetric_buffers(16 * 1024, false);
1122 }
1123 ATF_TC_WITHOUT_HEAD(sendrecv_32k_nonblocking);
1124 ATF_TC_BODY(sendrecv_32k_nonblocking, tc)
1125 {
1126 	test_sendrecv_symmetric_buffers(32 * 1024, false);
1127 }
1128 ATF_TC_WITHOUT_HEAD(sendrecv_64k_nonblocking);
1129 ATF_TC_BODY(sendrecv_64k_nonblocking, tc)
1130 {
1131 	test_sendrecv_symmetric_buffers(64 * 1024, false);
1132 }
1133 ATF_TC_WITHOUT_HEAD(sendrecv_128k_nonblocking);
1134 ATF_TC_BODY(sendrecv_128k_nonblocking, tc)
1135 {
1136 	test_sendrecv_symmetric_buffers(128 * 1024, false);
1137 }
1138 
1139 ATF_TC(random_eor_and_waitall);
1140 ATF_TC_HEAD(random_eor_and_waitall, tc)
1141 {
1142 	atf_tc_set_md_var(tc, "descr", "Test random sized send/recv with "
1143 	    "randomly placed MSG_EOR and randomly applied MSG_WAITALL on "
1144 	    "PF_UNIX/SOCK_SEQPACKET");
1145 }
1146 
1147 struct random_eor_params {
1148 	u_long recvspace;
1149 	char *sendbuf;
1150 	size_t *records;
1151 	u_int nrecords;
1152 	int sock;
1153 	u_short seed[6];
1154 };
1155 
1156 #define	RANDOM_TESTSIZE	((size_t)100 * 1024 * 1024)
1157 /* Below defines are factor of recvspace. */
1158 #define	RANDOM_MAXRECORD	10
1159 #define	RANDOM_SENDSIZE	2
1160 #define	RANDOM_RECVSIZE	4
1161 
1162 static void *
1163 sending_thread(void *arg)
1164 {
1165 	struct random_eor_params *params = arg;
1166 	size_t off = 0;
1167 	int eor = 0;
1168 
1169 	while (off < RANDOM_TESTSIZE) {
1170 		ssize_t len;
1171 		int flags;
1172 
1173 		len = nrand48(&params->seed[3]) %
1174 		    (RANDOM_SENDSIZE * params->recvspace);
1175 		if (off + len >= params->records[eor]) {
1176 			len = params->records[eor] - off;
1177 			flags = MSG_EOR;
1178 			eor++;
1179 		} else
1180 			flags = 0;
1181 		ATF_REQUIRE(send(params->sock, &params->sendbuf[off], len,
1182 		    flags) == len);
1183 		off += len;
1184 #ifdef DEBUG
1185 		printf("send %zd%s\n", off, flags ? " EOR" : "");
1186 #endif
1187 	}
1188 
1189 	return (NULL);
1190 }
1191 
1192 ATF_TC_BODY(random_eor_and_waitall, tc)
1193 {
1194 	struct random_eor_params params;
1195 	void *recvbuf;
1196 	pthread_t t;
1197 	size_t off;
1198 	int fd[2], eor;
1199 
1200 	atf_tc_skip("https://bugs.freebsd.org/279354");
1201 
1202 	arc4random_buf(params.seed, sizeof(params.seed));
1203 	printf("Using seed:");
1204 	for (u_int i = 0; i < (u_int)sizeof(params.seed)/sizeof(u_short); i++)
1205 		printf(" 0x%.4x,", params.seed[i]);
1206 	printf("\n");
1207 
1208 	ATF_REQUIRE((params.sendbuf = malloc(RANDOM_TESTSIZE)) != NULL);
1209 	for (u_int i = 0; i < RANDOM_TESTSIZE / (u_int )sizeof(long); i++)
1210 		((long *)params.sendbuf)[i] = nrand48(&params.seed[0]);
1211 
1212 	ATF_REQUIRE(sysctlbyname("net.local.seqpacket.recvspace",
1213 	    &params.recvspace, &(size_t){sizeof(u_long)}, NULL, 0) != -1);
1214 	ATF_REQUIRE((recvbuf =
1215 	    malloc(RANDOM_RECVSIZE * params.recvspace)) != NULL);
1216 
1217 	params.nrecords = 2 * RANDOM_TESTSIZE /
1218 	    (RANDOM_MAXRECORD * params.recvspace);
1219 
1220 	ATF_REQUIRE((params.records =
1221 	    malloc(params.nrecords * sizeof(size_t *))) != NULL);
1222 	off = 0;
1223 	for (u_int i = 0; i < params.nrecords; i++) {
1224 		off += 1 + nrand48(&params.seed[0]) %
1225 		    (RANDOM_MAXRECORD * params.recvspace);
1226 		if (off > RANDOM_TESTSIZE) {
1227 			params.nrecords = i;
1228 			break;
1229 		}
1230 		params.records[i] = off;
1231 	}
1232 	params.records[params.nrecords - 1] = RANDOM_TESTSIZE;
1233 
1234 	ATF_REQUIRE(socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, fd) == 0);
1235 	params.sock = fd[0];
1236 	ATF_REQUIRE(pthread_create(&t, NULL, sending_thread, &params) == 0);
1237 
1238 	off = 0;
1239 	eor = 0;
1240 	while (off < RANDOM_TESTSIZE) {
1241 		struct iovec iov = {
1242 			.iov_base = recvbuf,
1243 			.iov_len = nrand48(&params.seed[0]) %
1244 			    (RANDOM_RECVSIZE * params.recvspace)
1245 		};
1246 		struct msghdr hdr = {
1247 			.msg_iov = &iov,
1248 			.msg_iovlen = 1,
1249 		};
1250 		size_t len;
1251 		int waitall = iov.iov_len & 0x1 ? MSG_WAITALL : 0;
1252 
1253 		len = recvmsg(fd[1], &hdr, waitall);
1254 		if (waitall && !(hdr.msg_flags & MSG_EOR))
1255 			ATF_CHECK_EQ_MSG(len, iov.iov_len,
1256 			    "recvmsg(MSG_WAITALL): %zd, expected %zd",
1257 			    len, iov.iov_len);
1258 		if (off + len == params.records[eor]) {
1259 			ATF_REQUIRE_MSG(hdr.msg_flags & MSG_EOR,
1260 			    "recvmsg(): expected EOR @ %zd", off + len);
1261 			eor++;
1262 		} else {
1263 			ATF_REQUIRE_MSG(off + len < params.records[eor],
1264 			    "recvmsg() past EOR: %zd, expected %zd",
1265 			    off + len, params.records[eor]);
1266 			ATF_REQUIRE_MSG(!(hdr.msg_flags & MSG_EOR),
1267 			    "recvmsg() spurious EOR at %zd, expected %zd",
1268 			    off + len, params.records[eor]);
1269 		}
1270 		ATF_REQUIRE_MSG(0 == memcmp(params.sendbuf + off, recvbuf, len),
1271 		    "data corruption past %zd", off);
1272 		off += len;
1273 #ifdef DEBUG
1274 		printf("recv %zd%s %zd/%zd%s\n", off,
1275 		    (hdr.msg_flags & MSG_EOR) ?  " EOR" : "",
1276 		    len, iov.iov_len,
1277 		    waitall ? " WAITALL" : "");
1278 #endif
1279 	}
1280 
1281 	ATF_REQUIRE(pthread_join(t, NULL) == 0);
1282 	free(params.sendbuf);
1283 	free(recvbuf);
1284 	free(params.records);
1285 }
1286 
1287 /*
1288  * Main.
1289  */
1290 
1291 ATF_TP_ADD_TCS(tp)
1292 {
1293 	/* Basic creation and connection tests */
1294 	ATF_TP_ADD_TC(tp, create_socket);
1295 	ATF_TP_ADD_TC(tp, create_socketpair);
1296 	ATF_TP_ADD_TC(tp, listen_unbound);
1297 	ATF_TP_ADD_TC(tp, bind);
1298 	ATF_TP_ADD_TC(tp, listen_bound);
1299 	ATF_TP_ADD_TC(tp, connect);
1300 	ATF_TP_ADD_TC(tp, accept);
1301 	ATF_TP_ADD_TC(tp, fcntl_nonblock);
1302 	ATF_TP_ADD_TC(tp, resize_buffers);
1303 	ATF_TP_ADD_TC(tp, resize_connected_buffers);
1304 
1305 	/* Unthreaded I/O tests */
1306 	ATF_TP_ADD_TC(tp, send_recv);
1307 	ATF_TP_ADD_TC(tp, send_recv_nonblocking);
1308 	ATF_TP_ADD_TC(tp, send_recv_with_connect);
1309 	ATF_TP_ADD_TC(tp, sendto_recvfrom);
1310 	ATF_TP_ADD_TC(tp, send_before_accept);
1311 	ATF_TP_ADD_TC(tp, send_to_closed);
1312 	ATF_TP_ADD_TC(tp, implied_connect);
1313 	ATF_TP_ADD_TC(tp, shutdown_send);
1314 	ATF_TP_ADD_TC(tp, shutdown_send_sigpipe);
1315 	ATF_TP_ADD_TC(tp, eagain_8k_8k);
1316 	ATF_TP_ADD_TC(tp, eagain_8k_128k);
1317 	ATF_TP_ADD_TC(tp, eagain_128k_8k);
1318 	ATF_TP_ADD_TC(tp, eagain_128k_128k);
1319 	ATF_TP_ADD_TC(tp, sendrecv_8k);
1320 	ATF_TP_ADD_TC(tp, sendrecv_16k);
1321 	ATF_TP_ADD_TC(tp, sendrecv_32k);
1322 	ATF_TP_ADD_TC(tp, sendrecv_64k);
1323 	ATF_TP_ADD_TC(tp, sendrecv_128k);
1324 	ATF_TP_ADD_TC(tp, sendrecv_8k_nonblocking);
1325 	ATF_TP_ADD_TC(tp, sendrecv_16k_nonblocking);
1326 	ATF_TP_ADD_TC(tp, sendrecv_32k_nonblocking);
1327 	ATF_TP_ADD_TC(tp, sendrecv_64k_nonblocking);
1328 	ATF_TP_ADD_TC(tp, sendrecv_128k_nonblocking);
1329 	ATF_TP_ADD_TC(tp, rcvbuf_oversized);
1330 	ATF_TP_ADD_TC(tp, pipe_simulator_8k_8k);
1331 	ATF_TP_ADD_TC(tp, pipe_simulator_8k_128k);
1332 	ATF_TP_ADD_TC(tp, pipe_simulator_128k_8k);
1333 	ATF_TP_ADD_TC(tp, pipe_simulator_128k_128k);
1334 
1335 	/* Threaded I/O tests with blocking sockets */
1336 	ATF_TP_ADD_TC(tp, pipe_8k_8k);
1337 	ATF_TP_ADD_TC(tp, pipe_8k_128k);
1338 	ATF_TP_ADD_TC(tp, pipe_128k_8k);
1339 	ATF_TP_ADD_TC(tp, pipe_128k_128k);
1340 	ATF_TP_ADD_TC(tp, random_eor_and_waitall);
1341 
1342 	return atf_no_error();
1343 }
1344