xref: /linux/tools/testing/selftests/net/mptcp/mptcp_inq.c (revision fd37c2ecb21f7aee04ccca5f561469f07d00063c)
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