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/10/tests/sys/kern/unix_seqpacket_test.c 317834 2017-05-05 16:24:35Z brooks $");
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
do_socketpair(int * sv)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
do_socketpair_nonblocking(int * sv)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*
mk_pair_of_sockets(int * sv)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
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
119 static volatile sig_atomic_t got_sigpipe = 0;
120 static void
shutdown_send_sigpipe_handler(int __unused x)121 shutdown_send_sigpipe_handler(int __unused x)
122 {
123 got_sigpipe = 1;
124 }
125
126 /*
127 * Parameterized test function bodies
128 */
129 static void
test_eagain(int sndbufsize,int rcvbufsize)130 test_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
167 static void
test_sendrecv_symmetric_buffers(int bufsize,int blocking)168 test_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
211 static void
test_pipe_simulator(int sndbufsize,int rcvbufsize)212 test_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
288 typedef struct {
289 ssize_t pktsize;
290 int numpkts;
291 int so;
292 } test_pipe_thread_data_t;
293
294 static void*
test_pipe_writer(void * args)295 test_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
316 static void*
test_pipe_reader(void * args)317 test_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
343 static void
test_pipe(int sndbufsize,int rcvbufsize)344 test_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 */
394 ATF_TC_WITHOUT_HEAD(create_socket);
ATF_TC_BODY(create_socket,tc)395 ATF_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) */
405 ATF_TC_WITHOUT_HEAD(create_socketpair);
ATF_TC_BODY(create_socketpair,tc)406 ATF_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 */
421 ATF_TC_WITHOUT_HEAD(listen_unbound);
ATF_TC_BODY(listen_unbound,tc)422 ATF_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 */
435 ATF_TC_WITHOUT_HEAD(bind);
ATF_TC_BODY(bind,tc)436 ATF_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 */
456 ATF_TC_WITHOUT_HEAD(listen_bound);
ATF_TC_BODY(listen_bound,tc)457 ATF_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 */
479 ATF_TC_WITHOUT_HEAD(connect);
ATF_TC_BODY(connect,tc)480 ATF_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 */
512 ATF_TC_WITHOUT_HEAD(accept);
ATF_TC_BODY(accept,tc)513 ATF_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 */
524 ATF_TC_WITHOUT_HEAD(fcntl_nonblock);
ATF_TC_BODY(fcntl_nonblock,tc)525 ATF_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 */
539 ATF_TC_WITHOUT_HEAD(resize_buffers);
ATF_TC_BODY(resize_buffers,tc)540 ATF_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 */
579 ATF_TC_WITHOUT_HEAD(resize_connected_buffers);
ATF_TC_BODY(resize_connected_buffers,tc)580 ATF_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 */
635 ATF_TC_WITHOUT_HEAD(send_recv);
ATF_TC_BODY(send_recv,tc)636 ATF_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 */
671 ATF_TC_WITHOUT_HEAD(sendto_recvfrom);
ATF_TC_BODY(sendto_recvfrom,tc)672 ATF_TC_BODY(sendto_recvfrom, tc)
673 {
674 const char* path;
675 struct sockaddr_storage from;
676 int sv[2];
677 const int bufsize = 64;
678 const char *data = "data";
679 char recv_buf[bufsize];
680 ssize_t datalen;
681 ssize_t ssize, rsize;
682 socklen_t fromlen;
683
684 /* setup the socket pair */
685 path = mk_pair_of_sockets(sv);
686
687 /* send and receive a small packet */
688 datalen = strlen(data) + 1; /* +1 for the null */
689 ssize = sendto(sv[0], data, datalen, MSG_EOR, NULL, 0);
690 if (ssize < 0) {
691 perror("send");
692 atf_tc_fail("send returned < 0");
693 }
694 ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
695 datalen, ssize);
696
697 fromlen = sizeof(from);
698 rsize = recvfrom(sv[1], recv_buf, bufsize, MSG_WAITALL,
699 (struct sockaddr*)&from, &fromlen);
700 if (ssize < 0) {
701 perror("recvfrom");
702 atf_tc_fail("recvfrom returned < 0");
703 }
704 ATF_CHECK_EQ(datalen, rsize);
705
706 /*
707 * FreeBSD does not currently provide the source address for SEQ_PACKET
708 * AF_UNIX sockets, and POSIX does not require it, so these two checks
709 * are disabled. If FreeBSD gains that feature in the future, then
710 * these checks may be reenabled
711 */
712 /* ATF_CHECK_EQ(PF_LOCAL, from.ss_family); */
713 /* ATF_CHECK_STREQ(path, ((struct sockaddr_un*)&from)->sun_path); */
714 close(sv[0]);
715 close(sv[1]);
716 }
717
718 /*
719 * send(2) and recv(2) a single short record with sockets created the
720 * traditional way, involving bind, listen, connect, and accept
721 */
722 ATF_TC_WITHOUT_HEAD(send_recv_with_connect);
ATF_TC_BODY(send_recv_with_connect,tc)723 ATF_TC_BODY(send_recv_with_connect, tc)
724 {
725 int sv[2];
726 const int bufsize = 64;
727 const char *data = "data";
728 char recv_buf[bufsize];
729 ssize_t datalen;
730 ssize_t ssize, rsize;
731
732 mk_pair_of_sockets(sv);
733
734 /* send and receive a small packet */
735 datalen = strlen(data) + 1; /* +1 for the null */
736 ssize = send(sv[0], data, datalen, MSG_EOR);
737 if (ssize < 0) {
738 perror("send");
739 atf_tc_fail("send returned < 0");
740 }
741 ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
742 datalen, ssize);
743
744 rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
745 ATF_CHECK_EQ(datalen, rsize);
746 close(sv[0]);
747 close(sv[1]);
748 }
749
750 /* send(2) should fail on a shutdown socket */
751 ATF_TC_WITHOUT_HEAD(shutdown_send);
ATF_TC_BODY(shutdown_send,tc)752 ATF_TC_BODY(shutdown_send, tc)
753 {
754 int s;
755 const char data[] = "data";
756 ssize_t ssize;
757
758 s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
759 ATF_REQUIRE(s >= 0);
760 ATF_CHECK_EQ(0, shutdown(s, SHUT_RDWR));
761 /* USE MSG_NOSIGNAL so we don't get SIGPIPE */
762 ssize = send(s, data, sizeof(data), MSG_EOR | MSG_NOSIGNAL);
763 ATF_CHECK_EQ(EPIPE, errno);
764 ATF_CHECK_EQ(-1, ssize);
765 close(s);
766 }
767
768 /* send(2) should cause SIGPIPE on a shutdown socket */
769 ATF_TC_WITHOUT_HEAD(shutdown_send_sigpipe);
ATF_TC_BODY(shutdown_send_sigpipe,tc)770 ATF_TC_BODY(shutdown_send_sigpipe, tc)
771 {
772 int s;
773 const char data[] = "data";
774 ssize_t ssize;
775
776 s = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
777 ATF_REQUIRE(s >= 0);
778 ATF_CHECK_EQ(0, shutdown(s, SHUT_RDWR));
779 ATF_REQUIRE(SIG_ERR != signal(SIGPIPE, shutdown_send_sigpipe_handler));
780 ssize = send(s, data, sizeof(data), MSG_EOR);
781 ATF_CHECK_EQ(1, got_sigpipe);
782 close(s);
783 }
784
785 /* nonblocking send(2) and recv(2) a single short record */
786 ATF_TC_WITHOUT_HEAD(send_recv_nonblocking);
ATF_TC_BODY(send_recv_nonblocking,tc)787 ATF_TC_BODY(send_recv_nonblocking, tc)
788 {
789 int sv[2];
790 const int bufsize = 64;
791 const char *data = "data";
792 char recv_buf[bufsize];
793 ssize_t datalen;
794 ssize_t ssize, rsize;
795
796 /* setup the socket pair */
797 do_socketpair_nonblocking(sv);
798
799 /* Verify that there is nothing to receive */
800 rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
801 ATF_CHECK_EQ(EAGAIN, errno);
802 ATF_CHECK_EQ(-1, rsize);
803
804 /* send and receive a small packet */
805 datalen = strlen(data) + 1; /* +1 for the null */
806 ssize = send(sv[0], data, datalen, MSG_EOR);
807 if (ssize < 0) {
808 perror("send");
809 atf_tc_fail("send returned < 0");
810 }
811 ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd",
812 datalen, ssize);
813
814 rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL);
815 ATF_CHECK_EQ(datalen, rsize);
816 close(sv[0]);
817 close(sv[1]);
818 }
819
820 /*
821 * We should get EMSGSIZE if we try to send a message larger than the socket
822 * buffer, with blocking sockets
823 */
824 ATF_TC_WITHOUT_HEAD(emsgsize);
ATF_TC_BODY(emsgsize,tc)825 ATF_TC_BODY(emsgsize, tc)
826 {
827 int sv[2];
828 const int sndbufsize = 8192;
829 const int rcvbufsize = 8192;
830 const size_t pktsize = (sndbufsize + rcvbufsize) * 2;
831 char sndbuf[pktsize];
832 ssize_t ssize;
833
834 /* setup the socket pair */
835 do_socketpair(sv);
836 /* Setup the buffers */
837 ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
838 sizeof(sndbufsize)));
839 ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
840 sizeof(rcvbufsize)));
841
842 ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
843 ATF_CHECK_EQ(EMSGSIZE, errno);
844 ATF_CHECK_EQ(-1, ssize);
845 close(sv[0]);
846 close(sv[1]);
847 }
848
849 /*
850 * We should get EMSGSIZE if we try to send a message larger than the socket
851 * buffer, with nonblocking sockets
852 */
853 ATF_TC_WITHOUT_HEAD(emsgsize_nonblocking);
ATF_TC_BODY(emsgsize_nonblocking,tc)854 ATF_TC_BODY(emsgsize_nonblocking, tc)
855 {
856 int sv[2];
857 const int sndbufsize = 8192;
858 const int rcvbufsize = 8192;
859 const size_t pktsize = (sndbufsize + rcvbufsize) * 2;
860 char sndbuf[pktsize];
861 ssize_t ssize;
862
863 /* setup the socket pair */
864 do_socketpair_nonblocking(sv);
865 /* Setup the buffers */
866 ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
867 sizeof(sndbufsize)));
868 ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
869 sizeof(rcvbufsize)));
870
871 ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
872 ATF_CHECK_EQ(EMSGSIZE, errno);
873 ATF_CHECK_EQ(-1, ssize);
874 close(sv[0]);
875 close(sv[1]);
876 }
877
878
879 /*
880 * We should get EAGAIN if we try to send a message larger than the socket
881 * buffer, with nonblocking sockets. Test with several different sockbuf sizes
882 */
883 ATF_TC_WITHOUT_HEAD(eagain_8k_8k);
ATF_TC_BODY(eagain_8k_8k,tc)884 ATF_TC_BODY(eagain_8k_8k, tc)
885 {
886 test_eagain(8192, 8192);
887 }
888 ATF_TC_WITHOUT_HEAD(eagain_8k_128k);
ATF_TC_BODY(eagain_8k_128k,tc)889 ATF_TC_BODY(eagain_8k_128k, tc)
890 {
891 test_eagain(8192, 131072);
892 }
893 ATF_TC_WITHOUT_HEAD(eagain_128k_8k);
ATF_TC_BODY(eagain_128k_8k,tc)894 ATF_TC_BODY(eagain_128k_8k, tc)
895 {
896 test_eagain(131072, 8192);
897 }
898 ATF_TC_WITHOUT_HEAD(eagain_128k_128k);
ATF_TC_BODY(eagain_128k_128k,tc)899 ATF_TC_BODY(eagain_128k_128k, tc)
900 {
901 test_eagain(131072, 131072);
902 }
903
904
905 /*
906 * nonblocking send(2) and recv(2) of several records, which should collectively
907 * fill up the send buffer but not the receive buffer
908 */
909 ATF_TC_WITHOUT_HEAD(rcvbuf_oversized);
ATF_TC_BODY(rcvbuf_oversized,tc)910 ATF_TC_BODY(rcvbuf_oversized, tc)
911 {
912 int i;
913 int sv[2];
914 const ssize_t pktsize = 1024;
915 const int sndbufsize = 8192;
916 const int rcvbufsize = 131072;
917 const size_t geometric_mean_bufsize = 32768;
918 const int numpkts = geometric_mean_bufsize / pktsize;
919 char sndbuf[pktsize];
920 char recv_buf[pktsize];
921 ssize_t ssize, rsize;
922
923 /* setup the socket pair */
924 do_socketpair_nonblocking(sv);
925 ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize,
926 sizeof(sndbufsize)));
927 ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
928 sizeof(rcvbufsize)));
929
930 /*
931 * Send and receive packets that are collectively greater than the send
932 * buffer, but less than the receive buffer
933 */
934 for (i=0; i < numpkts; i++) {
935 /* Fill the buffer */
936 memset(sndbuf, i, pktsize);
937
938 /* send the packet */
939 ssize = send(sv[0], sndbuf, pktsize, MSG_EOR);
940 if (ssize < 0) {
941 perror("send");
942 atf_tc_fail("send returned < 0");
943 }
944 ATF_CHECK_EQ_MSG(pktsize, ssize,
945 "expected %zd=send(...) but got %zd", pktsize, ssize);
946
947 /* Receive it */
948
949 rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL);
950 if (rsize < 0) {
951 perror("recv");
952 atf_tc_fail("recv returned < 0");
953 }
954 ATF_CHECK_EQ_MSG(pktsize, rsize,
955 "expected %zd=send(...) but got %zd", pktsize, rsize);
956
957 /* Verify the contents */
958 ATF_CHECK_EQ_MSG(0, memcmp(sndbuf, recv_buf, pktsize),
959 "Received data miscompare");
960 }
961
962 /* Trying to receive again should return EAGAIN */
963 rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL);
964 ATF_CHECK_EQ(EAGAIN, errno);
965 ATF_CHECK_EQ(-1, rsize);
966 close(sv[0]);
967 close(sv[1]);
968 }
969
970 /*
971 * Simulate the behavior of a blocking pipe. The sender will send until his
972 * buffer fills up, then we'll simulate a scheduler switch that will allow the
973 * receiver to read until his buffer empties. Repeat the process until the
974 * transfer is complete.
975 * Repeat the test with multiple send and receive buffer sizes
976 */
977 ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_8k);
ATF_TC_BODY(pipe_simulator_8k_8k,tc)978 ATF_TC_BODY(pipe_simulator_8k_8k, tc)
979 {
980 test_pipe_simulator(8192, 8192);
981 }
982
983 ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_128k);
ATF_TC_BODY(pipe_simulator_8k_128k,tc)984 ATF_TC_BODY(pipe_simulator_8k_128k, tc)
985 {
986 test_pipe_simulator(8192, 131072);
987 }
988
989 ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_8k);
ATF_TC_BODY(pipe_simulator_128k_8k,tc)990 ATF_TC_BODY(pipe_simulator_128k_8k, tc)
991 {
992 test_pipe_simulator(131072, 8192);
993 }
994
995 ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_128k);
ATF_TC_BODY(pipe_simulator_128k_128k,tc)996 ATF_TC_BODY(pipe_simulator_128k_128k, tc)
997 {
998 test_pipe_simulator(131072, 131072);
999 }
1000
1001 /*
1002 * Test blocking I/O by passing data between two threads. The total amount of
1003 * data will be >> buffer size to force blocking. Repeat the test with multiple
1004 * send and receive buffer sizes
1005 */
1006 ATF_TC_WITHOUT_HEAD(pipe_8k_8k);
ATF_TC_BODY(pipe_8k_8k,tc)1007 ATF_TC_BODY(pipe_8k_8k, tc)
1008 {
1009 test_pipe(8192, 8192);
1010 }
1011
1012 ATF_TC_WITHOUT_HEAD(pipe_8k_128k);
ATF_TC_BODY(pipe_8k_128k,tc)1013 ATF_TC_BODY(pipe_8k_128k, tc)
1014 {
1015 test_pipe(8192, 131072);
1016 }
1017
1018 ATF_TC_WITHOUT_HEAD(pipe_128k_8k);
ATF_TC_BODY(pipe_128k_8k,tc)1019 ATF_TC_BODY(pipe_128k_8k, tc)
1020 {
1021 test_pipe(131072, 8192);
1022 }
1023
1024 ATF_TC_WITHOUT_HEAD(pipe_128k_128k);
ATF_TC_BODY(pipe_128k_128k,tc)1025 ATF_TC_BODY(pipe_128k_128k, tc)
1026 {
1027 test_pipe(131072, 131072);
1028 }
1029
1030
1031 /*
1032 * Test single-packet I/O with and without blocking, with symmetric buffers of
1033 * various sizes
1034 */
1035 ATF_TC_WITHOUT_HEAD(sendrecv_8k);
ATF_TC_BODY(sendrecv_8k,tc)1036 ATF_TC_BODY(sendrecv_8k, tc)
1037 {
1038 test_sendrecv_symmetric_buffers(8 * 1024, true);
1039 }
1040 ATF_TC_WITHOUT_HEAD(sendrecv_16k);
ATF_TC_BODY(sendrecv_16k,tc)1041 ATF_TC_BODY(sendrecv_16k, tc)
1042 {
1043 test_sendrecv_symmetric_buffers(16 * 1024, true);
1044 }
1045 ATF_TC_WITHOUT_HEAD(sendrecv_32k);
ATF_TC_BODY(sendrecv_32k,tc)1046 ATF_TC_BODY(sendrecv_32k, tc)
1047 {
1048 test_sendrecv_symmetric_buffers(32 * 1024, true);
1049 }
1050 ATF_TC_WITHOUT_HEAD(sendrecv_64k);
ATF_TC_BODY(sendrecv_64k,tc)1051 ATF_TC_BODY(sendrecv_64k, tc)
1052 {
1053 test_sendrecv_symmetric_buffers(64 * 1024, true);
1054 }
1055 ATF_TC_WITHOUT_HEAD(sendrecv_128k);
ATF_TC_BODY(sendrecv_128k,tc)1056 ATF_TC_BODY(sendrecv_128k, tc)
1057 {
1058 test_sendrecv_symmetric_buffers(128 * 1024, true);
1059 }
1060 ATF_TC_WITHOUT_HEAD(sendrecv_8k_nonblocking);
ATF_TC_BODY(sendrecv_8k_nonblocking,tc)1061 ATF_TC_BODY(sendrecv_8k_nonblocking, tc)
1062 {
1063 test_sendrecv_symmetric_buffers(8 * 1024, false);
1064 }
1065 ATF_TC_WITHOUT_HEAD(sendrecv_16k_nonblocking);
ATF_TC_BODY(sendrecv_16k_nonblocking,tc)1066 ATF_TC_BODY(sendrecv_16k_nonblocking, tc)
1067 {
1068 test_sendrecv_symmetric_buffers(16 * 1024, false);
1069 }
1070 ATF_TC_WITHOUT_HEAD(sendrecv_32k_nonblocking);
ATF_TC_BODY(sendrecv_32k_nonblocking,tc)1071 ATF_TC_BODY(sendrecv_32k_nonblocking, tc)
1072 {
1073 test_sendrecv_symmetric_buffers(32 * 1024, false);
1074 }
1075 ATF_TC_WITHOUT_HEAD(sendrecv_64k_nonblocking);
ATF_TC_BODY(sendrecv_64k_nonblocking,tc)1076 ATF_TC_BODY(sendrecv_64k_nonblocking, tc)
1077 {
1078 test_sendrecv_symmetric_buffers(64 * 1024, false);
1079 }
1080 ATF_TC_WITHOUT_HEAD(sendrecv_128k_nonblocking);
ATF_TC_BODY(sendrecv_128k_nonblocking,tc)1081 ATF_TC_BODY(sendrecv_128k_nonblocking, tc)
1082 {
1083 test_sendrecv_symmetric_buffers(128 * 1024, false);
1084 }
1085
1086
1087 /*
1088 * Main.
1089 */
1090
ATF_TP_ADD_TCS(tp)1091 ATF_TP_ADD_TCS(tp)
1092 {
1093 /* Basic creation and connection tests */
1094 ATF_TP_ADD_TC(tp, create_socket);
1095 ATF_TP_ADD_TC(tp, create_socketpair);
1096 ATF_TP_ADD_TC(tp, listen_unbound);
1097 ATF_TP_ADD_TC(tp, bind);
1098 ATF_TP_ADD_TC(tp, listen_bound);
1099 ATF_TP_ADD_TC(tp, connect);
1100 ATF_TP_ADD_TC(tp, accept);
1101 ATF_TP_ADD_TC(tp, fcntl_nonblock);
1102 ATF_TP_ADD_TC(tp, resize_buffers);
1103 ATF_TP_ADD_TC(tp, resize_connected_buffers);
1104
1105 /* Unthreaded I/O tests */
1106 ATF_TP_ADD_TC(tp, send_recv);
1107 ATF_TP_ADD_TC(tp, send_recv_nonblocking);
1108 ATF_TP_ADD_TC(tp, send_recv_with_connect);
1109 ATF_TP_ADD_TC(tp, sendto_recvfrom);
1110 ATF_TP_ADD_TC(tp, shutdown_send);
1111 ATF_TP_ADD_TC(tp, shutdown_send_sigpipe);
1112 ATF_TP_ADD_TC(tp, emsgsize);
1113 ATF_TP_ADD_TC(tp, emsgsize_nonblocking);
1114 ATF_TP_ADD_TC(tp, eagain_8k_8k);
1115 ATF_TP_ADD_TC(tp, eagain_8k_128k);
1116 ATF_TP_ADD_TC(tp, eagain_128k_8k);
1117 ATF_TP_ADD_TC(tp, eagain_128k_128k);
1118 ATF_TP_ADD_TC(tp, sendrecv_8k);
1119 ATF_TP_ADD_TC(tp, sendrecv_16k);
1120 ATF_TP_ADD_TC(tp, sendrecv_32k);
1121 ATF_TP_ADD_TC(tp, sendrecv_64k);
1122 ATF_TP_ADD_TC(tp, sendrecv_128k);
1123 ATF_TP_ADD_TC(tp, sendrecv_8k_nonblocking);
1124 ATF_TP_ADD_TC(tp, sendrecv_16k_nonblocking);
1125 ATF_TP_ADD_TC(tp, sendrecv_32k_nonblocking);
1126 ATF_TP_ADD_TC(tp, sendrecv_64k_nonblocking);
1127 ATF_TP_ADD_TC(tp, sendrecv_128k_nonblocking);
1128 ATF_TP_ADD_TC(tp, rcvbuf_oversized);
1129 ATF_TP_ADD_TC(tp, pipe_simulator_8k_8k);
1130 ATF_TP_ADD_TC(tp, pipe_simulator_8k_128k);
1131 ATF_TP_ADD_TC(tp, pipe_simulator_128k_8k);
1132 ATF_TP_ADD_TC(tp, pipe_simulator_128k_128k);
1133
1134 /* Threaded I/O tests with blocking sockets */
1135 ATF_TP_ADD_TC(tp, pipe_8k_8k);
1136 ATF_TP_ADD_TC(tp, pipe_8k_128k);
1137 ATF_TP_ADD_TC(tp, pipe_128k_8k);
1138 ATF_TP_ADD_TC(tp, pipe_128k_128k);
1139
1140 return atf_no_error();
1141 }
1142