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