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