|
27 | 27 | #include <netinet/in.h> |
28 | 28 |
|
29 | 29 | #include <linux/tcp.h> |
| 30 | +#include <linux/sockios.h> |
30 | 31 |
|
31 | 32 | static int pf = AF_INET; |
32 | 33 | static int proto_tx = IPPROTO_MPTCP; |
@@ -660,6 +661,116 @@ static void connect_one_server(int fd, int pipefd) |
660 | 661 | close(fd); |
661 | 662 | } |
662 | 663 |
|
| 664 | +/* wait up to timeout milliseconds */ |
| 665 | +static void wait_for_ack(int fd, int timeout, size_t total) |
| 666 | +{ |
| 667 | + int i; |
| 668 | + |
| 669 | + for (i = 0; i < timeout; i++) { |
| 670 | + int nsd, ret, queued = -1; |
| 671 | + struct timespec req; |
| 672 | + |
| 673 | + ret = ioctl(fd, TIOCOUTQ, &queued); |
| 674 | + if (ret < 0) |
| 675 | + die_perror("TIOCOUTQ"); |
| 676 | + |
| 677 | + ret = ioctl(fd, SIOCOUTQNSD, &nsd); |
| 678 | + if (ret < 0) |
| 679 | + die_perror("SIOCOUTQNSD"); |
| 680 | + |
| 681 | + if ((size_t)queued > total) |
| 682 | + xerror("TIOCOUTQ %u, but only %zu expected\n", queued, total); |
| 683 | + assert(nsd <= queued); |
| 684 | + |
| 685 | + if (queued == 0) |
| 686 | + return; |
| 687 | + |
| 688 | + /* wait for peer to ack rx of all data */ |
| 689 | + req.tv_sec = 0; |
| 690 | + req.tv_nsec = 1 * 1000 * 1000ul; /* 1ms */ |
| 691 | + nanosleep(&req, NULL); |
| 692 | + } |
| 693 | + |
| 694 | + xerror("still tx data queued after %u ms\n", timeout); |
| 695 | +} |
| 696 | + |
| 697 | +static void connect_one_server_inq(int fd, int unixfd) |
| 698 | +{ |
| 699 | + size_t len, i, total, sent; |
| 700 | + char buf[4096], buf2[4096]; |
| 701 | + ssize_t ret; |
| 702 | + |
| 703 | + len = rand() % (sizeof(buf) - 1); |
| 704 | + |
| 705 | + if (len < 128) |
| 706 | + len = 128; |
| 707 | + |
| 708 | + for (i = 0; i < len ; i++) { |
| 709 | + buf[i] = rand() % 26; |
| 710 | + buf[i] += 'A'; |
| 711 | + } |
| 712 | + |
| 713 | + buf[i] = '\n'; |
| 714 | + |
| 715 | + /* un-block server */ |
| 716 | + ret = read(unixfd, buf2, 4); |
| 717 | + assert(ret == 4); |
| 718 | + |
| 719 | + assert(strncmp(buf2, "xmit", 4) == 0); |
| 720 | + |
| 721 | + ret = write(unixfd, &len, sizeof(len)); |
| 722 | + assert(ret == (ssize_t)sizeof(len)); |
| 723 | + |
| 724 | + ret = write(fd, buf, len); |
| 725 | + if (ret < 0) |
| 726 | + die_perror("write"); |
| 727 | + |
| 728 | + if (ret != (ssize_t)len) |
| 729 | + xerror("short write"); |
| 730 | + |
| 731 | + ret = read(unixfd, buf2, 4); |
| 732 | + assert(strncmp(buf2, "huge", 4) == 0); |
| 733 | + |
| 734 | + total = rand() % (16 * 1024 * 1024); |
| 735 | + total += (1 * 1024 * 1024); |
| 736 | + sent = total; |
| 737 | + |
| 738 | + ret = write(unixfd, &total, sizeof(total)); |
| 739 | + assert(ret == (ssize_t)sizeof(total)); |
| 740 | + |
| 741 | + wait_for_ack(fd, 5000, len); |
| 742 | + |
| 743 | + while (total > 0) { |
| 744 | + if (total > sizeof(buf)) |
| 745 | + len = sizeof(buf); |
| 746 | + else |
| 747 | + len = total; |
| 748 | + |
| 749 | + ret = write(fd, buf, len); |
| 750 | + if (ret < 0) |
| 751 | + die_perror("write"); |
| 752 | + total -= ret; |
| 753 | + |
| 754 | + /* we don't have to care about buf content, only |
| 755 | + * number of total bytes sent |
| 756 | + */ |
| 757 | + } |
| 758 | + |
| 759 | + ret = read(unixfd, buf2, 4); |
| 760 | + assert(ret == 4); |
| 761 | + assert(strncmp(buf2, "shut", 4) == 0); |
| 762 | + |
| 763 | + wait_for_ack(fd, 5000, sent); |
| 764 | + |
| 765 | + ret = write(fd, buf, 1); |
| 766 | + assert(ret == 1); |
| 767 | + close(fd); |
| 768 | + ret = write(unixfd, "closed", 6); |
| 769 | + assert(ret == 6); |
| 770 | + |
| 771 | + close(unixfd); |
| 772 | +} |
| 773 | + |
663 | 774 | static void process_one_client(int fd, int pipefd) |
664 | 775 | { |
665 | 776 | ssize_t ret, ret2, ret3; |
@@ -961,7 +1072,10 @@ static int client(int ipcfd) |
961 | 1072 |
|
962 | 1073 | test_ip_tos_sockopt(fd); |
963 | 1074 |
|
964 | | - connect_one_server(fd, ipcfd); |
| 1075 | + if (inq) |
| 1076 | + connect_one_server_inq(fd, ipcfd); |
| 1077 | + else |
| 1078 | + connect_one_server(fd, ipcfd); |
965 | 1079 |
|
966 | 1080 | return 0; |
967 | 1081 | } |
|
0 commit comments