1 // SPDX-License-Identifier: GPL-2.0
2 /* Author: Dmitry Safonov <dima@arista.com> */
3 #include <inttypes.h>
4 #include "aolib.h"
5 
server_fn(void * arg)6 static void *server_fn(void *arg)
7 {
8 	int sk, lsk;
9 	ssize_t bytes;
10 
11 	lsk = test_listen_socket(this_ip_addr, test_server_port, 1);
12 
13 	if (test_add_key(lsk, DEFAULT_TEST_PASSWORD, this_ip_dest, -1, 100, 100))
14 		test_error("setsockopt(TCP_AO_ADD_KEY)");
15 	synchronize_threads();
16 
17 	if (test_wait_fd(lsk, TEST_TIMEOUT_SEC, 0))
18 		test_error("test_wait_fd()");
19 
20 	sk = accept(lsk, NULL, NULL);
21 	if (sk < 0)
22 		test_error("accept()");
23 
24 	synchronize_threads();
25 
26 	bytes = test_server_run(sk, 0, 0);
27 
28 	test_fail("server served: %zd", bytes);
29 	return NULL;
30 }
31 
client_fn(void * arg)32 static void *client_fn(void *arg)
33 {
34 	int sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
35 	uint64_t before_aogood, after_aogood;
36 	const size_t nr_packets = 20;
37 	struct netstat *ns_before, *ns_after;
38 	struct tcp_ao_counters ao1, ao2;
39 
40 	if (sk < 0)
41 		test_error("socket()");
42 
43 	if (test_add_key(sk, DEFAULT_TEST_PASSWORD, this_ip_dest, -1, 100, 100))
44 		test_error("setsockopt(TCP_AO_ADD_KEY)");
45 
46 	synchronize_threads();
47 	if (test_connect_socket(sk, this_ip_dest, test_server_port) <= 0)
48 		test_error("failed to connect()");
49 	synchronize_threads();
50 
51 	ns_before = netstat_read();
52 	before_aogood = netstat_get(ns_before, "TCPAOGood", NULL);
53 	if (test_get_tcp_ao_counters(sk, &ao1))
54 		test_error("test_get_tcp_ao_counters()");
55 
56 	if (test_client_verify(sk, 100, nr_packets, TEST_TIMEOUT_SEC)) {
57 		test_fail("verify failed");
58 		return NULL;
59 	}
60 
61 	ns_after = netstat_read();
62 	after_aogood = netstat_get(ns_after, "TCPAOGood", NULL);
63 	if (test_get_tcp_ao_counters(sk, &ao2))
64 		test_error("test_get_tcp_ao_counters()");
65 	netstat_print_diff(ns_before, ns_after);
66 	netstat_free(ns_before);
67 	netstat_free(ns_after);
68 
69 	if (nr_packets > (after_aogood - before_aogood)) {
70 		test_fail("TCPAOGood counter mismatch: %zu > (%" PRIu64 " - %" PRIu64 ")",
71 				nr_packets, after_aogood, before_aogood);
72 		return NULL;
73 	}
74 	if (test_tcp_ao_counters_cmp("connect", &ao1, &ao2, TEST_CNT_GOOD))
75 		return NULL;
76 
77 	test_ok("connect TCPAOGood %" PRIu64 "/%" PRIu64 "/%" PRIu64 " => %" PRIu64 "/%" PRIu64 "/%" PRIu64 ", sent %zu",
78 			before_aogood, ao1.ao_info_pkt_good,
79 			ao1.key_cnts[0].pkt_good,
80 			after_aogood, ao2.ao_info_pkt_good,
81 			ao2.key_cnts[0].pkt_good,
82 			nr_packets);
83 	return NULL;
84 }
85 
main(int argc,char * argv[])86 int main(int argc, char *argv[])
87 {
88 	test_init(2, server_fn, client_fn);
89 	return 0;
90 }
91