Home | History | Annotate | Download | only in netstress
      1 /*
      2  * Copyright (c) 2014-2016 Oracle and/or its affiliates. All Rights Reserved.
      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 as
      6  * published by the Free Software Foundation; either version 2 of
      7  * the License, or (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it would 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, see <http://www.gnu.org/licenses/>.
     16  *
     17  * Author: Alexey Kodanev <alexey.kodanev (at) oracle.com>
     18  *
     19  */
     20 
     21 #include <pthread.h>
     22 #include <stdlib.h>
     23 #include <limits.h>
     24 #include <sys/types.h>
     25 #include <sys/socket.h>
     26 #include <netdb.h>
     27 #include <netinet/in.h>
     28 #include <arpa/inet.h>
     29 #include <poll.h>
     30 #include <time.h>
     31 #include <string.h>
     32 #include <unistd.h>
     33 #include <errno.h>
     34 
     35 #include "lapi/posix_clocks.h"
     36 #include "tst_safe_pthread.h"
     37 #include "tst_test.h"
     38 
     39 static const int max_msg_len = (1 << 16) - 1;
     40 
     41 /* TCP server requiers */
     42 #ifndef TCP_FASTOPEN
     43 #define TCP_FASTOPEN	23
     44 #endif
     45 
     46 #ifndef SO_BUSY_POLL
     47 #define SO_BUSY_POLL	46
     48 #endif
     49 
     50 /* TCP client requiers */
     51 #ifndef MSG_FASTOPEN
     52 #define MSG_FASTOPEN	0x20000000 /* Send data in TCP SYN */
     53 #endif
     54 
     55 enum {
     56 	SERVER_HOST = 0,
     57 	CLIENT_HOST,
     58 };
     59 static char *client_mode;
     60 
     61 enum {
     62 	TFO_DISABLED = 0,
     63 	TFO_ENABLED,
     64 };
     65 static int tfo_value = -1;
     66 static char *fastopen_api;
     67 
     68 static const char tfo_cfg[]		= "/proc/sys/net/ipv4/tcp_fastopen";
     69 static const char tcp_tw_reuse[]	= "/proc/sys/net/ipv4/tcp_tw_reuse";
     70 static int tw_reuse_changed;
     71 static int tfo_cfg_value;
     72 static int tfo_cfg_changed;
     73 static int tfo_queue_size	= 100;
     74 static int max_queue_len	= 100;
     75 static const int client_byte	= 0x43;
     76 static const int server_byte	= 0x53;
     77 static const int start_byte	= 0x24;
     78 static const int start_fin_byte	= 0x25;
     79 static const int end_byte	= 0x0a;
     80 static int client_msg_size	= 32;
     81 static int server_msg_size	= 128;
     82 static char *client_msg;
     83 static char *server_msg;
     84 
     85 /*
     86  * The number of requests from client after
     87  * which server has to close the connection.
     88  */
     89 static int server_max_requests	= 3;
     90 static int client_max_requests	= 10;
     91 static int clients_num;
     92 static char *tcp_port		= "61000";
     93 static char *server_addr	= "localhost";
     94 static int busy_poll		= -1;
     95 static char *use_udp;
     96 /* server socket */
     97 static int sfd;
     98 
     99 /* how long a client must wait for the server's reply, microsec */
    100 static long wait_timeout = 60000000L;
    101 
    102 /* in the end test will save time result in this file */
    103 static char *rpath = "tfo_result";
    104 
    105 static char *verbose;
    106 
    107 static char *narg, *Narg, *qarg, *rarg, *Rarg, *aarg, *Targ, *barg, *targ;
    108 
    109 /* common structure for TCP/UDP server and TCP/UDP client */
    110 struct net_func {
    111 	void (*init)(void);
    112 	void (*run)(void);
    113 	void (*cleanup)(void);
    114 };
    115 static struct net_func net;
    116 
    117 #define MAX_THREADS	10000
    118 static pthread_attr_t attr;
    119 static pthread_t *thread_ids;
    120 
    121 static struct addrinfo *remote_addrinfo;
    122 static struct addrinfo *local_addrinfo;
    123 static struct sockaddr_storage remote_addr;
    124 static socklen_t remote_addr_len;
    125 
    126 static void init_socket_opts(int sd)
    127 {
    128 	if (busy_poll >= 0) {
    129 		SAFE_SETSOCKOPT(sd, SOL_SOCKET, SO_BUSY_POLL,
    130 			&busy_poll, sizeof(busy_poll));
    131 	}
    132 }
    133 
    134 static void do_cleanup(void)
    135 {
    136 	free(client_msg);
    137 	free(server_msg);
    138 
    139 	if (net.cleanup)
    140 		net.cleanup();
    141 
    142 	if (tfo_cfg_changed) {
    143 		tst_res(TINFO, "unset '%s' back to '%d'",
    144 			tfo_cfg, tfo_cfg_value);
    145 		SAFE_FILE_PRINTF(tfo_cfg, "%d", tfo_cfg_value);
    146 	}
    147 
    148 	if (tw_reuse_changed) {
    149 		SAFE_FILE_PRINTF(tcp_tw_reuse, "0");
    150 		tst_res(TINFO, "unset '%s' back to '0'", tcp_tw_reuse);
    151 	}
    152 }
    153 TST_DECLARE_ONCE_FN(cleanup, do_cleanup)
    154 
    155 static int sock_recv_poll(int fd, char *buf, int buf_size, int offset)
    156 {
    157 	struct pollfd pfd;
    158 	pfd.fd = fd;
    159 	pfd.events = POLLIN;
    160 	int len = -1;
    161 
    162 	while (1) {
    163 		errno = 0;
    164 		int ret = poll(&pfd, 1, wait_timeout / 1000);
    165 		if (ret == -1) {
    166 			if (errno == EINTR)
    167 				continue;
    168 			break;
    169 		}
    170 
    171 		if (ret == 0) {
    172 			errno = ETIME;
    173 			break;
    174 		}
    175 
    176 		if (ret != 1 || !(pfd.revents & POLLIN))
    177 			break;
    178 
    179 		errno = 0;
    180 		len = recvfrom(fd, buf + offset, buf_size - offset,
    181 			       MSG_DONTWAIT, (struct sockaddr *)&remote_addr,
    182 			       &remote_addr_len);
    183 
    184 		if (len == -1 && errno == EINTR)
    185 			continue;
    186 
    187 		break;
    188 	}
    189 
    190 	return len;
    191 }
    192 
    193 static int client_recv(int *fd, char *buf)
    194 {
    195 	int len, offset = 0;
    196 
    197 	while (1) {
    198 		errno = 0;
    199 		len = sock_recv_poll(*fd, buf, server_msg_size, offset);
    200 
    201 		/* socket closed or msg is not valid */
    202 		if (len < 1 || (offset + len) > server_msg_size ||
    203 		   (buf[0] != start_byte && buf[0] != start_fin_byte)) {
    204 			if (!errno)
    205 				errno = ENOMSG;
    206 			break;
    207 		}
    208 		offset += len;
    209 		if (buf[offset - 1] != end_byte)
    210 			continue;
    211 
    212 		if (verbose) {
    213 			tst_res_hexd(TINFO, buf, offset,
    214 				"msg recv from sock %d:", *fd);
    215 		}
    216 
    217 		/* recv last msg, close socket */
    218 		if (buf[0] == start_fin_byte)
    219 			break;
    220 		return 0;
    221 	}
    222 
    223 	SAFE_CLOSE(*fd);
    224 	return (errno) ? -1 : 0;
    225 }
    226 
    227 static int client_connect_send(const char *msg, int size)
    228 {
    229 	int cfd = SAFE_SOCKET(remote_addrinfo->ai_family,
    230 			 remote_addrinfo->ai_socktype, 0);
    231 
    232 	init_socket_opts(cfd);
    233 
    234 	if (fastopen_api) {
    235 		/* Replaces connect() + send()/write() */
    236 		SAFE_SENDTO(1, cfd, msg, size, MSG_FASTOPEN | MSG_NOSIGNAL,
    237 			remote_addrinfo->ai_addr, remote_addrinfo->ai_addrlen);
    238 	} else {
    239 		/* old TCP API */
    240 		SAFE_CONNECT(cfd, remote_addrinfo->ai_addr,
    241 			     remote_addrinfo->ai_addrlen);
    242 		SAFE_SEND(1, cfd, msg, size, MSG_NOSIGNAL);
    243 	}
    244 
    245 	return cfd;
    246 }
    247 
    248 void *client_fn(LTP_ATTRIBUTE_UNUSED void *arg)
    249 {
    250 	char buf[server_msg_size];
    251 	int cfd, i = 0;
    252 	intptr_t err = 0;
    253 
    254 	/* connect & send requests */
    255 	cfd = client_connect_send(client_msg, client_msg_size);
    256 	if (cfd == -1) {
    257 		err = errno;
    258 		goto out;
    259 	}
    260 
    261 	if (client_recv(&cfd, buf)) {
    262 		err = errno;
    263 		goto out;
    264 	}
    265 
    266 	for (i = 1; i < client_max_requests; ++i) {
    267 		if (use_udp)
    268 			goto send;
    269 
    270 		if (cfd == -1) {
    271 			cfd = client_connect_send(client_msg, client_msg_size);
    272 			if (cfd == -1) {
    273 				err = errno;
    274 				goto out;
    275 			}
    276 
    277 			if (client_recv(&cfd, buf)) {
    278 				err = errno;
    279 				break;
    280 			}
    281 			continue;
    282 		}
    283 
    284 send:
    285 		if (verbose) {
    286 			tst_res_hexd(TINFO, client_msg, client_msg_size,
    287 				"try to send msg[%d]", i);
    288 		}
    289 
    290 		SAFE_SEND(1, cfd, client_msg, client_msg_size, MSG_NOSIGNAL);
    291 
    292 		if (client_recv(&cfd, buf)) {
    293 			err = errno;
    294 			break;
    295 		}
    296 	}
    297 
    298 	if (cfd != -1)
    299 		SAFE_CLOSE(cfd);
    300 
    301 out:
    302 	if (i != client_max_requests)
    303 		tst_res(TWARN, "client exit on '%d' request", i);
    304 
    305 	return (void *) err;
    306 }
    307 
    308 union net_size_field {
    309 	char bytes[2];
    310 	uint16_t value;
    311 };
    312 
    313 static void make_client_request(void)
    314 {
    315 	client_msg[0] = start_byte;
    316 
    317 	/* set size for reply */
    318 	union net_size_field net_size;
    319 	net_size.value = htons(server_msg_size);
    320 	client_msg[1] = net_size.bytes[0];
    321 	client_msg[2] = net_size.bytes[1];
    322 
    323 	client_msg[client_msg_size - 1] = end_byte;
    324 }
    325 
    326 static int parse_client_request(const char *msg)
    327 {
    328 	union net_size_field net_size;
    329 	net_size.bytes[0] = msg[1];
    330 	net_size.bytes[1] = msg[2];
    331 	int size = ntohs(net_size.value);
    332 	if (size < 2 || size > max_msg_len)
    333 		return -1;
    334 
    335 	return size;
    336 }
    337 
    338 static struct timespec tv_client_start;
    339 static struct timespec tv_client_end;
    340 
    341 static void client_init(void)
    342 {
    343 	if (clients_num >= MAX_THREADS) {
    344 		tst_brk(TBROK, "Unexpected num of clients '%d'",
    345 			clients_num);
    346 	}
    347 
    348 	thread_ids = SAFE_MALLOC(sizeof(pthread_t) * clients_num);
    349 
    350 	client_msg = SAFE_MALLOC(client_msg_size);
    351 	memset(client_msg, client_byte, client_msg_size);
    352 
    353 	make_client_request();
    354 
    355 	struct addrinfo hints;
    356 	memset(&hints, 0, sizeof(struct addrinfo));
    357 	hints.ai_family = AF_UNSPEC;
    358 	hints.ai_socktype = (use_udp) ? SOCK_DGRAM : SOCK_STREAM;
    359 	hints.ai_flags = 0;
    360 	hints.ai_protocol = 0;
    361 
    362 	int err = getaddrinfo(server_addr, tcp_port, &hints, &remote_addrinfo);
    363 	if (err) {
    364 		tst_brk(TBROK, "getaddrinfo of '%s' failed, %s",
    365 			server_addr, gai_strerror(err));
    366 	}
    367 
    368 	tst_res(TINFO, "Running the test over IPv%s",
    369 		(remote_addrinfo->ai_family == AF_INET6) ? "6" : "4");
    370 
    371 	clock_gettime(CLOCK_MONOTONIC_RAW, &tv_client_start);
    372 	int i;
    373 	for (i = 0; i < clients_num; ++i)
    374 		SAFE_PTHREAD_CREATE(&thread_ids[i], 0, client_fn, NULL);
    375 }
    376 
    377 static void client_run(void)
    378 {
    379 	void *res = NULL;
    380 	long clnt_time = 0;
    381 	int i;
    382 	for (i = 0; i < clients_num; ++i) {
    383 		pthread_join(thread_ids[i], &res);
    384 		if (res) {
    385 			tst_brk(TBROK, "client[%d] failed: %s",
    386 				i, strerror((intptr_t)res));
    387 		}
    388 	}
    389 
    390 	clock_gettime(CLOCK_MONOTONIC_RAW, &tv_client_end);
    391 	clnt_time = (tv_client_end.tv_sec - tv_client_start.tv_sec) * 1000 +
    392 		(tv_client_end.tv_nsec - tv_client_start.tv_nsec) / 1000000;
    393 
    394 	tst_res(TINFO, "total time '%ld' ms", clnt_time);
    395 
    396 	/* ask server to terminate */
    397 	client_msg[0] = start_fin_byte;
    398 	int cfd = client_connect_send(client_msg, client_msg_size);
    399 	if (cfd != -1) {
    400 		shutdown(cfd, SHUT_WR);
    401 		SAFE_CLOSE(cfd);
    402 	}
    403 	/* the script tcp_fastopen_run.sh will remove it */
    404 	SAFE_FILE_PRINTF(rpath, "%ld", clnt_time);
    405 
    406 	tst_res(TPASS, "test completed");
    407 }
    408 
    409 static void client_cleanup(void)
    410 {
    411 	free(thread_ids);
    412 
    413 	if (remote_addrinfo)
    414 		freeaddrinfo(remote_addrinfo);
    415 }
    416 
    417 static void make_server_reply(char *send_msg, int size)
    418 {
    419 	memset(send_msg, server_byte, size - 1);
    420 	send_msg[0] = start_byte;
    421 	send_msg[size - 1] = end_byte;
    422 }
    423 
    424 void *server_fn(void *cfd)
    425 {
    426 	int client_fd = (intptr_t) cfd;
    427 	int num_requests = 0, offset = 0;
    428 	/* Reply will be constructed from first client request */
    429 	char send_msg[max_msg_len];
    430 	int send_msg_size = 0;
    431 	char recv_msg[max_msg_len];
    432 	ssize_t recv_len;
    433 
    434 	send_msg[0] = '\0';
    435 
    436 	init_socket_opts(client_fd);
    437 
    438 	while (1) {
    439 		recv_len = sock_recv_poll(client_fd, recv_msg,
    440 			max_msg_len, offset);
    441 
    442 		if (recv_len == 0)
    443 			break;
    444 
    445 		if (recv_len < 0 || (offset + recv_len) > max_msg_len ||
    446 		   (recv_msg[0] != start_byte &&
    447 		    recv_msg[0] != start_fin_byte)) {
    448 			tst_res(TFAIL, "recv failed, sock '%d'", client_fd);
    449 			goto out;
    450 		}
    451 
    452 		offset += recv_len;
    453 
    454 		if (recv_msg[offset - 1] != end_byte) {
    455 			/* msg is not complete, continue recv */
    456 			continue;
    457 		}
    458 
    459 		/* client asks to terminate */
    460 		if (recv_msg[0] == start_fin_byte)
    461 			goto out;
    462 
    463 		if (verbose) {
    464 			tst_res_hexd(TINFO, recv_msg, offset,
    465 				"msg recv from sock %d:", client_fd);
    466 		}
    467 
    468 		/* if we send reply for the first time, construct it here */
    469 		if (send_msg[0] != start_byte) {
    470 			send_msg_size = parse_client_request(recv_msg);
    471 			if (send_msg_size < 0) {
    472 				tst_res(TFAIL, "wrong msg size '%d'",
    473 					send_msg_size);
    474 				goto out;
    475 			}
    476 			make_server_reply(send_msg, send_msg_size);
    477 		}
    478 
    479 		offset = 0;
    480 
    481 		/*
    482 		 * It will tell client that server is going
    483 		 * to close this connection.
    484 		 */
    485 		if (!use_udp && ++num_requests >= server_max_requests)
    486 			send_msg[0] = start_fin_byte;
    487 
    488 		SAFE_SENDTO(1, client_fd, send_msg, send_msg_size, MSG_NOSIGNAL,
    489 			(struct sockaddr *)&remote_addr, remote_addr_len);
    490 
    491 		if (!use_udp && num_requests >= server_max_requests) {
    492 			/* max reqs, close socket */
    493 			shutdown(client_fd, SHUT_WR);
    494 			break;
    495 		}
    496 	}
    497 
    498 	SAFE_CLOSE(client_fd);
    499 	return NULL;
    500 
    501 out:
    502 	SAFE_CLOSE(client_fd);
    503 	tst_brk(TBROK, "Server closed");
    504 	return NULL;
    505 }
    506 
    507 static pthread_t server_thread_add(intptr_t client_fd)
    508 {
    509 	pthread_t id;
    510 	SAFE_PTHREAD_CREATE(&id, &attr, server_fn, (void *) client_fd);
    511 	return id;
    512 }
    513 
    514 static void server_init(void)
    515 {
    516 	struct addrinfo hints;
    517 	memset(&hints, 0, sizeof(struct addrinfo));
    518 	hints.ai_family = AF_INET6;
    519 	hints.ai_socktype = (use_udp) ? SOCK_DGRAM : SOCK_STREAM;
    520 	hints.ai_flags = AI_PASSIVE;
    521 
    522 	int err = getaddrinfo(NULL, tcp_port, &hints, &local_addrinfo);
    523 
    524 	if (err)
    525 		tst_brk(TBROK, "getaddrinfo failed, %s", gai_strerror(err));
    526 
    527 	if (!local_addrinfo)
    528 		tst_brk(TBROK, "failed to get the address");
    529 
    530 	/* IPv6 socket is also able to access IPv4 protocol stack */
    531 	sfd = SAFE_SOCKET(AF_INET6, local_addrinfo->ai_socktype, 0);
    532 	const int flag = 1;
    533 	SAFE_SETSOCKOPT(sfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
    534 
    535 	tst_res(TINFO, "assigning a name to the server socket...");
    536 	SAFE_BIND(sfd, local_addrinfo->ai_addr, local_addrinfo->ai_addrlen);
    537 
    538 	freeaddrinfo(local_addrinfo);
    539 
    540 	if (use_udp)
    541 		return;
    542 
    543 	init_socket_opts(sfd);
    544 
    545 	if (fastopen_api) {
    546 		SAFE_SETSOCKOPT(sfd, IPPROTO_TCP, TCP_FASTOPEN,
    547 			&tfo_queue_size, sizeof(tfo_queue_size));
    548 	}
    549 
    550 	SAFE_LISTEN(sfd, max_queue_len);
    551 	tst_res(TINFO, "Listen on the socket '%d', port '%s'", sfd, tcp_port);
    552 }
    553 
    554 static void server_cleanup(void)
    555 {
    556 	SAFE_CLOSE(sfd);
    557 }
    558 
    559 static void server_run_udp(void)
    560 {
    561 	pthread_t p_id = server_thread_add(sfd);
    562 
    563 	SAFE_PTHREAD_JOIN(p_id, NULL);
    564 }
    565 
    566 static void server_run(void)
    567 {
    568 	/* IPv4 source address will be mapped to IPv6 address */
    569 	struct sockaddr_in6 addr6;
    570 	socklen_t addr_size = sizeof(addr6);
    571 
    572 	pthread_attr_init(&attr);
    573 
    574 	/*
    575 	 * detaching threads allow to reclaim thread's resources
    576 	 * once a thread finishes its work.
    577 	 */
    578 	if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
    579 		tst_brk(TBROK | TERRNO, "setdetachstate failed");
    580 
    581 	while (1) {
    582 		int client_fd = accept(sfd, (struct sockaddr *)&addr6,
    583 			&addr_size);
    584 
    585 		if (client_fd == -1)
    586 			tst_brk(TBROK, "Can't create client socket");
    587 
    588 		if (verbose) {
    589 			char addr_buf[INET6_ADDRSTRLEN];
    590 			tst_res(TINFO, "conn: port '%d', addr '%s'",
    591 				addr6.sin6_port, inet_ntop(AF_INET6,
    592 				&addr6.sin6_addr, addr_buf, INET6_ADDRSTRLEN));
    593 		}
    594 
    595 		server_thread_add(client_fd);
    596 	}
    597 }
    598 
    599 static void require_root(const char *file)
    600 {
    601 	if (!geteuid())
    602 		return;
    603 	tst_brk(TCONF, "Test needs to be run as root to change %s", file);
    604 }
    605 
    606 static void check_tfo_value(void)
    607 {
    608 	/* Check if we can write to tcp_fastopen knob. We might be
    609 	 * inside netns and either have read-only permission or
    610 	 * doesn't have the knob at all.
    611 	 */
    612 	if (access(tfo_cfg, W_OK) < 0) {
    613 		/* TODO check /proc/self/ns/ or TST_USE_NETNS env var */
    614 		tst_res(TINFO, "can't read %s, assume server runs in netns",
    615 			tfo_cfg);
    616 		return;
    617 	}
    618 
    619 	SAFE_FILE_SCANF(tfo_cfg, "%d", &tfo_cfg_value);
    620 	tst_res(TINFO, "'%s' is %d", tfo_cfg, tfo_cfg_value);
    621 
    622 	/* The check can be the first in this function but set here
    623 	 * to allow to print information about the currently set config
    624 	 */
    625 	if (tfo_value < 0)
    626 		return;
    627 
    628 	if (tfo_cfg_value == tfo_value)
    629 		return;
    630 
    631 	require_root(tfo_cfg);
    632 
    633 	tst_res(TINFO, "set '%s' to '%d'", tfo_cfg, tfo_value);
    634 
    635 	SAFE_FILE_PRINTF(tfo_cfg, "%d", tfo_value);
    636 	tfo_cfg_changed = 1;
    637 }
    638 
    639 static void check_tw_reuse(void)
    640 {
    641 	if (access(tcp_tw_reuse, W_OK) < 0)
    642 		return;
    643 
    644 	int reuse_value = 0;
    645 
    646 	SAFE_FILE_SCANF(tcp_tw_reuse, "%d", &reuse_value);
    647 	if (reuse_value) {
    648 		tst_res(TINFO, "tcp_tw_reuse is already set");
    649 		return;
    650 	}
    651 
    652 	require_root(tfo_cfg);
    653 
    654 	SAFE_FILE_PRINTF(tcp_tw_reuse, "1");
    655 	tw_reuse_changed = 1;
    656 	tst_res(TINFO, "set '%s' to '1'", tcp_tw_reuse);
    657 }
    658 
    659 static void setup(void)
    660 {
    661 	if (tst_parse_int(aarg, &clients_num, 1, INT_MAX))
    662 		tst_brk(TBROK, "Invalid client number '%s'", aarg);
    663 	if (tst_parse_int(rarg, &client_max_requests, 1, INT_MAX))
    664 		tst_brk(TBROK, "Invalid client max requests '%s'", rarg);
    665 	if (tst_parse_int(Rarg, &server_max_requests, 1, INT_MAX))
    666 		tst_brk(TBROK, "Invalid server max requests '%s'", Rarg);
    667 	if (tst_parse_int(narg, &client_msg_size, 3, max_msg_len))
    668 		tst_brk(TBROK, "Invalid client msg size '%s'", narg);
    669 	if (tst_parse_int(Narg, &server_msg_size, 3, max_msg_len))
    670 		tst_brk(TBROK, "Invalid server msg size '%s'", Narg);
    671 	if (tst_parse_int(qarg, &tfo_queue_size, 1, INT_MAX))
    672 		tst_brk(TBROK, "Invalid TFO queue size '%s'", qarg);
    673 	if (tst_parse_long(Targ, &wait_timeout, 0L, LONG_MAX))
    674 		tst_brk(TBROK, "Invalid wait timeout '%s'", Targ);
    675 	if (tst_parse_int(barg, &busy_poll, 0, INT_MAX))
    676 		tst_brk(TBROK, "Invalid busy poll timeout'%s'", barg);
    677 	if (tst_parse_int(targ, &tfo_value, 0, INT_MAX))
    678 		tst_brk(TBROK, "Invalid net.ipv4.tcp_fastopen '%s'", targ);
    679 
    680 	/* if client_num is not set, use num of processors */
    681 	if (!clients_num)
    682 		clients_num = sysconf(_SC_NPROCESSORS_ONLN);
    683 
    684 	if (tfo_value > 0 && tst_kvercmp(3, 7, 0) < 0)
    685 		tst_brk(TCONF, "Test must be run with kernel 3.7 or newer");
    686 
    687 	if (busy_poll >= 0 && tst_kvercmp(3, 11, 0) < 0)
    688 		tst_brk(TCONF, "Test must be run with kernel 3.11 or newer");
    689 
    690 	if (client_mode) {
    691 		tst_res(TINFO, "connection: addr '%s', port '%s'",
    692 			server_addr, tcp_port);
    693 		tst_res(TINFO, "client max req: %d", client_max_requests);
    694 		tst_res(TINFO, "clients num: %d", clients_num);
    695 		tst_res(TINFO, "client msg size: %d", client_msg_size);
    696 		tst_res(TINFO, "server msg size: %d", server_msg_size);
    697 		net.init	= client_init;
    698 		net.run		= client_run;
    699 		net.cleanup	= client_cleanup;
    700 
    701 		check_tw_reuse();
    702 	} else {
    703 		tst_res(TINFO, "max requests '%d'",
    704 			server_max_requests);
    705 		net.init	= server_init;
    706 		net.run		= (use_udp) ? server_run_udp : server_run;
    707 		net.cleanup	= (use_udp) ? NULL : server_cleanup;
    708 	}
    709 
    710 	remote_addr_len = sizeof(struct sockaddr_storage);
    711 
    712 	if (use_udp) {
    713 		tst_res(TINFO, "using UDP");
    714 		fastopen_api = NULL;
    715 	} else {
    716 		tst_res(TINFO, "TCP %s is using %s TCP API.",
    717 			(client_mode) ? "client" : "server",
    718 			(fastopen_api) ? "Fastopen" : "old");
    719 
    720 		check_tfo_value();
    721 	}
    722 
    723 	net.init();
    724 }
    725 
    726 static void do_test(void)
    727 {
    728 	net.run();
    729 }
    730 
    731 static struct tst_option options[] = {
    732 	{"v", &verbose, "-v       Verbose"},
    733 	{"f", &fastopen_api, "-f       Use TFO API, default is old API"},
    734 	{"t:", &targ, "-t x     Set tcp_fastopen value"},
    735 
    736 	{"g:", &tcp_port, "-g x     x - server port"},
    737 	{"b:", &barg, "-b x     x - low latency busy poll timeout"},
    738 	{"U", &use_udp, "-U       Use UDP\n"},
    739 
    740 	{"H:", &server_addr, "Client:\n-H x     Server name or IP address"},
    741 	{"l", &client_mode, "-l       Become client, default is server"},
    742 	{"a:", &aarg, "-a x     Number of clients running in parallel"},
    743 	{"r:", &rarg, "-r x     Number of client requests"},
    744 	{"n:", &narg, "-n x     Client message size"},
    745 	{"N:", &Narg, "-N x     Server message size"},
    746 	{"T:", &Targ, "-T x     Reply timeout in microsec."},
    747 	{"d:", &rpath, "-d x     x is a path to file where result is saved\n"},
    748 
    749 	{"R:", &Rarg, "Server:\n-R x     x requests after which conn.closed"},
    750 	{"q:", &qarg, "-q x     x - TFO queue"},
    751 	{NULL, NULL, NULL}
    752 };
    753 
    754 static struct tst_test test = {
    755 	.tid = "netstress",
    756 	.test_all = do_test,
    757 	.setup = setup,
    758 	.cleanup = cleanup,
    759 	.options = options
    760 };
    761