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