From cfbad63021242f1471f491f4cfdbc40fe17d52da Mon Sep 17 00:00:00 2001 From: luwenpeng Date: Thu, 11 Apr 2024 11:26:50 +0800 Subject: [PATCH] Duplicated packet filter supports IPv4-Based TCP / UDP packet (IPv6 is not supported, because IPv6 does not have an IPid and cannot distinguish between retransmissions and duplicates) --- .../duplicated_packet_filter.cpp | 29 +++++++++++++------ .../duplicated_packet_filter.h | 2 +- src/session/session_manager.cpp | 29 +++++++++++++------ src/session/session_manager.h | 11 +++---- src/session/test/gtest_filter_tcp_dupkt.cpp | 28 +++++++++--------- .../test/gtest_overload_evict_tcp_sess.cpp | 12 ++++---- .../test/gtest_overload_evict_udp_sess.cpp | 20 ++++++------- 7 files changed, 77 insertions(+), 54 deletions(-) diff --git a/src/duplicated_packet_filter/duplicated_packet_filter.cpp b/src/duplicated_packet_filter/duplicated_packet_filter.cpp index 7e66457..cdfa8c3 100644 --- a/src/duplicated_packet_filter/duplicated_packet_filter.cpp +++ b/src/duplicated_packet_filter/duplicated_packet_filter.cpp @@ -2,12 +2,13 @@ #include "dablooms.h" #include "tcp_utils.h" +#include "udp_utils.h" #include "ipv4_utils.h" #include "duplicated_packet_filter.h" struct duplicated_packet_key { - // TCP + // TCP or UDP uint32_t seq; uint32_t ack; uint16_t src_port; /* host order */ @@ -38,8 +39,8 @@ static inline int duplicated_packet_key_get(const struct packet *packet, struct { return -1; } - const struct packet_layer *tcp_layer = packet_get_innermost_layer(packet, LAYER_TYPE_TCP); - if (tcp_layer == NULL) + const struct packet_layer *l4_layer = packet_get_innermost_layer(packet, LAYER_TYPE_L4); + if (l4_layer == NULL) { return -1; } @@ -51,12 +52,22 @@ static inline int duplicated_packet_key_get(const struct packet *packet, struct key->src_addr = ipv4_hdr_get_src_addr(iphdr); key->dst_addr = ipv4_hdr_get_dst_addr(iphdr); - const struct tcphdr *tcphdr = (const struct tcphdr *)tcp_layer->hdr_ptr; - key->seq = tcp_hdr_get_seq(tcphdr); - key->ack = tcp_hdr_get_ack(tcphdr); - key->src_port = tcp_hdr_get_src_port(tcphdr); - key->dst_port = tcp_hdr_get_dst_port(tcphdr); - key->l4_checksum = tcp_hdr_get_checksum(tcphdr); + if (l4_layer->type == LAYER_TYPE_TCP) + { + const struct tcphdr *tcphdr = (const struct tcphdr *)l4_layer->hdr_ptr; + key->seq = tcp_hdr_get_seq(tcphdr); + key->ack = tcp_hdr_get_ack(tcphdr); + key->src_port = tcp_hdr_get_src_port(tcphdr); + key->dst_port = tcp_hdr_get_dst_port(tcphdr); + key->l4_checksum = tcp_hdr_get_checksum(tcphdr); + } + else + { + const struct udphdr *udphdr = (const struct udphdr *)l4_layer->hdr_ptr; + key->src_port = udp_hdr_get_src_port(udphdr); + key->dst_port = udp_hdr_get_dst_port(udphdr); + key->l4_checksum = udp_hdr_get_checksum(udphdr); + } return 0; } diff --git a/src/duplicated_packet_filter/duplicated_packet_filter.h b/src/duplicated_packet_filter/duplicated_packet_filter.h index ab23493..212fffc 100644 --- a/src/duplicated_packet_filter/duplicated_packet_filter.h +++ b/src/duplicated_packet_filter/duplicated_packet_filter.h @@ -6,7 +6,7 @@ extern "C" { #endif -// Duplicated Packet Filter for IPv4-Based TCP Packet +// Duplicated Packet Filter for IPv4 Packet #include "log.h" #include "packet_private.h" diff --git a/src/session/session_manager.cpp b/src/session/session_manager.cpp index de7eea5..63ada99 100644 --- a/src/session/session_manager.cpp +++ b/src/session/session_manager.cpp @@ -411,7 +411,7 @@ static int tcp_overload_bypass(struct session_manager *mgr, const struct tuple6 { if (key->ip_proto == IPPROTO_TCP && mgr->stat.nr_tcp_sess_used >= mgr->opts.max_tcp_session_num) { - mgr->stat.nr_tcp_pkts_bypass_no_space++; + mgr->stat.nr_tcp_pkts_nospace_bypass++; return 1; } return 0; @@ -420,7 +420,7 @@ static int udp_overload_bypass(struct session_manager *mgr, const struct tuple6 { if (key->ip_proto == IPPROTO_UDP && mgr->stat.nr_udp_sess_used >= mgr->opts.max_udp_session_num) { - mgr->stat.nr_udp_pkts_bypass_no_space++; + mgr->stat.nr_udp_pkts_nospace_bypass++; return 1; } return 0; @@ -429,7 +429,7 @@ static int evicted_session_bypass(struct session_manager *mgr, const struct tupl { if (mgr->opts.evicted_session_filter_enable && evicted_session_filter_lookup(mgr->evicte_sess_filter, key, now)) { - mgr->stat.nr_udp_pkts_bypass_hit_evc++; + mgr->stat.nr_udp_pkts_evctd_bypass++; return 1; } @@ -450,7 +450,18 @@ static int duplicated_packet_bypass(struct session_manager *mgr, struct session { session_inc_stat(sess, dir, STAT_DUP_PKTS_BYPASS, 1); session_inc_stat(sess, dir, STAT_DUP_BYTES_BYPASS, packet_get_len(pkt)); - mgr->stat.nr_tcp_pkts_bypass_hit_dup++; + switch (session_get_type(sess)) + { + case SESSION_TYPE_TCP: + mgr->stat.nr_tcp_pkts_duped_bypass++; + break; + case SESSION_TYPE_UDP: + mgr->stat.nr_udp_pkts_duped_bypass++; + break; + default: + assert(0); + break; + } session_set_dup_traffic(sess); return 1; } @@ -555,7 +566,7 @@ static struct session *session_manager_new_tcp_session(struct session_manager *m uint8_t flags = tcp_hdr_get_flags(hdr); if (!(flags & TH_SYN)) { - mgr->stat.nr_tcp_pkts_bypass_miss_sess++; + mgr->stat.nr_tcp_pkts_nosess_bypass++; return NULL; } @@ -935,13 +946,13 @@ int session_manager_update_session(struct session_manager *mgr, struct session * { return -1; } + if (duplicated_packet_bypass(mgr, sess, pkt, &key, now)) + { + return -1; + } switch (session_get_type(sess)) { case SESSION_TYPE_TCP: - if (duplicated_packet_bypass(mgr, sess, pkt, &key, now)) - { - return -1; - } return session_manager_update_tcp_session(mgr, sess, pkt, &key, now); case SESSION_TYPE_UDP: return session_manager_update_udp_session(mgr, sess, pkt, &key, now); diff --git a/src/session/session_manager.h b/src/session/session_manager.h index 3a99084..3f38672 100644 --- a/src/session/session_manager.h +++ b/src/session/session_manager.h @@ -75,11 +75,12 @@ struct session_manager_stat uint64_t nr_udp_sess_evicted; // sum // Packet - uint64_t nr_udp_pkts_bypass_no_space; // sum - uint64_t nr_tcp_pkts_bypass_no_space; // sum - uint64_t nr_tcp_pkts_bypass_miss_sess; // sum - uint64_t nr_tcp_pkts_bypass_hit_dup; // sum - uint64_t nr_udp_pkts_bypass_hit_evc; // sum + uint64_t nr_udp_pkts_nospace_bypass; // sum + uint64_t nr_tcp_pkts_nospace_bypass; // sum + uint64_t nr_tcp_pkts_nosess_bypass; // sum + uint64_t nr_tcp_pkts_duped_bypass; // sum + uint64_t nr_udp_pkts_duped_bypass; // sum + uint64_t nr_udp_pkts_evctd_bypass; // sum // TCP segments uint64_t nr_tcp_seg_received; // sum diff --git a/src/session/test/gtest_filter_tcp_dupkt.cpp b/src/session/test/gtest_filter_tcp_dupkt.cpp index 874cc31..584c6cf 100644 --- a/src/session/test/gtest_filter_tcp_dupkt.cpp +++ b/src/session/test/gtest_filter_tcp_dupkt.cpp @@ -77,7 +77,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SYN_DUP) EXPECT_TRUE(session_has_dup_traffic(sess) == 0); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 0); // C2S SYN dup Packet printf("\n=> Packet Parse: TCP C2S SYN dup packet\n"); @@ -92,7 +92,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SYN_DUP) EXPECT_TRUE(session_has_dup_traffic(sess) == 1); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 1); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 1); // C2S SYN retransmission Packet printf("\n=> Packet Parse: TCP C2S SYN retransmission packet\n"); @@ -110,7 +110,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SYN_DUP) EXPECT_TRUE(session_has_dup_traffic(sess) == 1); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 1); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 1); session_manager_free(mgr); } @@ -140,7 +140,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SYNACK_DUP) EXPECT_TRUE(session_has_dup_traffic(sess) == 0); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 0); // S2C SYNACK dup Packet printf("\n=> Packet Parse: TCP S2C SYNACK dup packet\n"); @@ -155,7 +155,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SYNACK_DUP) EXPECT_TRUE(session_has_dup_traffic(sess) == 1); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 1); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 1); // S2C SYNACK retransmission Packet printf("\n=> Packet Parse: TCP S2C SYNACK retransmission packet\n"); @@ -173,7 +173,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SYNACK_DUP) EXPECT_TRUE(session_has_dup_traffic(sess) == 1); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 1); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 1); session_manager_free(mgr); } @@ -204,7 +204,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SKIP) EXPECT_TRUE(session_has_dup_traffic(sess) == 0); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 0); // C2S SYN retransmission Packet printf("\n=> Packet Parse: TCP C2S SYN retransmission packet\n"); @@ -221,7 +221,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SKIP) EXPECT_TRUE(session_has_dup_traffic(sess) == 0); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 0); // C2S SYN retransmission Packet printf("\n=> Packet Parse: TCP C2S SYN retransmission packet\n"); @@ -238,7 +238,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SKIP) EXPECT_TRUE(session_has_dup_traffic(sess) == 0); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 0); // C2S SYN dup Packet printf("\n=> Packet Parse: TCP C2S SYN dup packet\n"); @@ -253,7 +253,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SKIP) EXPECT_TRUE(session_has_dup_traffic(sess) == 0); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 0); session_manager_free(mgr); } @@ -286,7 +286,7 @@ TEST(TCP_DUPKT_FILTER_DISABLE, SYN_DUP) EXPECT_TRUE(session_has_dup_traffic(sess) == 0); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 0); // C2S SYN dup Packet printf("\n=> Packet Parse: TCP C2S SYN dup packet\n"); @@ -301,7 +301,7 @@ TEST(TCP_DUPKT_FILTER_DISABLE, SYN_DUP) EXPECT_TRUE(session_has_dup_traffic(sess) == 0); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 0); session_manager_free(mgr); } @@ -334,7 +334,7 @@ TEST(TCP_DUPKT_FILTER_DISABLE, SYNACK_DUP) EXPECT_TRUE(session_has_dup_traffic(sess) == 0); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 0); // S2C SYNACK dup Packet printf("\n=> Packet Parse: TCP S2C SYNACK dup packet\n"); @@ -349,7 +349,7 @@ TEST(TCP_DUPKT_FILTER_DISABLE, SYNACK_DUP) EXPECT_TRUE(session_has_dup_traffic(sess) == 0); stat = session_manager_get_stat(mgr); EXPECT_TRUE(stat); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_hit_dup == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_duped_bypass == 0); session_manager_free(mgr); } diff --git a/src/session/test/gtest_overload_evict_tcp_sess.cpp b/src/session/test/gtest_overload_evict_tcp_sess.cpp index 462d635..10b0025 100644 --- a/src/session/test/gtest_overload_evict_tcp_sess.cpp +++ b/src/session/test/gtest_overload_evict_tcp_sess.cpp @@ -86,8 +86,8 @@ TEST(TCP_OVERLOAD, EVICT_OLD_SESS) EXPECT_TRUE(stat->nr_tcp_sess_closing == 0); EXPECT_TRUE(stat->nr_tcp_sess_closed == RX_BURST_MAX); // have evicted, have't free EXPECT_TRUE(stat->nr_tcp_sess_evicted == RX_BURST_MAX); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_no_space == 0); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_miss_sess == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_nospace_bypass == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_nosess_bypass == 0); session_manager_free(mgr); } @@ -127,8 +127,8 @@ TEST(TCP_OVERLOAD, EVICT_NEW_SESS) EXPECT_TRUE(stat->nr_tcp_sess_closing == 0); EXPECT_TRUE(stat->nr_tcp_sess_closed == 0); EXPECT_TRUE(stat->nr_tcp_sess_evicted == 0); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_no_space == 0); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_miss_sess == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_nospace_bypass == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_nosess_bypass == 0); // table full, evict new session for (uint32_t i = 0; i < RX_BURST_MAX; i++) @@ -147,8 +147,8 @@ TEST(TCP_OVERLOAD, EVICT_NEW_SESS) EXPECT_TRUE(stat->nr_tcp_sess_closing == 0); EXPECT_TRUE(stat->nr_tcp_sess_closed == 0); EXPECT_TRUE(stat->nr_tcp_sess_evicted == 0); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_no_space == RX_BURST_MAX); - EXPECT_TRUE(stat->nr_tcp_pkts_bypass_miss_sess == 0); + EXPECT_TRUE(stat->nr_tcp_pkts_nospace_bypass == RX_BURST_MAX); + EXPECT_TRUE(stat->nr_tcp_pkts_nosess_bypass == 0); session_manager_free(mgr); } diff --git a/src/session/test/gtest_overload_evict_udp_sess.cpp b/src/session/test/gtest_overload_evict_udp_sess.cpp index 8d4c72c..1755e39 100644 --- a/src/session/test/gtest_overload_evict_udp_sess.cpp +++ b/src/session/test/gtest_overload_evict_udp_sess.cpp @@ -87,8 +87,8 @@ TEST(UDP_OVERLOAD, EVICT_OLD_SESS) EXPECT_TRUE(stat->nr_udp_sess_closing == 0); EXPECT_TRUE(stat->nr_udp_sess_closed == RX_BURST_MAX); // have evicted, have't free EXPECT_TRUE(stat->nr_udp_sess_evicted == RX_BURST_MAX); - EXPECT_TRUE(stat->nr_udp_pkts_bypass_no_space == 0); - EXPECT_TRUE(stat->nr_udp_pkts_bypass_hit_evc == 0); + EXPECT_TRUE(stat->nr_udp_pkts_nospace_bypass == 0); + EXPECT_TRUE(stat->nr_udp_pkts_evctd_bypass == 0); // evicted session while (1) @@ -120,8 +120,8 @@ TEST(UDP_OVERLOAD, EVICT_OLD_SESS) EXPECT_TRUE(stat->nr_udp_sess_closing == 0); EXPECT_TRUE(stat->nr_udp_sess_closed == 0); EXPECT_TRUE(stat->nr_udp_sess_evicted == RX_BURST_MAX); - EXPECT_TRUE(stat->nr_udp_pkts_bypass_no_space == 0); - EXPECT_TRUE(stat->nr_udp_pkts_bypass_hit_evc == RX_BURST_MAX); + EXPECT_TRUE(stat->nr_udp_pkts_nospace_bypass == 0); + EXPECT_TRUE(stat->nr_udp_pkts_evctd_bypass == RX_BURST_MAX); // evicted session timeout packet_set_ip_src_addr(&pkt, 0); @@ -137,8 +137,8 @@ TEST(UDP_OVERLOAD, EVICT_OLD_SESS) EXPECT_TRUE(stat->nr_udp_sess_closing == 0); EXPECT_TRUE(stat->nr_udp_sess_closed == 1); // have evicted, have't free EXPECT_TRUE(stat->nr_udp_sess_evicted == RX_BURST_MAX + 1); - EXPECT_TRUE(stat->nr_udp_pkts_bypass_no_space == 0); - EXPECT_TRUE(stat->nr_udp_pkts_bypass_hit_evc == RX_BURST_MAX); + EXPECT_TRUE(stat->nr_udp_pkts_nospace_bypass == 0); + EXPECT_TRUE(stat->nr_udp_pkts_evctd_bypass == RX_BURST_MAX); session_manager_free(mgr); } @@ -178,8 +178,8 @@ TEST(UDP_OVERLOAD, EVICT_NEW_SESS) EXPECT_TRUE(stat->nr_udp_sess_closing == 0); EXPECT_TRUE(stat->nr_udp_sess_closed == 0); EXPECT_TRUE(stat->nr_udp_sess_evicted == 0); - EXPECT_TRUE(stat->nr_udp_pkts_bypass_no_space == 0); - EXPECT_TRUE(stat->nr_udp_pkts_bypass_hit_evc == 0); + EXPECT_TRUE(stat->nr_udp_pkts_nospace_bypass == 0); + EXPECT_TRUE(stat->nr_udp_pkts_evctd_bypass == 0); // evicted session EXPECT_TRUE(session_manager_get_evicted_session(mgr) == NULL); @@ -201,8 +201,8 @@ TEST(UDP_OVERLOAD, EVICT_NEW_SESS) EXPECT_TRUE(stat->nr_udp_sess_closing == 0); EXPECT_TRUE(stat->nr_udp_sess_closed == 0); EXPECT_TRUE(stat->nr_udp_sess_evicted == 0); - EXPECT_TRUE(stat->nr_udp_pkts_bypass_no_space == RX_BURST_MAX); - EXPECT_TRUE(stat->nr_udp_pkts_bypass_hit_evc == 0); + EXPECT_TRUE(stat->nr_udp_pkts_nospace_bypass == RX_BURST_MAX); + EXPECT_TRUE(stat->nr_udp_pkts_evctd_bypass == 0); session_manager_free(mgr); }