#include #include "snowflake.h" #include "session_private.h" #include "session_manager.h" #include "packet_private.h" #include "packet_parser.h" #include "test_packets.h" struct session_manager_options opts = { // max session number .max_tcp_session_num = 256, .max_udp_session_num = 256, // session overload .tcp_overload_evict_old_sess = 1, // 1: evict old session, 0: bypass new session .udp_overload_evict_old_sess = 1, // 1: evict old session, 0: bypass new session // tcp timeout .tcp_init_timeout = 1, .tcp_handshake_timeout = 2, .tcp_data_timeout = 3, .tcp_half_closed_timeout = 4, .tcp_time_wait_timeout = 5, .tcp_discard_timeout = 6, .tcp_unverified_rst_timeout = 7, // udp timeout .udp_data_timeout = 8, .udp_discard_timeout = 0, // duplicate packet filter .duplicated_packet_filter_enable = 1, .duplicated_packet_filter_capacity = 1000, .duplicated_packet_filter_timeout = 10, .duplicated_packet_filter_error_rate = 0.0001, // evicted session filter .evicted_session_filter_enable = 1, .evicted_session_filter_capacity = 1000, .evicted_session_filter_timeout = 10, .evicted_session_filter_error_rate = 0.0001, // TCP Reassembly .tcp_reassembly_enable = 1, .tcp_reassembly_max_timeout = 60000, .tcp_reassembly_max_segments = 16, }; static inline void packet_overwrite_src_addr(struct packet *pkt, struct in_addr addr) { const struct raw_layer *ipv4_layer = packet_get_innermost_raw_layer(pkt, LAYER_PROTO_IPV4); struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; hdr->ip_src = addr; } static inline void mached_session_print(const char *title, struct session_manager *mgr, uint64_t mached_sess_ids[], uint64_t mached_sess_num) { struct session *sess = NULL; printf("%-*s mached_sess_num: %lu\n", 40, title, mached_sess_num); for (uint64_t i = 0; i < mached_sess_num; i++) { sess = session_manager_lookup_session_by_id(mgr, mached_sess_ids[i]); printf("session id: %lu, addr: %s, type: %s, state: %s, start: %lu, last: %lu\n", mached_sess_ids[i], session_get0_readable_addr(sess), session_type_to_str(session_get_type(sess)), session_state_to_str(session_get_current_state(sess)), session_get_timestamp(sess, SESSION_TIMESTAMP_START), session_get_timestamp(sess, SESSION_TIMESTAMP_LAST)); } } #if 1 TEST(SESS_MGR_SCAN, OPTS) { char buff[1500] = {0}; uint64_t mached_sess_num = 0; uint64_t mached_sess_ids[1460]; struct packet pkt; struct session *sess = NULL; struct session_manager *mgr = NULL; struct in_addr v4_src_addr1 = {}; struct in_addr v4_src_addr2 = {}; struct in_addr v4_src_addr3 = {}; struct in_addr v4_dst_addr = {}; struct in_addr v4_min_addr = {}; struct in_addr v4_max_addr = {}; struct in_addr v4_src_subnet_beg = {}; struct in_addr v4_src_subnet_end = {}; struct in_addr v4_dst_subnet_beg = {}; struct in_addr v4_dst_subnet_end = {}; v4_src_addr1.s_addr = inet_addr("192.168.1.1"); v4_src_addr2.s_addr = inet_addr("192.168.1.2"); v4_src_addr3.s_addr = inet_addr("192.168.1.3"); v4_dst_addr.s_addr = inet_addr("93.184.216.34"); v4_min_addr.s_addr = inet_addr("0.0.0.0"); v4_max_addr.s_addr = inet_addr("255.255.255.255"); v4_src_subnet_beg.s_addr = inet_addr("192.168.1.0"); v4_src_subnet_end.s_addr = inet_addr("192.168.1.255"); v4_dst_subnet_beg.s_addr = inet_addr("93.184.216.0"); v4_dst_subnet_end.s_addr = inet_addr("93.184.216.255"); struct in6_addr v6_src_addr = {}; struct in6_addr v6_dst_addr = {}; struct in6_addr v6_min_addr = {}; struct in6_addr v6_max_addr = {}; struct in6_addr v6_src_subnet_beg = {}; struct in6_addr v6_src_subnet_end = {}; struct in6_addr v6_dst_subnet_beg = {}; struct in6_addr v6_dst_subnet_end = {}; inet_pton(AF_INET6, "dead::beef", &v6_src_addr); inet_pton(AF_INET6, "cafe::babe", &v6_dst_addr); inet_pton(AF_INET6, "0000:0000:0000:0000:0000:0000:0000:0000", &v6_min_addr); inet_pton(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", &v6_max_addr); inet_pton(AF_INET6, "dead::0000", &v6_src_subnet_beg); inet_pton(AF_INET6, "dead::ffff", &v6_src_subnet_end); inet_pton(AF_INET6, "cafe::0000", &v6_dst_subnet_beg); inet_pton(AF_INET6, "cafe::ffff", &v6_dst_subnet_end); mgr = session_manager_new(&opts, 1); EXPECT_TRUE(mgr != NULL); // new session memset(&pkt, 0, sizeof(pkt)); memcpy(buff, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)buff, sizeof(tcp_pkt1_c2s_syn)); packet_overwrite_src_addr(&pkt, v4_src_addr1); EXPECT_TRUE(session_manager_lookup_session_by_packet(mgr, &pkt) == NULL); sess = session_manager_new_session(mgr, &pkt, 1); EXPECT_TRUE(sess); // new session memset(&pkt, 0, sizeof(pkt)); memcpy(buff, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)buff, sizeof(tcp_pkt1_c2s_syn)); packet_overwrite_src_addr(&pkt, v4_src_addr2); EXPECT_TRUE(session_manager_lookup_session_by_packet(mgr, &pkt) == NULL); sess = session_manager_new_session(mgr, &pkt, 2); EXPECT_TRUE(sess); // new session memset(&pkt, 0, sizeof(pkt)); memcpy(buff, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)buff, sizeof(tcp_pkt1_c2s_syn)); packet_overwrite_src_addr(&pkt, v4_src_addr3); EXPECT_TRUE(session_manager_lookup_session_by_packet(mgr, &pkt) == NULL); sess = session_manager_new_session(mgr, &pkt, 3); EXPECT_TRUE(sess); // new session memset(&pkt, 0, sizeof(pkt)); packet_parse(&pkt, (const char *)ipv6_in_ipv6_udp, sizeof(ipv6_in_ipv6_udp)); EXPECT_TRUE(session_manager_lookup_session_by_packet(mgr, &pkt) == NULL); sess = session_manager_new_session(mgr, &pkt, 4); EXPECT_TRUE(sess); struct session_scan_opts scan = {}; // scan.flags = SESSION_SCAN_TYPE | SESSION_SCAN_STATE | SESSION_SCAN_SIP | SESSION_SCAN_DIP | SESSION_SCAN_SPORT | SESSION_SCAN_DPORT | SESSION_SCAN_CREATE_TIME | SESSION_SCAN_LAST_PKT_TIME; scan.cursor = 0; scan.count = 1460; scan.last_pkt_time_ms[0] = 0; scan.last_pkt_time_ms[1] = UINT64_MAX; // SESSION_SCAN_TYPE scan.flags = SESSION_SCAN_TYPE; scan.type = SESSION_TYPE_TCP; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 3); mached_session_print("SESSION_SCAN_TYPE: (TCP)", mgr, mached_sess_ids, mached_sess_num); scan.type = SESSION_TYPE_UDP; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 1); mached_session_print("SESSION_SCAN_TYPE: (UDP)", mgr, mached_sess_ids, mached_sess_num); // SESSION_SCAN_STATE scan.flags = SESSION_SCAN_STATE; scan.state = SESSION_STATE_OPENING; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 4); mached_session_print("SESSION_SCAN_STATE: (OPENING)", mgr, mached_sess_ids, mached_sess_num); scan.state = SESSION_STATE_ACTIVE; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 0); mached_session_print("SESSION_SCAN_STATE: (ACTIVE)", mgr, mached_sess_ids, mached_sess_num); scan.state = SESSION_STATE_CLOSING; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 0); mached_session_print("SESSION_SCAN_STATE: (CLOSING)", mgr, mached_sess_ids, mached_sess_num); scan.state = SESSION_STATE_DISCARD; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 0); mached_session_print("SESSION_SCAN_STATE: (DISCARD)", mgr, mached_sess_ids, mached_sess_num); scan.state = SESSION_STATE_CLOSED; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 0); mached_session_print("SESSION_SCAN_STATE: (CLOSED)", mgr, mached_sess_ids, mached_sess_num); // SESSION_SCAN_SIP scan.flags = SESSION_SCAN_SIP; scan.addr_family = AF_INET; scan.src_addr[0].v4 = v4_src_addr1; scan.src_addr[1].v4 = v4_src_addr1; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 1); mached_session_print("SESSION_SCAN_SIP: (IPv4)", mgr, mached_sess_ids, mached_sess_num); scan.addr_family = AF_INET; scan.src_addr[0].v4 = v4_src_subnet_beg; scan.src_addr[1].v4 = v4_src_subnet_end; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 3); mached_session_print("SESSION_SCAN_SIP: (IPv4 SUBNET)", mgr, mached_sess_ids, mached_sess_num); scan.addr_family = AF_INET; scan.src_addr[0].v4 = v4_min_addr; scan.src_addr[1].v4 = v4_max_addr; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 3); mached_session_print("SESSION_SCAN_SIP: (IPv4 MIN MAX)", mgr, mached_sess_ids, mached_sess_num); scan.addr_family = AF_INET6; memcpy(&scan.src_addr[0].v6, &v6_src_addr, sizeof(v6_src_addr)); memcpy(&scan.src_addr[1].v6, &v6_src_addr, sizeof(v6_src_addr)); mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 1); mached_session_print("SESSION_SCAN_SIP: (IPv6)", mgr, mached_sess_ids, mached_sess_num); scan.addr_family = AF_INET6; memcpy(&scan.src_addr[0].v6, &v6_src_subnet_beg, sizeof(v6_src_subnet_beg)); memcpy(&scan.src_addr[1].v6, &v6_src_subnet_end, sizeof(v6_src_subnet_end)); mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 1); mached_session_print("SESSION_SCAN_SIP: (IPv6 SUBNET)", mgr, mached_sess_ids, mached_sess_num); scan.addr_family = AF_INET6; memcpy(&scan.src_addr[0].v6, &v6_min_addr, sizeof(v6_min_addr)); memcpy(&scan.src_addr[1].v6, &v6_max_addr, sizeof(v6_max_addr)); mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 1); mached_session_print("SESSION_SCAN_SIP: (IPv6 MIN MAX)", mgr, mached_sess_ids, mached_sess_num); // SESSION_SCAN_DIP scan.flags = SESSION_SCAN_DIP; scan.addr_family = AF_INET; scan.dst_addr[0].v4 = v4_dst_addr; scan.dst_addr[1].v4 = v4_dst_addr; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 3); mached_session_print("SESSION_SCAN_DIP: (IPv4)", mgr, mached_sess_ids, mached_sess_num); scan.addr_family = AF_INET; scan.dst_addr[0].v4 = v4_dst_subnet_beg; scan.dst_addr[1].v4 = v4_dst_subnet_end; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 3); mached_session_print("SESSION_SCAN_DIP: (IPv4 SUBNET)", mgr, mached_sess_ids, mached_sess_num); scan.addr_family = AF_INET; scan.dst_addr[0].v4 = v4_min_addr; scan.dst_addr[1].v4 = v4_max_addr; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 3); mached_session_print("SESSION_SCAN_DIP: (IPv4 MIN MAX)", mgr, mached_sess_ids, mached_sess_num); scan.addr_family = AF_INET6; memcpy(&scan.dst_addr[0].v6, &v6_dst_addr, sizeof(v6_dst_addr)); memcpy(&scan.dst_addr[1].v6, &v6_dst_addr, sizeof(v6_dst_addr)); mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 1); mached_session_print("SESSION_SCAN_DIP: (IPv6)", mgr, mached_sess_ids, mached_sess_num); scan.addr_family = AF_INET6; memcpy(&scan.dst_addr[0].v6, &v6_dst_subnet_beg, sizeof(v6_dst_subnet_beg)); memcpy(&scan.dst_addr[1].v6, &v6_dst_subnet_end, sizeof(v6_dst_subnet_end)); mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 1); mached_session_print("SESSION_SCAN_DIP: (IPv6 SUBNET)", mgr, mached_sess_ids, mached_sess_num); scan.addr_family = AF_INET6; memcpy(&scan.dst_addr[0].v6, &v6_min_addr, sizeof(v6_min_addr)); memcpy(&scan.dst_addr[1].v6, &v6_max_addr, sizeof(v6_max_addr)); mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 1); mached_session_print("SESSION_SCAN_DIP: (IPv6 MIN MAX)", mgr, mached_sess_ids, mached_sess_num); // SESSION_SCAN_SPORT scan.flags = SESSION_SCAN_SPORT; scan.src_port = htons(60111); mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 3); mached_session_print("SESSION_SCAN_SPORT: (HIT)", mgr, mached_sess_ids, mached_sess_num); scan.src_port = htons(60110); mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 0); mached_session_print("SESSION_SCAN_SPORT: (MISS)", mgr, mached_sess_ids, mached_sess_num); // SESSION_SCAN_DPORT scan.flags = SESSION_SCAN_DPORT; scan.dst_port = htons(80); mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 3); mached_session_print("SESSION_SCAN_DPORT: (HIT)", mgr, mached_sess_ids, mached_sess_num); scan.dst_port = htons(81); mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 0); mached_session_print("SESSION_SCAN_DPORT: (MISS)", mgr, mached_sess_ids, mached_sess_num); // SESSION_SCAN_CREATE_TIME scan.flags = SESSION_SCAN_CREATE_TIME; scan.create_time_ms[0] = 0; scan.create_time_ms[1] = UINT64_MAX; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 4); mached_session_print("SESSION_SCAN_CREATE_TIME: (HIT)", mgr, mached_sess_ids, mached_sess_num); scan.create_time_ms[0] = 1; scan.create_time_ms[1] = 2; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 2); mached_session_print("SESSION_SCAN_CREATE_TIME: (HIT)", mgr, mached_sess_ids, mached_sess_num); scan.create_time_ms[0] = 0; scan.create_time_ms[1] = 0; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 0); mached_session_print("SESSION_SCAN_CREATE_TIME: (MISS)", mgr, mached_sess_ids, mached_sess_num); scan.create_time_ms[0] = UINT64_MAX; scan.create_time_ms[1] = UINT64_MAX; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 0); mached_session_print("SESSION_SCAN_CREATE_TIME: (MISS)", mgr, mached_sess_ids, mached_sess_num); // SESSION_SCAN_LAST_PKT_TIME scan.flags = SESSION_SCAN_LAST_PKT_TIME; scan.last_pkt_time_ms[0] = 0; scan.last_pkt_time_ms[1] = UINT64_MAX; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 4); mached_session_print("SESSION_SCAN_LAST_PKT_TIME: (HIT)", mgr, mached_sess_ids, mached_sess_num); scan.last_pkt_time_ms[0] = 1; scan.last_pkt_time_ms[1] = 2; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 2); mached_session_print("SESSION_SCAN_LAST_PKT_TIME: (HIT)", mgr, mached_sess_ids, mached_sess_num); scan.last_pkt_time_ms[0] = 0; scan.last_pkt_time_ms[1] = 0; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 0); mached_session_print("SESSION_SCAN_LAST_PKT_TIME: (MISS)", mgr, mached_sess_ids, mached_sess_num); scan.last_pkt_time_ms[0] = UINT64_MAX; scan.last_pkt_time_ms[1] = UINT64_MAX; mached_sess_num = session_manager_scan(mgr, &scan, mached_sess_ids, sizeof(mached_sess_ids) / sizeof(mached_sess_ids[0])); EXPECT_TRUE(mached_sess_num == 0); mached_session_print("SESSION_SCAN_LAST_PKT_TIME: (MISS)", mgr, mached_sess_ids, mached_sess_num); session_manager_free(mgr); } #endif int main(int argc, char **argv) { struct snowflake_options opt = { .snowflake_base = 1, .snowflake_offset = 2, }; snowflake_id_init(&opt); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }