brintos

brintos / linux-shallow public Read only

0
0
Text · 5.5 KiB · 3ecd2b5 Raw
189 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Author: Dmitry Safonov <dima@arista.com> */3#include <inttypes.h>4#include "aolib.h"5 6static union tcp_addr local_addr;7 8static void __setup_lo_intf(const char *lo_intf,9			    const char *addr_str, uint8_t prefix)10{11	if (inet_pton(TEST_FAMILY, addr_str, &local_addr) != 1)12		test_error("Can't convert local ip address");13 14	if (ip_addr_add(lo_intf, TEST_FAMILY, local_addr, prefix))15		test_error("Failed to add %s ip address", lo_intf);16 17	if (link_set_up(lo_intf))18		test_error("Failed to bring %s up", lo_intf);19}20 21static void setup_lo_intf(const char *lo_intf)22{23#ifdef IPV6_TEST24	__setup_lo_intf(lo_intf, "::1", 128);25#else26	__setup_lo_intf(lo_intf, "127.0.0.1", 8);27#endif28}29 30static void tcp_self_connect(const char *tst, unsigned int port,31			     bool different_keyids, bool check_restore)32{33	struct tcp_ao_counters before_ao, after_ao;34	uint64_t before_aogood, after_aogood;35	struct netstat *ns_before, *ns_after;36	const size_t nr_packets = 20;37	struct tcp_ao_repair ao_img;38	struct tcp_sock_state img;39	sockaddr_af addr;40	int sk;41 42	tcp_addr_to_sockaddr_in(&addr, &local_addr, htons(port));43 44	sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);45	if (sk < 0)46		test_error("socket()");47 48	if (different_keyids) {49		if (test_add_key(sk, DEFAULT_TEST_PASSWORD, local_addr, -1, 5, 7))50			test_error("setsockopt(TCP_AO_ADD_KEY)");51		if (test_add_key(sk, DEFAULT_TEST_PASSWORD, local_addr, -1, 7, 5))52			test_error("setsockopt(TCP_AO_ADD_KEY)");53	} else {54		if (test_add_key(sk, DEFAULT_TEST_PASSWORD, local_addr, -1, 100, 100))55			test_error("setsockopt(TCP_AO_ADD_KEY)");56	}57 58	if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0)59		test_error("bind()");60 61	ns_before = netstat_read();62	before_aogood = netstat_get(ns_before, "TCPAOGood", NULL);63	if (test_get_tcp_ao_counters(sk, &before_ao))64		test_error("test_get_tcp_ao_counters()");65 66	if (__test_connect_socket(sk, "lo", (struct sockaddr *)&addr,67				  sizeof(addr), TEST_TIMEOUT_SEC) < 0) {68		ns_after = netstat_read();69		netstat_print_diff(ns_before, ns_after);70		test_error("failed to connect()");71	}72 73	if (test_client_verify(sk, 100, nr_packets, TEST_TIMEOUT_SEC)) {74		test_fail("%s: tcp connection verify failed", tst);75		close(sk);76		return;77	}78 79	ns_after = netstat_read();80	after_aogood = netstat_get(ns_after, "TCPAOGood", NULL);81	if (test_get_tcp_ao_counters(sk, &after_ao))82		test_error("test_get_tcp_ao_counters()");83	if (!check_restore) {84		/* to debug: netstat_print_diff(ns_before, ns_after); */85		netstat_free(ns_before);86	}87	netstat_free(ns_after);88 89	if (after_aogood <= before_aogood) {90		test_fail("%s: TCPAOGood counter mismatch: %" PRIu64 " <= %" PRIu64,91			  tst, after_aogood, before_aogood);92		close(sk);93		return;94	}95 96	if (test_tcp_ao_counters_cmp(tst, &before_ao, &after_ao, TEST_CNT_GOOD)) {97		close(sk);98		return;99	}100 101	if (!check_restore) {102		test_ok("%s: connect TCPAOGood %" PRIu64 " => %" PRIu64,103				tst, before_aogood, after_aogood);104		close(sk);105		return;106	}107 108	test_enable_repair(sk);109	test_sock_checkpoint(sk, &img, &addr);110#ifdef IPV6_TEST111	addr.sin6_port = htons(port + 1);112#else113	addr.sin_port = htons(port + 1);114#endif115	test_ao_checkpoint(sk, &ao_img);116	test_kill_sk(sk);117 118	sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);119	if (sk < 0)120		test_error("socket()");121 122	test_enable_repair(sk);123	__test_sock_restore(sk, "lo", &img, &addr, &addr, sizeof(addr));124	if (different_keyids) {125		if (test_add_repaired_key(sk, DEFAULT_TEST_PASSWORD, 0,126					  local_addr, -1, 7, 5))127			test_error("setsockopt(TCP_AO_ADD_KEY)");128		if (test_add_repaired_key(sk, DEFAULT_TEST_PASSWORD, 0,129					  local_addr, -1, 5, 7))130			test_error("setsockopt(TCP_AO_ADD_KEY)");131	} else {132		if (test_add_repaired_key(sk, DEFAULT_TEST_PASSWORD, 0,133					  local_addr, -1, 100, 100))134			test_error("setsockopt(TCP_AO_ADD_KEY)");135	}136	test_ao_restore(sk, &ao_img);137	test_disable_repair(sk);138	test_sock_state_free(&img);139	if (test_client_verify(sk, 100, nr_packets, TEST_TIMEOUT_SEC)) {140		test_fail("%s: tcp connection verify failed", tst);141		close(sk);142		return;143	}144	ns_after = netstat_read();145	after_aogood = netstat_get(ns_after, "TCPAOGood", NULL);146	/* to debug: netstat_print_diff(ns_before, ns_after); */147	netstat_free(ns_before);148	netstat_free(ns_after);149	close(sk);150	if (after_aogood <= before_aogood) {151		test_fail("%s: TCPAOGood counter mismatch: %" PRIu64 " <= %" PRIu64,152			  tst, after_aogood, before_aogood);153		return;154	}155	test_ok("%s: connect TCPAOGood %" PRIu64 " => %" PRIu64,156			tst, before_aogood, after_aogood);157}158 159static void *client_fn(void *arg)160{161	unsigned int port = test_server_port;162 163	setup_lo_intf("lo");164 165	tcp_self_connect("self-connect(same keyids)", port++, false, false);166 167	/* expecting rnext to change based on the first segment RNext != Current */168	trace_ao_event_expect(TCP_AO_RNEXT_REQUEST, local_addr, local_addr,169			      port, port, 0, -1, -1, -1, -1, -1, 7, 5, -1);170	tcp_self_connect("self-connect(different keyids)", port++, true, false);171	tcp_self_connect("self-connect(restore)", port, false, true);172	port += 2; /* restore test restores over different port */173	trace_ao_event_expect(TCP_AO_RNEXT_REQUEST, local_addr, local_addr,174			      port, port, 0, -1, -1, -1, -1, -1, 7, 5, -1);175	/* intentionally on restore they are added to the socket in different order */176	trace_ao_event_expect(TCP_AO_RNEXT_REQUEST, local_addr, local_addr,177			      port + 1, port + 1, 0, -1, -1, -1, -1, -1, 5, 7, -1);178	tcp_self_connect("self-connect(restore, different keyids)", port, true, true);179	port += 2; /* restore test restores over different port */180 181	return NULL;182}183 184int main(int argc, char *argv[])185{186	test_init(5, client_fn, NULL);187	return 0;188}189