diff --git a/src/packet/tcp_helpers.h b/src/packet/tcp_helpers.h index b238131..f8fa560 100644 --- a/src/packet/tcp_helpers.h +++ b/src/packet/tcp_helpers.h @@ -129,6 +129,16 @@ static inline const uint8_t *tcp_hdr_get_opt_ptr(const struct tcphdr *hdr) return ((const uint8_t *)hdr) + sizeof(struct tcphdr); } +static inline void tcp_hdr_set_flags(struct tcphdr *hdr, uint8_t flags) +{ + hdr->th_flags = flags; +} + +static inline void tcp_hdr_set_flag_rst(struct tcphdr *hdr) +{ + hdr->th_flags |= TH_RST; +} + #ifdef __cpluscplus } #endif diff --git a/src/session/session_manager.cpp b/src/session/session_manager.cpp index 98e8fb3..51eec9a 100644 --- a/src/session/session_manager.cpp +++ b/src/session/session_manager.cpp @@ -107,7 +107,10 @@ static void tcp_init_timeout_cb(struct session *sess, void *arg) struct session_manager *mgr = (struct session_manager *)arg; assert(mgr != NULL); - session_set_closing_reasion(sess, CLOSING_BY_TIMEOUT); + if (session_get_closing_reasion(sess) == 0) + { + session_set_closing_reasion(sess, CLOSING_BY_TIMEOUT); + } session_manager_update_tcp_to_closing(mgr, sess, 1); } @@ -117,7 +120,10 @@ static void tcp_handshake_timeout_cb(struct session *sess, void *arg) struct session_manager *mgr = (struct session_manager *)arg; assert(mgr != NULL); - session_set_closing_reasion(sess, CLOSING_BY_TIMEOUT); + if (session_get_closing_reasion(sess) == 0) + { + session_set_closing_reasion(sess, CLOSING_BY_TIMEOUT); + } session_manager_update_tcp_to_closing(mgr, sess, 1); } @@ -127,7 +133,10 @@ static void tcp_data_timeout_cb(struct session *sess, void *arg) struct session_manager *mgr = (struct session_manager *)arg; assert(mgr != NULL); - session_set_closing_reasion(sess, CLOSING_BY_TIMEOUT); + if (session_get_closing_reasion(sess) == 0) + { + session_set_closing_reasion(sess, CLOSING_BY_TIMEOUT); + } session_manager_update_tcp_to_closing(mgr, sess, 1); } @@ -137,7 +146,10 @@ static void tcp_half_closed_timeout_cb(struct session *sess, void *arg) struct session_manager *mgr = (struct session_manager *)arg; assert(mgr != NULL); - session_set_closing_reasion(sess, CLOSING_BY_TIMEOUT); + if (session_get_closing_reasion(sess) == 0) + { + session_set_closing_reasion(sess, CLOSING_BY_TIMEOUT); + } session_manager_update_tcp_to_closing(mgr, sess, 1); } @@ -156,7 +168,10 @@ static void udp_data_timeout_cb(struct session *sess, void *arg) struct session_manager *mgr = (struct session_manager *)arg; assert(mgr != NULL); - session_set_closing_reasion(sess, CLOSING_BY_TIMEOUT); + if (session_get_closing_reasion(sess) == 0) + { + session_set_closing_reasion(sess, CLOSING_BY_TIMEOUT); + } session_manager_update_udp_to_closing(mgr, sess); } @@ -734,7 +749,7 @@ static void session_manager_handle_tcp_on_opening(struct session_manager *mgr, s static void session_manager_handle_tcp_on_active(struct session_manager *mgr, struct session *sess, enum tcp_state tcp_old_state, enum tcp_state tcp_curr_state) { // active -> closing - if ((tcp_curr_state & TCP_C2S_FIN_RECVED) && (tcp_curr_state | TCP_S2C_FIN_RECVED)) + if ((tcp_curr_state & TCP_C2S_FIN_RECVED) && (tcp_curr_state & TCP_S2C_FIN_RECVED)) { SESSION_LOG_DEBUG("TCP FIN-FIN received, session %lu active -> closing", session_get_id(sess)); session_manager_update_tcp_to_closing(mgr, sess, 1); diff --git a/src/session/test/CMakeLists.txt b/src/session/test/CMakeLists.txt index c86773e..8670376 100644 --- a/src/session/test/CMakeLists.txt +++ b/src/session/test/CMakeLists.txt @@ -23,6 +23,9 @@ target_link_libraries(gtest_tcp_init_to_opening session_manager gtest) add_executable(gtest_tcp_opening_to_active gtest_tcp_opening_to_active.cpp) target_link_libraries(gtest_tcp_opening_to_active session_manager gtest) +add_executable(gtest_tcp_active_to_closing gtest_tcp_active_to_closing.cpp) +target_link_libraries(gtest_tcp_active_to_closing session_manager gtest) + include(GoogleTest) gtest_discover_tests(gtest_session) gtest_discover_tests(gtest_session_pool) @@ -30,4 +33,5 @@ gtest_discover_tests(gtest_session_table) gtest_discover_tests(gtest_session_timer) gtest_discover_tests(gtest_session_queue) gtest_discover_tests(gtest_tcp_init_to_opening) -gtest_discover_tests(gtest_tcp_opening_to_active) \ No newline at end of file +gtest_discover_tests(gtest_tcp_opening_to_active) +gtest_discover_tests(gtest_tcp_active_to_closing) \ No newline at end of file diff --git a/src/session/test/gtest_tcp_active_to_closing.cpp b/src/session/test/gtest_tcp_active_to_closing.cpp new file mode 100644 index 0000000..907a0fb --- /dev/null +++ b/src/session/test/gtest_tcp_active_to_closing.cpp @@ -0,0 +1,443 @@ +// TCP state machine test: active -> closing + +#include "test_state_machine.h" + +static void build_active_tcp_session(struct session_manager *mgr, struct session *sess) +{ + char buffer[1024] = {0}; + struct packet pkt; + + // SYN Packet + printf("=> packet parse: TCP C2S SYN packet\n"); + packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); + printf("<= packet parse\n\n"); + sess = session_manager_update_session(mgr, &pkt); + EXPECT_TRUE(sess); + + EXPECT_TRUE(session_get_id(sess) == 0); + tuple6_tostring(session_get0_key(sess), buffer, sizeof(buffer)); + EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); + EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S); + EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING); + EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP); + EXPECT_TRUE(session_get_dup_traffic_flag(sess) == 0); + EXPECT_TRUE(session_get_closing_reasion(sess) == 0); + EXPECT_TRUE(session_get_c2s_bytes(sess) == 78); + EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); + EXPECT_TRUE(session_get_c2s_packets(sess) == 1); + EXPECT_TRUE(session_get_s2c_packets(sess) == 0); + EXPECT_TRUE(session_get_create_time(sess) == timestamp_get_msec()); + EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_msec()); + EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); + EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); + EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYN_RECVED); + EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); + EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); + EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess)); + + __session_dispatch(sess); + + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); + + sleep(1); + timestamp_update(); + + // C2S DATA Packet + printf("=> packet parse: TCP C2S DATA packet\n"); + packet_parse(&pkt, (const char *)tcp_pkt4_c2s_http_req, sizeof(tcp_pkt4_c2s_http_req)); + printf("<= packet parse\n\n"); + sess = session_manager_update_session(mgr, &pkt); + EXPECT_TRUE(sess); + + EXPECT_TRUE(session_get_id(sess) == 0); + tuple6_tostring(session_get0_key(sess), buffer, sizeof(buffer)); + EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); + EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S); + EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_ACTIVE); + EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP); + EXPECT_TRUE(session_get_dup_traffic_flag(sess) == 0); + EXPECT_TRUE(session_get_closing_reasion(sess) == 0); + EXPECT_TRUE(session_get_c2s_bytes(sess) == 78 + 145); + EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); + EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); + EXPECT_TRUE(session_get_s2c_packets(sess) == 0); + EXPECT_TRUE(session_get_create_time(sess) < timestamp_get_msec()); + EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_msec()); + EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); + EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); + EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_DATA_RECVED)); + EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); + EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); + + __session_dispatch(sess); + + __session_manager_count(mgr, 0, 1, 0, 0, 0, 0); + + sleep(1); + timestamp_update(); +} + +/****************************************************************************** + * case: TCP active -> closing (by FIN-FIN) + ******************************************************************************/ + +#if 1 +TEST(TCP_ACTIVE_TO_CLOSING, BY_FIN_FIN) +{ + char buffer[1024] = {0}; + struct packet pkt; + struct session *sess = NULL; + struct session_manager *mgr = NULL; + + timestamp_update(); + + mgr = session_manager_create(&config); + EXPECT_TRUE(mgr != NULL); + + // SYN Packet & C2S DATA Packet + build_active_tcp_session(mgr, sess); + + // C2S FIN Packet + printf("=> packet parse: TCP C2S FIN packet\n"); + packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin)); + printf("<= packet parse\n\n"); + sess = session_manager_update_session(mgr, &pkt); + EXPECT_TRUE(sess); + + EXPECT_TRUE(session_get_id(sess) == 0); + tuple6_tostring(session_get0_key(sess), buffer, sizeof(buffer)); + EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); + EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S); + EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_ACTIVE); + EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP); + EXPECT_TRUE(session_get_dup_traffic_flag(sess) == 0); + EXPECT_TRUE(session_get_closing_reasion(sess) == CLOSING_BY_CLIENT_FIN); + EXPECT_TRUE(session_get_c2s_bytes(sess) == 78 + 145 + 66); + EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); + EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1); + EXPECT_TRUE(session_get_s2c_packets(sess) == 0); + EXPECT_TRUE(session_get_create_time(sess) < timestamp_get_msec()); + EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_msec()); + EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); + EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); + EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_C2S_FIN_RECVED)); + EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); + EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); + + __session_dispatch(sess); + + __session_manager_count(mgr, 0, 1, 0, 0, 0, 0); + + sleep(1); + timestamp_update(); + + // S2C FIN Packet + printf("=> packet parse: TCP S2C FIN packet\n"); + packet_parse(&pkt, (const char *)tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin)); + printf("<= packet parse\n\n"); + sess = session_manager_update_session(mgr, &pkt); + EXPECT_TRUE(sess); + + EXPECT_TRUE(session_get_id(sess) == 0); + tuple6_tostring(session_get0_key(sess), buffer, sizeof(buffer)); + EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); + EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S); + EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSING); + EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP); + EXPECT_TRUE(session_get_dup_traffic_flag(sess) == 0); + EXPECT_TRUE(session_get_closing_reasion(sess) == CLOSING_BY_CLIENT_FIN); + EXPECT_TRUE(session_get_c2s_bytes(sess) == 78 + 145 + 66); + EXPECT_TRUE(session_get_s2c_bytes(sess) == 66); + EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1); + EXPECT_TRUE(session_get_s2c_packets(sess) == 1); + EXPECT_TRUE(session_get_create_time(sess) < timestamp_get_msec()); + EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_msec()); + EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); + EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); + EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_S2C_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_C2S_FIN_RECVED | TCP_S2C_FIN_RECVED)); + EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); + EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); + + __session_dispatch(sess); + + __session_manager_count(mgr, 0, 0, 1, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_CLIENT_FIN); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); + + session_manager_destroy(mgr); +} +#endif + +/****************************************************************************** + * case: TCP active -> closing (by C2S RST) + ******************************************************************************/ + +#if 1 +TEST(TCP_ACTIVE_TO_CLOSING, BY_C2S_RST) +{ + char buffer[1024] = {0}; + struct packet pkt; + struct session *sess = NULL; + struct session_manager *mgr = NULL; + + timestamp_update(); + + mgr = session_manager_create(&config); + EXPECT_TRUE(mgr != NULL); + + // SYN Packet & C2S DATA Packet + build_active_tcp_session(mgr, sess); + + // C2S RST Packet + printf("=> packet parse: TCP C2S RST packet\n"); + char tcp_pkt_c2s_rst[1500] = {0}; + memcpy(tcp_pkt_c2s_rst, tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin)); + packet_parse(&pkt, (const char *)tcp_pkt_c2s_rst, sizeof(tcp_pkt9_c2s_fin)); + const struct layer_record *tcp_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_TCP); + EXPECT_TRUE(tcp_layer); + struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr; + tcp_hdr_set_flags(hdr, 0); + tcp_hdr_set_flag_rst(hdr); + printf("<= packet parse\n\n"); + sess = session_manager_update_session(mgr, &pkt); + EXPECT_TRUE(sess); + + EXPECT_TRUE(session_get_id(sess) == 0); + tuple6_tostring(session_get0_key(sess), buffer, sizeof(buffer)); + EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); + EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S); + EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSING); + EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP); + EXPECT_TRUE(session_get_dup_traffic_flag(sess) == 0); + EXPECT_TRUE(session_get_closing_reasion(sess) == CLOSING_BY_CLIENT_RST); + EXPECT_TRUE(session_get_c2s_bytes(sess) == 78 + 145 + 66); + EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); + EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1); + EXPECT_TRUE(session_get_s2c_packets(sess) == 0); + EXPECT_TRUE(session_get_create_time(sess) < timestamp_get_msec()); + EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_msec()); + EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); + EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); + EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_C2S_RST_RECVED)); + EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); + EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); + + __session_dispatch(sess); + + __session_manager_count(mgr, 0, 0, 1, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_CLIENT_RST); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); + + session_manager_destroy(mgr); +} +#endif + +/****************************************************************************** + * case: TCP active -> closing (by S2C RST) + ******************************************************************************/ + +#if 1 +TEST(TCP_ACTIVE_TO_CLOSING, BY_S2C_RST) +{ + char buffer[1024] = {0}; + struct packet pkt; + struct session *sess = NULL; + struct session_manager *mgr = NULL; + + timestamp_update(); + + mgr = session_manager_create(&config); + EXPECT_TRUE(mgr != NULL); + + // SYN Packet & C2S DATA Packet + build_active_tcp_session(mgr, sess); + + // S2C RST Packet + printf("=> packet parse: TCP S2C RST packet\n"); + char tcp_pkt_s2c_rst[1500] = {0}; + memcpy(tcp_pkt_s2c_rst, tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin)); + packet_parse(&pkt, (const char *)tcp_pkt_s2c_rst, sizeof(tcp_pkt10_s2c_fin)); + const struct layer_record *tcp_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_TCP); + EXPECT_TRUE(tcp_layer); + struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr; + tcp_hdr_set_flags(hdr, 0); + tcp_hdr_set_flag_rst(hdr); + printf("<= packet parse\n\n"); + sess = session_manager_update_session(mgr, &pkt); + EXPECT_TRUE(sess); + + EXPECT_TRUE(session_get_id(sess) == 0); + tuple6_tostring(session_get0_key(sess), buffer, sizeof(buffer)); + EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); + EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S); + EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSING); + EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP); + EXPECT_TRUE(session_get_dup_traffic_flag(sess) == 0); + EXPECT_TRUE(session_get_closing_reasion(sess) == CLOSING_BY_SERVER_RST); + EXPECT_TRUE(session_get_c2s_bytes(sess) == 78 + 145); + EXPECT_TRUE(session_get_s2c_bytes(sess) == 66); + EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); + EXPECT_TRUE(session_get_s2c_packets(sess) == 1); + EXPECT_TRUE(session_get_create_time(sess) < timestamp_get_msec()); + EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_msec()); + EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); + EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); + EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_S2C_RST_RECVED)); + EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); + EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); + + __session_dispatch(sess); + + __session_manager_count(mgr, 0, 0, 1, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_SERVER_RST); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); + + session_manager_destroy(mgr); +} +#endif + +/****************************************************************************** + * case: TCP active -> closing (by date timeout) + ******************************************************************************/ + +#if 1 +TEST(TCP_ACTIVE_TO_CLOSING, BY_DATA_TIMEOUT) +{ + struct session *sess = NULL; + struct session_manager *mgr = NULL; + + timestamp_update(); + + mgr = session_manager_create(&config); + EXPECT_TRUE(mgr != NULL); + + // SYN Packet & C2S DATA Packet + build_active_tcp_session(mgr, sess); + + __session_manager_count(mgr, 0, 1, 0, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_TIMEOUT); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); + + session_manager_destroy(mgr); +} +#endif + +/****************************************************************************** + * case: TCP active -> closing (by C2S half closed timeout) + ******************************************************************************/ + +#if 1 +TEST(TCP_ACTIVE_TO_CLOSING, BY_C2S_HALF_CLOSED_TIMEOUT) +{ + char buffer[1024] = {0}; + struct packet pkt; + struct session *sess = NULL; + struct session_manager *mgr = NULL; + + timestamp_update(); + + mgr = session_manager_create(&config); + EXPECT_TRUE(mgr != NULL); + + // SYN Packet & C2S DATA Packet + build_active_tcp_session(mgr, sess); + + // C2S FIN Packet + printf("=> packet parse: TCP C2S FIN packet\n"); + packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin)); + printf("<= packet parse\n\n"); + sess = session_manager_update_session(mgr, &pkt); + EXPECT_TRUE(sess); + + EXPECT_TRUE(session_get_id(sess) == 0); + tuple6_tostring(session_get0_key(sess), buffer, sizeof(buffer)); + EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); + EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S); + EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_ACTIVE); + EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP); + EXPECT_TRUE(session_get_dup_traffic_flag(sess) == 0); + EXPECT_TRUE(session_get_closing_reasion(sess) == CLOSING_BY_CLIENT_FIN); + EXPECT_TRUE(session_get_c2s_bytes(sess) == 78 + 145 + 66); + EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); + EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1); + EXPECT_TRUE(session_get_s2c_packets(sess) == 0); + EXPECT_TRUE(session_get_create_time(sess) < timestamp_get_msec()); + EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_msec()); + EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); + EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); + EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_C2S_FIN_RECVED)); + EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); + EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); + + __session_dispatch(sess); + + __session_manager_count(mgr, 0, 1, 0, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_CLIENT_FIN); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); + + session_manager_destroy(mgr); +} +#endif + +/****************************************************************************** + * case: TCP active -> closing (by S2C half closed timeout) + ******************************************************************************/ + +#if 1 +TEST(TCP_ACTIVE_TO_CLOSING, BY_S2C_HALF_CLOSED_TIMEOUT) +{ + char buffer[1024] = {0}; + struct packet pkt; + struct session *sess = NULL; + struct session_manager *mgr = NULL; + + timestamp_update(); + + mgr = session_manager_create(&config); + EXPECT_TRUE(mgr != NULL); + + // SYN Packet & C2S DATA Packet + build_active_tcp_session(mgr, sess); + + // S2C FIN Packet + printf("=> packet parse: TCP S2C FIN packet\n"); + packet_parse(&pkt, (const char *)tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin)); + printf("<= packet parse\n\n"); + sess = session_manager_update_session(mgr, &pkt); + EXPECT_TRUE(sess); + + EXPECT_TRUE(session_get_id(sess) == 0); + tuple6_tostring(session_get0_key(sess), buffer, sizeof(buffer)); + EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); + EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S); + EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_ACTIVE); + EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP); + EXPECT_TRUE(session_get_dup_traffic_flag(sess) == 0); + EXPECT_TRUE(session_get_closing_reasion(sess) == CLOSING_BY_SERVER_FIN); + EXPECT_TRUE(session_get_c2s_bytes(sess) == 78 + 145); + EXPECT_TRUE(session_get_s2c_bytes(sess) == 66); + EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); + EXPECT_TRUE(session_get_s2c_packets(sess) == 1); + EXPECT_TRUE(session_get_create_time(sess) < timestamp_get_msec()); + EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_msec()); + EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); + EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); + EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_S2C_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_S2C_FIN_RECVED)); + EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); + EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); + + __session_dispatch(sess); + + __session_manager_count(mgr, 0, 1, 0, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_SERVER_FIN); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); + + session_manager_destroy(mgr); +} +#endif + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/session/test/gtest_tcp_init_to_opening.cpp b/src/session/test/gtest_tcp_init_to_opening.cpp index 6c8faea..a88f10a 100644 --- a/src/session/test/gtest_tcp_init_to_opening.cpp +++ b/src/session/test/gtest_tcp_init_to_opening.cpp @@ -1,58 +1,6 @@ // TCP state machine test: init -> opening -#include - -#include "session_private.h" -#include "timestamp.h" -#include "session_manager.h" -#include "ipv4_helpers.h" -#include "test_packets.h" - -struct session_manager_config config = { - // max session number - .max_tcp_session_num = 3, - .max_udp_session_num = 3, - - // tcp timeout - .tcp_timeout_init = 2, - .tcp_timeout_handshake = 2, - .tcp_timeout_data = 2, - .tcp_timeout_half_closed = 2, - .tcp_timeout_time_wait = 2, - .tcp_timeout_discard = 2, - - // udp timeout - .udp_timeout_data = 1, - - // tcp duplicate packet filter - .tcp_dupkt_filter_enable = 1, - .tcp_dupkt_filter_capacity = 1000, - .tcp_dupkt_filter_timeout = 10, - .tcp_dupkt_filter_error_rate = 0.0001, - - // udp eviction filter - .udp_eviction_filter_enable = 1, - .udp_eviction_filter_capacity = 1000, - .udp_eviction_filter_timeout = 10, - .udp_eviction_filter_error_rate = 0.0001, -}; - -static void __session_dispatch(struct session *sess) -{ - if (sess == NULL) - { - return; - } - - printf("\n"); - printf("=> session dispatch: %p\n", sess); - session_dump(sess); - printf("<= session dispatch\n"); - printf("\n"); - - session_set0_cur_pkt(sess, NULL); - session_set_cur_dir(sess, SESSION_DIR_NONE); -} +#include "test_state_machine.h" /****************************************************************************** * case: TCP init -> opening (by SYN) @@ -101,27 +49,9 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); - - for (int i = 0; i < 3; i++) - { - timestamp_update(); - __session_dispatch(session_manager_get_expired_session(mgr)); - __session_dispatch(session_manager_get_evicted_session(mgr)); - sleep(1); - } - - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_TIMEOUT); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); session_manager_destroy(mgr); } @@ -174,27 +104,9 @@ TEST(TCP_INIT_TO_OPENING, BY_SYNACK) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); - - for (int i = 0; i < 3; i++) - { - timestamp_update(); - __session_dispatch(session_manager_get_expired_session(mgr)); - __session_dispatch(session_manager_get_evicted_session(mgr)); - sleep(1); - } - - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_TIMEOUT); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); session_manager_destroy(mgr); } @@ -247,12 +159,7 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_SYNACK) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); sleep(1); timestamp_update(); @@ -287,27 +194,9 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_SYNACK) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); - - for (int i = 0; i < 3; i++) - { - timestamp_update(); - __session_dispatch(session_manager_get_expired_session(mgr)); - __session_dispatch(session_manager_get_evicted_session(mgr)); - sleep(1); - } - - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_TIMEOUT); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); session_manager_destroy(mgr); } @@ -360,12 +249,7 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_SYNACK_ACK) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); sleep(1); timestamp_update(); @@ -400,12 +284,7 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_SYNACK_ACK) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); sleep(1); timestamp_update(); @@ -437,27 +316,11 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_SYNACK_ACK) EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_dispatch(sess); - for (int i = 0; i < 3; i++) - { - timestamp_update(); - __session_dispatch(session_manager_get_expired_session(mgr)); - __session_dispatch(session_manager_get_evicted_session(mgr)); - sleep(1); - } - - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_TIMEOUT); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); session_manager_destroy(mgr); } @@ -512,19 +375,16 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_RETRANSMISSION) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); sleep(1); timestamp_update(); // SYN Packet retransmission printf("=> packet parse: TCP C2S SYN retransmission packet\n"); - packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); + char tcp_pkt_c2s_syn_retransmission[1500] = {0}; + memcpy(tcp_pkt_c2s_syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); + packet_parse(&pkt, (const char *)tcp_pkt_c2s_syn_retransmission, sizeof(tcp_pkt1_c2s_syn)); const struct layer_record *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4); EXPECT_TRUE(ipv4_layer); const struct ip *hdr = (const struct ip *)ipv4_layer->hdr_ptr; @@ -556,27 +416,9 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_RETRANSMISSION) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); - - for (int i = 0; i < 3; i++) - { - timestamp_update(); - __session_dispatch(session_manager_get_expired_session(mgr)); - __session_dispatch(session_manager_get_evicted_session(mgr)); - sleep(1); - } - - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_TIMEOUT); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); session_manager_destroy(mgr); } @@ -631,19 +473,16 @@ TEST(TCP_INIT_TO_OPENING, BY_SYNACK_RETRANSMISSION) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); sleep(1); timestamp_update(); // SYNACK Packet retransmission printf("=> packet parse: TCP S2C SYNACK retransmission packet\n"); - packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); + char tcp_pkt_s2c_synack_retransmission[1500] = {0}; + memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); + packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack)); const struct layer_record *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4); EXPECT_TRUE(ipv4_layer); const struct ip *hdr = (const struct ip *)ipv4_layer->hdr_ptr; @@ -675,27 +514,9 @@ TEST(TCP_INIT_TO_OPENING, BY_SYNACK_RETRANSMISSION) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); - - for (int i = 0; i < 3; i++) - { - timestamp_update(); - __session_dispatch(session_manager_get_expired_session(mgr)); - __session_dispatch(session_manager_get_evicted_session(mgr)); - sleep(1); - } - - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_TIMEOUT); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); session_manager_destroy(mgr); } @@ -748,12 +569,7 @@ TEST(TCP_INIT_TO_OPENING, BY_C2S_ASMMETRIC) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); sleep(1); timestamp_update(); @@ -786,27 +602,11 @@ TEST(TCP_INIT_TO_OPENING, BY_C2S_ASMMETRIC) EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess)); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_dispatch(sess); - for (int i = 0; i < 3; i++) - { - timestamp_update(); - __session_dispatch(session_manager_get_expired_session(mgr)); - __session_dispatch(session_manager_get_evicted_session(mgr)); - sleep(1); - } - - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_TIMEOUT); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); session_manager_destroy(mgr); } @@ -859,12 +659,7 @@ TEST(TCP_INIT_TO_OPENING, BY_S2C_ASMMETRIC) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); sleep(1); timestamp_update(); @@ -899,27 +694,9 @@ TEST(TCP_INIT_TO_OPENING, BY_S2C_ASMMETRIC) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); - - for (int i = 0; i < 3; i++) - { - timestamp_update(); - __session_dispatch(session_manager_get_expired_session(mgr)); - __session_dispatch(session_manager_get_evicted_session(mgr)); - sleep(1); - } - - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_TIMEOUT); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); session_manager_destroy(mgr); } diff --git a/src/session/test/gtest_tcp_opening_to_active.cpp b/src/session/test/gtest_tcp_opening_to_active.cpp index 1e3e068..c2e6643 100644 --- a/src/session/test/gtest_tcp_opening_to_active.cpp +++ b/src/session/test/gtest_tcp_opening_to_active.cpp @@ -1,58 +1,6 @@ // TCP state machine test: opening -> active -#include - -#include "session_private.h" -#include "timestamp.h" -#include "session_manager.h" -#include "ipv4_helpers.h" -#include "test_packets.h" - -struct session_manager_config config = { - // max session number - .max_tcp_session_num = 3, - .max_udp_session_num = 3, - - // tcp timeout - .tcp_timeout_init = 2, - .tcp_timeout_handshake = 2, - .tcp_timeout_data = 2, - .tcp_timeout_half_closed = 2, - .tcp_timeout_time_wait = 2, - .tcp_timeout_discard = 2, - - // udp timeout - .udp_timeout_data = 1, - - // tcp duplicate packet filter - .tcp_dupkt_filter_enable = 1, - .tcp_dupkt_filter_capacity = 1000, - .tcp_dupkt_filter_timeout = 10, - .tcp_dupkt_filter_error_rate = 0.0001, - - // udp eviction filter - .udp_eviction_filter_enable = 1, - .udp_eviction_filter_capacity = 1000, - .udp_eviction_filter_timeout = 10, - .udp_eviction_filter_error_rate = 0.0001, -}; - -static void __session_dispatch(struct session *sess) -{ - if (sess == NULL) - { - return; - } - - printf("\n"); - printf("=> session dispatch: %p\n", sess); - session_dump(sess); - printf("<= session dispatch\n"); - printf("\n"); - - session_set0_cur_pkt(sess, NULL); - session_set_cur_dir(sess, SESSION_DIR_NONE); -} +#include "test_state_machine.h" /****************************************************************************** * case: TCP opening -> active (by C2S DATA) @@ -101,12 +49,7 @@ TEST(TCP_OPENING_TO_ACTIVE, BY_SYN_C2S_DATA) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); sleep(1); timestamp_update(); @@ -138,27 +81,11 @@ TEST(TCP_OPENING_TO_ACTIVE, BY_SYN_C2S_DATA) EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_dispatch(sess); - for (int i = 0; i < 3; i++) - { - timestamp_update(); - __session_dispatch(session_manager_get_expired_session(mgr)); - __session_dispatch(session_manager_get_evicted_session(mgr)); - sleep(1); - } - - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 0, 1, 0, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_TIMEOUT); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); session_manager_destroy(mgr); } @@ -211,12 +138,7 @@ TEST(TCP_OPENING_TO_ACTIVE, BY_SYNACK_S2C_DATA) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 1, 0, 0, 0, 0, 0); sleep(1); timestamp_update(); @@ -250,27 +172,9 @@ TEST(TCP_OPENING_TO_ACTIVE, BY_SYNACK_S2C_DATA) __session_dispatch(sess); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 1); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); - - for (int i = 0; i < 3; i++) - { - timestamp_update(); - __session_dispatch(session_manager_get_expired_session(mgr)); - __session_dispatch(session_manager_get_evicted_session(mgr)); - sleep(1); - } - - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == 0); - EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == 0); + __session_manager_count(mgr, 0, 1, 0, 0, 0, 0); + __session_manager_dispatch(mgr, CLOSING_BY_TIMEOUT); + __session_manager_count(mgr, 0, 0, 0, 0, 0, 0); session_manager_destroy(mgr); } diff --git a/src/session/test/test_state_machine.h b/src/session/test/test_state_machine.h new file mode 100644 index 0000000..591a9db --- /dev/null +++ b/src/session/test/test_state_machine.h @@ -0,0 +1,101 @@ +#ifndef _TEST_STATE_MACHINE_H +#define _TEST_STATE_MACHINE_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +#include + +#include "session_private.h" +#include "timestamp.h" +#include "session_manager.h" +#include "ipv4_helpers.h" +#include "tcp_helpers.h" +#include "test_packets.h" + +struct session_manager_config config = { + // max session number + .max_tcp_session_num = 3, + .max_udp_session_num = 3, + + // tcp timeout + .tcp_timeout_init = 2, + .tcp_timeout_handshake = 2, + .tcp_timeout_data = 2, + .tcp_timeout_half_closed = 2, + .tcp_timeout_time_wait = 2, + .tcp_timeout_discard = 2, + + // udp timeout + .udp_timeout_data = 1, + + // tcp duplicate packet filter + .tcp_dupkt_filter_enable = 1, + .tcp_dupkt_filter_capacity = 1000, + .tcp_dupkt_filter_timeout = 10, + .tcp_dupkt_filter_error_rate = 0.0001, + + // udp eviction filter + .udp_eviction_filter_enable = 1, + .udp_eviction_filter_capacity = 1000, + .udp_eviction_filter_timeout = 10, + .udp_eviction_filter_error_rate = 0.0001, +}; + +static void __session_dispatch(struct session *sess) +{ + if (sess == NULL) + { + return; + } + + printf("\n"); + printf("=> session dispatch: %p\n", sess); + session_dump(sess); + printf("<= session dispatch\n"); + printf("\n"); + + session_set0_cur_pkt(sess, NULL); + session_set_cur_dir(sess, SESSION_DIR_NONE); +} + +static void __session_manager_dispatch(struct session_manager *mgr, enum closing_reasion reason) +{ + struct session *sess; + for (int i = 0; i < 3; i++) + { + timestamp_update(); + sess = session_manager_get_expired_session(mgr); + __session_dispatch(sess); + if (sess && session_get_state(sess) == SESSION_STATE_CLOSING) + { + EXPECT_TRUE(session_get_closing_reasion(sess) == reason); + } + sess = session_manager_get_evicted_session(mgr); + __session_dispatch(sess); + if (sess && session_get_state(sess) == SESSION_STATE_CLOSING) + { + EXPECT_TRUE(session_get_closing_reasion(sess) == reason); + } + sleep(1); + } +} + +static void __session_manager_count(struct session_manager *mgr, uint64_t tcp_opening_num, uint64_t tcp_active_num, uint64_t tcp_closing_num, uint64_t udp_opening_num, uint64_t udp_active_num, uint64_t udp_closing_num) +{ + EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_OPENING) == tcp_opening_num); + EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_ACTIVE) == tcp_active_num); + EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_TCP, SESSION_STATE_CLOSING) == tcp_closing_num); + + EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_OPENING) == udp_opening_num); + EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_ACTIVE) == udp_active_num); + EXPECT_TRUE(session_manager_get_session_number(mgr, SESSION_TYPE_UDP, SESSION_STATE_CLOSING) == udp_closing_num); +} + +#ifdef __cpluscplus +} +#endif + +#endif