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