unix_seqpacket_test.c revision 321165
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: stable/11/tests/sys/kern/unix_seqpacket_test.c 321165 2017-07-18 18:51:34Z ngie $");
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
46static void
47do_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
58static void
59do_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 */
76static const char*
77mk_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
95	/* Create the other socket */
96	s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
97	ATF_REQUIRE(s2 >= 0);
98	err = connect(s2, (struct sockaddr*)&sun, sizeof(sun));
99	if (err != 0) {
100		perror("connect");
101		atf_tc_fail("connect(2) failed");
102	}
103
104	/* Accept it */
105	s1 = accept(s, NULL, NULL);
106	if (s1 == -1) {
107		perror("accept");
108		atf_tc_fail("accept(2) failed");
109	}
110
111	sv[0] = s1;
112	sv[1] = s2;
113
114	close(s);
115
116	return (path);
117}
118
119static volatile sig_atomic_t got_sigpipe = 0;
120static void
121shutdown_send_sigpipe_handler(int __unused x)
122{
123	got_sigpipe = 1;
124}
125
126/*
127 * Parameterized test function bodies
128 */
129static void
130test_eagain(int sndbufsize, int rcvbufsize)
131{
132	int i;
133	int sv[2];
134	const size_t totalsize = (sndbufsize + rcvbufsize) * 2;
135	const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4;
136	const int numpkts = totalsize / pktsize;
137	char sndbuf[pktsize];
138	ssize_t ssize;
139
140	/* setup the socket pair */
141	do_socketpair_nonblocking(sv);
142	/* Setup the buffers */
143	ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
144	    sizeof(sndbufsize)));
145	ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
146	    sizeof(rcvbufsize)));
147
148	bzero(sndbuf, pktsize);
149	/* Send data until we get EAGAIN */
150	for(i=0; i < numpkts; i++) {
151		ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
152		if (ssize == -1) {
153			if (errno == EAGAIN) {
154				close(sv[0]);
155				close(sv[1]);
156				atf_tc_pass();
157			}
158			else {
159				perror("send");
160				atf_tc_fail("send returned < 0 but not EAGAIN");
161			}
162		}
163	}
164	atf_tc_fail("Never got EAGAIN");
165}
166
167static void
168test_sendrecv_symmetric_buffers(int bufsize, int blocking) {
169	int s;
170	int sv[2];
171	const ssize_t pktsize = bufsize / 2;
172	char sndbuf[pktsize];
173	char recv_buf[pktsize];
174	ssize_t ssize, rsize;
175
176	/* setup the socket pair */
177	if (blocking)
178		do_socketpair(sv);
179	else
180		do_socketpair_nonblocking(sv);
181
182	/* Setup the buffers */
183	s = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize));
184	ATF_REQUIRE_EQ(0, s);
185	s = setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(bufsize));
186	ATF_REQUIRE_EQ(0, s);
187
188	/* Fill the send buffer */
189	bzero(sndbuf, pktsize);
190
191	/* send and receive the packet */
192	ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
193	if (ssize < 0) {
194		perror("send");
195		atf_tc_fail("send returned < 0");
196	}
197	ATF_CHECK_EQ_MSG(pktsize, ssize, "expected %zd=send(...) but got %zd",
198	    pktsize, ssize);
199
200	rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL);
201	if (rsize < 0) {
202		perror("recv");
203		atf_tc_fail("recv returned < 0");
204	}
205	ATF_CHECK_EQ_MSG(pktsize, rsize, "expected %zd=send(...) but got %zd",
206	    pktsize, rsize);
207	close(sv[0]);
208	close(sv[1]);
209}
210
211static void
212test_pipe_simulator(int sndbufsize, int rcvbufsize)
213{
214	int num_sent, num_received;
215	int sv[2];
216	const ssize_t pktsize = MIN(sndbufsize, rcvbufsize) / 4;
217	int numpkts;
218	char sndbuf[pktsize];
219	char rcvbuf[pktsize];
220	char comparebuf[pktsize];
221	ssize_t ssize, rsize;
222	bool currently_sending = true;
223
224	/* setup the socket pair */
225	do_socketpair_nonblocking(sv);
226	/* Setup the buffers */
227	ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
228	    sizeof(sndbufsize)));
229	ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
230	    sizeof(rcvbufsize)));
231
232	/* Send a total amount of data comfortably greater than the buffers */
233	numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize;
234	for (num_sent=0, num_received=0;
235	     num_sent < numpkts || num_received < numpkts; ) {
236		if (currently_sending && num_sent < numpkts) {
237			/* The simulated sending process */
238			/* fill the buffer */
239			memset(sndbuf, num_sent, pktsize);
240			ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
241			if (ssize < 0) {
242				/*
243				 * XXX: This is bug-compatible with the kernel.
244				 * The kernel returns EMSGSIZE when it should
245				 * return EAGAIN
246				 */
247				if (errno == EAGAIN || errno == EMSGSIZE)
248					currently_sending = false;
249				else {
250					perror("send");
251					atf_tc_fail("send failed");
252				}
253			} else  {
254				ATF_CHECK_EQ_MSG(pktsize, ssize,
255				    "expected %zd=send(...) but got %zd",
256				    pktsize, ssize);
257				num_sent++;
258			}
259		} else {
260			/* The simulated receiving process */
261			rsize = recv(sv[1], rcvbuf, pktsize, MSG_WAITALL);
262			if (rsize < 0) {
263				if (errno == EAGAIN) {
264					currently_sending = true;
265					ATF_REQUIRE_MSG(num_sent < numpkts,
266					    "Packets were lost!");
267				}
268				else {
269					perror("recv");
270					atf_tc_fail("recv failed");
271				}
272			} else  {
273				ATF_CHECK_EQ_MSG(pktsize, rsize,
274				    "expected %zd=recv(...) but got %zd",
275				    pktsize, rsize);
276				memset(comparebuf, num_received, pktsize);
277				ATF_CHECK_EQ_MSG(0, memcmp(comparebuf, rcvbuf,
278				    			   pktsize),
279				    "Received data miscompare");
280				num_received++;
281			}
282		}
283	}
284	close(sv[0]);
285	close(sv[1]);
286}
287
288typedef struct {
289	ssize_t	pktsize;
290	int	numpkts;
291	int	so;
292} test_pipe_thread_data_t;
293
294static void*
295test_pipe_writer(void* args)
296{
297	test_pipe_thread_data_t* td = args;
298	char sndbuf[td->pktsize];
299	ssize_t ssize;
300	int i;
301
302	for(i=0; i < td->numpkts; i++) {
303			memset(sndbuf, i, td->pktsize);
304			ssize = send(td->so, sndbuf, td->pktsize, MSG_EOR);
305			if (ssize < 0) {
306				perror("send");
307				atf_tc_fail("send returned < 0");
308			}
309			ATF_CHECK_EQ_MSG(td->pktsize, ssize,
310			    		 "expected %zd=send(...) but got %zd",
311			    		  td->pktsize, ssize);
312	}
313	return (0);
314}
315
316static void*
317test_pipe_reader(void* args)
318{
319	test_pipe_thread_data_t* td = args;
320	char rcvbuf[td->pktsize];
321	char comparebuf[td->pktsize];
322	ssize_t rsize;
323	int i, d;
324
325	for(i=0; i < td->numpkts; i++) {
326		memset(comparebuf, i, td->pktsize);
327		rsize = recv(td->so, rcvbuf, td->pktsize, MSG_WAITALL);
328		if (rsize < 0) {
329			perror("recv");
330			atf_tc_fail("recv returned < 0");
331		}
332		ATF_CHECK_EQ_MSG(td->pktsize, rsize,
333		    		 "expected %zd=send(...) but got %zd",
334				 td->pktsize, rsize);
335		d = memcmp(comparebuf, rcvbuf, td->pktsize);
336		ATF_CHECK_EQ_MSG(0, d,
337		    		 "Received data miscompare on packet %d", i);
338	}
339	return (0);
340}
341
342
343static void
344test_pipe(int sndbufsize, int rcvbufsize)
345{
346	test_pipe_thread_data_t writer_data, reader_data;
347	pthread_t writer, reader;
348	int sv[2];
349	const size_t pktsize = MIN(sndbufsize, rcvbufsize) / 4;
350	int numpkts;
351
352	/* setup the socket pair */
353	do_socketpair(sv);
354	/* Setup the buffers */
355	ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
356	    sizeof(sndbufsize)));
357	ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
358	    sizeof(rcvbufsize)));
359
360	/* Send a total amount of data comfortably greater than the buffers */
361	numpkts = MAX(sndbufsize, rcvbufsize) * 8 / pktsize;
362
363	/* Start the child threads */
364	writer_data.pktsize = pktsize;
365	writer_data.numpkts = numpkts;
366	writer_data.so = sv[0];
367	reader_data.pktsize = pktsize;
368	reader_data.numpkts = numpkts;
369	reader_data.so = sv[1];
370	ATF_REQUIRE_EQ(0, pthread_create(&writer, NULL, test_pipe_writer,
371	    				 (void*)&writer_data));
372	/*
373	 * Give the writer time to start writing, and hopefully block, before
374	 * starting the reader.  This increases the likelihood of the test case
375	 * failing due to PR kern/185812
376	 */
377	usleep(1000);
378	ATF_REQUIRE_EQ(0, pthread_create(&reader, NULL, test_pipe_reader,
379	    				 (void*)&reader_data));
380
381	/* Join the children */
382	ATF_REQUIRE_EQ(0, pthread_join(writer, NULL));
383	ATF_REQUIRE_EQ(0, pthread_join(reader, NULL));
384	close(sv[0]);
385	close(sv[1]);
386}
387
388
389/*
390 * Test Cases
391 */
392
393/* Create a SEQPACKET socket */
394ATF_TC_WITHOUT_HEAD(create_socket);
395ATF_TC_BODY(create_socket, tc)
396{
397	int s;
398
399	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
400	ATF_REQUIRE(s >= 0);
401	close(s);
402}
403
404/* Create SEQPACKET sockets using socketpair(2) */
405ATF_TC_WITHOUT_HEAD(create_socketpair);
406ATF_TC_BODY(create_socketpair, tc)
407{
408	int sv[2];
409	int s;
410
411	s = socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, sv);
412	ATF_CHECK_EQ(0, s);
413	ATF_CHECK(sv[0] >= 0);
414	ATF_CHECK(sv[1] >= 0);
415	ATF_CHECK(sv[0] != sv[1]);
416	close(sv[0]);
417	close(sv[1]);
418}
419
420/* Call listen(2) without first calling bind(2).  It should fail */
421ATF_TC_WITHOUT_HEAD(listen_unbound);
422ATF_TC_BODY(listen_unbound, tc)
423{
424	int s, r;
425
426	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
427	ATF_REQUIRE(s > 0);
428	r = listen(s, -1);
429	/* expect listen to fail since we haven't called bind(2) */
430	ATF_CHECK(r != 0);
431	close(s);
432}
433
434/* Bind the socket to a file */
435ATF_TC_WITHOUT_HEAD(bind);
436ATF_TC_BODY(bind, tc)
437{
438	struct sockaddr_un sun;
439	/* ATF's isolation mechanisms will guarantee uniqueness of this file */
440	const char *path = "sock";
441	int s, r;
442
443	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
444	ATF_REQUIRE(s >= 0);
445
446	bzero(&sun, sizeof(sun));
447	sun.sun_family = AF_LOCAL;
448	sun.sun_len = sizeof(sun);
449	strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
450	r = bind(s, (struct sockaddr *)&sun, sizeof(sun));
451	ATF_CHECK_EQ(0, r);
452	close(s);
453}
454
455/* listen(2) a socket that is already bound(2) should succeed */
456ATF_TC_WITHOUT_HEAD(listen_bound);
457ATF_TC_BODY(listen_bound, tc)
458{
459	struct sockaddr_un sun;
460	/* ATF's isolation mechanisms will guarantee uniqueness of this file */
461	const char *path = "sock";
462	int s, r, l;
463
464	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
465	ATF_REQUIRE(s >= 0);
466
467	bzero(&sun, sizeof(sun));
468	sun.sun_family = AF_LOCAL;
469	sun.sun_len = sizeof(sun);
470	strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
471	r = bind(s, (struct sockaddr *)&sun, sizeof(sun));
472	l = listen(s, -1);
473	ATF_CHECK_EQ(0, r);
474	ATF_CHECK_EQ(0, l);
475	close(s);
476}
477
478/* connect(2) can make a connection */
479ATF_TC_WITHOUT_HEAD(connect);
480ATF_TC_BODY(connect, tc)
481{
482	struct sockaddr_un sun;
483	/* ATF's isolation mechanisms will guarantee uniqueness of this file */
484	const char *path = "sock";
485	int s, r, err, l, s2;
486
487	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
488	ATF_REQUIRE(s >= 0);
489
490	bzero(&sun, sizeof(sun));
491	sun.sun_family = AF_LOCAL;
492	sun.sun_len = sizeof(sun);
493	strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
494	r = bind(s, (struct sockaddr *)&sun, sizeof(sun));
495	l = listen(s, -1);
496	ATF_CHECK_EQ(0, r);
497	ATF_CHECK_EQ(0, l);
498
499	/* Create the other socket */
500	s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
501	ATF_REQUIRE(s2 >= 0);
502	err = connect(s2, (struct sockaddr*)&sun, sizeof(sun));
503	if (err != 0) {
504		perror("connect");
505		atf_tc_fail("connect(2) failed");
506	}
507	close(s);
508	close(s2);
509}
510
511/* accept(2) can receive a connection */
512ATF_TC_WITHOUT_HEAD(accept);
513ATF_TC_BODY(accept, tc)
514{
515	int sv[2];
516
517	mk_pair_of_sockets(sv);
518	close(sv[0]);
519	close(sv[1]);
520}
521
522
523/* Set O_NONBLOCK on the socket */
524ATF_TC_WITHOUT_HEAD(fcntl_nonblock);
525ATF_TC_BODY(fcntl_nonblock, tc)
526{
527	int s;
528
529	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
530	ATF_REQUIRE(s >= 0);
531	if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) {
532		perror("fcntl");
533		atf_tc_fail("fcntl failed");
534	}
535	close(s);
536}
537
538/* Resize the send and receive buffers */
539ATF_TC_WITHOUT_HEAD(resize_buffers);
540ATF_TC_BODY(resize_buffers, tc)
541{
542	int s;
543	int sndbuf = 12345;
544	int rcvbuf = 23456;
545	int xs, xr;
546	socklen_t sl = sizeof(xs);
547
548	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
549	ATF_REQUIRE(s >= 0);
550
551	printf("                       Socket Buffer Sizes\n");
552	printf("                              | SNDBUF  | RCVBUF  |\n");
553	ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl));
554	ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl));
555	printf("Default                       | %7d | %7d |\n", xs, xr);
556
557	if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) != 0){
558		perror("setsockopt");
559		atf_tc_fail("setsockopt(SO_SNDBUF) failed");
560	}
561	ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl));
562	ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl));
563	printf("After changing SNDBUF         | %7d | %7d |\n", xs, xr);
564
565	if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) != 0){
566		perror("setsockopt");
567		atf_tc_fail("setsockopt(SO_RCVBUF) failed");
568	}
569	ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_SNDBUF, &xs, &sl));
570	ATF_CHECK_EQ(0, getsockopt(s, SOL_SOCKET, SO_RCVBUF, &xr, &sl));
571	printf("After changing RCVBUF         | %7d | %7d |\n", xs, xr);
572	close(s);
573}
574
575/*
576 * Resize the send and receive buffers of a connected socketpair
577 * Print some useful debugging info too
578 */
579ATF_TC_WITHOUT_HEAD(resize_connected_buffers);
580ATF_TC_BODY(resize_connected_buffers, tc)
581{
582	int sv[2];
583	int sndbuf = 12345;
584	int rcvbuf = 23456;
585	int err;
586	int ls, lr, rs, rr;
587	socklen_t sl = sizeof(ls);
588
589	/* setup the socket pair */
590	do_socketpair(sv);
591
592	printf("                       Socket Buffer Sizes\n");
593	printf("                              | Left Socket       | Right Socket      |\n");
594	printf("                              | SNDBUF  | RCVBUF  | SNDBUF  | RCVBUF  |\n");
595	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl));
596	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl));
597	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl));
598	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl));
599	printf("Default                       | %7d | %7d | %7d | %7d |\n",
600	    ls, lr, rs, rr);
601
602	/* Update one side's send buffer */
603	err = setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf));
604	if (err != 0){
605		perror("setsockopt");
606		atf_tc_fail("setsockopt(SO_SNDBUF) failed");
607	}
608
609	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl));
610	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl));
611	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl));
612	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl));
613	printf("After changing Left's SNDBUF  | %7d | %7d | %7d | %7d |\n",
614	    ls, lr, rs, rr);
615
616	/* Update the same side's receive buffer */
617	err = setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
618	if (err != 0){
619		perror("setsockopt");
620		atf_tc_fail("setsockopt(SO_RCVBUF) failed");
621	}
622
623	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &ls, &sl));
624	ATF_CHECK_EQ(0, getsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &lr, &sl));
625	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &rs, &sl));
626	ATF_CHECK_EQ(0, getsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rr, &sl));
627	printf("After changing Left's RCVBUF  | %7d | %7d | %7d | %7d |\n",
628	    ls, lr, rs, rr);
629	close(sv[0]);
630	close(sv[1]);
631}
632
633
634/* send(2) and recv(2) a single short record */
635ATF_TC_WITHOUT_HEAD(send_recv);
636ATF_TC_BODY(send_recv, tc)
637{
638	int sv[2];
639	const int bufsize = 64;
640	const char *data = "data";
641	char recv_buf[bufsize];
642	ssize_t datalen;
643	ssize_t ssize, rsize;
644
645	/* setup the socket pair */
646	do_socketpair(sv);
647
648	/* send and receive a small packet */
649	datalen = strlen(data) + 1;	/* +1 for the null */
650	ssize = send(sv[0], data, datalen, MSG_EOR);
651	if (ssize < 0) {
652		perror("send");
653		atf_tc_fail("send returned < 0");
654	}
655	ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
656	    datalen, ssize);
657
658	rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
659	ATF_CHECK_EQ(datalen, rsize);
660	close(sv[0]);
661	close(sv[1]);
662}
663
664/* sendto(2) and recvfrom(2) a single short record
665 * According to The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004
666 * Edition, sendto(2) is exactly the same as send(2) on a connection-mode socket
667 *
668 * According to the same spec, not all protocols are required to provide the
669 * source addres in recvfrom(2).
670 */
671ATF_TC_WITHOUT_HEAD(sendto_recvfrom);
672ATF_TC_BODY(sendto_recvfrom, tc)
673{
674#ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS
675	const char* path;
676#endif
677	struct sockaddr_storage from;
678	int sv[2];
679	const int bufsize = 64;
680	const char *data = "data";
681	char recv_buf[bufsize];
682	ssize_t datalen;
683	ssize_t ssize, rsize;
684	socklen_t fromlen;
685
686	/* setup the socket pair */
687#ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS
688	path =
689#endif
690		mk_pair_of_sockets(sv);
691
692	/* send and receive a small packet */
693	datalen = strlen(data) + 1;	/* +1 for the null */
694	ssize = sendto(sv[0], data, datalen, MSG_EOR, NULL, 0);
695	if (ssize < 0) {
696		perror("send");
697		atf_tc_fail("send returned < 0");
698	}
699	ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
700	    datalen, ssize);
701
702	fromlen = sizeof(from);
703	rsize = recvfrom(sv[1], recv_buf, bufsize, MSG_WAITALL,
704	    (struct sockaddr*)&from, &fromlen);
705	if (ssize < 0) {
706		perror("recvfrom");
707		atf_tc_fail("recvfrom returned < 0");
708	}
709	ATF_CHECK_EQ(datalen, rsize);
710
711#ifdef TEST_SEQ_PACKET_SOURCE_ADDRESS
712	/*
713	 * FreeBSD does not currently provide the source address for SEQ_PACKET
714	 * AF_UNIX sockets, and POSIX does not require it, so these two checks
715	 * are disabled.  If FreeBSD gains that feature in the future, then
716	 * these checks may be reenabled
717	 */
718	ATF_CHECK_EQ(PF_LOCAL, from.ss_family);
719	ATF_CHECK_STREQ(path, ((struct sockaddr_un*)&from)->sun_path);
720#endif
721	close(sv[0]);
722	close(sv[1]);
723}
724
725/*
726 * send(2) and recv(2) a single short record with sockets created the
727 * traditional way, involving bind, listen, connect, and accept
728 */
729ATF_TC_WITHOUT_HEAD(send_recv_with_connect);
730ATF_TC_BODY(send_recv_with_connect, tc)
731{
732	int sv[2];
733	const int bufsize = 64;
734	const char *data = "data";
735	char recv_buf[bufsize];
736	ssize_t datalen;
737	ssize_t ssize, rsize;
738
739	mk_pair_of_sockets(sv);
740
741	/* send and receive a small packet */
742	datalen = strlen(data) + 1;	/* +1 for the null */
743	ssize = send(sv[0], data, datalen, MSG_EOR);
744	if (ssize < 0) {
745		perror("send");
746		atf_tc_fail("send returned < 0");
747	}
748	ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
749	    datalen, ssize);
750
751	rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
752	ATF_CHECK_EQ(datalen, rsize);
753	close(sv[0]);
754	close(sv[1]);
755}
756
757/* send(2) should fail on a shutdown socket */
758ATF_TC_WITHOUT_HEAD(shutdown_send);
759ATF_TC_BODY(shutdown_send, tc)
760{
761	struct sockaddr_un sun;
762	/* ATF's isolation mechanisms will guarantee uniqueness of this file */
763	const char *path = "sock";
764	const char *data = "data";
765	ssize_t datalen, ssize;
766	int s, err, s2;
767
768	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
769	ATF_REQUIRE(s >= 0);
770
771	bzero(&sun, sizeof(sun));
772	sun.sun_family = AF_LOCAL;
773	sun.sun_len = sizeof(sun);
774	strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
775	err = bind(s, (struct sockaddr *)&sun, sizeof(sun));
776	err = listen(s, -1);
777	ATF_CHECK_EQ(0, err);
778
779	/* Create the other socket */
780	s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
781	ATF_REQUIRE(s2 >= 0);
782	err = connect(s2, (struct sockaddr*)&sun, sizeof(sun));
783	if (err != 0) {
784		perror("connect");
785		atf_tc_fail("connect(2) failed");
786	}
787
788	ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR));
789	datalen = strlen(data) + 1;	/* +1 for the null */
790	/* USE MSG_NOSIGNAL so we don't get SIGPIPE */
791	ssize = send(s2, data, datalen, MSG_EOR | MSG_NOSIGNAL);
792	ATF_CHECK_EQ(EPIPE, errno);
793	ATF_CHECK_EQ(-1, ssize);
794	close(s);
795	close(s2);
796}
797
798/* send(2) should cause SIGPIPE on a shutdown socket */
799ATF_TC_WITHOUT_HEAD(shutdown_send_sigpipe);
800ATF_TC_BODY(shutdown_send_sigpipe, tc)
801{
802	struct sockaddr_un sun;
803	/* ATF's isolation mechanisms will guarantee uniqueness of this file */
804	const char *path = "sock";
805	const char *data = "data";
806	ssize_t datalen;
807	int s, err, s2;
808
809	s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
810	ATF_REQUIRE(s >= 0);
811
812	bzero(&sun, sizeof(sun));
813	sun.sun_family = AF_LOCAL;
814	sun.sun_len = sizeof(sun);
815	strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
816	err = bind(s, (struct sockaddr *)&sun, sizeof(sun));
817	err = listen(s, -1);
818	ATF_CHECK_EQ(0, err);
819
820	/* Create the other socket */
821	s2 = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
822	ATF_REQUIRE(s2 >= 0);
823	err = connect(s2, (struct sockaddr*)&sun, sizeof(sun));
824	if (err != 0) {
825		perror("connect");
826		atf_tc_fail("connect(2) failed");
827	}
828
829	ATF_CHECK_EQ(0, shutdown(s2, SHUT_RDWR));
830	ATF_REQUIRE(SIG_ERR != signal(SIGPIPE, shutdown_send_sigpipe_handler));
831	datalen = strlen(data) + 1;	/* +1 for the null */
832	(void)send(s2, data, sizeof(*data), MSG_EOR);
833	ATF_CHECK_EQ(1, got_sigpipe);
834	close(s);
835	close(s2);
836}
837
838/* nonblocking send(2) and recv(2) a single short record */
839ATF_TC_WITHOUT_HEAD(send_recv_nonblocking);
840ATF_TC_BODY(send_recv_nonblocking, tc)
841{
842	int sv[2];
843	const int bufsize = 64;
844	const char *data = "data";
845	char recv_buf[bufsize];
846	ssize_t datalen;
847	ssize_t ssize, rsize;
848
849	/* setup the socket pair */
850	do_socketpair_nonblocking(sv);
851
852	/* Verify that there is nothing to receive */
853	rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
854	ATF_CHECK_EQ(EAGAIN, errno);
855	ATF_CHECK_EQ(-1, rsize);
856
857	/* send and receive a small packet */
858	datalen = strlen(data) + 1;	/* +1 for the null */
859	ssize = send(sv[0], data, datalen, MSG_EOR);
860	if (ssize < 0) {
861		perror("send");
862		atf_tc_fail("send returned < 0");
863	}
864	ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
865	    datalen, ssize);
866
867	rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
868	ATF_CHECK_EQ(datalen, rsize);
869	close(sv[0]);
870	close(sv[1]);
871}
872
873/*
874 * We should get EMSGSIZE if we try to send a message larger than the socket
875 * buffer, with blocking sockets
876 */
877ATF_TC_WITHOUT_HEAD(emsgsize);
878ATF_TC_BODY(emsgsize, tc)
879{
880	int sv[2];
881	const int sndbufsize = 8192;
882	const int rcvbufsize = 8192;
883	const size_t pktsize = (sndbufsize + rcvbufsize) * 2;
884	char sndbuf[pktsize];
885	ssize_t ssize;
886
887	/* setup the socket pair */
888	do_socketpair(sv);
889	/* Setup the buffers */
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	ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
896	ATF_CHECK_EQ(EMSGSIZE, errno);
897	ATF_CHECK_EQ(-1, ssize);
898	close(sv[0]);
899	close(sv[1]);
900}
901
902/*
903 * We should get EMSGSIZE if we try to send a message larger than the socket
904 * buffer, with nonblocking sockets
905 */
906ATF_TC_WITHOUT_HEAD(emsgsize_nonblocking);
907ATF_TC_BODY(emsgsize_nonblocking, tc)
908{
909	int sv[2];
910	const int sndbufsize = 8192;
911	const int rcvbufsize = 8192;
912	const size_t pktsize = (sndbufsize + rcvbufsize) * 2;
913	char sndbuf[pktsize];
914	ssize_t ssize;
915
916	/* setup the socket pair */
917	do_socketpair_nonblocking(sv);
918	/* Setup the buffers */
919	ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
920	    sizeof(sndbufsize)));
921	ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
922	    sizeof(rcvbufsize)));
923
924	ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
925	ATF_CHECK_EQ(EMSGSIZE, errno);
926	ATF_CHECK_EQ(-1, ssize);
927	close(sv[0]);
928	close(sv[1]);
929}
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 */
936ATF_TC_WITHOUT_HEAD(eagain_8k_8k);
937ATF_TC_BODY(eagain_8k_8k, tc)
938{
939	test_eagain(8192, 8192);
940}
941ATF_TC_WITHOUT_HEAD(eagain_8k_128k);
942ATF_TC_BODY(eagain_8k_128k, tc)
943{
944	test_eagain(8192, 131072);
945}
946ATF_TC_WITHOUT_HEAD(eagain_128k_8k);
947ATF_TC_BODY(eagain_128k_8k, tc)
948{
949	test_eagain(131072, 8192);
950}
951ATF_TC_WITHOUT_HEAD(eagain_128k_128k);
952ATF_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 */
962ATF_TC_WITHOUT_HEAD(rcvbuf_oversized);
963ATF_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 */
1030ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_8k);
1031ATF_TC_BODY(pipe_simulator_8k_8k, tc)
1032{
1033	test_pipe_simulator(8192, 8192);
1034}
1035
1036ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_128k);
1037ATF_TC_BODY(pipe_simulator_8k_128k, tc)
1038{
1039	test_pipe_simulator(8192, 131072);
1040}
1041
1042ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_8k);
1043ATF_TC_BODY(pipe_simulator_128k_8k, tc)
1044{
1045	test_pipe_simulator(131072, 8192);
1046}
1047
1048ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_128k);
1049ATF_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 */
1059ATF_TC_WITHOUT_HEAD(pipe_8k_8k);
1060ATF_TC_BODY(pipe_8k_8k, tc)
1061{
1062	test_pipe(8192, 8192);
1063}
1064
1065ATF_TC_WITHOUT_HEAD(pipe_8k_128k);
1066ATF_TC_BODY(pipe_8k_128k, tc)
1067{
1068	test_pipe(8192, 131072);
1069}
1070
1071ATF_TC_WITHOUT_HEAD(pipe_128k_8k);
1072ATF_TC_BODY(pipe_128k_8k, tc)
1073{
1074	test_pipe(131072, 8192);
1075}
1076
1077ATF_TC_WITHOUT_HEAD(pipe_128k_128k);
1078ATF_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 */
1088ATF_TC_WITHOUT_HEAD(sendrecv_8k);
1089ATF_TC_BODY(sendrecv_8k, tc)
1090{
1091	test_sendrecv_symmetric_buffers(8 * 1024, true);
1092}
1093ATF_TC_WITHOUT_HEAD(sendrecv_16k);
1094ATF_TC_BODY(sendrecv_16k, tc)
1095{
1096	test_sendrecv_symmetric_buffers(16 * 1024, true);
1097}
1098ATF_TC_WITHOUT_HEAD(sendrecv_32k);
1099ATF_TC_BODY(sendrecv_32k, tc)
1100{
1101	test_sendrecv_symmetric_buffers(32 * 1024, true);
1102}
1103ATF_TC_WITHOUT_HEAD(sendrecv_64k);
1104ATF_TC_BODY(sendrecv_64k, tc)
1105{
1106	test_sendrecv_symmetric_buffers(64 * 1024, true);
1107}
1108ATF_TC_WITHOUT_HEAD(sendrecv_128k);
1109ATF_TC_BODY(sendrecv_128k, tc)
1110{
1111	test_sendrecv_symmetric_buffers(128 * 1024, true);
1112}
1113ATF_TC_WITHOUT_HEAD(sendrecv_8k_nonblocking);
1114ATF_TC_BODY(sendrecv_8k_nonblocking, tc)
1115{
1116	test_sendrecv_symmetric_buffers(8 * 1024, false);
1117}
1118ATF_TC_WITHOUT_HEAD(sendrecv_16k_nonblocking);
1119ATF_TC_BODY(sendrecv_16k_nonblocking, tc)
1120{
1121	test_sendrecv_symmetric_buffers(16 * 1024, false);
1122}
1123ATF_TC_WITHOUT_HEAD(sendrecv_32k_nonblocking);
1124ATF_TC_BODY(sendrecv_32k_nonblocking, tc)
1125{
1126	test_sendrecv_symmetric_buffers(32 * 1024, false);
1127}
1128ATF_TC_WITHOUT_HEAD(sendrecv_64k_nonblocking);
1129ATF_TC_BODY(sendrecv_64k_nonblocking, tc)
1130{
1131	test_sendrecv_symmetric_buffers(64 * 1024, false);
1132}
1133ATF_TC_WITHOUT_HEAD(sendrecv_128k_nonblocking);
1134ATF_TC_BODY(sendrecv_128k_nonblocking, tc)
1135{
1136	test_sendrecv_symmetric_buffers(128 * 1024, false);
1137}
1138
1139
1140/*
1141 * Main.
1142 */
1143
1144ATF_TP_ADD_TCS(tp)
1145{
1146	/* Basic creation and connection tests */
1147	ATF_TP_ADD_TC(tp, create_socket);
1148	ATF_TP_ADD_TC(tp, create_socketpair);
1149	ATF_TP_ADD_TC(tp, listen_unbound);
1150	ATF_TP_ADD_TC(tp, bind);
1151	ATF_TP_ADD_TC(tp, listen_bound);
1152	ATF_TP_ADD_TC(tp, connect);
1153	ATF_TP_ADD_TC(tp, accept);
1154	ATF_TP_ADD_TC(tp, fcntl_nonblock);
1155	ATF_TP_ADD_TC(tp, resize_buffers);
1156	ATF_TP_ADD_TC(tp, resize_connected_buffers);
1157
1158	/* Unthreaded I/O tests */
1159	ATF_TP_ADD_TC(tp, send_recv);
1160	ATF_TP_ADD_TC(tp, send_recv_nonblocking);
1161	ATF_TP_ADD_TC(tp, send_recv_with_connect);
1162	ATF_TP_ADD_TC(tp, sendto_recvfrom);
1163	ATF_TP_ADD_TC(tp, shutdown_send);
1164	ATF_TP_ADD_TC(tp, shutdown_send_sigpipe);
1165	ATF_TP_ADD_TC(tp, emsgsize);
1166	ATF_TP_ADD_TC(tp, emsgsize_nonblocking);
1167	ATF_TP_ADD_TC(tp, eagain_8k_8k);
1168	ATF_TP_ADD_TC(tp, eagain_8k_128k);
1169	ATF_TP_ADD_TC(tp, eagain_128k_8k);
1170	ATF_TP_ADD_TC(tp, eagain_128k_128k);
1171	ATF_TP_ADD_TC(tp, sendrecv_8k);
1172	ATF_TP_ADD_TC(tp, sendrecv_16k);
1173	ATF_TP_ADD_TC(tp, sendrecv_32k);
1174	ATF_TP_ADD_TC(tp, sendrecv_64k);
1175	ATF_TP_ADD_TC(tp, sendrecv_128k);
1176	ATF_TP_ADD_TC(tp, sendrecv_8k_nonblocking);
1177	ATF_TP_ADD_TC(tp, sendrecv_16k_nonblocking);
1178	ATF_TP_ADD_TC(tp, sendrecv_32k_nonblocking);
1179	ATF_TP_ADD_TC(tp, sendrecv_64k_nonblocking);
1180	ATF_TP_ADD_TC(tp, sendrecv_128k_nonblocking);
1181	ATF_TP_ADD_TC(tp, rcvbuf_oversized);
1182	ATF_TP_ADD_TC(tp, pipe_simulator_8k_8k);
1183	ATF_TP_ADD_TC(tp, pipe_simulator_8k_128k);
1184	ATF_TP_ADD_TC(tp, pipe_simulator_128k_8k);
1185	ATF_TP_ADD_TC(tp, pipe_simulator_128k_128k);
1186
1187	/* Threaded I/O tests with blocking sockets */
1188	ATF_TP_ADD_TC(tp, pipe_8k_8k);
1189	ATF_TP_ADD_TC(tp, pipe_8k_128k);
1190	ATF_TP_ADD_TC(tp, pipe_128k_8k);
1191	ATF_TP_ADD_TC(tp, pipe_128k_128k);
1192
1193	return atf_no_error();
1194}
1195