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