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 /* 898 * https://syzkaller.appspot.com/bug?id=ac94349a29f2efc40e9274239e4ca9b2c473a4e7 899 */ 900 ATF_TC_WITHOUT_HEAD(shutdown_o_async); 901 ATF_TC_BODY(shutdown_o_async, tc) 902 { 903 int sv[2]; 904 905 do_socketpair(sv); 906 907 ATF_CHECK_EQ(0, fcntl(sv[0], F_SETFL, O_ASYNC)); 908 ATF_CHECK_EQ(0, shutdown(sv[0], SHUT_WR)); 909 close(sv[0]); 910 close(sv[1]); 911 } 912 913 /* 914 * If peer had done SHUT_WR on their side, our recv(2) shouldn't block. 915 */ 916 ATF_TC_WITHOUT_HEAD(shutdown_recv); 917 ATF_TC_BODY(shutdown_recv, tc) 918 { 919 char buf[10]; 920 int sv[2]; 921 922 do_socketpair(sv); 923 ATF_CHECK_EQ(0, shutdown(sv[0], SHUT_WR)); 924 ATF_CHECK_EQ(0, recv(sv[1], buf, sizeof(buf), 0)); 925 close(sv[0]); 926 close(sv[1]); 927 } 928 929 /* nonblocking send(2) and recv(2) a single short record */ 930 ATF_TC_WITHOUT_HEAD(send_recv_nonblocking); 931 ATF_TC_BODY(send_recv_nonblocking, tc) 932 { 933 int sv[2]; 934 const int bufsize = 64; 935 const char *data = "data"; 936 char recv_buf[bufsize]; 937 ssize_t datalen; 938 ssize_t ssize, rsize; 939 940 /* setup the socket pair */ 941 do_socketpair_nonblocking(sv); 942 943 /* Verify that there is nothing to receive */ 944 rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 945 ATF_CHECK_EQ(EAGAIN, errno); 946 ATF_CHECK_EQ(-1, rsize); 947 948 /* send and receive a small packet */ 949 datalen = strlen(data) + 1; /* +1 for the null */ 950 ssize = send(sv[0], data, datalen, MSG_EOR); 951 if (ssize < 0) { 952 perror("send"); 953 atf_tc_fail("send returned < 0"); 954 } 955 ATF_CHECK_EQ_MSG(datalen, ssize, "expected %zd=send(...) but got %zd", 956 datalen, ssize); 957 958 rsize = recv(sv[1], recv_buf, bufsize, MSG_WAITALL); 959 ATF_CHECK_EQ(datalen, rsize); 960 close(sv[0]); 961 close(sv[1]); 962 } 963 964 /* 965 * We should get EAGAIN if we try to send a message larger than the socket 966 * buffer, with nonblocking sockets. Test with several different sockbuf sizes 967 */ 968 ATF_TC_WITHOUT_HEAD(eagain_8k_8k); 969 ATF_TC_BODY(eagain_8k_8k, tc) 970 { 971 test_eagain(8192, 8192); 972 } 973 ATF_TC_WITHOUT_HEAD(eagain_8k_128k); 974 ATF_TC_BODY(eagain_8k_128k, tc) 975 { 976 test_eagain(8192, 131072); 977 } 978 ATF_TC_WITHOUT_HEAD(eagain_128k_8k); 979 ATF_TC_BODY(eagain_128k_8k, tc) 980 { 981 test_eagain(131072, 8192); 982 } 983 ATF_TC_WITHOUT_HEAD(eagain_128k_128k); 984 ATF_TC_BODY(eagain_128k_128k, tc) 985 { 986 test_eagain(131072, 131072); 987 } 988 989 990 /* 991 * nonblocking send(2) and recv(2) of several records, which should collectively 992 * fill up the send buffer but not the receive buffer 993 */ 994 ATF_TC_WITHOUT_HEAD(rcvbuf_oversized); 995 ATF_TC_BODY(rcvbuf_oversized, tc) 996 { 997 int i; 998 int sv[2]; 999 const ssize_t pktsize = 1024; 1000 const int sndbufsize = 8192; 1001 const int rcvbufsize = 131072; 1002 const size_t geometric_mean_bufsize = 32768; 1003 const int numpkts = geometric_mean_bufsize / pktsize; 1004 char sndbuf[pktsize]; 1005 char recv_buf[pktsize]; 1006 ssize_t ssize, rsize; 1007 1008 /* setup the socket pair */ 1009 do_socketpair_nonblocking(sv); 1010 ATF_REQUIRE_EQ(0, setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &sndbufsize, 1011 sizeof(sndbufsize))); 1012 ATF_REQUIRE_EQ(0, setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &rcvbufsize, 1013 sizeof(rcvbufsize))); 1014 1015 /* 1016 * Send and receive packets that are collectively greater than the send 1017 * buffer, but less than the receive buffer 1018 */ 1019 for (i=0; i < numpkts; i++) { 1020 /* Fill the buffer */ 1021 memset(sndbuf, i, pktsize); 1022 1023 /* send the packet */ 1024 ssize = send(sv[0], sndbuf, pktsize, MSG_EOR); 1025 if (ssize < 0) { 1026 perror("send"); 1027 atf_tc_fail("send returned < 0"); 1028 } 1029 ATF_CHECK_EQ_MSG(pktsize, ssize, 1030 "expected %zd=send(...) but got %zd", pktsize, ssize); 1031 1032 /* Receive it */ 1033 1034 rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 1035 if (rsize < 0) { 1036 perror("recv"); 1037 atf_tc_fail("recv returned < 0"); 1038 } 1039 ATF_CHECK_EQ_MSG(pktsize, rsize, 1040 "expected %zd=send(...) but got %zd", pktsize, rsize); 1041 1042 /* Verify the contents */ 1043 ATF_CHECK_EQ_MSG(0, memcmp(sndbuf, recv_buf, pktsize), 1044 "Received data miscompare"); 1045 } 1046 1047 /* Trying to receive again should return EAGAIN */ 1048 rsize = recv(sv[1], recv_buf, pktsize, MSG_WAITALL); 1049 ATF_CHECK_EQ(EAGAIN, errno); 1050 ATF_CHECK_EQ(-1, rsize); 1051 close(sv[0]); 1052 close(sv[1]); 1053 } 1054 1055 /* 1056 * Simulate the behavior of a blocking pipe. The sender will send until his 1057 * buffer fills up, then we'll simulate a scheduler switch that will allow the 1058 * receiver to read until his buffer empties. Repeat the process until the 1059 * transfer is complete. 1060 * Repeat the test with multiple send and receive buffer sizes 1061 */ 1062 ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_8k); 1063 ATF_TC_BODY(pipe_simulator_8k_8k, tc) 1064 { 1065 test_pipe_simulator(8192, 8192); 1066 } 1067 1068 ATF_TC_WITHOUT_HEAD(pipe_simulator_8k_128k); 1069 ATF_TC_BODY(pipe_simulator_8k_128k, tc) 1070 { 1071 test_pipe_simulator(8192, 131072); 1072 } 1073 1074 ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_8k); 1075 ATF_TC_BODY(pipe_simulator_128k_8k, tc) 1076 { 1077 test_pipe_simulator(131072, 8192); 1078 } 1079 1080 ATF_TC_WITHOUT_HEAD(pipe_simulator_128k_128k); 1081 ATF_TC_BODY(pipe_simulator_128k_128k, tc) 1082 { 1083 test_pipe_simulator(131072, 131072); 1084 } 1085 1086 /* 1087 * Test blocking I/O by passing data between two threads. The total amount of 1088 * data will be >> buffer size to force blocking. Repeat the test with multiple 1089 * send and receive buffer sizes 1090 */ 1091 ATF_TC_WITHOUT_HEAD(pipe_8k_8k); 1092 ATF_TC_BODY(pipe_8k_8k, tc) 1093 { 1094 test_pipe(8192, 8192); 1095 } 1096 1097 ATF_TC_WITHOUT_HEAD(pipe_8k_128k); 1098 ATF_TC_BODY(pipe_8k_128k, tc) 1099 { 1100 test_pipe(8192, 131072); 1101 } 1102 1103 ATF_TC_WITHOUT_HEAD(pipe_128k_8k); 1104 ATF_TC_BODY(pipe_128k_8k, tc) 1105 { 1106 test_pipe(131072, 8192); 1107 } 1108 1109 ATF_TC_WITHOUT_HEAD(pipe_128k_128k); 1110 ATF_TC_BODY(pipe_128k_128k, tc) 1111 { 1112 test_pipe(131072, 131072); 1113 } 1114 1115 1116 /* 1117 * Test single-packet I/O with and without blocking, with symmetric buffers of 1118 * various sizes 1119 */ 1120 ATF_TC_WITHOUT_HEAD(sendrecv_8k); 1121 ATF_TC_BODY(sendrecv_8k, tc) 1122 { 1123 test_sendrecv_symmetric_buffers(8 * 1024, true); 1124 } 1125 ATF_TC_WITHOUT_HEAD(sendrecv_16k); 1126 ATF_TC_BODY(sendrecv_16k, tc) 1127 { 1128 test_sendrecv_symmetric_buffers(16 * 1024, true); 1129 } 1130 ATF_TC_WITHOUT_HEAD(sendrecv_32k); 1131 ATF_TC_BODY(sendrecv_32k, tc) 1132 { 1133 test_sendrecv_symmetric_buffers(32 * 1024, true); 1134 } 1135 ATF_TC_WITHOUT_HEAD(sendrecv_64k); 1136 ATF_TC_BODY(sendrecv_64k, tc) 1137 { 1138 test_sendrecv_symmetric_buffers(64 * 1024, true); 1139 } 1140 ATF_TC_WITHOUT_HEAD(sendrecv_128k); 1141 ATF_TC_BODY(sendrecv_128k, tc) 1142 { 1143 test_sendrecv_symmetric_buffers(128 * 1024, true); 1144 } 1145 ATF_TC_WITHOUT_HEAD(sendrecv_8k_nonblocking); 1146 ATF_TC_BODY(sendrecv_8k_nonblocking, tc) 1147 { 1148 test_sendrecv_symmetric_buffers(8 * 1024, false); 1149 } 1150 ATF_TC_WITHOUT_HEAD(sendrecv_16k_nonblocking); 1151 ATF_TC_BODY(sendrecv_16k_nonblocking, tc) 1152 { 1153 test_sendrecv_symmetric_buffers(16 * 1024, false); 1154 } 1155 ATF_TC_WITHOUT_HEAD(sendrecv_32k_nonblocking); 1156 ATF_TC_BODY(sendrecv_32k_nonblocking, tc) 1157 { 1158 test_sendrecv_symmetric_buffers(32 * 1024, false); 1159 } 1160 ATF_TC_WITHOUT_HEAD(sendrecv_64k_nonblocking); 1161 ATF_TC_BODY(sendrecv_64k_nonblocking, tc) 1162 { 1163 test_sendrecv_symmetric_buffers(64 * 1024, false); 1164 } 1165 ATF_TC_WITHOUT_HEAD(sendrecv_128k_nonblocking); 1166 ATF_TC_BODY(sendrecv_128k_nonblocking, tc) 1167 { 1168 test_sendrecv_symmetric_buffers(128 * 1024, false); 1169 } 1170 1171 ATF_TC(random_eor_and_waitall); 1172 ATF_TC_HEAD(random_eor_and_waitall, tc) 1173 { 1174 atf_tc_set_md_var(tc, "descr", "Test random sized send/recv with " 1175 "randomly placed MSG_EOR and randomly applied MSG_WAITALL on " 1176 "PF_UNIX/SOCK_SEQPACKET"); 1177 } 1178 1179 struct random_eor_params { 1180 u_long recvspace; 1181 char *sendbuf; 1182 size_t *records; 1183 u_int nrecords; 1184 int sock; 1185 u_short seed[6]; 1186 }; 1187 1188 #define RANDOM_TESTSIZE ((size_t)100 * 1024 * 1024) 1189 /* Below defines are factor of recvspace. */ 1190 #define RANDOM_MAXRECORD 10 1191 #define RANDOM_SENDSIZE 2 1192 #define RANDOM_RECVSIZE 4 1193 1194 static void * 1195 sending_thread(void *arg) 1196 { 1197 struct random_eor_params *params = arg; 1198 size_t off = 0; 1199 int eor = 0; 1200 1201 while (off < RANDOM_TESTSIZE) { 1202 ssize_t len; 1203 int flags; 1204 1205 len = nrand48(¶ms->seed[3]) % 1206 (RANDOM_SENDSIZE * params->recvspace); 1207 if (off + len >= params->records[eor]) { 1208 len = params->records[eor] - off; 1209 flags = MSG_EOR; 1210 eor++; 1211 } else 1212 flags = 0; 1213 ATF_REQUIRE(send(params->sock, ¶ms->sendbuf[off], len, 1214 flags) == len); 1215 off += len; 1216 #ifdef DEBUG 1217 printf("send %zd%s\n", off, flags ? " EOR" : ""); 1218 #endif 1219 } 1220 1221 return (NULL); 1222 } 1223 1224 ATF_TC_BODY(random_eor_and_waitall, tc) 1225 { 1226 struct random_eor_params params; 1227 void *recvbuf; 1228 pthread_t t; 1229 size_t off; 1230 int fd[2], eor; 1231 1232 arc4random_buf(params.seed, sizeof(params.seed)); 1233 printf("Using seed:"); 1234 for (u_int i = 0; i < (u_int)sizeof(params.seed)/sizeof(u_short); i++) 1235 printf(" 0x%.4x,", params.seed[i]); 1236 printf("\n"); 1237 1238 ATF_REQUIRE((params.sendbuf = malloc(RANDOM_TESTSIZE)) != NULL); 1239 for (u_int i = 0; i < RANDOM_TESTSIZE / (u_int )sizeof(long); i++) 1240 ((long *)params.sendbuf)[i] = nrand48(¶ms.seed[0]); 1241 1242 ATF_REQUIRE(sysctlbyname("net.local.seqpacket.recvspace", 1243 ¶ms.recvspace, &(size_t){sizeof(u_long)}, NULL, 0) != -1); 1244 ATF_REQUIRE((recvbuf = 1245 malloc(RANDOM_RECVSIZE * params.recvspace)) != NULL); 1246 1247 params.nrecords = 2 * RANDOM_TESTSIZE / 1248 (RANDOM_MAXRECORD * params.recvspace); 1249 1250 ATF_REQUIRE((params.records = 1251 malloc(params.nrecords * sizeof(size_t *))) != NULL); 1252 off = 0; 1253 for (u_int i = 0; i < params.nrecords; i++) { 1254 off += 1 + nrand48(¶ms.seed[0]) % 1255 (RANDOM_MAXRECORD * params.recvspace); 1256 if (off > RANDOM_TESTSIZE) { 1257 params.nrecords = i; 1258 break; 1259 } 1260 params.records[i] = off; 1261 } 1262 params.records[params.nrecords - 1] = RANDOM_TESTSIZE; 1263 1264 ATF_REQUIRE(socketpair(PF_LOCAL, SOCK_SEQPACKET, 0, fd) == 0); 1265 params.sock = fd[0]; 1266 ATF_REQUIRE(pthread_create(&t, NULL, sending_thread, ¶ms) == 0); 1267 1268 off = 0; 1269 eor = 0; 1270 while (off < RANDOM_TESTSIZE) { 1271 struct iovec iov = { 1272 .iov_base = recvbuf, 1273 .iov_len = nrand48(¶ms.seed[0]) % 1274 (RANDOM_RECVSIZE * params.recvspace) 1275 }; 1276 struct msghdr hdr = { 1277 .msg_iov = &iov, 1278 .msg_iovlen = 1, 1279 }; 1280 size_t len; 1281 int waitall = iov.iov_len & 0x1 ? MSG_WAITALL : 0; 1282 1283 len = recvmsg(fd[1], &hdr, waitall); 1284 if (waitall && !(hdr.msg_flags & MSG_EOR)) 1285 ATF_CHECK_EQ_MSG(len, iov.iov_len, 1286 "recvmsg(MSG_WAITALL): %zd, expected %zd", 1287 len, iov.iov_len); 1288 if (off + len == params.records[eor]) { 1289 ATF_REQUIRE_MSG(hdr.msg_flags & MSG_EOR, 1290 "recvmsg(): expected EOR @ %zd", off + len); 1291 eor++; 1292 } else { 1293 ATF_REQUIRE_MSG(off + len < params.records[eor], 1294 "recvmsg() past EOR: %zd, expected %zd", 1295 off + len, params.records[eor]); 1296 ATF_REQUIRE_MSG(!(hdr.msg_flags & MSG_EOR), 1297 "recvmsg() spurious EOR at %zd, expected %zd", 1298 off + len, params.records[eor]); 1299 } 1300 ATF_REQUIRE_MSG(0 == memcmp(params.sendbuf + off, recvbuf, len), 1301 "data corruption past %zd", off); 1302 off += len; 1303 #ifdef DEBUG 1304 printf("recv %zd%s %zd/%zd%s\n", off, 1305 (hdr.msg_flags & MSG_EOR) ? " EOR" : "", 1306 len, iov.iov_len, 1307 waitall ? " WAITALL" : ""); 1308 #endif 1309 } 1310 1311 ATF_REQUIRE(pthread_join(t, NULL) == 0); 1312 free(params.sendbuf); 1313 free(recvbuf); 1314 free(params.records); 1315 } 1316 1317 /* 1318 * Main. 1319 */ 1320 1321 ATF_TP_ADD_TCS(tp) 1322 { 1323 /* Basic creation and connection tests */ 1324 ATF_TP_ADD_TC(tp, create_socket); 1325 ATF_TP_ADD_TC(tp, create_socketpair); 1326 ATF_TP_ADD_TC(tp, listen_unbound); 1327 ATF_TP_ADD_TC(tp, bind); 1328 ATF_TP_ADD_TC(tp, listen_bound); 1329 ATF_TP_ADD_TC(tp, connect); 1330 ATF_TP_ADD_TC(tp, accept); 1331 ATF_TP_ADD_TC(tp, fcntl_nonblock); 1332 ATF_TP_ADD_TC(tp, resize_buffers); 1333 ATF_TP_ADD_TC(tp, resize_connected_buffers); 1334 1335 /* Unthreaded I/O tests */ 1336 ATF_TP_ADD_TC(tp, send_recv); 1337 ATF_TP_ADD_TC(tp, send_recv_nonblocking); 1338 ATF_TP_ADD_TC(tp, send_recv_with_connect); 1339 ATF_TP_ADD_TC(tp, sendto_recvfrom); 1340 ATF_TP_ADD_TC(tp, send_before_accept); 1341 ATF_TP_ADD_TC(tp, send_to_closed); 1342 ATF_TP_ADD_TC(tp, implied_connect); 1343 ATF_TP_ADD_TC(tp, shutdown_send); 1344 ATF_TP_ADD_TC(tp, shutdown_send_sigpipe); 1345 ATF_TP_ADD_TC(tp, shutdown_o_async); 1346 ATF_TP_ADD_TC(tp, shutdown_recv); 1347 ATF_TP_ADD_TC(tp, eagain_8k_8k); 1348 ATF_TP_ADD_TC(tp, eagain_8k_128k); 1349 ATF_TP_ADD_TC(tp, eagain_128k_8k); 1350 ATF_TP_ADD_TC(tp, eagain_128k_128k); 1351 ATF_TP_ADD_TC(tp, sendrecv_8k); 1352 ATF_TP_ADD_TC(tp, sendrecv_16k); 1353 ATF_TP_ADD_TC(tp, sendrecv_32k); 1354 ATF_TP_ADD_TC(tp, sendrecv_64k); 1355 ATF_TP_ADD_TC(tp, sendrecv_128k); 1356 ATF_TP_ADD_TC(tp, sendrecv_8k_nonblocking); 1357 ATF_TP_ADD_TC(tp, sendrecv_16k_nonblocking); 1358 ATF_TP_ADD_TC(tp, sendrecv_32k_nonblocking); 1359 ATF_TP_ADD_TC(tp, sendrecv_64k_nonblocking); 1360 ATF_TP_ADD_TC(tp, sendrecv_128k_nonblocking); 1361 ATF_TP_ADD_TC(tp, rcvbuf_oversized); 1362 ATF_TP_ADD_TC(tp, pipe_simulator_8k_8k); 1363 ATF_TP_ADD_TC(tp, pipe_simulator_8k_128k); 1364 ATF_TP_ADD_TC(tp, pipe_simulator_128k_8k); 1365 ATF_TP_ADD_TC(tp, pipe_simulator_128k_128k); 1366 1367 /* Threaded I/O tests with blocking sockets */ 1368 ATF_TP_ADD_TC(tp, pipe_8k_8k); 1369 ATF_TP_ADD_TC(tp, pipe_8k_128k); 1370 ATF_TP_ADD_TC(tp, pipe_128k_8k); 1371 ATF_TP_ADD_TC(tp, pipe_128k_128k); 1372 ATF_TP_ADD_TC(tp, random_eor_and_waitall); 1373 1374 return atf_no_error(); 1375 } 1376