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