1 #include <stdlib.h> 2 #include <stdio.h> 3 #include <string.h> 4 #include <signal.h> 5 #include <sys/param.h> 6 #include <sys/wait.h> 7 #include <sys/socket.h> 8 #include <sys/ioctl.h> 9 #include <unistd.h> 10 #include <fcntl.h> 11 12 #include "common.h" 13 #include "socklib.h" 14 15 /* 0 = check, 1 = generate source, 2 = generate CSV */ 16 #define SOCKLIB_SWEEP_GENERATE 0 17 18 #if SOCKLIB_SWEEP_GENERATE 19 /* Link against minix/usr.bin/trace/error.o to make this work! */ 20 const char *get_error_name(int err); 21 22 #if SOCKLIB_SWEEP_GENERATE == 2 23 static const char *statename[S_MAX] = { 24 "S_NEW", 25 "S_N_SHUT_R", 26 "S_N_SHUT_W", 27 "S_N_SHUT_RW", 28 "S_BOUND", 29 "S_LISTENING", 30 "S_L_SHUT_R", 31 "S_L_SHUT_W", 32 "S_L_SHUT_RW", 33 "S_CONNECTING", 34 "S_C_SHUT_R", 35 "S_C_SHUT_W", 36 "S_C_SHUT_RW", 37 "S_CONNECTED", 38 "S_ACCEPTED", 39 "S_SHUT_R", 40 "S_SHUT_W", 41 "S_SHUT_RW", 42 "S_RSHUT_R", 43 "S_RSHUT_W", 44 "S_RSHUT_RW", 45 "S_SHUT2_R", 46 "S_SHUT2_W", 47 "S_SHUT2_RW", 48 "S_PRE_EOF", 49 "S_AT_EOF", 50 "S_POST_EOF", 51 "S_PRE_SHUT_R", 52 "S_EOF_SHUT_R", 53 "S_POST_SHUT_R", 54 "S_PRE_SHUT_W", 55 "S_EOF_SHUT_W", 56 "S_POST_SHUT_W", 57 "S_PRE_SHUT_RW", 58 "S_EOF_SHUT_RW", 59 "S_POST_SHUT_RW", 60 "S_PRE_RESET", 61 "S_AT_RESET", 62 "S_POST_RESET", 63 "S_FAILED", 64 "S_POST_FAILED", 65 }; 66 #endif 67 68 static const char *callname[C_MAX] = { 69 "C_ACCEPT", 70 "C_BIND", 71 "C_CONNECT", 72 "C_GETPEERNAME", 73 "C_GETSOCKNAME", 74 "C_GETSOCKOPT_ERR", 75 "C_GETSOCKOPT_KA", 76 "C_GETSOCKOPT_RB", 77 "C_IOCTL_NREAD", 78 "C_LISTEN", 79 "C_RECV", 80 "C_RECVFROM", 81 "C_SEND", 82 "C_SENDTO", 83 "C_SELECT_R", 84 "C_SELECT_W", 85 "C_SELECT_X", 86 "C_SETSOCKOPT_BC", 87 "C_SETSOCKOPT_KA", 88 "C_SETSOCKOPT_L", 89 "C_SETSOCKOPT_RA", 90 "C_SHUTDOWN_R", 91 "C_SHUTDOWN_RW", 92 "C_SHUTDOWN_W", 93 }; 94 #endif 95 96 static int socklib_sigpipe; 97 98 /* 99 * Signal handler for SIGPIPE signals. 100 */ 101 static void 102 socklib_signal(int sig) 103 { 104 105 if (sig != SIGPIPE) e(0); 106 107 socklib_sigpipe++; 108 } 109 110 /* 111 * The given socket file descriptor 'fd' has been set up in the desired state. 112 * Perform the given call 'call' on it, possibly using local socket address 113 * 'local_addr' (for binding) or remote socket address 'remote_addr' (for 114 * connecting or to store resulting addresses), both of size 'addr_len'. 115 * Return the result of the call, using a positive value if the call succeeded, 116 * or a negated errno code if the call failed. 117 */ 118 int 119 socklib_sweep_call(enum call call, int fd, struct sockaddr * local_addr, 120 struct sockaddr * remote_addr, socklen_t addr_len) 121 { 122 char data[1]; 123 struct linger l; 124 fd_set fd_set; 125 struct timeval tv; 126 socklen_t len; 127 int i, r, fd2; 128 129 fd2 = -1; 130 131 switch (call) { 132 case C_ACCEPT: 133 r = accept(fd, remote_addr, &addr_len); 134 135 if (r >= 0) 136 fd2 = r; 137 138 break; 139 140 case C_BIND: 141 r = bind(fd, local_addr, addr_len); 142 143 break; 144 145 case C_CONNECT: 146 r = connect(fd, remote_addr, addr_len); 147 148 break; 149 150 case C_GETPEERNAME: 151 r = getpeername(fd, remote_addr, &addr_len); 152 153 break; 154 155 case C_GETSOCKNAME: 156 r = getsockname(fd, remote_addr, &addr_len); 157 158 break; 159 160 case C_GETSOCKOPT_ERR: 161 len = sizeof(i); 162 163 r = getsockopt(fd, SOL_SOCKET, SO_ERROR, &i, &len); 164 165 /* 166 * We assume this call always succeeds, and test against the 167 * pending error. 168 */ 169 if (r != 0) e(0); 170 if (i != 0) { 171 r = -1; 172 errno = i; 173 } 174 175 break; 176 177 case C_GETSOCKOPT_KA: 178 len = sizeof(i); 179 180 r = getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &i, &len); 181 182 break; 183 184 case C_GETSOCKOPT_RB: 185 len = sizeof(i); 186 187 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &i, &len); 188 189 break; 190 191 case C_IOCTL_NREAD: 192 r = ioctl(fd, FIONREAD, &i); 193 194 /* On success, we test against the returned value here. */ 195 if (r == 0) 196 r = i; 197 198 break; 199 200 case C_LISTEN: 201 r = listen(fd, 1); 202 203 break; 204 205 case C_RECV: 206 r = recv(fd, data, sizeof(data), 0); 207 208 break; 209 210 case C_RECVFROM: 211 r = recvfrom(fd, data, sizeof(data), 0, remote_addr, 212 &addr_len); 213 214 break; 215 216 case C_SEND: 217 data[0] = 0; 218 219 r = send(fd, data, sizeof(data), 0); 220 221 break; 222 223 case C_SENDTO: 224 data[0] = 0; 225 226 r = sendto(fd, data, sizeof(data), 0, remote_addr, addr_len); 227 228 break; 229 230 case C_SETSOCKOPT_BC: 231 i = 0; 232 233 r = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &i, sizeof(i)); 234 235 break; 236 237 case C_SETSOCKOPT_KA: 238 i = 1; 239 240 r = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &i, sizeof(i)); 241 242 break; 243 244 case C_SETSOCKOPT_L: 245 l.l_onoff = 1; 246 l.l_linger = 0; 247 248 r = setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l)); 249 250 break; 251 252 case C_SETSOCKOPT_RA: 253 i = 1; 254 255 r = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); 256 257 break; 258 259 case C_SELECT_R: 260 case C_SELECT_W: 261 case C_SELECT_X: 262 FD_ZERO(&fd_set); 263 FD_SET(fd, &fd_set); 264 265 tv.tv_sec = 0; 266 tv.tv_usec = 0; 267 268 r = select(fd + 1, (call == C_SELECT_R) ? &fd_set : NULL, 269 (call == C_SELECT_W) ? &fd_set : NULL, 270 (call == C_SELECT_X) ? &fd_set : NULL, &tv); 271 272 break; 273 274 case C_SHUTDOWN_R: 275 r = shutdown(fd, SHUT_RD); 276 277 break; 278 279 case C_SHUTDOWN_W: 280 r = shutdown(fd, SHUT_WR); 281 282 break; 283 284 case C_SHUTDOWN_RW: 285 r = shutdown(fd, SHUT_RDWR); 286 287 break; 288 289 default: 290 r = -1; 291 errno = EINVAL; 292 e(0); 293 } 294 295 if (r < -1) e(0); 296 297 if (r == -1) 298 r = -errno; 299 300 if (fd2 >= 0 && close(fd2) != 0) e(0); 301 302 return r; 303 } 304 305 /* 306 * Perform a sweep of socket calls vs socket states, testing the outcomes 307 * against provided tables or (if SOCKLIB_SWEEP_GENERATE is set) reporting on 308 * the outcomes instead. The caller must provide the following: 309 * 310 * - the socket domain, type, and protocol to test; these are simply forwarded 311 * to the callback function (see below); 312 * - the set of S_ states to test, as array 'states' with 'nstates' elements; 313 * - unless generating output, a matrix of expected results as 'results', which 314 * is actually a two-dimensional array with dimensions [C_MAX][nstates], with 315 * either positive call output or a negated call errno code in each cell; 316 * - a callback function 'proc' that must set up a socket in the given state 317 * and pass it to socklib_sweep_call(). 318 * 319 * The 'states' array allows each socket sweep test to support a different set 320 * of states, because not every type of socket can be put in every possible 321 * state. All calls are always tried in each state, though. 322 * 323 * The sweep also tests for SIGPIPE generation, which assumes that all calls on 324 * SOCK_STREAM sockets that return EPIPE, also raise a SIGPIPE signal, and that 325 * no other SIGPIPE signal is ever raised otherwise. 326 * 327 * Standard e() error throwing is used for set-up and result mismatches. 328 */ 329 void 330 socklib_sweep(int domain, int type, int protocol, const enum state * states, 331 unsigned int nstates, const int * results, int (* proc)(int domain, 332 int type, int protocol, enum state, enum call)) 333 { 334 struct sigaction act, oact; 335 enum state state; 336 enum call call; 337 #if SOCKLIB_SWEEP_GENERATE 338 const char *name; 339 int res, *nresults; 340 #else 341 int res, exp; 342 #endif 343 344 memset(&act, 0, sizeof(act)); 345 act.sa_handler = socklib_signal; 346 if (sigaction(SIGPIPE, &act, &oact) != 0) e(0); 347 348 #if SOCKLIB_SWEEP_GENERATE 349 if ((nresults = malloc(nstates * C_MAX)) == NULL) e(0); 350 #endif 351 352 for (state = 0; state < nstates; state++) { 353 for (call = 0; call < C_MAX; call++) { 354 socklib_sigpipe = 0; 355 356 res = proc(domain, type, protocol, states[state], 357 call); 358 359 /* 360 * If the result was EPIPE and this is a stream-type 361 * socket, we must have received exactly one SIGPIPE 362 * signal. Otherwise, we must not have received one. 363 * Note that technically, the SIGPIPE could arrive 364 * sometime after this check, but with regular system 365 * service scheduling that will never happen. 366 */ 367 if (socklib_sigpipe != 368 (res == -EPIPE && type == SOCK_STREAM)) e(0); 369 370 #if SOCKLIB_SWEEP_GENERATE 371 nresults[call * nstates + state] = res; 372 #else 373 exp = results[call * nstates + state]; 374 375 if (res != exp) { 376 printf("FAIL state %d call %d res %d exp %d\n", 377 state, call, res, exp); 378 e(0); 379 } 380 #endif 381 } 382 } 383 384 if (sigaction(SIGPIPE, &oact, NULL) != 0) e(0); 385 386 #if SOCKLIB_SWEEP_GENERATE 387 #if SOCKLIB_SWEEP_GENERATE == 1 388 /* 389 * Generate a table in C form, ready to be pasted into test source. 390 * Obviously, generated results should be hand-checked carefully before 391 * being pasted into a test. Arguably these tables should be hand-made 392 * for maximum scrutiny, but I already checked the results from the 393 * CSV form (#define SOCKLIB_SWEEP_GENERATE 2) and have no desire for 394 * RSI -dcvmoole 395 */ 396 printf("\nstatic const int X_results[][__arraycount(X_states)] = {\n"); 397 for (call = 0; call < C_MAX; call++) { 398 if ((name = callname[call]) == NULL) e(0); 399 printf("\t[%s]%s%s%s= {", name, 400 (strlen(name) <= 21) ? "\t" : "", 401 (strlen(name) <= 13) ? "\t" : "", 402 (strlen(name) <= 5) ? "\t" : ""); 403 for (state = 0; state < nstates; state++) { 404 if (state % 4 == 0) 405 printf("\n\t\t"); 406 res = nresults[call * nstates + state]; 407 name = (res < 0) ? get_error_name(-res) : NULL; 408 if (name != NULL) { 409 printf("-%s,", name); 410 if ((state + 1) % 4 != 0 && 411 state < nstates - 1) 412 printf("%s%s", 413 (strlen(name) <= 13) ? "\t" : "", 414 (strlen(name) <= 5) ? "\t" : ""); 415 } else { 416 printf("%d,", res); 417 if ((state + 1) % 4 != 0 && 418 state < nstates - 1) 419 printf("\t\t"); 420 } 421 } 422 printf("\n\t},\n"); 423 } 424 printf("};\n"); 425 #elif SOCKLIB_SWEEP_GENERATE == 2 426 /* Generate table in CSV form. */ 427 printf("\n"); 428 for (state = 0; state < nstates; state++) 429 printf(",%s", statename[states[state]] + 2); 430 for (call = 0; call < C_MAX; call++) { 431 printf("\n%s", callname[call] + 2); 432 for (state = 0; state < nstates; state++) { 433 res = nresults[call * nstates + state]; 434 name = (res < 0) ? get_error_name(-res) : NULL; 435 if (name != NULL) 436 printf(",%s", name); 437 else 438 printf(",%d", res); 439 } 440 } 441 printf("\n"); 442 #endif 443 444 free(nresults); 445 #endif 446 } 447 448 /* 449 * Test for large sends and receives on stream sockets with MSG_WAITALL. 450 */ 451 void 452 socklib_large_transfers(int fd[2]) 453 { 454 char *buf; 455 pid_t pid; 456 int i, status; 457 458 #define LARGE_BUF (4096*1024) 459 460 if ((buf = malloc(LARGE_BUF)) == NULL) e(0); 461 memset(buf, 0, LARGE_BUF); 462 463 pid = fork(); 464 switch (pid) { 465 case 0: 466 errct = 0; 467 468 if (close(fd[0]) != 0) e(0); 469 470 /* Part 1. */ 471 if (recv(fd[1], buf, LARGE_BUF, MSG_WAITALL) != LARGE_BUF) 472 e(0); 473 474 for (i = 0; i < LARGE_BUF; i++) 475 if (buf[i] != (char)(i + (i >> 16))) e(0); 476 477 if (recv(fd[1], buf, LARGE_BUF, 478 MSG_DONTWAIT | MSG_WAITALL) != -1) e(0); 479 if (errno != EWOULDBLOCK) e(0); 480 481 /* Part 2. */ 482 if (send(fd[1], buf, LARGE_BUF / 2, 0) != LARGE_BUF / 2) e(0); 483 484 if (shutdown(fd[1], SHUT_WR) != 0) e(0); 485 486 /* Part 3. */ 487 memset(buf, 'y', LARGE_BUF); 488 489 if (recv(fd[1], buf, LARGE_BUF, MSG_WAITALL) != LARGE_BUF - 1) 490 e(0); 491 492 for (i = 0; i < LARGE_BUF - 1; i++) 493 if (buf[i] != (char)(i + (i >> 16))) e(0); 494 if (buf[LARGE_BUF - 1] != 'y') e(0); 495 496 if (recv(fd[1], buf, LARGE_BUF, MSG_WAITALL) != 0) e(0); 497 498 exit(errct); 499 case -1: 500 e(0); 501 } 502 503 if (close(fd[1]) != 0) e(0); 504 505 /* Part 1: check that a large send fully arrives. */ 506 for (i = 0; i < LARGE_BUF; i++) 507 buf[i] = (char)(i + (i >> 16)); 508 509 if (send(fd[0], buf, LARGE_BUF, 0) != LARGE_BUF) e(0); 510 511 /* Part 2: check that remote shutdown terminates a partial receive. */ 512 memset(buf, 'x', LARGE_BUF); 513 514 if (recv(fd[0], buf, LARGE_BUF, MSG_WAITALL) != LARGE_BUF / 2) e(0); 515 516 for (i = 0; i < LARGE_BUF / 2; i++) 517 if (buf[i] != (char)(i + (i >> 16))) e(0); 518 for (; i < LARGE_BUF; i++) 519 if (buf[i] != 'x') e(0); 520 521 if (recv(fd[0], buf, LARGE_BUF, MSG_WAITALL) != 0) e(0); 522 523 /* Part 3: check that remote close terminates a partial receive. */ 524 for (i = 0; i < LARGE_BUF; i++) 525 buf[i] = (char)(i + (i >> 16)); 526 527 if (send(fd[0], buf, LARGE_BUF - 1, 0) != LARGE_BUF - 1) e(0); 528 529 if (close(fd[0]) != 0) e(0); 530 531 if (waitpid(pid, &status, 0) != pid) e(0); 532 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0); 533 534 free(buf); 535 } 536 537 #define PRINT_STATS 0 538 539 /* 540 * A randomized producer-consumer test for stream sockets. As part of this, 541 * we also perform very basic bulk functionality tests of FIONREAD, MSG_PEEK, 542 * MSG_DONTWAIT, and MSG_WAITALL. 543 */ 544 void 545 socklib_producer_consumer(int fd[2]) 546 { 547 char *buf; 548 time_t t; 549 socklen_t len, size, off; 550 ssize_t r; 551 pid_t pid; 552 int i, rcvlen, status, exp, flags, num, stat[3] = { 0, 0, 0 }; 553 554 len = sizeof(rcvlen); 555 if (getsockopt(fd[0], SOL_SOCKET, SO_RCVBUF, &rcvlen, &len) != 0) e(0); 556 if (len != sizeof(rcvlen)) e(0); 557 558 size = rcvlen * 3; 559 560 if ((buf = malloc(size)) == NULL) e(0); 561 562 t = time(NULL); 563 564 /* 565 * We vary small versus large (random) send and receive sizes, 566 * splitting the entire transfer in four phases along those lines. 567 * 568 * In theory, the use of an extra system call, the use of MSG_PEEK, and 569 * the fact that without MSG_WAITALL a receive call may return any 570 * partial result, all contribute to the expectation that the consumer 571 * side will fall behind the producer. In order to test both filling 572 * and draining the receive queue, we use a somewhat larger small 573 * receive size for the consumer size (up to 256 bytes rather than 64) 574 * during each half of the four phases. The effectiveness of these 575 * numbers can be verified with statistics (disabled by default). 576 */ 577 #define TRANSFER_SIZE (16 * 1024 * 1024) 578 579 pid = fork(); 580 switch (pid) { 581 case 0: 582 errct = 0; 583 584 if (close(fd[0]) != 0) e(0); 585 586 srand48(t + 1); 587 588 for (off = 0; off < TRANSFER_SIZE; ) { 589 if (off < TRANSFER_SIZE / 2) 590 len = lrand48() % 591 ((off / (TRANSFER_SIZE / 8) % 2) ? 64 : 592 256); 593 else 594 len = lrand48() % size; 595 596 num = lrand48() % 16; 597 flags = 0; 598 if (num & 1) flags |= MSG_PEEK; 599 if (num & 2) flags |= MSG_WAITALL; 600 if (num & 4) flags |= MSG_DONTWAIT; 601 if (num & 8) { 602 /* 603 * Obviously there are race conditions here but 604 * the returned number should be a lower bound. 605 */ 606 if (ioctl(fd[1], FIONREAD, &exp) != 0) e(0); 607 if (exp < 0 || exp > rcvlen) e(0); 608 } else 609 exp = -1; 610 611 stat[0]++; 612 613 if ((r = recv(fd[1], buf, len, flags)) == -1) { 614 if (errno != EWOULDBLOCK) e(0); 615 if (exp > 0) e(0); 616 617 stat[2]++; 618 continue; 619 } 620 621 if (r < len) { 622 stat[1]++; 623 624 if (exp > r) e(0); 625 } 626 627 for (i = 0; i < r; i++) 628 if (buf[i] != (char)((off + i) + 629 ((off + i) >> 16))) e(0); 630 631 if (!(flags & MSG_PEEK)) { 632 off += r; 633 634 if ((flags & (MSG_DONTWAIT | MSG_WAITALL)) == 635 MSG_WAITALL && r != len && 636 off < TRANSFER_SIZE) e(0); 637 } 638 } 639 640 #if PRINT_STATS 641 /* 642 * The second and third numbers should ideally be a large but 643 * non-dominating fraction of the first one. 644 */ 645 printf("RECV: total %d short %d again %d\n", 646 stat[0], stat[1], stat[2]); 647 #endif 648 649 if (close(fd[1]) != 0) e(0); 650 exit(errct); 651 case -1: 652 e(0); 653 } 654 655 if (close(fd[1]) != 0) e(0); 656 657 srand48(t); 658 659 for (off = 0; off < TRANSFER_SIZE; ) { 660 if (off < TRANSFER_SIZE / 4 || 661 (off >= TRANSFER_SIZE / 2 && off < TRANSFER_SIZE * 3 / 4)) 662 len = lrand48() % 64; 663 else 664 len = lrand48() % size; 665 666 if (len > TRANSFER_SIZE - off) 667 len = TRANSFER_SIZE - off; 668 669 for (i = 0; i < len; i++) 670 buf[i] = (off + i) + ((off + i) >> 16); 671 672 flags = (lrand48() % 2) ? MSG_DONTWAIT : 0; 673 674 stat[0]++; 675 676 r = send(fd[0], buf, len, flags); 677 678 if (r != len) { 679 if (r > (ssize_t)len) e(0); 680 if (!(flags & MSG_DONTWAIT)) e(0); 681 if (r == -1) { 682 if (errno != EWOULDBLOCK) e(0); 683 r = 0; 684 685 stat[2]++; 686 } else 687 stat[1]++; 688 } 689 690 if (off / (TRANSFER_SIZE / 4) != 691 (off + r) / (TRANSFER_SIZE / 4)) 692 sleep(1); 693 694 off += r; 695 } 696 697 #if PRINT_STATS 698 /* 699 * The second and third numbers should ideally be a large but non- 700 * dominating fraction of the first one. 701 */ 702 printf("SEND: total %d short %d again %d\n", 703 stat[0], stat[1], stat[2]); 704 #endif 705 706 free(buf); 707 708 if (close(fd[0]) != 0) e(0); 709 710 if (waitpid(pid, &status, 0) != pid) e(0); 711 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0); 712 } 713 714 /* 715 * Signal handler which just needs to exist, so that invoking it will interrupt 716 * an ongoing system call. 717 */ 718 static void 719 socklib_got_signal(int sig __unused) 720 { 721 722 /* Nothing. */ 723 } 724 725 /* 726 * Test for receiving on stream sockets. The quick summary here is that 727 * recv(MSG_WAITALL) should keep suspending until as many bytes as requested 728 * are also received (or the call is interrupted, or no more can possibly be 729 * received - the meaning of the latter depends on the domain), and, 730 * SO_RCVLOWAT acts as an admission test for the receive: nothing is received 731 * until there are at least as many bytes are available in the receive buffer 732 * as the low receive watermark, or the whole receive request length, whichever 733 * is smaller. In addition, select(2) should use the same threshold. 734 */ 735 #define MAX_BYTES 2 /* set to 3 for slightly better(?) testing */ 736 #define USLEEP_TIME 250000 /* increase on wimpy platforms if needed */ 737 738 static void 739 socklib_stream_recv_sub(int (* socket_pair)(int, int, int, int *), int domain, 740 int type, int idata, int istate, int rlowat, int len, int bits, 741 int act, int (* break_recv)(int, const char *, size_t)) 742 { 743 const char *data = "ABCDE"; /* this limits MAX_BYTES to 3 */ 744 struct sigaction sa; 745 struct timeval tv; 746 fd_set fds; 747 char buf[3]; 748 pid_t pid; 749 int fd[2], val, flags, min, res, err; 750 int pfd[2], edata, tstate, fl, status; 751 752 if (socket_pair(domain, type, 0, fd) != 0) e(0); 753 754 /* 755 * Set up the initial condition on the sockets. 756 */ 757 if (idata > 0) 758 if (send(fd[1], data, idata, 0) != idata) e(0); 759 760 switch (istate) { 761 case 0: break; 762 case 1: if (shutdown(fd[0], SHUT_RD) != 0) e(0); break; 763 case 2: if (shutdown(fd[1], SHUT_WR) != 0) e(0); break; 764 case 3: if (close(fd[1]) != 0) e(0); break; 765 } 766 767 /* Set the low receive water mark. */ 768 if (setsockopt(fd[0], SOL_SOCKET, SO_RCVLOWAT, &rlowat, 769 sizeof(rlowat)) != 0) e(0); 770 771 /* SO_RCVLOWAT is always bounded by the actual receive length. */ 772 min = MIN(len, rlowat); 773 774 /* 775 * Do a quick select test to see if its result indeed matches whether 776 * the available data in the receive buffer meets the threshold. 777 */ 778 FD_ZERO(&fds); 779 FD_SET(fd[0], &fds); 780 tv.tv_sec = 0; 781 tv.tv_usec = 0; 782 res = select(fd[0] + 1, &fds, NULL, NULL, &tv); 783 if (res < 0 || res > 1) e(0); 784 if (res != (idata >= rlowat || istate > 0)) e(0); 785 if (res == 1 && !FD_ISSET(fd[0], &fds)) e(0); 786 787 /* Also do a quick test for ioctl(FIONREAD). */ 788 if (ioctl(fd[0], FIONREAD, &val) != 0) e(0); 789 if (val != ((istate != 1) ? idata : 0)) e(0); 790 791 /* Translate the given bits to receive call flags. */ 792 flags = 0; 793 if (bits & 1) flags |= MSG_PEEK; 794 if (bits & 2) flags |= MSG_DONTWAIT; 795 if (bits & 4) flags |= MSG_WAITALL; 796 797 /* 798 * Cut short a whole lot of cases, to avoid the overhead of forking, 799 * namely when we know the call should return immediately. This is 800 * the case when MSG_DONTWAIT is set, or if a termination condition has 801 * been raised, or if enough initial data are available to meet the 802 * conditions for the receive call. 803 */ 804 if ((flags & MSG_DONTWAIT) || istate > 0 || (idata >= min && 805 ((flags & (MSG_PEEK | MSG_WAITALL)) != MSG_WAITALL || 806 idata >= len))) { 807 res = recv(fd[0], buf, len, flags); 808 809 if (res == -1 && errno != EWOULDBLOCK) e(0); 810 811 /* 812 * If the socket has been shutdown locally, we will never get 813 * anything but zero. Otherwise, if we meet the SO_RCVLOWAT 814 * test, we should have received as much as was available and 815 * requested. Otherwise, if the remote end has been shut down 816 * or closed, we expected to get any available data or 817 * otherwise EOF (implied with idata==0). If none of these 818 * cases apply, we should have gotten EWOULDBLOCK. 819 */ 820 if (istate == 1) { 821 if (res != 0) e(0); 822 } else if (idata >= min) { 823 if (res != MIN(len, idata)) e(0); 824 if (strncmp(buf, data, res)) e(0); 825 } else if (istate > 0) { 826 if (res != idata) e(0); 827 if (strncmp(buf, data, res)) e(0); 828 } else 829 if (res != -1) e(0); 830 831 /* Early cleanup and return to avoid even more code clutter. */ 832 if (istate != 3 && close(fd[1]) != 0) e(0); 833 if (close(fd[0]) != 0) e(0); 834 835 return; 836 } 837 838 /* 839 * Now starts the interesting stuff: the receive call should now block, 840 * even though if we add MSG_DONTWAIT it may not return EWOULDBLOCK, 841 * because MSG_DONTWAIT overrides MSG_WAITALL. As such, we can only 842 * test our expectations by actually letting the call block, in a child 843 * process, and waiting. We do test as much of the above assumption as 844 * we can just for safety right here, but this is not a substitute for 845 * actually blocking even in these cases! 846 */ 847 if (!(flags & MSG_WAITALL)) { 848 if (recv(fd[0], buf, len, flags | MSG_DONTWAIT) != -1) e(0); 849 if (errno != EWOULDBLOCK) e(0); 850 } 851 852 /* 853 * If (act < 12), we send 0, 1, or 2 extra data bytes before forcing 854 * the receive call to terminate in one of four ways. 855 * 856 * If (act == 12), we use a signal to interrupt the receive call. 857 */ 858 if (act < 12) { 859 edata = act % 3; 860 tstate = act / 3; 861 } else 862 edata = tstate = 0; 863 864 if (pipe2(pfd, O_NONBLOCK) != 0) e(0); 865 866 pid = fork(); 867 switch (pid) { 868 case 0: 869 errct = 0; 870 871 if (close(fd[1]) != 0) e(0); 872 if (close(pfd[0]) != 0) e(0); 873 874 if (act == 12) { 875 memset(&sa, 0, sizeof(sa)); 876 sa.sa_handler = socklib_got_signal; 877 if (sigaction(SIGUSR1, &sa, NULL) != 0) e(0); 878 } 879 880 res = recv(fd[0], buf, len, flags); 881 err = errno; 882 883 if (write(pfd[1], &res, sizeof(res)) != sizeof(res)) e(0); 884 if (write(pfd[1], &err, sizeof(err)) != sizeof(err)) e(0); 885 886 if (res > 0 && strncmp(buf, data, res)) e(0); 887 888 exit(errct); 889 case -1: 890 e(0); 891 } 892 893 if (close(pfd[1]) != 0) e(0); 894 895 /* 896 * Allow the child to enter the blocking recv(2), and check the pipe 897 * to see if it is really blocked. 898 */ 899 if (usleep(USLEEP_TIME) != 0) e(0); 900 901 if (read(pfd[0], buf, 1) != -1) e(0); 902 if (errno != EAGAIN) e(0); 903 904 if (edata > 0) { 905 if (send(fd[1], &data[idata], edata, 0) != edata) e(0); 906 907 /* 908 * The threshold for the receive is now met if both the minimum 909 * is met and MSG_WAITALL was not set (or overridden by 910 * MSG_PEEK) or the entire request has been satisfied. 911 */ 912 if (idata + edata >= min && 913 ((flags & (MSG_PEEK | MSG_WAITALL)) != MSG_WAITALL || 914 idata + edata >= len)) { 915 if ((fl = fcntl(pfd[0], F_GETFL, 0)) == -1) e(0); 916 if (fcntl(pfd[0], F_SETFL, fl & ~O_NONBLOCK) != 0) 917 e(0); 918 919 if (read(pfd[0], &res, sizeof(res)) != sizeof(res)) 920 e(0); 921 if (read(pfd[0], &err, sizeof(err)) != sizeof(err)) 922 e(0); 923 924 if (res != MIN(idata + edata, len)) e(0); 925 926 /* Bail out. */ 927 goto cleanup; 928 } 929 930 /* Sleep and test once more. */ 931 if (usleep(USLEEP_TIME) != 0) e(0); 932 933 if (read(pfd[0], buf, 1) != -1) e(0); 934 if (errno != EAGAIN) e(0); 935 } 936 937 if (act < 12) { 938 /* 939 * Now test various ways to terminate the receive call. 940 */ 941 switch (tstate) { 942 case 0: if (shutdown(fd[0], SHUT_RD) != 0) e(0); break; 943 case 1: if (shutdown(fd[1], SHUT_WR) != 0) e(0); break; 944 case 2: if (close(fd[1]) != 0) e(0); fd[1] = -1; break; 945 case 3: fd[1] = break_recv(fd[1], data, strlen(data)); break; 946 } 947 } else 948 if (kill(pid, SIGUSR1) != 0) e(0); 949 950 if ((fl = fcntl(pfd[0], F_GETFL, 0)) == -1) e(0); 951 if (fcntl(pfd[0], F_SETFL, fl & ~O_NONBLOCK) != 0) e(0); 952 953 if (read(pfd[0], &res, sizeof(res)) != sizeof(res)) e(0); 954 if (read(pfd[0], &err, sizeof(err)) != sizeof(err)) e(0); 955 956 if (act < 12) { 957 /* 958 * If there were any data we should have received them now; 959 * after all the receive minimum stops being relevant when 960 * another condition has been raised. There is one exception: 961 * if the receive threshold was never met and we now shut down 962 * the socket for reading, EOF is acceptable as return value. 963 */ 964 if (tstate == 0 && idata + edata < min) { 965 if (res != 0) e(0); 966 } else if (idata + edata > 0) { 967 if (res != MIN(idata + edata, len)) e(0); 968 } else if (tstate == 3) { 969 if (fd[1] == -1) { 970 if (res != -1) e(0); 971 if (err != ECONNRESET) e(0); 972 } else 973 if (res != len) e(0); 974 } else 975 if (res != 0) e(0); 976 } else { 977 /* 978 * If the receive met the threshold before being interrupted, 979 * we should have received at least something. Otherwise, the 980 * receive was never admitted and should just return EINTR. 981 */ 982 if (idata >= min) { 983 if (res != MIN(idata, len)) e(0); 984 } else { 985 if (res != -1) e(0); 986 if (err != EINTR) e(0); 987 } 988 } 989 990 cleanup: 991 if (close(pfd[0]) != 0) e(0); 992 993 if (wait(&status) != pid) e(0); 994 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) e(0); 995 996 if (fd[1] != -1 && close(fd[1]) != 0) e(0); 997 if (close(fd[0]) != 0) e(0); 998 } 999 1000 /* 1001 * Test for receiving on stream sockets. In particular, test SO_RCVLOWAT, 1002 * MSG_PEEK, MSG_DONTWAIT, and MSG_WAITALL. 1003 */ 1004 void 1005 socklib_stream_recv(int (* socket_pair)(int, int, int, int *), int domain, 1006 int type, int (* break_recv)(int, const char *, size_t)) 1007 { 1008 int idata, istate, rlowat, len, bits, act; 1009 1010 /* Insanity. */ 1011 for (idata = 0; idata <= MAX_BYTES; idata++) 1012 for (istate = 0; istate <= 3; istate++) 1013 for (rlowat = 1; rlowat <= MAX_BYTES; rlowat++) 1014 for (len = 1; len <= MAX_BYTES; len++) 1015 for (bits = 0; bits < 8; bits++) 1016 for (act = 0; act <= 12; act++) 1017 socklib_stream_recv_sub 1018 (socket_pair, 1019 domain, type, 1020 idata, istate, 1021 rlowat, len, bits, 1022 act, break_recv); 1023 } 1024