1 /*
2  * Copyright (C) 2013-2021 Canonical, Ltd.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * This code is a complete clean re-write of the stress tool by
19  * Colin Ian King <colin.king@canonical.com> and attempts to be
20  * backwardly compatible with the stress tool by Amos Waterland
21  * <apw@rossby.metr.ou.edu> but has more stress tests and more
22  * functionality.
23  *
24  */
25 #include "stress-ng.h"
26 
27 #define MMAP_BUF_SIZE		(65536)
28 #define MMAP_IO_SIZE		(8192)	/* Must be less or equal to 8192 */
29 
30 #define SOCKET_OPT_SEND		(0x00)
31 #define SOCKET_OPT_SENDMSG	(0x01)
32 #define SOCKET_OPT_SENDMMSG	(0x02)
33 #define SOCKET_OPT_RANDOM	(0x03)
34 
35 #define SOCKET_OPT_RECV		(SOCKET_OPT_SEND)
36 #define SOCKET_OPT_RECVMSG	(SOCKET_OPT_SENDMSG)
37 #define SOCKET_OPT_RECVMMSG	(SOCKET_OPT_SENDMMSG)
38 
39 #if !defined(IPPROTO_TCP)
40 #define IPPROTO_TCP		(0)
41 #endif
42 
43 #define MSGVEC_SIZE		(4)
44 
45 #define PROC_CONG_CTRLS		"/proc/sys/net/ipv4/tcp_allowed_congestion_control"
46 
47 typedef struct {
48 	const char *optname;
49 	const int   optval;
50 } stress_socket_options_t;
51 
52 static const stress_help_t help[] = {
53 	{ "S N", "sock N",		"start N workers exercising socket I/O" },
54 	{ NULL,	"sock-domain D",	"specify socket domain, default is ipv4" },
55 	{ NULL,	"sock-nodelay",		"disable Nagle algorithm, send data immediately" },
56 	{ NULL,	"sock-ops N",		"stop after N socket bogo operations" },
57 	{ NULL,	"sock-opts option", 	"socket options [send|sendmsg|sendmmsg]" },
58 	{ NULL,	"sock-port P",		"use socket ports P to P + number of workers - 1" },
59 	{ NULL, "sock-protocol",	"use socket protocol P, default is tcp, can be mptcp" },
60 	{ NULL,	"sock-type T",		"socket type (stream, seqpacket)" },
61 	{ NULL, "sock-zerocopy",	"enable zero copy sends" },
62 	{ NULL,	NULL,			NULL }
63 };
64 
65 /*
66  *  stress_set_socket_option()
67  *	generic helper to set an option
68  */
stress_set_socket_option(const char * setting,const stress_socket_options_t options[],const char * opt)69 static int stress_set_socket_option(
70 	const char *setting,
71 	const stress_socket_options_t options[],
72 	const char *opt)
73 {
74 	size_t i;
75 
76 	for (i = 0; options[i].optname; i++) {
77 		if (!strcmp(opt, options[i].optname)) {
78 			int type = options[i].optval;
79 
80 			stress_set_setting(setting, TYPE_ID_INT, &type);
81 			return 0;
82 		}
83 	}
84 	(void)fprintf(stderr, "%s option '%s' not known, options are:", setting, opt);
85 	for (i = 0; options[i].optname; i++) {
86 		(void)fprintf(stderr, "%s %s",
87 			i == 0 ? "" : ",", options[i].optname);
88 	}
89 	(void)fprintf(stderr, "\n");
90 	return -1;
91 }
92 
93 /*
94  *  stress_set_socket_opts()
95  *	parse --sock-opts
96  */
stress_set_socket_opts(const char * opt)97 static int stress_set_socket_opts(const char *opt)
98 {
99 	static const stress_socket_options_t socket_opts[] = {
100 		{ "random",	SOCKET_OPT_RANDOM },
101 		{ "send",	SOCKET_OPT_SEND },
102 		{ "sendmsg",	SOCKET_OPT_SENDMSG },
103 #if defined(HAVE_SENDMMSG)
104 		{ "sendmmsg",	SOCKET_OPT_SENDMMSG },
105 #endif
106 		{ NULL,		0 }
107 	};
108 
109 	return stress_set_socket_option("sock-opts", socket_opts, opt);
110 }
111 
112 /*
113  *  stress_set_socket_type()
114  *	parse --sock-type
115  */
stress_set_socket_type(const char * opt)116 static int stress_set_socket_type(const char *opt)
117 {
118 	static const stress_socket_options_t socket_types[] = {
119 #if defined(SOCK_STREAM)
120 		{ "stream",	SOCK_STREAM  },
121 #endif
122 #if defined(SOCK_SEQPACKET)
123 		{ "seqpacket",	SOCK_SEQPACKET },
124 #endif
125 		{ NULL,		0 }
126 	};
127 
128 	return stress_set_socket_option("sock-type", socket_types, opt);
129 }
130 
131 /*
132  *  stress_set_socket_port()
133  *	set port to use
134  */
stress_set_socket_port(const char * opt)135 static int stress_set_socket_port(const char *opt)
136 {
137 	int socket_port;
138 
139 	stress_set_net_port("sock-port", opt,
140 		MIN_SOCKET_PORT, MAX_SOCKET_PORT - STRESS_PROCS_MAX,
141 		&socket_port);
142 	return stress_set_setting("sock-port", TYPE_ID_INT, &socket_port);
143 }
144 
145 /*
146  *  stress_set_socket_protocol()
147  *	parse --sock-protocol
148  */
stress_set_socket_protocol(const char * opt)149 static int stress_set_socket_protocol(const char *opt)
150 {
151 	static const stress_socket_options_t socket_protocols[] = {
152 		{ "tcp",	IPPROTO_TCP},
153 #if defined(IPPROTO_MPTCP)
154 		{ "mptcp",	IPPROTO_MPTCP},
155 #endif
156 		{ NULL,		0 }
157 	};
158 
159 	return stress_set_socket_option("sock-protocol", socket_protocols, opt);
160 }
161 
162 
163 /*
164  *  stress_set_socket_domain()
165  *	set the socket domain option
166  */
stress_set_socket_domain(const char * name)167 static int stress_set_socket_domain(const char *name)
168 {
169 	int ret, socket_domain;
170 
171 	ret = stress_set_net_domain(DOMAIN_ALL, "sock-domain",
172 				     name, &socket_domain);
173 	stress_set_setting("sock-domain", TYPE_ID_INT, &socket_domain);
174 
175 	return ret;
176 }
177 
178 /*
179  *  stress_set_socket_zerocopy()
180  *	set the socket zerocopy option
181  */
stress_set_socket_zerocopy(const char * opt)182 static int stress_set_socket_zerocopy(const char *opt)
183 {
184 #if defined(MSG_ZEROCOPY)
185 	bool socket_zerocopy = true;
186 
187 	(void)opt;
188 	return stress_set_setting("sock-zerocopy", TYPE_ID_BOOL, &socket_zerocopy);
189 #else
190 	(void)opt;
191 	pr_inf("sock: cannot enable sock-zerocopy, MSG_ZEROCOPY is not available\n");
192 	return 0;
193 #endif
194 }
195 
196 /*
197  *  stress_free_congestion_controls()
198  *	free congestion controls array
199  */
stress_free_congestion_controls(char * ctrls[],const size_t n)200 static void stress_free_congestion_controls(char *ctrls[], const size_t n)
201 {
202 	size_t i;
203 
204 	if (!ctrls)
205 		return;
206 
207 	for (i = 0; i < n; i++)
208 		free(ctrls[i]);
209 
210 	free(ctrls); /* cppcheck-suppress autovarInvalidDeallocation */
211 }
212 
213 /*
214  *  stress_get_congestion_controls()
215  *	get congestion controls, currently only for AF_INET. ctrls is a
216  *	pointer to an array of pointers to available congestion control names -
217  *	the array is allocated by this function, or NULL if it fails. Returns
218  *	the number of congestion controls, 0 if none found.
219  */
stress_get_congestion_controls(const int socket_domain,char ** ctrls[])220 static size_t stress_get_congestion_controls(const int socket_domain, char **ctrls[])
221 {
222 	char buf[4096], *ptr, *ctrl;
223 	char **array = NULL;
224 	size_t n_ctrls;
225 
226 	*ctrls = NULL;
227 
228 	if (socket_domain != AF_INET)
229 		return 0;
230 
231 	if (system_read(PROC_CONG_CTRLS, buf, sizeof(buf)) < 0)
232 		return 0;
233 
234 	for (n_ctrls = 0, ptr = buf; (ctrl = strtok(ptr, " ")) != NULL; ptr = NULL) {
235 		char **tmp, *newline = strchr(ctrl, '\n');
236 
237 		if (newline)
238 			*newline = '\0';
239 
240 		tmp = realloc(array , (sizeof(*array)) * (n_ctrls + 1));
241 		if (!tmp) {
242 			stress_free_congestion_controls(array, n_ctrls);
243 			return 0;
244 		}
245 		array = tmp;
246 		array[n_ctrls] = strdup(ctrl);
247 		if (!array[n_ctrls]) {
248 			stress_free_congestion_controls(array, n_ctrls);
249 			return 0;
250 		}
251 		n_ctrls++;
252 	}
253 
254 	*ctrls = array;
255 	return n_ctrls;
256 }
257 
258 /*
259  *  stress_sock_ioctl()
260  *	exercise various ioctl commands
261  */
stress_sock_ioctl(const int fd,const int socket_domain,const bool rt)262 static void stress_sock_ioctl(
263 	const int fd,
264 	const int socket_domain,
265 	const bool rt)
266 {
267 	(void)fd;
268 	(void)socket_domain;
269 	(void)rt;
270 
271 #if defined(FIOGETOWN)
272 	if (!rt) {
273 		int ret, own;
274 
275 		ret = ioctl(fd, FIOGETOWN, &own);
276 #if defined(FIOSETOWN)
277 		if (ret == 0)
278 			ret = ioctl(fd, FIOSETOWN, &own);
279 		(void)ret;
280 #endif
281 	}
282 #endif
283 
284 #if defined(SIOCGPGRP)
285 	if (!rt) {
286 		int ret, own;
287 
288 		ret = ioctl(fd, SIOCGPGRP, &own);
289 #if defined(SIOCSPGRP)
290 		if (ret == 0)
291 			ret = ioctl(fd, SIOCSPGRP, &own);
292 #endif
293 		(void)ret;
294 	}
295 #endif
296 #if defined(SIOCGIFCONF) && \
297     defined(HAVE_IFCONF)
298 	if (!rt) {
299 		int ret;
300 		struct ifconf ifc;
301 
302 		(void)memset(&ifc, 0, sizeof(ifc));
303 		ret = ioctl(fd, SIOCGIFCONF, &ifc);
304 		(void)ret;
305 	}
306 #endif
307 
308 	/*
309 	 *  On some 32 bit arches on some kernels/libc flavours
310 	 *  struct __kernel_old_timeval is not defined and causes
311 	 *  this ioctl to break the build. So only build it for
312 	 *  64 bit arches as a workaround.
313 	 */
314 #if defined(SIOCGSTAMP) &&	\
315     (ULONG_MAX > 4294967295UL)
316 	{
317 		int ret;
318 		struct timeval tv;
319 
320 		ret = ioctl(fd, SIOCGSTAMP, &tv);
321 		(void)ret;
322 	}
323 #endif
324 
325 #if defined(SIOCGSTAMP_NEW) &&	\
326     (ULONG_MAX > 4294967295UL)
327 	{
328 		int ret;
329 		struct timeval tv;
330 
331 		ret = ioctl(fd, SIOCGSTAMP_NEW, &tv);
332 		(void)ret;
333 	}
334 #endif
335 
336 #if defined(SIOCGSKNS)
337 	{
338 		int ns_fd;
339 
340 		ns_fd = ioctl(fd, SIOCGSKNS);
341 		if (ns_fd >= 0)
342 			(void)close(ns_fd);
343 	}
344 #endif
345 
346 #if defined(__linux__) &&	\
347     !defined(SIOCUNIXFILE)
348 #define SIOCUNIXFILE (SIOCPROTOPRIVATE + 0)
349 #endif
350 
351 #if defined(SIOCUNIXFILE)
352 	if (socket_domain == AF_UNIX) {
353 		int fd_unixfile;
354 
355 		fd_unixfile = ioctl(fd, SIOCUNIXFILE, 0);
356 		if (fd_unixfile >= 0)
357 			(void)close(fd_unixfile);
358 	}
359 #endif
360 }
361 
362 /*
363  *  stress_sock_invalid_recv()
364  *	exercise invalid recv* calls
365  */
stress_sock_invalid_recv(const int fd,const int opt)366 static void stress_sock_invalid_recv(const int fd, const int opt)
367 {
368 	ssize_t n;
369 	char buf[16];
370 	struct iovec vec[1];
371 	struct msghdr msg;
372 #if defined(HAVE_RECVMMSG)
373 	struct mmsghdr msgvec[MSGVEC_SIZE];
374 	struct timespec ts;
375 #endif
376 
377 	switch (opt) {
378 	case SOCKET_OPT_RECV:
379 		/* exercise invalid flags */
380 		n = recv(fd, buf, sizeof(buf), ~0);
381 		(void)n;
382 
383 		/* exercise invalid fd */
384 		n = recv(~0, buf, sizeof(buf), 0);
385 		(void)n;
386 		break;
387 	case SOCKET_OPT_RECVMSG:
388 		vec[0].iov_base = buf;
389 		vec[0].iov_len = sizeof(buf);
390 		(void)memset(&msg, 0, sizeof(msg));
391 		msg.msg_iov = vec;
392 		msg.msg_iovlen = 1;
393 
394 		/* exercise invalid flags */
395 		n = recvmsg(fd, &msg, ~0);
396 		(void)n;
397 
398 		/* exercise invalid fd */
399 		n = recvmsg(~0, &msg, 0);
400 		(void)n;
401 		break;
402 #if defined(HAVE_RECVMMSG)
403 	case SOCKET_OPT_RECVMMSG:
404 		(void)memset(msgvec, 0, sizeof(msgvec));
405 		vec[0].iov_base = buf;
406 		vec[0].iov_len = sizeof(buf);
407 		msgvec[0].msg_hdr.msg_iov = vec;
408 		msgvec[0].msg_hdr.msg_iovlen = 1;
409 
410 		/* exercise invalid flags */
411 		n = recvmmsg(fd, msgvec, MSGVEC_SIZE, ~0, NULL);
412 		(void)n;
413 
414 		/* exercise invalid fd */
415 		n = recvmmsg(~0, msgvec, MSGVEC_SIZE, 0, NULL);
416 		(void)n;
417 
418 		/* exercise invalid timespec */
419 		ts.tv_sec = 0;
420 		ts.tv_nsec = 0;
421 		n = recvmmsg(~0, msgvec, MSGVEC_SIZE, 0, &ts);
422 		(void)n;
423 		break;
424 #endif
425 	}
426 }
427 
428 /*
429  *  stress_sock_client()
430  *	client reader
431  */
stress_sock_client(const stress_args_t * args,char * buf,const pid_t ppid,const int socket_opts,const int socket_domain,const int socket_type,const int socket_protocol,const int socket_port,const bool rt,const bool socket_zerocopy)432 static void stress_sock_client(
433 	const stress_args_t *args,
434 	char *buf,
435 	const pid_t ppid,
436 	const int socket_opts,
437 	const int socket_domain,
438 	const int socket_type,
439 	const int socket_protocol,
440 	const int socket_port,
441 	const bool rt,
442 	const bool socket_zerocopy)
443 {
444 	struct sockaddr *addr;
445 	size_t n_ctrls;
446 	char **ctrls;
447 	int recvflag = 0;
448 
449 	(void)setpgid(0, g_pgrp);
450 	stress_parent_died_alarm();
451 	(void)sched_settings_apply(true);
452 
453 	n_ctrls = stress_get_congestion_controls(socket_domain, &ctrls);
454 
455 #if defined(MSG_ZEROCOPY)
456 	if (socket_zerocopy)
457 		recvflag |= MSG_ZEROCOPY;
458 #else
459 	(void)socket_zerocopy;
460 #endif
461 
462 	do {
463 		int fd;
464 		int retries = 0;
465 		static int count = 0;
466 		socklen_t addr_len = 0;
467 retry:
468 		if (!keep_stressing_flag()) {
469 			(void)kill(getppid(), SIGALRM);
470 			_exit(EXIT_FAILURE);
471 		}
472 
473 		/* Exercise illegal socket family  */
474 		fd = socket(~0, socket_type, socket_protocol);
475 		if (fd >= 0)
476 			(void)close(fd);
477 
478 		/* Exercise illegal socket type */
479 		fd = socket(socket_domain, ~0, socket_protocol);
480 		if (fd >= 0)
481 			(void)close(fd);
482 
483 		/* Exercise illegal socket protocol */
484 		fd = socket(socket_domain, socket_type, ~0);
485 		if (fd >= 0)
486 			(void)close(fd);
487 
488 		fd = socket(socket_domain, socket_type, socket_protocol);
489 		if (fd < 0) {
490 			pr_fail("%s: socket failed, errno=%d (%s)\n",
491 				args->name, errno, strerror(errno));
492 			/* failed, kick parent to finish */
493 			(void)kill(getppid(), SIGALRM);
494 			_exit(EXIT_FAILURE);
495 		}
496 
497 		stress_set_sockaddr(args->name, args->instance, ppid,
498 			socket_domain, socket_port,
499 			&addr, &addr_len, NET_ADDR_ANY);
500 		if (connect(fd, addr, addr_len) < 0) {
501 			int errno_tmp = errno;
502 
503 			(void)close(fd);
504 			(void)shim_usleep(10000);
505 			retries++;
506 			if (retries > 100) {
507 				/* Give up.. */
508 				pr_fail("%s: connect failed, errno=%d (%s)\n",
509 					args->name, errno_tmp, strerror(errno_tmp));
510 				(void)kill(getppid(), SIGALRM);
511 				_exit(EXIT_FAILURE);
512 			}
513 			goto retry;
514 		}
515 
516 #if defined(TCP_CONGESTION)
517 		/*
518 		 *  Randomly set congestion control
519 		 */
520 		if (n_ctrls > 0) {
521 			const int idx = stress_mwc16() % n_ctrls;
522 			const char *control = ctrls[idx];
523 			char name[256];
524 			socklen_t len;
525 
526 			len = (socklen_t)strlen(ctrls[idx]);
527 			(void)setsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, control, len);
528 			len = (socklen_t)sizeof(name);
529 			(void)getsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, name, &len);
530 		}
531 #endif
532 #if defined(IP_MTU)
533 		{
534 			int ret, mtu;
535 			socklen_t optlen;
536 
537 			optlen = sizeof(mtu);
538 			ret = getsockopt(fd, IPPROTO_IP, IP_MTU,
539 				&mtu, &optlen);
540 			if (ret == 0) {
541 				optlen = sizeof(mtu);
542 				ret = setsockopt(fd, IPPROTO_IP, IP_MTU,
543 					&mtu, optlen);
544 			}
545 			(void)ret;
546 		}
547 #endif
548 #if defined(IP_TOS) &&	\
549     defined(IPTOS_THROUGHPUT)
550 		{
551 			char tos = IPTOS_THROUGHPUT;
552 			socklen_t optlen = sizeof(tos);
553 
554 			(void)setsockopt(fd, IPPROTO_IP, IP_TOS,
555 				&tos, optlen);
556 			(void)getsockopt(fd, IPPROTO_IP, IP_TOS,
557 				&tos, &optlen);
558 		}
559 #endif
560 #if defined(SO_INCOMING_CPU)
561 		{
562 			int cpu;
563 			socklen_t optlen = sizeof(cpu);
564 
565 			(void)getsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU,
566 				&cpu, &optlen);
567 		}
568 #endif
569 		if ((socket_domain == AF_INET) || (socket_domain == AF_INET6)) {
570 #if defined(TCP_NODELAY)
571 			{
572 				int val = 0, ret;
573 				socklen_t optlen = sizeof(val);
574 
575 				ret = getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, &optlen);
576 				if (ret == 0) {
577 					optlen = sizeof(val);
578 					ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, optlen);
579 				}
580 				(void)ret;
581 			}
582 #endif
583 #if defined(TCP_CORK)
584 			{
585 				int val = 0, ret;
586 				socklen_t optlen = sizeof(val);
587 
588 				ret = getsockopt(fd, IPPROTO_TCP, TCP_CORK, &val, &optlen);
589 				if (ret == 0) {
590 					optlen = sizeof(val);
591 					ret = setsockopt(fd, IPPROTO_TCP, TCP_CORK, &val, optlen);
592 				}
593 				(void)ret;
594 			}
595 #endif
596 #if defined(TCP_DEFER_ACCEPT)
597 			{
598 				int val = 0, ret;
599 				socklen_t optlen = sizeof(val);
600 
601 				ret = getsockopt(fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &val, &optlen);
602 				if (ret == 0) {
603 					optlen = sizeof(val);
604 					ret = setsockopt(fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &val, optlen);
605 				}
606 				(void)ret;
607 			}
608 #endif
609 #if defined(TCP_KEEPCNT)
610 			{
611 				int val = 0, ret;
612 				socklen_t optlen = sizeof(val);
613 
614 				ret = getsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, &optlen);
615 				if (ret == 0) {
616 					optlen = sizeof(val);
617 					ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, optlen);
618 				}
619 				(void)ret;
620 			}
621 #endif
622 #if defined(TCP_KEEPIDLE)
623 			{
624 				int val = 0, ret;
625 				socklen_t optlen = sizeof(val);
626 
627 				ret = getsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, &optlen);
628 				if (ret == 0) {
629 					optlen = sizeof(val);
630 					ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, optlen);
631 				}
632 				(void)ret;
633 			}
634 #endif
635 #if defined(TCP_KEEPINTVL)
636 			{
637 				int val = 0, ret;
638 				socklen_t optlen = sizeof(val);
639 
640 				ret = getsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, &optlen);
641 				if (ret == 0) {
642 					optlen = sizeof(val);
643 					ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, optlen);
644 				}
645 				(void)ret;
646 			}
647 #endif
648 #if defined(TCP_LINGER2)
649 			{
650 				int val = 0, ret;
651 				socklen_t optlen = sizeof(val);
652 
653 				ret = getsockopt(fd, IPPROTO_TCP, TCP_LINGER2, &val, &optlen);
654 				if (ret == 0) {
655 					optlen = sizeof(val);
656 					ret = setsockopt(fd, IPPROTO_TCP, TCP_LINGER2, &val, optlen);
657 				}
658 				(void)ret;
659 			}
660 #endif
661 #if defined(TCP_MAXSEG)
662 			{
663 				int val = 0, ret;
664 				socklen_t optlen = sizeof(val);
665 
666 				ret = getsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &val, &optlen);
667 				if (ret == 0) {
668 					optlen = sizeof(val);
669 					ret = setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &val, optlen);
670 				}
671 				(void)ret;
672 			}
673 #endif
674 #if defined(TCP_SYNCNT)
675 			{
676 				int val = 0, ret;
677 				socklen_t optlen = sizeof(val);
678 
679 				ret = getsockopt(fd, IPPROTO_TCP, TCP_SYNCNT, &val, &optlen);
680 				if (ret == 0) {
681 					optlen = sizeof(val);
682 					ret = setsockopt(fd, IPPROTO_TCP, TCP_SYNCNT, &val, optlen);
683 				}
684 				(void)ret;
685 			}
686 #endif
687 #if defined(TCP_USER_TIMEOUT)
688 			{
689 				int val = 0, ret;
690 				socklen_t optlen = sizeof(val);
691 
692 				ret = getsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &val, &optlen);
693 				if (ret == 0) {
694 					optlen = sizeof(val);
695 					ret = setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &val, optlen);
696 				}
697 				(void)ret;
698 			}
699 #endif
700 #if defined(TCP_WINDOW_CLAMP)
701 			{
702 				int val = 0, ret;
703 				socklen_t optlen = sizeof(val);
704 
705 				ret = getsockopt(fd, IPPROTO_TCP, TCP_WINDOW_CLAMP, &val, &optlen);
706 				if (ret == 0) {
707 					optlen = sizeof(val);
708 					ret = setsockopt(fd, IPPROTO_TCP, TCP_WINDOW_CLAMP, &val, optlen);
709 				}
710 				(void)ret;
711 			}
712 #endif
713 		}
714 
715 		do {
716 			ssize_t n = 0;
717 			size_t i, j;
718 			char *recvfunc = "recv";
719 			struct msghdr msg;
720 			struct iovec vec[MMAP_IO_SIZE / 16];
721 #if defined(HAVE_RECVMMSG)
722 			struct mmsghdr msgvec[MSGVEC_SIZE];
723 			const int max_opt = 3;
724 #else
725 			const int max_opt = 2;
726 #endif
727 			const int opt = (socket_opts == SOCKET_OPT_RANDOM) ?
728 					stress_mwc8() % max_opt: socket_opts;
729 
730 #if defined(FIONREAD)
731 			/*
732 			 *  Exercise FIONREAD ioctl. Linux supports
733 			 *  this also with SIOCINQ but lets try and
734 			 *  do the more standard way of peeking the
735 			 *  pending data size.  Do this infrequently
736 			 *  to ensure we exercise it without impacting
737 			 *  performance.
738 			 */
739 			if ((count & 0x3ff) == 0) {
740 				int ret;
741 				size_t bytes = MMAP_IO_SIZE;
742 
743 				ret = ioctl(fd, FIONREAD, &bytes);
744 				(void)ret;
745 				count = 0;
746 
747 				if (bytes > MMAP_IO_SIZE)
748 					bytes = MMAP_IO_SIZE;
749 
750 			}
751 #endif
752 			/*  Periodically exercise invalid recv calls */
753 			if ((count & 0x7ff) == 0)
754 				stress_sock_invalid_recv(fd, opt);
755 #if defined(SIOCINQ)
756 			{
757 				int pending;
758 
759 				(void)ioctl(fd, SIOCINQ, &pending);
760 			}
761 #endif
762 
763 			/*
764 			 *  Receive using equivalent receive method
765 			 *  as the send
766 			 */
767 			switch (opt) {
768 			case SOCKET_OPT_RECV:
769 				recvfunc = "recv";
770 				n = recv(fd, buf, MMAP_IO_SIZE, recvflag);
771 				break;
772 			case SOCKET_OPT_RECVMSG:
773 				recvfunc = "recvmsg";
774 				for (j = 0, i = 16; i < MMAP_IO_SIZE; i += 16, j++) {
775 					vec[j].iov_base = buf;
776 					vec[j].iov_len = i;
777 				}
778 				(void)memset(&msg, 0, sizeof(msg));
779 				msg.msg_iov = vec;
780 				msg.msg_iovlen = j;
781 				n = recvmsg(fd, &msg, 0);
782 				break;
783 #if defined(HAVE_RECVMMSG)
784 			case SOCKET_OPT_RECVMMSG:
785 				recvfunc = "recvmmsg";
786 				(void)memset(msgvec, 0, sizeof(msgvec));
787 				for (j = 0, i = 16; i < MMAP_IO_SIZE; i += 16, j++) {
788 					vec[j].iov_base = buf;
789 					vec[j].iov_len = i;
790 				}
791 				for (i = 0; i < MSGVEC_SIZE; i++) {
792 					msgvec[i].msg_hdr.msg_iov = vec;
793 					msgvec[i].msg_hdr.msg_iovlen = j;
794 				}
795 				n = recvmmsg(fd, msgvec, MSGVEC_SIZE, 0, NULL);
796 				if (n > 0) {
797 					for (n = 0, i = 0; i < MSGVEC_SIZE; i++)
798 						n += msgvec[i].msg_len;
799 				}
800 				break;
801 #endif
802 			}
803 			if (n == 0)
804 				break;
805 			if (n < 0) {
806 				if ((errno != EINTR) && (errno != ECONNRESET))
807 					pr_fail("%s: %s failed, errno=%d (%s)\n",
808 						recvfunc, args->name,
809 						errno, strerror(errno));
810 				break;
811 			}
812 			count++;
813 		} while (keep_stressing(args));
814 
815 		stress_sock_ioctl(fd, socket_domain, rt);
816 #if defined(AF_INET) && 	\
817     defined(IPPROTO_IP)	&&	\
818     defined(IP_MTU)
819 		/* Exercise IP_MTU */
820 		if (socket_domain == AF_INET) {
821 			int ret, mtu;
822 			socklen_t mtu_len = sizeof(mtu);
823 
824 			ret = getsockopt(fd, IPPROTO_IP, IP_MTU, &mtu, &mtu_len);
825 			(void)ret;
826 		}
827 #endif
828 
829 		(void)shutdown(fd, SHUT_RDWR);
830 		(void)close(fd);
831 	} while (keep_stressing(args));
832 
833 #if defined(AF_UNIX) &&		\
834     defined(HAVE_SOCKADDR_UN)
835 	if (socket_domain == AF_UNIX) {
836 		struct sockaddr_un *addr_un = (struct sockaddr_un *)addr;
837 
838 		(void)unlink(addr_un->sun_path);
839 	}
840 #endif
841 	/* Inform parent we're all done */
842 	stress_free_congestion_controls(ctrls, n_ctrls);
843 
844 	(void)kill(getppid(), SIGALRM);
845 }
846 
847 /*
848  *  stress_sock_server()
849  *	server writer
850  */
stress_sock_server(const stress_args_t * args,char * buf,const pid_t pid,const pid_t ppid,const int socket_opts,const int socket_domain,const int socket_type,const int socket_protocol,const int socket_port,const bool rt,const bool socket_zerocopy)851 static int stress_sock_server(
852 	const stress_args_t *args,
853 	char *buf,
854 	const pid_t pid,
855 	const pid_t ppid,
856 	const int socket_opts,
857 	const int socket_domain,
858 	const int socket_type,
859 	const int socket_protocol,
860 	const int socket_port,
861 	const bool rt,
862 	const bool socket_zerocopy)
863 {
864 	int fd, status;
865 	int so_reuseaddr = 1;
866 	socklen_t addr_len = 0;
867 	struct sockaddr *addr = NULL;
868 	uint64_t msgs = 0;
869 	int rc = EXIT_SUCCESS;
870 	const size_t page_size = args->page_size;
871 	void *ptr = MAP_FAILED;
872 	const pid_t self = getpid();
873 	int sendflag = 0;
874 
875 #if defined(MSG_ZEROCOPY)
876 	if (socket_zerocopy)
877 		sendflag |= MSG_ZEROCOPY;
878 #else
879 	(void)socket_zerocopy;
880 #endif
881 
882 	(void)setpgid(pid, g_pgrp);
883 
884 	if (stress_sig_stop_stressing(args->name, SIGALRM) < 0) {
885 		rc = EXIT_FAILURE;
886 		goto die;
887 	}
888 
889 	if ((fd = socket(socket_domain, socket_type, socket_protocol)) < 0) {
890 		rc = exit_status(errno);
891 		pr_fail("%s: socket failed, errno=%d (%s)\n",
892 			args->name, errno, strerror(errno));
893 		goto die;
894 	}
895 	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
896 		&so_reuseaddr, sizeof(so_reuseaddr)) < 0) {
897 		pr_fail("%s: setsockopt failed, errno=%d (%s)\n",
898 			args->name, errno, strerror(errno));
899 		rc = EXIT_FAILURE;
900 		goto die_close;
901 	}
902 	/* exercise invalid setsockopt lengths */
903 	(void)setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr, 0);
904 	(void)setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr, -1);
905 
906 	/* exercise invalid setsockopt fd */
907 	(void)setsockopt(-1, SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr, sizeof(so_reuseaddr));
908 
909 	/* exercise invalid level */
910 	(void)setsockopt(fd, -1, SO_REUSEADDR, &so_reuseaddr, sizeof(so_reuseaddr));
911 
912 	/* exercise invalid optname */
913 	(void)setsockopt(fd, SOL_SOCKET, -1, &so_reuseaddr, sizeof(so_reuseaddr));
914 
915 	stress_set_sockaddr(args->name, args->instance, ppid,
916 		socket_domain, socket_port,
917 		&addr, &addr_len, NET_ADDR_ANY);
918 	if (bind(fd, addr, addr_len) < 0) {
919 		rc = exit_status(errno);
920 		pr_fail("%s: bind failed, errno=%d (%s)\n",
921 			args->name, errno, strerror(errno));
922 		goto die_close;
923 	}
924 	if (listen(fd, 10) < 0) {
925 		pr_fail("%s: listen failed, errno=%d (%s)\n",
926 			args->name, errno, strerror(errno));
927 		rc = EXIT_FAILURE;
928 		goto die_close;
929 	}
930 
931 	/*
932 	 * Some systems allow us to mmap onto the fd
933 	 * so try and do this just because we can
934 	 */
935 	ptr = mmap(NULL, page_size, PROT_READ, MAP_PRIVATE, fd, 0);
936 
937 	do {
938 		int sfd;
939 
940 		if (!keep_stressing(args))
941 			break;
942 
943 #if defined(HAVE_ACCEPT4)
944 		/*  Randomly use accept or accept4 to exercise both */
945 		if (stress_mwc1()) {
946 			sfd = accept4(fd, (struct sockaddr *)NULL, NULL, SOCK_CLOEXEC);
947 		} else {
948 			sfd = accept(fd, (struct sockaddr *)NULL, NULL);
949 		}
950 #else
951 		sfd = accept(fd, (struct sockaddr *)NULL, NULL);
952 #endif
953 		if (sfd >= 0) {
954 			size_t i, j;
955 			struct sockaddr saddr;
956 			socklen_t len;
957 			int sndbuf, opt;
958 			struct msghdr msg;
959 			struct iovec vec[MMAP_IO_SIZE / 16];
960 #if defined(HAVE_SENDMMSG)
961 			struct mmsghdr msgvec[MSGVEC_SIZE];
962 #endif
963 
964 			len = sizeof(saddr);
965 			if (getsockname(fd, &saddr, &len) < 0) {
966 				pr_fail("%s: getsockname failed, errno=%d (%s)\n",
967 					args->name, errno, strerror(errno));
968 				(void)close(sfd);
969 				break;
970 			}
971 			/*
972 			 *  Exercise illegal sockname lengths
973 			 */
974 			{
975 				int ret;
976 
977 				len = 0;
978 				ret = getsockname(fd, &saddr, &len);
979 				(void)ret;
980 
981 				len = 1;
982 				ret = getsockname(fd, &saddr, &len);
983 				(void)ret;
984 			}
985 
986 			len = sizeof(sndbuf);
987 			if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, &len) < 0) {
988 				pr_fail("%s: getsockopt failed, errno=%d (%s)\n",
989 					args->name, errno, strerror(errno));
990 				(void)close(sfd);
991 				break;
992 			}
993 #if defined(SOL_TCP) &&	\
994     defined(TCP_QUICKACK)
995 			{
996 				int ret, one = 1;
997 				/*
998 				 * We try do to a TCP_QUICKACK, failing is OK as
999 				 * it's just a faster optimization option
1000 				 */
1001 				ret = setsockopt(fd, SOL_TCP, TCP_QUICKACK, &one, sizeof(one));
1002 				(void)ret;
1003 			}
1004 #endif
1005 
1006 #if defined(SOL_TCP) &&	\
1007     defined(HAVE_NETINET_TCP_H)
1008 			if (g_opt_flags & OPT_FLAGS_SOCKET_NODELAY) {
1009 				int one = 1;
1010 
1011 				if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) {
1012 					pr_inf("%s: setsockopt TCP_NODELAY "
1013 						"failed and disabled, errno=%d (%s)\n",
1014 						args->name, errno, strerror(errno));
1015 					g_opt_flags &= ~OPT_FLAGS_SOCKET_NODELAY;
1016 				}
1017 			}
1018 #endif
1019 			(void)memset(buf, 'A' + (get_counter(args) % 26), MMAP_IO_SIZE);
1020 
1021 			if (socket_opts == SOCKET_OPT_RANDOM)
1022 				opt = stress_mwc8() % 3;
1023 			else
1024 				opt = socket_opts;
1025 
1026 			switch (opt) {
1027 			case SOCKET_OPT_SEND:
1028 				for (i = 16; i < MMAP_IO_SIZE; i += 16) {
1029 					ssize_t ret = send(sfd, buf, i, sendflag);
1030 					if (ret < 0) {
1031 						if ((errno != EINTR) && (errno != EPIPE))
1032 							pr_fail("%s: send failed, errno=%d (%s)\n",
1033 								args->name, errno, strerror(errno));
1034 						break;
1035 					} else
1036 						msgs++;
1037 				}
1038 				break;
1039 			case SOCKET_OPT_SENDMSG:
1040 				for (j = 0, i = 16; i < MMAP_IO_SIZE; i += 16, j++) {
1041 					vec[j].iov_base = buf;
1042 					vec[j].iov_len = i;
1043 				}
1044 				(void)memset(&msg, 0, sizeof(msg));
1045 				msg.msg_iov = vec;
1046 				msg.msg_iovlen = j;
1047 				if (sendmsg(sfd, &msg, 0) < 0) {
1048 					if ((errno != EINTR) && (errno != EPIPE))
1049 						pr_fail("%s: sendmsg failed, errno=%d (%s)\n",
1050 							args->name, errno, strerror(errno));
1051 				} else
1052 					msgs += j;
1053 				break;
1054 #if defined(HAVE_SENDMMSG)
1055 			case SOCKET_OPT_SENDMMSG:
1056 				(void)memset(msgvec, 0, sizeof(msgvec));
1057 				for (j = 0, i = 16; i < MMAP_IO_SIZE; i += 16, j++) {
1058 					vec[j].iov_base = buf;
1059 					vec[j].iov_len = i;
1060 				}
1061 				for (i = 0; i < MSGVEC_SIZE; i++) {
1062 					msgvec[i].msg_hdr.msg_iov = vec;
1063 					msgvec[i].msg_hdr.msg_iovlen = j;
1064 				}
1065 				if (sendmmsg(sfd, msgvec, MSGVEC_SIZE, 0) < 0) {
1066 					if ((errno != EINTR) && (errno != EPIPE))
1067 						pr_fail("%s: sendmmsg failed, errno=%d (%s)\n",
1068 							args->name, errno, strerror(errno));
1069 				} else
1070 					msgs += (MSGVEC_SIZE * j);
1071 				break;
1072 #endif
1073 			default:
1074 				/* Should never happen */
1075 				pr_err("%s: bad option %d\n", args->name, socket_opts);
1076 				(void)close(sfd);
1077 				goto die_close;
1078 			}
1079 			if (getpeername(sfd, &saddr, &len) < 0) {
1080 				if (errno != ENOTCONN)
1081 					pr_fail("%s: getpeername failed, errno=%d (%s)\n",
1082 						args->name, errno, strerror(errno));
1083 			}
1084 #if defined(SIOCOUTQ)
1085 			{
1086 				int pending;
1087 
1088 				(void)ioctl(sfd, SIOCOUTQ, &pending);
1089 			}
1090 #endif
1091 			stress_sock_ioctl(fd, socket_domain, rt);
1092 			stress_read_fdinfo(self, sfd);
1093 
1094 			(void)close(sfd);
1095 		}
1096 
1097 #if defined(HAVE_ACCEPT4)
1098 		/*
1099 		 *  Exercise accept4 with invalid flags
1100 		 */
1101 		sfd = accept4(fd, (struct sockaddr *)NULL, NULL, ~0);
1102 		if (sfd)
1103 			(void)close(sfd);
1104 #endif
1105 		inc_counter(args);
1106 	} while (keep_stressing(args));
1107 
1108 die_close:
1109 	(void)close(fd);
1110 die:
1111 	if (ptr != MAP_FAILED)
1112 		(void)munmap(ptr, page_size);
1113 #if defined(AF_UNIX) &&		\
1114     defined(HAVE_SOCKADDR_UN)
1115 	if (addr && (socket_domain == AF_UNIX)) {
1116 		struct sockaddr_un *addr_un = (struct sockaddr_un *)addr;
1117 
1118 		(void)unlink(addr_un->sun_path);
1119 	}
1120 #endif
1121 	if (pid) {
1122 		(void)kill(pid, SIGKILL);
1123 		(void)shim_waitpid(pid, &status, 0);
1124 	}
1125 	pr_dbg("%s: %" PRIu64 " messages sent\n", args->name, msgs);
1126 
1127 	return rc;
1128 }
1129 
stress_sock_sigpipe_handler(int signum)1130 static void stress_sock_sigpipe_handler(int signum)
1131 {
1132 	(void)signum;
1133 
1134 	keep_stressing_set_flag(false);
1135 }
1136 
1137 /*
1138  *  stress_sock_kernel_rt()
1139  * 	return true if kernel is PREEMPT_RT, true if
1140  * 	not sure, false if definitely not PREEMPT_RT.
1141  */
stress_sock_kernel_rt(void)1142 static bool stress_sock_kernel_rt(void)
1143 {
1144 #if defined(HAVE_UNAME) &&	\
1145     defined(HAVE_SYS_UTSNAME_H)
1146 	struct utsname buf;
1147 
1148 	if (uname(&buf) < 0)
1149 		return true;	/* Not sure, assume rt */
1150 
1151 	if (strstr(buf.version, "PREEMPT_RT"))
1152 		return true;	/* Definitely rt */
1153 
1154 	/* probably not RT */
1155 	return false;
1156 #else
1157 	return true;		/* Not sure, assume rt */
1158 #endif
1159 }
1160 
1161 /*
1162  *  stress_sock
1163  *	stress by heavy socket I/O
1164  */
stress_sock(const stress_args_t * args)1165 static int stress_sock(const stress_args_t *args)
1166 {
1167 	pid_t pid, ppid = getppid();
1168 	int socket_opts = SOCKET_OPT_SEND;
1169 	int socket_domain = AF_INET;
1170 	int socket_type = SOCK_STREAM;
1171 	int socket_port = DEFAULT_SOCKET_PORT;
1172 #if defined(IPPROTO_TCP)
1173 	int socket_protocol = IPPROTO_TCP;
1174 #else
1175 	int socket_protocol = 0;
1176 #endif
1177 	int socket_zerocopy = false;
1178 	int rc = EXIT_SUCCESS;
1179 	const bool rt = stress_sock_kernel_rt();
1180 	char *mmap_buffer;
1181 
1182 	(void)stress_get_setting("sock-domain", &socket_domain);
1183 	(void)stress_get_setting("sock-type", &socket_type);
1184 	(void)stress_get_setting("sock-protocol", &socket_protocol);
1185 	(void)stress_get_setting("sock-port", &socket_port);
1186 	(void)stress_get_setting("sock-opts", &socket_opts);
1187 	(void)stress_get_setting("sock-zerocopy", &socket_zerocopy);
1188 
1189 	pr_dbg("%s: process [%d] using socket port %d\n",
1190 		args->name, (int)args->pid, socket_port + (int)args->instance);
1191 
1192 	if (stress_sighandler(args->name, SIGPIPE, stress_sock_sigpipe_handler, NULL) < 0)
1193 		return EXIT_NO_RESOURCE;
1194 
1195 	mmap_buffer = (char *)mmap(NULL, MMAP_BUF_SIZE, PROT_READ | PROT_WRITE,
1196 				MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
1197 	if (mmap_buffer == MAP_FAILED) {
1198 		pr_inf("%s: cannot mmap I/O buffer, errno=%d (%s)\n",
1199 			args->name, errno, strerror(errno));
1200 		return EXIT_NO_RESOURCE;
1201 	}
1202 
1203 	stress_set_proc_state(args->name, STRESS_STATE_RUN);
1204 again:
1205 	pid = fork();
1206 	if (pid < 0) {
1207 		if (stress_redo_fork(errno))
1208 			goto again;
1209 		if (!keep_stressing(args)) {
1210 			rc = EXIT_SUCCESS;
1211 			goto finish;
1212 		}
1213 		pr_fail("%s: fork failed, errno=%d (%s)\n",
1214 			args->name, errno, strerror(errno));
1215 		return EXIT_FAILURE;
1216 	} else if (pid == 0) {
1217 		stress_sock_client(args, mmap_buffer, ppid, socket_opts,
1218 			socket_domain, socket_type, socket_protocol,
1219 			socket_port, rt, socket_zerocopy);
1220 		(void)munmap((void *)mmap_buffer, MMAP_BUF_SIZE);
1221 		_exit(rc);
1222 	} else {
1223 		rc = stress_sock_server(args, mmap_buffer, pid, ppid, socket_opts,
1224 			socket_domain, socket_type, socket_protocol,
1225 			socket_port, rt, socket_zerocopy);
1226 		(void)munmap((void *)mmap_buffer, MMAP_BUF_SIZE);
1227 
1228 	}
1229 finish:
1230 	stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
1231 
1232 	return rc;
1233 }
1234 
1235 static const stress_opt_set_func_t opt_set_funcs[] = {
1236 	{ OPT_sock_domain,	stress_set_socket_domain },
1237 	{ OPT_sock_opts,	stress_set_socket_opts },
1238 	{ OPT_sock_type,	stress_set_socket_type },
1239 	{ OPT_sock_port,	stress_set_socket_port },
1240 	{ OPT_sock_protocol,	stress_set_socket_protocol },
1241 	{ OPT_sock_zerocopy,	stress_set_socket_zerocopy },
1242 	{ 0,			NULL }
1243 };
1244 
1245 stressor_info_t stress_sock_info = {
1246 	.stressor = stress_sock,
1247 	.class = CLASS_NETWORK | CLASS_OS,
1248 	.opt_set_funcs = opt_set_funcs,
1249 	.help = help
1250 };
1251