1*b5188056SFlorian Westphal // SPDX-License-Identifier: GPL-2.0 2*b5188056SFlorian Westphal 3*b5188056SFlorian Westphal #define _GNU_SOURCE 4*b5188056SFlorian Westphal 5*b5188056SFlorian Westphal #include <assert.h> 6*b5188056SFlorian Westphal #include <errno.h> 7*b5188056SFlorian Westphal #include <fcntl.h> 8*b5188056SFlorian Westphal #include <limits.h> 9*b5188056SFlorian Westphal #include <string.h> 10*b5188056SFlorian Westphal #include <stdarg.h> 11*b5188056SFlorian Westphal #include <stdbool.h> 12*b5188056SFlorian Westphal #include <stdint.h> 13*b5188056SFlorian Westphal #include <inttypes.h> 14*b5188056SFlorian Westphal #include <stdio.h> 15*b5188056SFlorian Westphal #include <stdlib.h> 16*b5188056SFlorian Westphal #include <strings.h> 17*b5188056SFlorian Westphal #include <unistd.h> 18*b5188056SFlorian Westphal #include <time.h> 19*b5188056SFlorian Westphal 20*b5188056SFlorian Westphal #include <sys/ioctl.h> 21*b5188056SFlorian Westphal #include <sys/ioctl.h> 22*b5188056SFlorian Westphal #include <sys/socket.h> 23*b5188056SFlorian Westphal #include <sys/types.h> 24*b5188056SFlorian Westphal #include <sys/wait.h> 25*b5188056SFlorian Westphal 26*b5188056SFlorian Westphal #include <netdb.h> 27*b5188056SFlorian Westphal #include <netinet/in.h> 28*b5188056SFlorian Westphal 29*b5188056SFlorian Westphal #include <linux/tcp.h> 30*b5188056SFlorian Westphal #include <linux/sockios.h> 31*b5188056SFlorian Westphal 32*b5188056SFlorian Westphal #ifndef IPPROTO_MPTCP 33*b5188056SFlorian Westphal #define IPPROTO_MPTCP 262 34*b5188056SFlorian Westphal #endif 35*b5188056SFlorian Westphal #ifndef SOL_MPTCP 36*b5188056SFlorian Westphal #define SOL_MPTCP 284 37*b5188056SFlorian Westphal #endif 38*b5188056SFlorian Westphal 39*b5188056SFlorian Westphal static int pf = AF_INET; 40*b5188056SFlorian Westphal static int proto_tx = IPPROTO_MPTCP; 41*b5188056SFlorian Westphal static int proto_rx = IPPROTO_MPTCP; 42*b5188056SFlorian Westphal 43*b5188056SFlorian Westphal static void die_perror(const char *msg) 44*b5188056SFlorian Westphal { 45*b5188056SFlorian Westphal perror(msg); 46*b5188056SFlorian Westphal exit(1); 47*b5188056SFlorian Westphal } 48*b5188056SFlorian Westphal 49*b5188056SFlorian Westphal static void die_usage(int r) 50*b5188056SFlorian Westphal { 51*b5188056SFlorian Westphal fprintf(stderr, "Usage: mptcp_inq [-6] [ -t tcp|mptcp ] [ -r tcp|mptcp]\n"); 52*b5188056SFlorian Westphal exit(r); 53*b5188056SFlorian Westphal } 54*b5188056SFlorian Westphal 55*b5188056SFlorian Westphal static void xerror(const char *fmt, ...) 56*b5188056SFlorian Westphal { 57*b5188056SFlorian Westphal va_list ap; 58*b5188056SFlorian Westphal 59*b5188056SFlorian Westphal va_start(ap, fmt); 60*b5188056SFlorian Westphal vfprintf(stderr, fmt, ap); 61*b5188056SFlorian Westphal va_end(ap); 62*b5188056SFlorian Westphal fputc('\n', stderr); 63*b5188056SFlorian Westphal exit(1); 64*b5188056SFlorian Westphal } 65*b5188056SFlorian Westphal 66*b5188056SFlorian Westphal static const char *getxinfo_strerr(int err) 67*b5188056SFlorian Westphal { 68*b5188056SFlorian Westphal if (err == EAI_SYSTEM) 69*b5188056SFlorian Westphal return strerror(errno); 70*b5188056SFlorian Westphal 71*b5188056SFlorian Westphal return gai_strerror(err); 72*b5188056SFlorian Westphal } 73*b5188056SFlorian Westphal 74*b5188056SFlorian Westphal static void xgetaddrinfo(const char *node, const char *service, 75*b5188056SFlorian Westphal const struct addrinfo *hints, 76*b5188056SFlorian Westphal struct addrinfo **res) 77*b5188056SFlorian Westphal { 78*b5188056SFlorian Westphal int err = getaddrinfo(node, service, hints, res); 79*b5188056SFlorian Westphal 80*b5188056SFlorian Westphal if (err) { 81*b5188056SFlorian Westphal const char *errstr = getxinfo_strerr(err); 82*b5188056SFlorian Westphal 83*b5188056SFlorian Westphal fprintf(stderr, "Fatal: getaddrinfo(%s:%s): %s\n", 84*b5188056SFlorian Westphal node ? node : "", service ? service : "", errstr); 85*b5188056SFlorian Westphal exit(1); 86*b5188056SFlorian Westphal } 87*b5188056SFlorian Westphal } 88*b5188056SFlorian Westphal 89*b5188056SFlorian Westphal static int sock_listen_mptcp(const char * const listenaddr, 90*b5188056SFlorian Westphal const char * const port) 91*b5188056SFlorian Westphal { 92*b5188056SFlorian Westphal int sock; 93*b5188056SFlorian Westphal struct addrinfo hints = { 94*b5188056SFlorian Westphal .ai_protocol = IPPROTO_TCP, 95*b5188056SFlorian Westphal .ai_socktype = SOCK_STREAM, 96*b5188056SFlorian Westphal .ai_flags = AI_PASSIVE | AI_NUMERICHOST 97*b5188056SFlorian Westphal }; 98*b5188056SFlorian Westphal 99*b5188056SFlorian Westphal hints.ai_family = pf; 100*b5188056SFlorian Westphal 101*b5188056SFlorian Westphal struct addrinfo *a, *addr; 102*b5188056SFlorian Westphal int one = 1; 103*b5188056SFlorian Westphal 104*b5188056SFlorian Westphal xgetaddrinfo(listenaddr, port, &hints, &addr); 105*b5188056SFlorian Westphal hints.ai_family = pf; 106*b5188056SFlorian Westphal 107*b5188056SFlorian Westphal for (a = addr; a; a = a->ai_next) { 108*b5188056SFlorian Westphal sock = socket(a->ai_family, a->ai_socktype, proto_rx); 109*b5188056SFlorian Westphal if (sock < 0) 110*b5188056SFlorian Westphal continue; 111*b5188056SFlorian Westphal 112*b5188056SFlorian Westphal if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, 113*b5188056SFlorian Westphal sizeof(one))) 114*b5188056SFlorian Westphal perror("setsockopt"); 115*b5188056SFlorian Westphal 116*b5188056SFlorian Westphal if (bind(sock, a->ai_addr, a->ai_addrlen) == 0) 117*b5188056SFlorian Westphal break; /* success */ 118*b5188056SFlorian Westphal 119*b5188056SFlorian Westphal perror("bind"); 120*b5188056SFlorian Westphal close(sock); 121*b5188056SFlorian Westphal sock = -1; 122*b5188056SFlorian Westphal } 123*b5188056SFlorian Westphal 124*b5188056SFlorian Westphal freeaddrinfo(addr); 125*b5188056SFlorian Westphal 126*b5188056SFlorian Westphal if (sock < 0) 127*b5188056SFlorian Westphal xerror("could not create listen socket"); 128*b5188056SFlorian Westphal 129*b5188056SFlorian Westphal if (listen(sock, 20)) 130*b5188056SFlorian Westphal die_perror("listen"); 131*b5188056SFlorian Westphal 132*b5188056SFlorian Westphal return sock; 133*b5188056SFlorian Westphal } 134*b5188056SFlorian Westphal 135*b5188056SFlorian Westphal static int sock_connect_mptcp(const char * const remoteaddr, 136*b5188056SFlorian Westphal const char * const port, int proto) 137*b5188056SFlorian Westphal { 138*b5188056SFlorian Westphal struct addrinfo hints = { 139*b5188056SFlorian Westphal .ai_protocol = IPPROTO_TCP, 140*b5188056SFlorian Westphal .ai_socktype = SOCK_STREAM, 141*b5188056SFlorian Westphal }; 142*b5188056SFlorian Westphal struct addrinfo *a, *addr; 143*b5188056SFlorian Westphal int sock = -1; 144*b5188056SFlorian Westphal 145*b5188056SFlorian Westphal hints.ai_family = pf; 146*b5188056SFlorian Westphal 147*b5188056SFlorian Westphal xgetaddrinfo(remoteaddr, port, &hints, &addr); 148*b5188056SFlorian Westphal for (a = addr; a; a = a->ai_next) { 149*b5188056SFlorian Westphal sock = socket(a->ai_family, a->ai_socktype, proto); 150*b5188056SFlorian Westphal if (sock < 0) 151*b5188056SFlorian Westphal continue; 152*b5188056SFlorian Westphal 153*b5188056SFlorian Westphal if (connect(sock, a->ai_addr, a->ai_addrlen) == 0) 154*b5188056SFlorian Westphal break; /* success */ 155*b5188056SFlorian Westphal 156*b5188056SFlorian Westphal die_perror("connect"); 157*b5188056SFlorian Westphal } 158*b5188056SFlorian Westphal 159*b5188056SFlorian Westphal if (sock < 0) 160*b5188056SFlorian Westphal xerror("could not create connect socket"); 161*b5188056SFlorian Westphal 162*b5188056SFlorian Westphal freeaddrinfo(addr); 163*b5188056SFlorian Westphal return sock; 164*b5188056SFlorian Westphal } 165*b5188056SFlorian Westphal 166*b5188056SFlorian Westphal static int protostr_to_num(const char *s) 167*b5188056SFlorian Westphal { 168*b5188056SFlorian Westphal if (strcasecmp(s, "tcp") == 0) 169*b5188056SFlorian Westphal return IPPROTO_TCP; 170*b5188056SFlorian Westphal if (strcasecmp(s, "mptcp") == 0) 171*b5188056SFlorian Westphal return IPPROTO_MPTCP; 172*b5188056SFlorian Westphal 173*b5188056SFlorian Westphal die_usage(1); 174*b5188056SFlorian Westphal return 0; 175*b5188056SFlorian Westphal } 176*b5188056SFlorian Westphal 177*b5188056SFlorian Westphal static void parse_opts(int argc, char **argv) 178*b5188056SFlorian Westphal { 179*b5188056SFlorian Westphal int c; 180*b5188056SFlorian Westphal 181*b5188056SFlorian Westphal while ((c = getopt(argc, argv, "h6t:r:")) != -1) { 182*b5188056SFlorian Westphal switch (c) { 183*b5188056SFlorian Westphal case 'h': 184*b5188056SFlorian Westphal die_usage(0); 185*b5188056SFlorian Westphal break; 186*b5188056SFlorian Westphal case '6': 187*b5188056SFlorian Westphal pf = AF_INET6; 188*b5188056SFlorian Westphal break; 189*b5188056SFlorian Westphal case 't': 190*b5188056SFlorian Westphal proto_tx = protostr_to_num(optarg); 191*b5188056SFlorian Westphal break; 192*b5188056SFlorian Westphal case 'r': 193*b5188056SFlorian Westphal proto_rx = protostr_to_num(optarg); 194*b5188056SFlorian Westphal break; 195*b5188056SFlorian Westphal default: 196*b5188056SFlorian Westphal die_usage(1); 197*b5188056SFlorian Westphal break; 198*b5188056SFlorian Westphal } 199*b5188056SFlorian Westphal } 200*b5188056SFlorian Westphal } 201*b5188056SFlorian Westphal 202*b5188056SFlorian Westphal /* wait up to timeout milliseconds */ 203*b5188056SFlorian Westphal static void wait_for_ack(int fd, int timeout, size_t total) 204*b5188056SFlorian Westphal { 205*b5188056SFlorian Westphal int i; 206*b5188056SFlorian Westphal 207*b5188056SFlorian Westphal for (i = 0; i < timeout; i++) { 208*b5188056SFlorian Westphal int nsd, ret, queued = -1; 209*b5188056SFlorian Westphal struct timespec req; 210*b5188056SFlorian Westphal 211*b5188056SFlorian Westphal ret = ioctl(fd, TIOCOUTQ, &queued); 212*b5188056SFlorian Westphal if (ret < 0) 213*b5188056SFlorian Westphal die_perror("TIOCOUTQ"); 214*b5188056SFlorian Westphal 215*b5188056SFlorian Westphal ret = ioctl(fd, SIOCOUTQNSD, &nsd); 216*b5188056SFlorian Westphal if (ret < 0) 217*b5188056SFlorian Westphal die_perror("SIOCOUTQNSD"); 218*b5188056SFlorian Westphal 219*b5188056SFlorian Westphal if ((size_t)queued > total) 220*b5188056SFlorian Westphal xerror("TIOCOUTQ %u, but only %zu expected\n", queued, total); 221*b5188056SFlorian Westphal assert(nsd <= queued); 222*b5188056SFlorian Westphal 223*b5188056SFlorian Westphal if (queued == 0) 224*b5188056SFlorian Westphal return; 225*b5188056SFlorian Westphal 226*b5188056SFlorian Westphal /* wait for peer to ack rx of all data */ 227*b5188056SFlorian Westphal req.tv_sec = 0; 228*b5188056SFlorian Westphal req.tv_nsec = 1 * 1000 * 1000ul; /* 1ms */ 229*b5188056SFlorian Westphal nanosleep(&req, NULL); 230*b5188056SFlorian Westphal } 231*b5188056SFlorian Westphal 232*b5188056SFlorian Westphal xerror("still tx data queued after %u ms\n", timeout); 233*b5188056SFlorian Westphal } 234*b5188056SFlorian Westphal 235*b5188056SFlorian Westphal static void connect_one_server(int fd, int unixfd) 236*b5188056SFlorian Westphal { 237*b5188056SFlorian Westphal size_t len, i, total, sent; 238*b5188056SFlorian Westphal char buf[4096], buf2[4096]; 239*b5188056SFlorian Westphal ssize_t ret; 240*b5188056SFlorian Westphal 241*b5188056SFlorian Westphal len = rand() % (sizeof(buf) - 1); 242*b5188056SFlorian Westphal 243*b5188056SFlorian Westphal if (len < 128) 244*b5188056SFlorian Westphal len = 128; 245*b5188056SFlorian Westphal 246*b5188056SFlorian Westphal for (i = 0; i < len ; i++) { 247*b5188056SFlorian Westphal buf[i] = rand() % 26; 248*b5188056SFlorian Westphal buf[i] += 'A'; 249*b5188056SFlorian Westphal } 250*b5188056SFlorian Westphal 251*b5188056SFlorian Westphal buf[i] = '\n'; 252*b5188056SFlorian Westphal 253*b5188056SFlorian Westphal /* un-block server */ 254*b5188056SFlorian Westphal ret = read(unixfd, buf2, 4); 255*b5188056SFlorian Westphal assert(ret == 4); 256*b5188056SFlorian Westphal 257*b5188056SFlorian Westphal assert(strncmp(buf2, "xmit", 4) == 0); 258*b5188056SFlorian Westphal 259*b5188056SFlorian Westphal ret = write(unixfd, &len, sizeof(len)); 260*b5188056SFlorian Westphal assert(ret == (ssize_t)sizeof(len)); 261*b5188056SFlorian Westphal 262*b5188056SFlorian Westphal ret = write(fd, buf, len); 263*b5188056SFlorian Westphal if (ret < 0) 264*b5188056SFlorian Westphal die_perror("write"); 265*b5188056SFlorian Westphal 266*b5188056SFlorian Westphal if (ret != (ssize_t)len) 267*b5188056SFlorian Westphal xerror("short write"); 268*b5188056SFlorian Westphal 269*b5188056SFlorian Westphal ret = read(unixfd, buf2, 4); 270*b5188056SFlorian Westphal assert(strncmp(buf2, "huge", 4) == 0); 271*b5188056SFlorian Westphal 272*b5188056SFlorian Westphal total = rand() % (16 * 1024 * 1024); 273*b5188056SFlorian Westphal total += (1 * 1024 * 1024); 274*b5188056SFlorian Westphal sent = total; 275*b5188056SFlorian Westphal 276*b5188056SFlorian Westphal ret = write(unixfd, &total, sizeof(total)); 277*b5188056SFlorian Westphal assert(ret == (ssize_t)sizeof(total)); 278*b5188056SFlorian Westphal 279*b5188056SFlorian Westphal wait_for_ack(fd, 5000, len); 280*b5188056SFlorian Westphal 281*b5188056SFlorian Westphal while (total > 0) { 282*b5188056SFlorian Westphal if (total > sizeof(buf)) 283*b5188056SFlorian Westphal len = sizeof(buf); 284*b5188056SFlorian Westphal else 285*b5188056SFlorian Westphal len = total; 286*b5188056SFlorian Westphal 287*b5188056SFlorian Westphal ret = write(fd, buf, len); 288*b5188056SFlorian Westphal if (ret < 0) 289*b5188056SFlorian Westphal die_perror("write"); 290*b5188056SFlorian Westphal total -= ret; 291*b5188056SFlorian Westphal 292*b5188056SFlorian Westphal /* we don't have to care about buf content, only 293*b5188056SFlorian Westphal * number of total bytes sent 294*b5188056SFlorian Westphal */ 295*b5188056SFlorian Westphal } 296*b5188056SFlorian Westphal 297*b5188056SFlorian Westphal ret = read(unixfd, buf2, 4); 298*b5188056SFlorian Westphal assert(ret == 4); 299*b5188056SFlorian Westphal assert(strncmp(buf2, "shut", 4) == 0); 300*b5188056SFlorian Westphal 301*b5188056SFlorian Westphal wait_for_ack(fd, 5000, sent); 302*b5188056SFlorian Westphal 303*b5188056SFlorian Westphal ret = write(fd, buf, 1); 304*b5188056SFlorian Westphal assert(ret == 1); 305*b5188056SFlorian Westphal close(fd); 306*b5188056SFlorian Westphal ret = write(unixfd, "closed", 6); 307*b5188056SFlorian Westphal assert(ret == 6); 308*b5188056SFlorian Westphal 309*b5188056SFlorian Westphal close(unixfd); 310*b5188056SFlorian Westphal } 311*b5188056SFlorian Westphal 312*b5188056SFlorian Westphal static void get_tcp_inq(struct msghdr *msgh, unsigned int *inqv) 313*b5188056SFlorian Westphal { 314*b5188056SFlorian Westphal struct cmsghdr *cmsg; 315*b5188056SFlorian Westphal 316*b5188056SFlorian Westphal for (cmsg = CMSG_FIRSTHDR(msgh); cmsg ; cmsg = CMSG_NXTHDR(msgh, cmsg)) { 317*b5188056SFlorian Westphal if (cmsg->cmsg_level == IPPROTO_TCP && cmsg->cmsg_type == TCP_CM_INQ) { 318*b5188056SFlorian Westphal memcpy(inqv, CMSG_DATA(cmsg), sizeof(*inqv)); 319*b5188056SFlorian Westphal return; 320*b5188056SFlorian Westphal } 321*b5188056SFlorian Westphal } 322*b5188056SFlorian Westphal 323*b5188056SFlorian Westphal xerror("could not find TCP_CM_INQ cmsg type"); 324*b5188056SFlorian Westphal } 325*b5188056SFlorian Westphal 326*b5188056SFlorian Westphal static void process_one_client(int fd, int unixfd) 327*b5188056SFlorian Westphal { 328*b5188056SFlorian Westphal unsigned int tcp_inq; 329*b5188056SFlorian Westphal size_t expect_len; 330*b5188056SFlorian Westphal char msg_buf[4096]; 331*b5188056SFlorian Westphal char buf[4096]; 332*b5188056SFlorian Westphal char tmp[16]; 333*b5188056SFlorian Westphal struct iovec iov = { 334*b5188056SFlorian Westphal .iov_base = buf, 335*b5188056SFlorian Westphal .iov_len = 1, 336*b5188056SFlorian Westphal }; 337*b5188056SFlorian Westphal struct msghdr msg = { 338*b5188056SFlorian Westphal .msg_iov = &iov, 339*b5188056SFlorian Westphal .msg_iovlen = 1, 340*b5188056SFlorian Westphal .msg_control = msg_buf, 341*b5188056SFlorian Westphal .msg_controllen = sizeof(msg_buf), 342*b5188056SFlorian Westphal }; 343*b5188056SFlorian Westphal ssize_t ret, tot; 344*b5188056SFlorian Westphal 345*b5188056SFlorian Westphal ret = write(unixfd, "xmit", 4); 346*b5188056SFlorian Westphal assert(ret == 4); 347*b5188056SFlorian Westphal 348*b5188056SFlorian Westphal ret = read(unixfd, &expect_len, sizeof(expect_len)); 349*b5188056SFlorian Westphal assert(ret == (ssize_t)sizeof(expect_len)); 350*b5188056SFlorian Westphal 351*b5188056SFlorian Westphal if (expect_len > sizeof(buf)) 352*b5188056SFlorian Westphal xerror("expect len %zu exceeds buffer size", expect_len); 353*b5188056SFlorian Westphal 354*b5188056SFlorian Westphal for (;;) { 355*b5188056SFlorian Westphal struct timespec req; 356*b5188056SFlorian Westphal unsigned int queued; 357*b5188056SFlorian Westphal 358*b5188056SFlorian Westphal ret = ioctl(fd, FIONREAD, &queued); 359*b5188056SFlorian Westphal if (ret < 0) 360*b5188056SFlorian Westphal die_perror("FIONREAD"); 361*b5188056SFlorian Westphal if (queued > expect_len) 362*b5188056SFlorian Westphal xerror("FIONREAD returned %u, but only %zu expected\n", 363*b5188056SFlorian Westphal queued, expect_len); 364*b5188056SFlorian Westphal if (queued == expect_len) 365*b5188056SFlorian Westphal break; 366*b5188056SFlorian Westphal 367*b5188056SFlorian Westphal req.tv_sec = 0; 368*b5188056SFlorian Westphal req.tv_nsec = 1000 * 1000ul; 369*b5188056SFlorian Westphal nanosleep(&req, NULL); 370*b5188056SFlorian Westphal } 371*b5188056SFlorian Westphal 372*b5188056SFlorian Westphal /* read one byte, expect cmsg to return expected - 1 */ 373*b5188056SFlorian Westphal ret = recvmsg(fd, &msg, 0); 374*b5188056SFlorian Westphal if (ret < 0) 375*b5188056SFlorian Westphal die_perror("recvmsg"); 376*b5188056SFlorian Westphal 377*b5188056SFlorian Westphal if (msg.msg_controllen == 0) 378*b5188056SFlorian Westphal xerror("msg_controllen is 0"); 379*b5188056SFlorian Westphal 380*b5188056SFlorian Westphal get_tcp_inq(&msg, &tcp_inq); 381*b5188056SFlorian Westphal 382*b5188056SFlorian Westphal assert((size_t)tcp_inq == (expect_len - 1)); 383*b5188056SFlorian Westphal 384*b5188056SFlorian Westphal iov.iov_len = sizeof(buf); 385*b5188056SFlorian Westphal ret = recvmsg(fd, &msg, 0); 386*b5188056SFlorian Westphal if (ret < 0) 387*b5188056SFlorian Westphal die_perror("recvmsg"); 388*b5188056SFlorian Westphal 389*b5188056SFlorian Westphal /* should have gotten exact remainder of all pending data */ 390*b5188056SFlorian Westphal assert(ret == (ssize_t)tcp_inq); 391*b5188056SFlorian Westphal 392*b5188056SFlorian Westphal /* should be 0, all drained */ 393*b5188056SFlorian Westphal get_tcp_inq(&msg, &tcp_inq); 394*b5188056SFlorian Westphal assert(tcp_inq == 0); 395*b5188056SFlorian Westphal 396*b5188056SFlorian Westphal /* request a large swath of data. */ 397*b5188056SFlorian Westphal ret = write(unixfd, "huge", 4); 398*b5188056SFlorian Westphal assert(ret == 4); 399*b5188056SFlorian Westphal 400*b5188056SFlorian Westphal ret = read(unixfd, &expect_len, sizeof(expect_len)); 401*b5188056SFlorian Westphal assert(ret == (ssize_t)sizeof(expect_len)); 402*b5188056SFlorian Westphal 403*b5188056SFlorian Westphal /* peer should send us a few mb of data */ 404*b5188056SFlorian Westphal if (expect_len <= sizeof(buf)) 405*b5188056SFlorian Westphal xerror("expect len %zu too small\n", expect_len); 406*b5188056SFlorian Westphal 407*b5188056SFlorian Westphal tot = 0; 408*b5188056SFlorian Westphal do { 409*b5188056SFlorian Westphal iov.iov_len = sizeof(buf); 410*b5188056SFlorian Westphal ret = recvmsg(fd, &msg, 0); 411*b5188056SFlorian Westphal if (ret < 0) 412*b5188056SFlorian Westphal die_perror("recvmsg"); 413*b5188056SFlorian Westphal 414*b5188056SFlorian Westphal tot += ret; 415*b5188056SFlorian Westphal 416*b5188056SFlorian Westphal get_tcp_inq(&msg, &tcp_inq); 417*b5188056SFlorian Westphal 418*b5188056SFlorian Westphal if (tcp_inq > expect_len - tot) 419*b5188056SFlorian Westphal xerror("inq %d, remaining %d total_len %d\n", 420*b5188056SFlorian Westphal tcp_inq, expect_len - tot, (int)expect_len); 421*b5188056SFlorian Westphal 422*b5188056SFlorian Westphal assert(tcp_inq <= expect_len - tot); 423*b5188056SFlorian Westphal } while ((size_t)tot < expect_len); 424*b5188056SFlorian Westphal 425*b5188056SFlorian Westphal ret = write(unixfd, "shut", 4); 426*b5188056SFlorian Westphal assert(ret == 4); 427*b5188056SFlorian Westphal 428*b5188056SFlorian Westphal /* wait for hangup. Should have received one more byte of data. */ 429*b5188056SFlorian Westphal ret = read(unixfd, tmp, sizeof(tmp)); 430*b5188056SFlorian Westphal assert(ret == 6); 431*b5188056SFlorian Westphal assert(strncmp(tmp, "closed", 6) == 0); 432*b5188056SFlorian Westphal 433*b5188056SFlorian Westphal sleep(1); 434*b5188056SFlorian Westphal 435*b5188056SFlorian Westphal iov.iov_len = 1; 436*b5188056SFlorian Westphal ret = recvmsg(fd, &msg, 0); 437*b5188056SFlorian Westphal if (ret < 0) 438*b5188056SFlorian Westphal die_perror("recvmsg"); 439*b5188056SFlorian Westphal assert(ret == 1); 440*b5188056SFlorian Westphal 441*b5188056SFlorian Westphal get_tcp_inq(&msg, &tcp_inq); 442*b5188056SFlorian Westphal 443*b5188056SFlorian Westphal /* tcp_inq should be 1 due to received fin. */ 444*b5188056SFlorian Westphal assert(tcp_inq == 1); 445*b5188056SFlorian Westphal 446*b5188056SFlorian Westphal iov.iov_len = 1; 447*b5188056SFlorian Westphal ret = recvmsg(fd, &msg, 0); 448*b5188056SFlorian Westphal if (ret < 0) 449*b5188056SFlorian Westphal die_perror("recvmsg"); 450*b5188056SFlorian Westphal 451*b5188056SFlorian Westphal /* expect EOF */ 452*b5188056SFlorian Westphal assert(ret == 0); 453*b5188056SFlorian Westphal get_tcp_inq(&msg, &tcp_inq); 454*b5188056SFlorian Westphal assert(tcp_inq == 1); 455*b5188056SFlorian Westphal 456*b5188056SFlorian Westphal close(fd); 457*b5188056SFlorian Westphal } 458*b5188056SFlorian Westphal 459*b5188056SFlorian Westphal static int xaccept(int s) 460*b5188056SFlorian Westphal { 461*b5188056SFlorian Westphal int fd = accept(s, NULL, 0); 462*b5188056SFlorian Westphal 463*b5188056SFlorian Westphal if (fd < 0) 464*b5188056SFlorian Westphal die_perror("accept"); 465*b5188056SFlorian Westphal 466*b5188056SFlorian Westphal return fd; 467*b5188056SFlorian Westphal } 468*b5188056SFlorian Westphal 469*b5188056SFlorian Westphal static int server(int unixfd) 470*b5188056SFlorian Westphal { 471*b5188056SFlorian Westphal int fd = -1, r, on = 1; 472*b5188056SFlorian Westphal 473*b5188056SFlorian Westphal switch (pf) { 474*b5188056SFlorian Westphal case AF_INET: 475*b5188056SFlorian Westphal fd = sock_listen_mptcp("127.0.0.1", "15432"); 476*b5188056SFlorian Westphal break; 477*b5188056SFlorian Westphal case AF_INET6: 478*b5188056SFlorian Westphal fd = sock_listen_mptcp("::1", "15432"); 479*b5188056SFlorian Westphal break; 480*b5188056SFlorian Westphal default: 481*b5188056SFlorian Westphal xerror("Unknown pf %d\n", pf); 482*b5188056SFlorian Westphal break; 483*b5188056SFlorian Westphal } 484*b5188056SFlorian Westphal 485*b5188056SFlorian Westphal r = write(unixfd, "conn", 4); 486*b5188056SFlorian Westphal assert(r == 4); 487*b5188056SFlorian Westphal 488*b5188056SFlorian Westphal alarm(15); 489*b5188056SFlorian Westphal r = xaccept(fd); 490*b5188056SFlorian Westphal 491*b5188056SFlorian Westphal if (-1 == setsockopt(r, IPPROTO_TCP, TCP_INQ, &on, sizeof(on))) 492*b5188056SFlorian Westphal die_perror("setsockopt"); 493*b5188056SFlorian Westphal 494*b5188056SFlorian Westphal process_one_client(r, unixfd); 495*b5188056SFlorian Westphal 496*b5188056SFlorian Westphal return 0; 497*b5188056SFlorian Westphal } 498*b5188056SFlorian Westphal 499*b5188056SFlorian Westphal static int client(int unixfd) 500*b5188056SFlorian Westphal { 501*b5188056SFlorian Westphal int fd = -1; 502*b5188056SFlorian Westphal 503*b5188056SFlorian Westphal alarm(15); 504*b5188056SFlorian Westphal 505*b5188056SFlorian Westphal switch (pf) { 506*b5188056SFlorian Westphal case AF_INET: 507*b5188056SFlorian Westphal fd = sock_connect_mptcp("127.0.0.1", "15432", proto_tx); 508*b5188056SFlorian Westphal break; 509*b5188056SFlorian Westphal case AF_INET6: 510*b5188056SFlorian Westphal fd = sock_connect_mptcp("::1", "15432", proto_tx); 511*b5188056SFlorian Westphal break; 512*b5188056SFlorian Westphal default: 513*b5188056SFlorian Westphal xerror("Unknown pf %d\n", pf); 514*b5188056SFlorian Westphal } 515*b5188056SFlorian Westphal 516*b5188056SFlorian Westphal connect_one_server(fd, unixfd); 517*b5188056SFlorian Westphal 518*b5188056SFlorian Westphal return 0; 519*b5188056SFlorian Westphal } 520*b5188056SFlorian Westphal 521*b5188056SFlorian Westphal static void init_rng(void) 522*b5188056SFlorian Westphal { 523*b5188056SFlorian Westphal int fd = open("/dev/urandom", O_RDONLY); 524*b5188056SFlorian Westphal unsigned int foo; 525*b5188056SFlorian Westphal 526*b5188056SFlorian Westphal if (fd > 0) { 527*b5188056SFlorian Westphal int ret = read(fd, &foo, sizeof(foo)); 528*b5188056SFlorian Westphal 529*b5188056SFlorian Westphal if (ret < 0) 530*b5188056SFlorian Westphal srand(fd + foo); 531*b5188056SFlorian Westphal close(fd); 532*b5188056SFlorian Westphal } 533*b5188056SFlorian Westphal 534*b5188056SFlorian Westphal srand(foo); 535*b5188056SFlorian Westphal } 536*b5188056SFlorian Westphal 537*b5188056SFlorian Westphal static pid_t xfork(void) 538*b5188056SFlorian Westphal { 539*b5188056SFlorian Westphal pid_t p = fork(); 540*b5188056SFlorian Westphal 541*b5188056SFlorian Westphal if (p < 0) 542*b5188056SFlorian Westphal die_perror("fork"); 543*b5188056SFlorian Westphal else if (p == 0) 544*b5188056SFlorian Westphal init_rng(); 545*b5188056SFlorian Westphal 546*b5188056SFlorian Westphal return p; 547*b5188056SFlorian Westphal } 548*b5188056SFlorian Westphal 549*b5188056SFlorian Westphal static int rcheck(int wstatus, const char *what) 550*b5188056SFlorian Westphal { 551*b5188056SFlorian Westphal if (WIFEXITED(wstatus)) { 552*b5188056SFlorian Westphal if (WEXITSTATUS(wstatus) == 0) 553*b5188056SFlorian Westphal return 0; 554*b5188056SFlorian Westphal fprintf(stderr, "%s exited, status=%d\n", what, WEXITSTATUS(wstatus)); 555*b5188056SFlorian Westphal return WEXITSTATUS(wstatus); 556*b5188056SFlorian Westphal } else if (WIFSIGNALED(wstatus)) { 557*b5188056SFlorian Westphal xerror("%s killed by signal %d\n", what, WTERMSIG(wstatus)); 558*b5188056SFlorian Westphal } else if (WIFSTOPPED(wstatus)) { 559*b5188056SFlorian Westphal xerror("%s stopped by signal %d\n", what, WSTOPSIG(wstatus)); 560*b5188056SFlorian Westphal } 561*b5188056SFlorian Westphal 562*b5188056SFlorian Westphal return 111; 563*b5188056SFlorian Westphal } 564*b5188056SFlorian Westphal 565*b5188056SFlorian Westphal int main(int argc, char *argv[]) 566*b5188056SFlorian Westphal { 567*b5188056SFlorian Westphal int e1, e2, wstatus; 568*b5188056SFlorian Westphal pid_t s, c, ret; 569*b5188056SFlorian Westphal int unixfds[2]; 570*b5188056SFlorian Westphal 571*b5188056SFlorian Westphal parse_opts(argc, argv); 572*b5188056SFlorian Westphal 573*b5188056SFlorian Westphal e1 = socketpair(AF_UNIX, SOCK_DGRAM, 0, unixfds); 574*b5188056SFlorian Westphal if (e1 < 0) 575*b5188056SFlorian Westphal die_perror("pipe"); 576*b5188056SFlorian Westphal 577*b5188056SFlorian Westphal s = xfork(); 578*b5188056SFlorian Westphal if (s == 0) 579*b5188056SFlorian Westphal return server(unixfds[1]); 580*b5188056SFlorian Westphal 581*b5188056SFlorian Westphal close(unixfds[1]); 582*b5188056SFlorian Westphal 583*b5188056SFlorian Westphal /* wait until server bound a socket */ 584*b5188056SFlorian Westphal e1 = read(unixfds[0], &e1, 4); 585*b5188056SFlorian Westphal assert(e1 == 4); 586*b5188056SFlorian Westphal 587*b5188056SFlorian Westphal c = xfork(); 588*b5188056SFlorian Westphal if (c == 0) 589*b5188056SFlorian Westphal return client(unixfds[0]); 590*b5188056SFlorian Westphal 591*b5188056SFlorian Westphal close(unixfds[0]); 592*b5188056SFlorian Westphal 593*b5188056SFlorian Westphal ret = waitpid(s, &wstatus, 0); 594*b5188056SFlorian Westphal if (ret == -1) 595*b5188056SFlorian Westphal die_perror("waitpid"); 596*b5188056SFlorian Westphal e1 = rcheck(wstatus, "server"); 597*b5188056SFlorian Westphal ret = waitpid(c, &wstatus, 0); 598*b5188056SFlorian Westphal if (ret == -1) 599*b5188056SFlorian Westphal die_perror("waitpid"); 600*b5188056SFlorian Westphal e2 = rcheck(wstatus, "client"); 601*b5188056SFlorian Westphal 602*b5188056SFlorian Westphal return e1 ? e1 : e2; 603*b5188056SFlorian Westphal } 604