1 // SPDX-License-Identifier: GPL-2.0 2 3 #define _GNU_SOURCE 4 5 #include <errno.h> 6 #include <limits.h> 7 #include <fcntl.h> 8 #include <string.h> 9 #include <stdarg.h> 10 #include <stdbool.h> 11 #include <stdint.h> 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <strings.h> 15 #include <signal.h> 16 #include <unistd.h> 17 #include <time.h> 18 19 #include <sys/poll.h> 20 #include <sys/sendfile.h> 21 #include <sys/stat.h> 22 #include <sys/socket.h> 23 #include <sys/types.h> 24 #include <sys/mman.h> 25 26 #include <netdb.h> 27 #include <netinet/in.h> 28 29 #include <linux/tcp.h> 30 #include <linux/time_types.h> 31 32 extern int optind; 33 34 #ifndef IPPROTO_MPTCP 35 #define IPPROTO_MPTCP 262 36 #endif 37 #ifndef TCP_ULP 38 #define TCP_ULP 31 39 #endif 40 41 static int poll_timeout = 10 * 1000; 42 static bool listen_mode; 43 static bool quit; 44 45 enum cfg_mode { 46 CFG_MODE_POLL, 47 CFG_MODE_MMAP, 48 CFG_MODE_SENDFILE, 49 }; 50 51 enum cfg_peek { 52 CFG_NONE_PEEK, 53 CFG_WITH_PEEK, 54 CFG_AFTER_PEEK, 55 }; 56 57 static enum cfg_mode cfg_mode = CFG_MODE_POLL; 58 static enum cfg_peek cfg_peek = CFG_NONE_PEEK; 59 static const char *cfg_host; 60 static const char *cfg_port = "12000"; 61 static int cfg_sock_proto = IPPROTO_MPTCP; 62 static bool tcpulp_audit; 63 static int pf = AF_INET; 64 static int cfg_sndbuf; 65 static int cfg_rcvbuf; 66 static bool cfg_join; 67 static bool cfg_remove; 68 static unsigned int cfg_time; 69 static unsigned int cfg_do_w; 70 static int cfg_wait; 71 static uint32_t cfg_mark; 72 73 struct cfg_cmsg_types { 74 unsigned int cmsg_enabled:1; 75 unsigned int timestampns:1; 76 }; 77 78 static struct cfg_cmsg_types cfg_cmsg_types; 79 80 static void die_usage(void) 81 { 82 fprintf(stderr, "Usage: mptcp_connect [-6] [-u] [-s MPTCP|TCP] [-p port] [-m mode]" 83 "[-l] [-w sec] [-t num] [-T num] connect_address\n"); 84 fprintf(stderr, "\t-6 use ipv6\n"); 85 fprintf(stderr, "\t-t num -- set poll timeout to num\n"); 86 fprintf(stderr, "\t-T num -- set expected runtime to num ms\n"); 87 fprintf(stderr, "\t-S num -- set SO_SNDBUF to num\n"); 88 fprintf(stderr, "\t-R num -- set SO_RCVBUF to num\n"); 89 fprintf(stderr, "\t-p num -- use port num\n"); 90 fprintf(stderr, "\t-s [MPTCP|TCP] -- use mptcp(default) or tcp sockets\n"); 91 fprintf(stderr, "\t-m [poll|mmap|sendfile] -- use poll(default)/mmap+write/sendfile\n"); 92 fprintf(stderr, "\t-M mark -- set socket packet mark\n"); 93 fprintf(stderr, "\t-u -- check mptcp ulp\n"); 94 fprintf(stderr, "\t-w num -- wait num sec before closing the socket\n"); 95 fprintf(stderr, "\t-c cmsg -- test cmsg type <cmsg>\n"); 96 fprintf(stderr, 97 "\t-P [saveWithPeek|saveAfterPeek] -- save data with/after MSG_PEEK form tcp socket\n"); 98 exit(1); 99 } 100 101 static void xerror(const char *fmt, ...) 102 { 103 va_list ap; 104 105 va_start(ap, fmt); 106 vfprintf(stderr, fmt, ap); 107 va_end(ap); 108 exit(1); 109 } 110 111 static void handle_signal(int nr) 112 { 113 quit = true; 114 } 115 116 static const char *getxinfo_strerr(int err) 117 { 118 if (err == EAI_SYSTEM) 119 return strerror(errno); 120 121 return gai_strerror(err); 122 } 123 124 static void xgetnameinfo(const struct sockaddr *addr, socklen_t addrlen, 125 char *host, socklen_t hostlen, 126 char *serv, socklen_t servlen) 127 { 128 int flags = NI_NUMERICHOST | NI_NUMERICSERV; 129 int err = getnameinfo(addr, addrlen, host, hostlen, serv, servlen, 130 flags); 131 132 if (err) { 133 const char *errstr = getxinfo_strerr(err); 134 135 fprintf(stderr, "Fatal: getnameinfo: %s\n", errstr); 136 exit(1); 137 } 138 } 139 140 static void xgetaddrinfo(const char *node, const char *service, 141 const struct addrinfo *hints, 142 struct addrinfo **res) 143 { 144 int err = getaddrinfo(node, service, hints, res); 145 146 if (err) { 147 const char *errstr = getxinfo_strerr(err); 148 149 fprintf(stderr, "Fatal: getaddrinfo(%s:%s): %s\n", 150 node ? node : "", service ? service : "", errstr); 151 exit(1); 152 } 153 } 154 155 static void set_rcvbuf(int fd, unsigned int size) 156 { 157 int err; 158 159 err = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); 160 if (err) { 161 perror("set SO_RCVBUF"); 162 exit(1); 163 } 164 } 165 166 static void set_sndbuf(int fd, unsigned int size) 167 { 168 int err; 169 170 err = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); 171 if (err) { 172 perror("set SO_SNDBUF"); 173 exit(1); 174 } 175 } 176 177 static void set_mark(int fd, uint32_t mark) 178 { 179 int err; 180 181 err = setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)); 182 if (err) { 183 perror("set SO_MARK"); 184 exit(1); 185 } 186 } 187 188 static int sock_listen_mptcp(const char * const listenaddr, 189 const char * const port) 190 { 191 int sock; 192 struct addrinfo hints = { 193 .ai_protocol = IPPROTO_TCP, 194 .ai_socktype = SOCK_STREAM, 195 .ai_flags = AI_PASSIVE | AI_NUMERICHOST 196 }; 197 198 hints.ai_family = pf; 199 200 struct addrinfo *a, *addr; 201 int one = 1; 202 203 xgetaddrinfo(listenaddr, port, &hints, &addr); 204 hints.ai_family = pf; 205 206 for (a = addr; a; a = a->ai_next) { 207 sock = socket(a->ai_family, a->ai_socktype, cfg_sock_proto); 208 if (sock < 0) 209 continue; 210 211 if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, 212 sizeof(one))) 213 perror("setsockopt"); 214 215 if (bind(sock, a->ai_addr, a->ai_addrlen) == 0) 216 break; /* success */ 217 218 perror("bind"); 219 close(sock); 220 sock = -1; 221 } 222 223 freeaddrinfo(addr); 224 225 if (sock < 0) { 226 fprintf(stderr, "Could not create listen socket\n"); 227 return sock; 228 } 229 230 if (listen(sock, 20)) { 231 perror("listen"); 232 close(sock); 233 return -1; 234 } 235 236 return sock; 237 } 238 239 static bool sock_test_tcpulp(const char * const remoteaddr, 240 const char * const port) 241 { 242 struct addrinfo hints = { 243 .ai_protocol = IPPROTO_TCP, 244 .ai_socktype = SOCK_STREAM, 245 }; 246 struct addrinfo *a, *addr; 247 int sock = -1, ret = 0; 248 bool test_pass = false; 249 250 hints.ai_family = AF_INET; 251 252 xgetaddrinfo(remoteaddr, port, &hints, &addr); 253 for (a = addr; a; a = a->ai_next) { 254 sock = socket(a->ai_family, a->ai_socktype, IPPROTO_TCP); 255 if (sock < 0) { 256 perror("socket"); 257 continue; 258 } 259 ret = setsockopt(sock, IPPROTO_TCP, TCP_ULP, "mptcp", 260 sizeof("mptcp")); 261 if (ret == -1 && errno == EOPNOTSUPP) 262 test_pass = true; 263 close(sock); 264 265 if (test_pass) 266 break; 267 if (!ret) 268 fprintf(stderr, 269 "setsockopt(TCP_ULP) returned 0\n"); 270 else 271 perror("setsockopt(TCP_ULP)"); 272 } 273 return test_pass; 274 } 275 276 static int sock_connect_mptcp(const char * const remoteaddr, 277 const char * const port, int proto) 278 { 279 struct addrinfo hints = { 280 .ai_protocol = IPPROTO_TCP, 281 .ai_socktype = SOCK_STREAM, 282 }; 283 struct addrinfo *a, *addr; 284 int sock = -1; 285 286 hints.ai_family = pf; 287 288 xgetaddrinfo(remoteaddr, port, &hints, &addr); 289 for (a = addr; a; a = a->ai_next) { 290 sock = socket(a->ai_family, a->ai_socktype, proto); 291 if (sock < 0) { 292 perror("socket"); 293 continue; 294 } 295 296 if (cfg_mark) 297 set_mark(sock, cfg_mark); 298 299 if (connect(sock, a->ai_addr, a->ai_addrlen) == 0) 300 break; /* success */ 301 302 perror("connect()"); 303 close(sock); 304 sock = -1; 305 } 306 307 freeaddrinfo(addr); 308 return sock; 309 } 310 311 static size_t do_rnd_write(const int fd, char *buf, const size_t len) 312 { 313 static bool first = true; 314 unsigned int do_w; 315 ssize_t bw; 316 317 do_w = rand() & 0xffff; 318 if (do_w == 0 || do_w > len) 319 do_w = len; 320 321 if (cfg_join && first && do_w > 100) 322 do_w = 100; 323 324 if (cfg_remove && do_w > cfg_do_w) 325 do_w = cfg_do_w; 326 327 bw = write(fd, buf, do_w); 328 if (bw < 0) 329 perror("write"); 330 331 /* let the join handshake complete, before going on */ 332 if (cfg_join && first) { 333 usleep(200000); 334 first = false; 335 } 336 337 if (cfg_remove) 338 usleep(200000); 339 340 return bw; 341 } 342 343 static size_t do_write(const int fd, char *buf, const size_t len) 344 { 345 size_t offset = 0; 346 347 while (offset < len) { 348 size_t written; 349 ssize_t bw; 350 351 bw = write(fd, buf + offset, len - offset); 352 if (bw < 0) { 353 perror("write"); 354 return 0; 355 } 356 357 written = (size_t)bw; 358 offset += written; 359 } 360 361 return offset; 362 } 363 364 static void process_cmsg(struct msghdr *msgh) 365 { 366 struct __kernel_timespec ts; 367 bool ts_found = false; 368 struct cmsghdr *cmsg; 369 370 for (cmsg = CMSG_FIRSTHDR(msgh); cmsg ; cmsg = CMSG_NXTHDR(msgh, cmsg)) { 371 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMPNS_NEW) { 372 memcpy(&ts, CMSG_DATA(cmsg), sizeof(ts)); 373 ts_found = true; 374 continue; 375 } 376 } 377 378 if (cfg_cmsg_types.timestampns) { 379 if (!ts_found) 380 xerror("TIMESTAMPNS not present\n"); 381 } 382 } 383 384 static ssize_t do_recvmsg_cmsg(const int fd, char *buf, const size_t len) 385 { 386 char msg_buf[8192]; 387 struct iovec iov = { 388 .iov_base = buf, 389 .iov_len = len, 390 }; 391 struct msghdr msg = { 392 .msg_iov = &iov, 393 .msg_iovlen = 1, 394 .msg_control = msg_buf, 395 .msg_controllen = sizeof(msg_buf), 396 }; 397 int flags = 0; 398 int ret = recvmsg(fd, &msg, flags); 399 400 if (ret <= 0) 401 return ret; 402 403 if (msg.msg_controllen && !cfg_cmsg_types.cmsg_enabled) 404 xerror("got %lu bytes of cmsg data, expected 0\n", 405 (unsigned long)msg.msg_controllen); 406 407 if (msg.msg_controllen == 0 && cfg_cmsg_types.cmsg_enabled) 408 xerror("%s\n", "got no cmsg data"); 409 410 if (msg.msg_controllen) 411 process_cmsg(&msg); 412 413 return ret; 414 } 415 416 static ssize_t do_rnd_read(const int fd, char *buf, const size_t len) 417 { 418 int ret = 0; 419 char tmp[16384]; 420 size_t cap = rand(); 421 422 cap &= 0xffff; 423 424 if (cap == 0) 425 cap = 1; 426 else if (cap > len) 427 cap = len; 428 429 if (cfg_peek == CFG_WITH_PEEK) { 430 ret = recv(fd, buf, cap, MSG_PEEK); 431 ret = (ret < 0) ? ret : read(fd, tmp, ret); 432 } else if (cfg_peek == CFG_AFTER_PEEK) { 433 ret = recv(fd, buf, cap, MSG_PEEK); 434 ret = (ret < 0) ? ret : read(fd, buf, cap); 435 } else if (cfg_cmsg_types.cmsg_enabled) { 436 ret = do_recvmsg_cmsg(fd, buf, cap); 437 } else { 438 ret = read(fd, buf, cap); 439 } 440 441 return ret; 442 } 443 444 static void set_nonblock(int fd) 445 { 446 int flags = fcntl(fd, F_GETFL); 447 448 if (flags == -1) 449 return; 450 451 fcntl(fd, F_SETFL, flags | O_NONBLOCK); 452 } 453 454 static int copyfd_io_poll(int infd, int peerfd, int outfd, bool *in_closed_after_out) 455 { 456 struct pollfd fds = { 457 .fd = peerfd, 458 .events = POLLIN | POLLOUT, 459 }; 460 unsigned int woff = 0, wlen = 0; 461 char wbuf[8192]; 462 463 set_nonblock(peerfd); 464 465 for (;;) { 466 char rbuf[8192]; 467 ssize_t len; 468 469 if (fds.events == 0) 470 break; 471 472 switch (poll(&fds, 1, poll_timeout)) { 473 case -1: 474 if (errno == EINTR) 475 continue; 476 perror("poll"); 477 return 1; 478 case 0: 479 fprintf(stderr, "%s: poll timed out (events: " 480 "POLLIN %u, POLLOUT %u)\n", __func__, 481 fds.events & POLLIN, fds.events & POLLOUT); 482 return 2; 483 } 484 485 if (fds.revents & POLLIN) { 486 len = do_rnd_read(peerfd, rbuf, sizeof(rbuf)); 487 if (len == 0) { 488 /* no more data to receive: 489 * peer has closed its write side 490 */ 491 fds.events &= ~POLLIN; 492 493 if ((fds.events & POLLOUT) == 0) { 494 *in_closed_after_out = true; 495 /* and nothing more to send */ 496 break; 497 } 498 499 /* Else, still have data to transmit */ 500 } else if (len < 0) { 501 perror("read"); 502 return 3; 503 } 504 505 do_write(outfd, rbuf, len); 506 } 507 508 if (fds.revents & POLLOUT) { 509 if (wlen == 0) { 510 woff = 0; 511 wlen = read(infd, wbuf, sizeof(wbuf)); 512 } 513 514 if (wlen > 0) { 515 ssize_t bw; 516 517 bw = do_rnd_write(peerfd, wbuf + woff, wlen); 518 if (bw < 0) 519 return 111; 520 521 woff += bw; 522 wlen -= bw; 523 } else if (wlen == 0) { 524 /* We have no more data to send. */ 525 fds.events &= ~POLLOUT; 526 527 if ((fds.events & POLLIN) == 0) 528 /* ... and peer also closed already */ 529 break; 530 531 /* ... but we still receive. 532 * Close our write side, ev. give some time 533 * for address notification and/or checking 534 * the current status 535 */ 536 if (cfg_wait) 537 usleep(cfg_wait); 538 shutdown(peerfd, SHUT_WR); 539 } else { 540 if (errno == EINTR) 541 continue; 542 perror("read"); 543 return 4; 544 } 545 } 546 547 if (fds.revents & (POLLERR | POLLNVAL)) { 548 fprintf(stderr, "Unexpected revents: " 549 "POLLERR/POLLNVAL(%x)\n", fds.revents); 550 return 5; 551 } 552 } 553 554 /* leave some time for late join/announce */ 555 if (cfg_remove) 556 usleep(cfg_wait); 557 558 close(peerfd); 559 return 0; 560 } 561 562 static int do_recvfile(int infd, int outfd) 563 { 564 ssize_t r; 565 566 do { 567 char buf[16384]; 568 569 r = do_rnd_read(infd, buf, sizeof(buf)); 570 if (r > 0) { 571 if (write(outfd, buf, r) != r) 572 break; 573 } else if (r < 0) { 574 perror("read"); 575 } 576 } while (r > 0); 577 578 return (int)r; 579 } 580 581 static int do_mmap(int infd, int outfd, unsigned int size) 582 { 583 char *inbuf = mmap(NULL, size, PROT_READ, MAP_SHARED, infd, 0); 584 ssize_t ret = 0, off = 0; 585 size_t rem; 586 587 if (inbuf == MAP_FAILED) { 588 perror("mmap"); 589 return 1; 590 } 591 592 rem = size; 593 594 while (rem > 0) { 595 ret = write(outfd, inbuf + off, rem); 596 597 if (ret < 0) { 598 perror("write"); 599 break; 600 } 601 602 off += ret; 603 rem -= ret; 604 } 605 606 munmap(inbuf, size); 607 return rem; 608 } 609 610 static int get_infd_size(int fd) 611 { 612 struct stat sb; 613 ssize_t count; 614 int err; 615 616 err = fstat(fd, &sb); 617 if (err < 0) { 618 perror("fstat"); 619 return -1; 620 } 621 622 if ((sb.st_mode & S_IFMT) != S_IFREG) { 623 fprintf(stderr, "%s: stdin is not a regular file\n", __func__); 624 return -2; 625 } 626 627 count = sb.st_size; 628 if (count > INT_MAX) { 629 fprintf(stderr, "File too large: %zu\n", count); 630 return -3; 631 } 632 633 return (int)count; 634 } 635 636 static int do_sendfile(int infd, int outfd, unsigned int count) 637 { 638 while (count > 0) { 639 ssize_t r; 640 641 r = sendfile(outfd, infd, NULL, count); 642 if (r < 0) { 643 perror("sendfile"); 644 return 3; 645 } 646 647 count -= r; 648 } 649 650 return 0; 651 } 652 653 static int copyfd_io_mmap(int infd, int peerfd, int outfd, 654 unsigned int size, bool *in_closed_after_out) 655 { 656 int err; 657 658 if (listen_mode) { 659 err = do_recvfile(peerfd, outfd); 660 if (err) 661 return err; 662 663 err = do_mmap(infd, peerfd, size); 664 } else { 665 err = do_mmap(infd, peerfd, size); 666 if (err) 667 return err; 668 669 shutdown(peerfd, SHUT_WR); 670 671 err = do_recvfile(peerfd, outfd); 672 *in_closed_after_out = true; 673 } 674 675 return err; 676 } 677 678 static int copyfd_io_sendfile(int infd, int peerfd, int outfd, 679 unsigned int size, bool *in_closed_after_out) 680 { 681 int err; 682 683 if (listen_mode) { 684 err = do_recvfile(peerfd, outfd); 685 if (err) 686 return err; 687 688 err = do_sendfile(infd, peerfd, size); 689 } else { 690 err = do_sendfile(infd, peerfd, size); 691 if (err) 692 return err; 693 err = do_recvfile(peerfd, outfd); 694 *in_closed_after_out = true; 695 } 696 697 return err; 698 } 699 700 static int copyfd_io(int infd, int peerfd, int outfd) 701 { 702 bool in_closed_after_out = false; 703 struct timespec start, end; 704 int file_size; 705 int ret; 706 707 if (cfg_time && (clock_gettime(CLOCK_MONOTONIC, &start) < 0)) 708 xerror("can not fetch start time %d", errno); 709 710 switch (cfg_mode) { 711 case CFG_MODE_POLL: 712 ret = copyfd_io_poll(infd, peerfd, outfd, &in_closed_after_out); 713 break; 714 715 case CFG_MODE_MMAP: 716 file_size = get_infd_size(infd); 717 if (file_size < 0) 718 return file_size; 719 ret = copyfd_io_mmap(infd, peerfd, outfd, file_size, &in_closed_after_out); 720 break; 721 722 case CFG_MODE_SENDFILE: 723 file_size = get_infd_size(infd); 724 if (file_size < 0) 725 return file_size; 726 ret = copyfd_io_sendfile(infd, peerfd, outfd, file_size, &in_closed_after_out); 727 break; 728 729 default: 730 fprintf(stderr, "Invalid mode %d\n", cfg_mode); 731 732 die_usage(); 733 return 1; 734 } 735 736 if (ret) 737 return ret; 738 739 if (cfg_time) { 740 unsigned int delta_ms; 741 742 if (clock_gettime(CLOCK_MONOTONIC, &end) < 0) 743 xerror("can not fetch end time %d", errno); 744 delta_ms = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000; 745 if (delta_ms > cfg_time) { 746 xerror("transfer slower than expected! runtime %d ms, expected %d ms", 747 delta_ms, cfg_time); 748 } 749 750 /* show the runtime only if this end shutdown(wr) before receiving the EOF, 751 * (that is, if this end got the longer runtime) 752 */ 753 if (in_closed_after_out) 754 fprintf(stderr, "%d", delta_ms); 755 } 756 757 return 0; 758 } 759 760 static void check_sockaddr(int pf, struct sockaddr_storage *ss, 761 socklen_t salen) 762 { 763 struct sockaddr_in6 *sin6; 764 struct sockaddr_in *sin; 765 socklen_t wanted_size = 0; 766 767 switch (pf) { 768 case AF_INET: 769 wanted_size = sizeof(*sin); 770 sin = (void *)ss; 771 if (!sin->sin_port) 772 fprintf(stderr, "accept: something wrong: ip connection from port 0"); 773 break; 774 case AF_INET6: 775 wanted_size = sizeof(*sin6); 776 sin6 = (void *)ss; 777 if (!sin6->sin6_port) 778 fprintf(stderr, "accept: something wrong: ipv6 connection from port 0"); 779 break; 780 default: 781 fprintf(stderr, "accept: Unknown pf %d, salen %u\n", pf, salen); 782 return; 783 } 784 785 if (salen != wanted_size) 786 fprintf(stderr, "accept: size mismatch, got %d expected %d\n", 787 (int)salen, wanted_size); 788 789 if (ss->ss_family != pf) 790 fprintf(stderr, "accept: pf mismatch, expect %d, ss_family is %d\n", 791 (int)ss->ss_family, pf); 792 } 793 794 static void check_getpeername(int fd, struct sockaddr_storage *ss, socklen_t salen) 795 { 796 struct sockaddr_storage peerss; 797 socklen_t peersalen = sizeof(peerss); 798 799 if (getpeername(fd, (struct sockaddr *)&peerss, &peersalen) < 0) { 800 perror("getpeername"); 801 return; 802 } 803 804 if (peersalen != salen) { 805 fprintf(stderr, "%s: %d vs %d\n", __func__, peersalen, salen); 806 return; 807 } 808 809 if (memcmp(ss, &peerss, peersalen)) { 810 char a[INET6_ADDRSTRLEN]; 811 char b[INET6_ADDRSTRLEN]; 812 char c[INET6_ADDRSTRLEN]; 813 char d[INET6_ADDRSTRLEN]; 814 815 xgetnameinfo((struct sockaddr *)ss, salen, 816 a, sizeof(a), b, sizeof(b)); 817 818 xgetnameinfo((struct sockaddr *)&peerss, peersalen, 819 c, sizeof(c), d, sizeof(d)); 820 821 fprintf(stderr, "%s: memcmp failure: accept %s vs peername %s, %s vs %s salen %d vs %d\n", 822 __func__, a, c, b, d, peersalen, salen); 823 } 824 } 825 826 static void check_getpeername_connect(int fd) 827 { 828 struct sockaddr_storage ss; 829 socklen_t salen = sizeof(ss); 830 char a[INET6_ADDRSTRLEN]; 831 char b[INET6_ADDRSTRLEN]; 832 833 if (getpeername(fd, (struct sockaddr *)&ss, &salen) < 0) { 834 perror("getpeername"); 835 return; 836 } 837 838 xgetnameinfo((struct sockaddr *)&ss, salen, 839 a, sizeof(a), b, sizeof(b)); 840 841 if (strcmp(cfg_host, a) || strcmp(cfg_port, b)) 842 fprintf(stderr, "%s: %s vs %s, %s vs %s\n", __func__, 843 cfg_host, a, cfg_port, b); 844 } 845 846 static void maybe_close(int fd) 847 { 848 unsigned int r = rand(); 849 850 if (!(cfg_join || cfg_remove) && (r & 1)) 851 close(fd); 852 } 853 854 int main_loop_s(int listensock) 855 { 856 struct sockaddr_storage ss; 857 struct pollfd polls; 858 socklen_t salen; 859 int remotesock; 860 861 polls.fd = listensock; 862 polls.events = POLLIN; 863 864 switch (poll(&polls, 1, poll_timeout)) { 865 case -1: 866 perror("poll"); 867 return 1; 868 case 0: 869 fprintf(stderr, "%s: timed out\n", __func__); 870 close(listensock); 871 return 2; 872 } 873 874 salen = sizeof(ss); 875 remotesock = accept(listensock, (struct sockaddr *)&ss, &salen); 876 if (remotesock >= 0) { 877 maybe_close(listensock); 878 check_sockaddr(pf, &ss, salen); 879 check_getpeername(remotesock, &ss, salen); 880 881 return copyfd_io(0, remotesock, 1); 882 } 883 884 perror("accept"); 885 886 return 1; 887 } 888 889 static void init_rng(void) 890 { 891 int fd = open("/dev/urandom", O_RDONLY); 892 unsigned int foo; 893 894 if (fd > 0) { 895 int ret = read(fd, &foo, sizeof(foo)); 896 897 if (ret < 0) 898 srand(fd + foo); 899 close(fd); 900 } 901 902 srand(foo); 903 } 904 905 static void xsetsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen) 906 { 907 int err; 908 909 err = setsockopt(fd, level, optname, optval, optlen); 910 if (err) { 911 perror("setsockopt"); 912 exit(1); 913 } 914 } 915 916 static void apply_cmsg_types(int fd, const struct cfg_cmsg_types *cmsg) 917 { 918 static const unsigned int on = 1; 919 920 if (cmsg->timestampns) 921 xsetsockopt(fd, SOL_SOCKET, SO_TIMESTAMPNS_NEW, &on, sizeof(on)); 922 } 923 924 static void parse_cmsg_types(const char *type) 925 { 926 char *next = strchr(type, ','); 927 unsigned int len = 0; 928 929 cfg_cmsg_types.cmsg_enabled = 1; 930 931 if (next) { 932 parse_cmsg_types(next + 1); 933 len = next - type; 934 } else { 935 len = strlen(type); 936 } 937 938 if (strncmp(type, "TIMESTAMPNS", len) == 0) { 939 cfg_cmsg_types.timestampns = 1; 940 return; 941 } 942 943 fprintf(stderr, "Unrecognized cmsg option %s\n", type); 944 exit(1); 945 } 946 947 int main_loop(void) 948 { 949 int fd; 950 951 /* listener is ready. */ 952 fd = sock_connect_mptcp(cfg_host, cfg_port, cfg_sock_proto); 953 if (fd < 0) 954 return 2; 955 956 check_getpeername_connect(fd); 957 958 if (cfg_rcvbuf) 959 set_rcvbuf(fd, cfg_rcvbuf); 960 if (cfg_sndbuf) 961 set_sndbuf(fd, cfg_sndbuf); 962 if (cfg_cmsg_types.cmsg_enabled) 963 apply_cmsg_types(fd, &cfg_cmsg_types); 964 965 return copyfd_io(0, fd, 1); 966 } 967 968 int parse_proto(const char *proto) 969 { 970 if (!strcasecmp(proto, "MPTCP")) 971 return IPPROTO_MPTCP; 972 if (!strcasecmp(proto, "TCP")) 973 return IPPROTO_TCP; 974 975 fprintf(stderr, "Unknown protocol: %s\n.", proto); 976 die_usage(); 977 978 /* silence compiler warning */ 979 return 0; 980 } 981 982 int parse_mode(const char *mode) 983 { 984 if (!strcasecmp(mode, "poll")) 985 return CFG_MODE_POLL; 986 if (!strcasecmp(mode, "mmap")) 987 return CFG_MODE_MMAP; 988 if (!strcasecmp(mode, "sendfile")) 989 return CFG_MODE_SENDFILE; 990 991 fprintf(stderr, "Unknown test mode: %s\n", mode); 992 fprintf(stderr, "Supported modes are:\n"); 993 fprintf(stderr, "\t\t\"poll\" - interleaved read/write using poll()\n"); 994 fprintf(stderr, "\t\t\"mmap\" - send entire input file (mmap+write), then read response (-l will read input first)\n"); 995 fprintf(stderr, "\t\t\"sendfile\" - send entire input file (sendfile), then read response (-l will read input first)\n"); 996 997 die_usage(); 998 999 /* silence compiler warning */ 1000 return 0; 1001 } 1002 1003 int parse_peek(const char *mode) 1004 { 1005 if (!strcasecmp(mode, "saveWithPeek")) 1006 return CFG_WITH_PEEK; 1007 if (!strcasecmp(mode, "saveAfterPeek")) 1008 return CFG_AFTER_PEEK; 1009 1010 fprintf(stderr, "Unknown: %s\n", mode); 1011 fprintf(stderr, "Supported MSG_PEEK mode are:\n"); 1012 fprintf(stderr, 1013 "\t\t\"saveWithPeek\" - recv data with flags 'MSG_PEEK' and save the peek data into file\n"); 1014 fprintf(stderr, 1015 "\t\t\"saveAfterPeek\" - read and save data into file after recv with flags 'MSG_PEEK'\n"); 1016 1017 die_usage(); 1018 1019 /* silence compiler warning */ 1020 return 0; 1021 } 1022 1023 static int parse_int(const char *size) 1024 { 1025 unsigned long s; 1026 1027 errno = 0; 1028 1029 s = strtoul(size, NULL, 0); 1030 1031 if (errno) { 1032 fprintf(stderr, "Invalid sndbuf size %s (%s)\n", 1033 size, strerror(errno)); 1034 die_usage(); 1035 } 1036 1037 if (s > INT_MAX) { 1038 fprintf(stderr, "Invalid sndbuf size %s (%s)\n", 1039 size, strerror(ERANGE)); 1040 die_usage(); 1041 } 1042 1043 return (int)s; 1044 } 1045 1046 static void parse_opts(int argc, char **argv) 1047 { 1048 int c; 1049 1050 while ((c = getopt(argc, argv, "6jr:lp:s:hut:T:m:S:R:w:M:P:c:")) != -1) { 1051 switch (c) { 1052 case 'j': 1053 cfg_join = true; 1054 cfg_mode = CFG_MODE_POLL; 1055 break; 1056 case 'r': 1057 cfg_remove = true; 1058 cfg_mode = CFG_MODE_POLL; 1059 cfg_wait = 400000; 1060 cfg_do_w = atoi(optarg); 1061 if (cfg_do_w <= 0) 1062 cfg_do_w = 50; 1063 break; 1064 case 'l': 1065 listen_mode = true; 1066 break; 1067 case 'p': 1068 cfg_port = optarg; 1069 break; 1070 case 's': 1071 cfg_sock_proto = parse_proto(optarg); 1072 break; 1073 case 'h': 1074 die_usage(); 1075 break; 1076 case 'u': 1077 tcpulp_audit = true; 1078 break; 1079 case '6': 1080 pf = AF_INET6; 1081 break; 1082 case 't': 1083 poll_timeout = atoi(optarg) * 1000; 1084 if (poll_timeout <= 0) 1085 poll_timeout = -1; 1086 break; 1087 case 'T': 1088 cfg_time = atoi(optarg); 1089 break; 1090 case 'm': 1091 cfg_mode = parse_mode(optarg); 1092 break; 1093 case 'S': 1094 cfg_sndbuf = parse_int(optarg); 1095 break; 1096 case 'R': 1097 cfg_rcvbuf = parse_int(optarg); 1098 break; 1099 case 'w': 1100 cfg_wait = atoi(optarg)*1000000; 1101 break; 1102 case 'M': 1103 cfg_mark = strtol(optarg, NULL, 0); 1104 break; 1105 case 'P': 1106 cfg_peek = parse_peek(optarg); 1107 break; 1108 case 'c': 1109 parse_cmsg_types(optarg); 1110 break; 1111 } 1112 } 1113 1114 if (optind + 1 != argc) 1115 die_usage(); 1116 cfg_host = argv[optind]; 1117 1118 if (strchr(cfg_host, ':')) 1119 pf = AF_INET6; 1120 } 1121 1122 int main(int argc, char *argv[]) 1123 { 1124 init_rng(); 1125 1126 signal(SIGUSR1, handle_signal); 1127 parse_opts(argc, argv); 1128 1129 if (tcpulp_audit) 1130 return sock_test_tcpulp(cfg_host, cfg_port) ? 0 : 1; 1131 1132 if (listen_mode) { 1133 int fd = sock_listen_mptcp(cfg_host, cfg_port); 1134 1135 if (fd < 0) 1136 return 1; 1137 1138 if (cfg_rcvbuf) 1139 set_rcvbuf(fd, cfg_rcvbuf); 1140 if (cfg_sndbuf) 1141 set_sndbuf(fd, cfg_sndbuf); 1142 if (cfg_mark) 1143 set_mark(fd, cfg_mark); 1144 if (cfg_cmsg_types.cmsg_enabled) 1145 apply_cmsg_types(fd, &cfg_cmsg_types); 1146 1147 return main_loop_s(fd); 1148 } 1149 1150 return main_loop(); 1151 } 1152