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