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