session manager support tcp reassembly

This commit is contained in:
luwenpeng
2024-03-26 15:09:03 +08:00
parent 5b92d6d8de
commit eb281ab789
30 changed files with 1917 additions and 88 deletions

View File

@@ -9,6 +9,6 @@ add_library(session_manager
)
target_include_directories(session_manager PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(session_manager PUBLIC ${CMAKE_SOURCE_DIR}/src/stellar)
target_link_libraries(session_manager timeout id_generator duplicated_packet_filter evicted_session_filter log)
target_link_libraries(session_manager timeout id_generator duplicated_packet_filter evicted_session_filter log tcp_reassembly)
add_subdirectory(test)

View File

@@ -236,6 +236,47 @@ enum session_dir session_get_cur_dir(const struct session *sess)
return sess->cur_dir;
}
/******************************************************************************
* session tcp reassembly
******************************************************************************/
const char *session_peek_tcp_payload(struct session *sess, uint32_t *len)
{
if (sess->type != SESSION_TYPE_TCP)
{
*len = 0;
assert(0);
return NULL;
}
if (sess->cur_dir == SESSION_DIR_C2S)
{
return tcp_reassembly_peek(sess->c2s_reassembly, len);
}
else
{
return tcp_reassembly_peek(sess->s2c_reassembly, len);
}
}
void session_consume_tcp_payload(struct session *sess, uint32_t len)
{
if (sess->type != SESSION_TYPE_TCP)
{
assert(0);
return;
}
if (sess->cur_dir == SESSION_DIR_C2S)
{
tcp_reassembly_consume(sess->c2s_reassembly, len);
}
else
{
tcp_reassembly_consume(sess->s2c_reassembly, len);
}
}
/******************************************************************************
* session ex data
******************************************************************************/
@@ -327,7 +368,7 @@ void session_free_ex_data(struct session *sess, uint8_t idx)
sess->ex_data[idx] = NULL;
}
void session_clean(struct session *sess)
void session_free_all_ex_data(struct session *sess)
{
if (sess)
{
@@ -335,18 +376,6 @@ void session_clean(struct session *sess)
{
session_free_ex_data(sess, i);
}
if (sess->c2s_1st_pkt)
{
packet_free(sess->c2s_1st_pkt);
sess->c2s_1st_pkt = NULL;
}
if (sess->s2c_1st_pkt)
{
packet_free(sess->s2c_1st_pkt);
sess->s2c_1st_pkt = NULL;
}
}
}

View File

@@ -121,6 +121,13 @@ const struct packet *session_get0_cur_pkt(const struct session *sess);
void session_set_cur_dir(struct session *sess, enum session_dir dir);
enum session_dir session_get_cur_dir(const struct session *sess);
/******************************************************************************
* session tcp reassembly
******************************************************************************/
const char *session_peek_tcp_payload(struct session *sess, uint32_t *len);
void session_consume_tcp_payload(struct session *sess, uint32_t len);
/******************************************************************************
* session ex data
******************************************************************************/
@@ -150,7 +157,7 @@ void *session_get0_ex_data(const struct session *sess, uint8_t idx);
* if user want to free ex_data, should use session_free_ex_data.
*/
void session_free_ex_data(struct session *sess, uint8_t idx);
void session_clean(struct session *sess);
void session_free_all_ex_data(struct session *sess);
/******************************************************************************
* session expire

View File

@@ -32,6 +32,8 @@ struct session_manager
#define EVICTE_SESSION_BURST (RX_BURST_MAX)
struct tcp_reassembly_options tcp_reassembly_opts = {0};
/******************************************************************************
* Options
******************************************************************************/
@@ -150,6 +152,20 @@ static int check_options(struct session_manager_options *opts)
return -1;
}
}
// TCP reassembly opts
if (opts->tcp_reassembly_enable != 0 && opts->tcp_reassembly_enable != 1)
{
SESSION_LOG_ERROR("invalid tcp reassembly enable, support range: 0-1");
return -1;
}
if (opts->tcp_reassembly_enable)
{
if (opts->tcp_reassembly_max_timeout < 1 || opts->tcp_reassembly_max_timeout > 60000)
{
SESSION_LOG_ERROR("invalid tcp reassembly max timeout, support range: 1-60,000");
return -1;
}
}
return 0;
}
@@ -500,16 +516,31 @@ static struct session *session_manager_new_tcp_session(struct session_manager *m
assert(0);
return NULL;
}
mgr->stat.tcp_sess.nr_sess_used++;
session_init(sess);
session_set_id(sess, id_generator_alloc());
sess->c2s_reassembly = tcp_reassembly_new(&tcp_reassembly_opts);
sess->s2c_reassembly = tcp_reassembly_new(&tcp_reassembly_opts);
if (sess->c2s_reassembly == NULL || sess->s2c_reassembly == NULL)
{
assert(0);
session_pool_push(mgr->sess_pool, sess);
return NULL;
}
mgr->stat.tcp_sess.nr_sess_used++;
enum session_dir dir = tcp_hdr_get_ack_flag(hdr) ? SESSION_DIR_S2C : SESSION_DIR_C2S;
enum session_state next_state = session_transition_run(SESSION_STATE_INIT, TCP_SYN);
session_transition_log(sess, SESSION_STATE_INIT, next_state, TCP_SYN);
session_update(sess, next_state, pkt, key, dir, now);
session_transition_log(sess, SESSION_STATE_INIT, next_state, TCP_SYN);
session_stat_inc(&mgr->stat.tcp_sess, next_state);
tcp_reassembly_init(dir == SESSION_DIR_C2S ? sess->c2s_reassembly : sess->s2c_reassembly, tcp_hdr_get_seq(hdr));
if (tcp_layer->pld_len)
{
tcp_reassembly_insert(dir == SESSION_DIR_C2S ? sess->c2s_reassembly : sess->s2c_reassembly,
tcp_hdr_get_seq(hdr), tcp_layer->pld_ptr, tcp_layer->pld_len, now);
}
uint64_t timeout = tcp_hdr_get_ack_flag(hdr) ? opts->tcp_timeout_handshake : opts->tcp_timeout_init;
timer_update(mgr->sess_timer, sess, now + timeout);
session_table_add(mgr->tcp_sess_table, key, sess);
@@ -542,8 +573,8 @@ static struct session *session_manager_new_udp_session(struct session_manager *m
enum session_dir dir = identify_direction_by_port(ntohs(key->src_port), ntohs(key->dst_port));
enum session_state next_state = session_transition_run(SESSION_STATE_INIT, UDP_DATA);
session_transition_log(sess, SESSION_STATE_INIT, next_state, UDP_DATA);
session_update(sess, next_state, pkt, key, dir, now);
session_transition_log(sess, SESSION_STATE_INIT, next_state, UDP_DATA);
session_stat_inc(&mgr->stat.udp_sess, next_state);
timer_update(mgr->sess_timer, sess, now + opts->udp_timeout_data);
@@ -564,10 +595,22 @@ static int session_manager_update_tcp_session(struct session_manager *mgr, struc
inputs |= tcp_layer->pld_len ? TCP_DATA : NONE;
enum session_state curr_state = session_get_state(sess);
enum session_state next_state = session_transition_run(curr_state, inputs);
session_transition_log(sess, curr_state, next_state, inputs);
session_update(sess, next_state, pkt, key, dir, now);
session_transition_log(sess, curr_state, next_state, inputs);
session_stat_update(mgr, sess, curr_state, next_state);
if (tcp_hdr_get_syn_flag(hdr))
{
tcp_reassembly_init(dir == SESSION_DIR_C2S ? sess->c2s_reassembly : sess->s2c_reassembly, tcp_hdr_get_seq(hdr));
}
tcp_reassembly_expire(sess->c2s_reassembly, now);
tcp_reassembly_expire(sess->s2c_reassembly, now);
if (tcp_layer->pld_len)
{
tcp_reassembly_insert(dir == SESSION_DIR_C2S ? sess->c2s_reassembly : sess->s2c_reassembly,
tcp_hdr_get_seq(hdr), tcp_layer->pld_ptr, tcp_layer->pld_len, now);
}
// select next timeout
uint64_t timeout = 0;
switch (next_state)
@@ -616,8 +659,8 @@ static int session_manager_update_udp_session(struct session_manager *mgr, struc
enum session_dir dir = identify_direction_by_history(sess, key);
enum session_state curr_state = session_get_state(sess);
enum session_state next_state = session_transition_run(curr_state, UDP_DATA);
session_transition_log(sess, curr_state, next_state, UDP_DATA);
session_update(sess, next_state, pkt, key, dir, now);
session_transition_log(sess, curr_state, next_state, UDP_DATA);
session_stat_update(mgr, sess, curr_state, next_state);
timer_update(mgr->sess_timer, sess, now + opts->udp_timeout_data);
@@ -653,6 +696,13 @@ struct session_manager *session_manager_new(struct session_manager_options *opts
.timeout_sec = opts->evicted_session_filter_timeout,
.error_rate = opts->evicted_session_filter_error_rate,
};
tcp_reassembly_opts = {
.enable = opts->tcp_reassembly_enable,
.max_timeout = opts->tcp_reassembly_max_timeout,
.max_segments = opts->tcp_reassembly_max_segments,
.max_bytes = opts->tcp_reassembly_max_bytes,
};
mgr->sess_pool = session_pool_new(opts->max_tcp_session_num + opts->max_udp_session_num);
mgr->tcp_sess_table = session_table_new();
mgr->udp_sess_table = session_table_new();
@@ -738,6 +788,8 @@ void session_manager_free_session(struct session_manager *mgr, struct session *s
switch (session_get_type(sess))
{
case SESSION_TYPE_TCP:
tcp_reassembly_free(sess->c2s_reassembly);
tcp_reassembly_free(sess->s2c_reassembly);
session_table_del(mgr->tcp_sess_table, session_get0_key(sess));
session_stat_dec(&mgr->stat.tcp_sess, session_get_state(sess));
mgr->stat.tcp_sess.nr_sess_used--;
@@ -754,7 +806,9 @@ void session_manager_free_session(struct session_manager *mgr, struct session *s
session_set0_cur_pkt(sess, NULL);
session_set_cur_dir(sess, SESSION_DIR_NONE);
session_clean(sess);
packet_free(sess->c2s_1st_pkt);
packet_free(sess->s2c_1st_pkt);
session_free_all_ex_data(sess);
session_pool_push(mgr->sess_pool, sess);
sess = NULL;
}

View File

@@ -44,6 +44,12 @@ struct session_manager_options
uint32_t evicted_session_filter_capacity;
uint32_t evicted_session_filter_timeout; // ms, Range: 1-60,000
double evicted_session_filter_error_rate;
// TCP reassembly
uint8_t tcp_reassembly_enable;
uint32_t tcp_reassembly_max_timeout; // ms, Range: 1-60,000
uint32_t tcp_reassembly_max_segments; // 0: unlimited
uint32_t tcp_reassembly_max_bytes; // 0: unlimited
};
struct session_stat

View File

@@ -13,8 +13,9 @@ extern "C"
#include "timeout.h"
#include "uthash.h"
#include "session.h"
#include "tcp_reassembly.h"
#define EX_DATA_MAX_COUNT 128
#define EX_DATA_MAX_COUNT 16
struct session
{
@@ -50,6 +51,13 @@ struct session
// session user data
void *user_data;
/******************************
* Session TCP Reassembly
******************************/
struct tcp_reassembly *c2s_reassembly;
struct tcp_reassembly *s2c_reassembly;
/******************************
* Session Current Packet
******************************/

View File

@@ -90,6 +90,13 @@ target_link_libraries(gtest_overload_evict_udp_sess session_manager gtest)
add_executable(gtest_session_transition gtest_session_transition.cpp)
target_link_libraries(gtest_session_transition session_manager gtest)
###############################################################################
# gtest tcp reassembly
###############################################################################
add_executable(gtest_sess_mgr_tcp_reassembly gtest_sess_mgr_tcp_reassembly.cpp)
target_link_libraries(gtest_sess_mgr_tcp_reassembly session_manager gtest)
###############################################################################
# gtest
###############################################################################
@@ -121,3 +128,5 @@ gtest_discover_tests(gtest_overload_evict_tcp_sess)
gtest_discover_tests(gtest_overload_evict_udp_sess)
gtest_discover_tests(gtest_session_transition)
gtest_discover_tests(gtest_sess_mgr_tcp_reassembly)

View File

@@ -37,6 +37,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
static void packet_set_ip_id(struct packet *pkt, uint16_t ip_id)

View File

@@ -39,6 +39,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
static void packet_set_tcp_src_addr(struct packet *pkt, uint32_t addr)

View File

@@ -39,6 +39,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
static void packet_set_tcp_src_addr(struct packet *pkt, uint32_t addr)

View File

@@ -0,0 +1,349 @@
#include <gtest/gtest.h>
#include "session.h"
#include "session_manager.h"
#include "ipv4_utils.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_timeout_init = 1,
.tcp_timeout_handshake = 2,
.tcp_timeout_data = 3,
.tcp_timeout_half_closed = 4,
.tcp_timeout_time_wait = 5,
.tcp_timeout_discard = 6,
// udp timeout
.udp_timeout_data = 7,
// 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 = 0,
.tcp_reassembly_max_bytes = 0,
};
static void hex_dump(const char *payload, uint32_t len)
{
printf("Payload Length: %d\n", len);
for (uint32_t i = 0; i < len; i++)
{
if (i > 0 && i % 16 == 0)
{
printf("\n");
}
printf("%02x ", (uint8_t)payload[i]);
}
printf("\n");
}
#if 1
TEST(SESS_MGR_TCP_REASSEMBLY, OUT_OF_ORDER)
{
uint32_t len = 0;
const char *payload = NULL;
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet
printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_out_of_order_pkt1, sizeof(tcp_out_of_order_pkt1));
printf("<= Packet Parse: done\n\n");
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload == NULL);
EXPECT_TRUE(len == 0);
// C2S ACK Packet
printf("\n=> Packet Parse: TCP C2S ACK packet\n");
packet_parse(&pkt, (const char *)tcp_out_of_order_pkt2, sizeof(tcp_out_of_order_pkt2));
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload == NULL);
EXPECT_TRUE(len == 0);
// C2S Data Packet 2222
printf("\n=> Packet Parse: TCP C2S Data packet\n");
packet_parse(&pkt, (const char *)tcp_out_of_order_pkt3, sizeof(tcp_out_of_order_pkt3));
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload == NULL);
EXPECT_TRUE(len == 0);
// C2S Data Packet 3333
printf("\n=> Packet Parse: TCP C2S Data packet\n");
packet_parse(&pkt, (const char *)tcp_out_of_order_pkt4, sizeof(tcp_out_of_order_pkt4));
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 4) == 0);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload == NULL);
EXPECT_TRUE(len == 0);
// C2S Data Packet 4444
printf("\n=> Packet Parse: TCP C2S Data packet\n");
packet_parse(&pkt, (const char *)tcp_out_of_order_pkt5, sizeof(tcp_out_of_order_pkt5));
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 5) == 0);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload == NULL);
EXPECT_TRUE(len == 0);
// C2S Data Packet 5555
printf("\n=> Packet Parse: TCP C2S Data packet\n");
packet_parse(&pkt, (const char *)tcp_out_of_order_pkt6, sizeof(tcp_out_of_order_pkt6));
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 6) == 0);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload == NULL);
EXPECT_TRUE(len == 0);
// C2S Data Packet 1111
printf("\n=> Packet Parse: TCP C2S Data packet\n");
packet_parse(&pkt, (const char *)tcp_out_of_order_pkt7, sizeof(tcp_out_of_order_pkt7));
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 7) == 0);
/*
* 11111111111111111111111111111111111111111111111111111111111111
* 22222222222222222222222222222222222222222222222222222222222222
* 33333333333333333333333333333333333333333333333333333333333333
* 44444444444444444444444444444444444444444444444444444444444444
* 55555555555555555555555555555555555555555555555555555555555555
*/
unsigned char payload1[] = {
0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x0a};
unsigned char payload2[] = {
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x0a};
unsigned char payload3[] = {
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x0a};
unsigned char payload4[] = {
0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x0a};
unsigned char payload5[] = {
0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x0a};
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload != NULL);
EXPECT_TRUE(len == sizeof(payload1));
EXPECT_TRUE(memcmp((void *)payload, payload1, sizeof(payload1)) == 0);
hex_dump(payload, len);
session_consume_tcp_payload(sess, len);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload != NULL);
EXPECT_TRUE(len == sizeof(payload2));
EXPECT_TRUE(memcmp((void *)payload, payload2, sizeof(payload2)) == 0);
hex_dump(payload, len);
session_consume_tcp_payload(sess, len);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload != NULL);
EXPECT_TRUE(len == sizeof(payload3));
EXPECT_TRUE(memcmp((void *)payload, payload3, sizeof(payload3)) == 0);
hex_dump(payload, len);
session_consume_tcp_payload(sess, len);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload != NULL);
EXPECT_TRUE(len == sizeof(payload4));
EXPECT_TRUE(memcmp((void *)payload, payload4, sizeof(payload4)) == 0);
hex_dump(payload, len);
session_consume_tcp_payload(sess, len);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload != NULL);
EXPECT_TRUE(len == sizeof(payload5));
EXPECT_TRUE(memcmp((void *)payload, payload5, sizeof(payload5)) == 0);
hex_dump(payload, len);
session_consume_tcp_payload(sess, len);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 7 + opts.tcp_timeout_data) == NULL); // active -> closing
sess = session_manager_get_expired_session(mgr, 7 + opts.tcp_timeout_data + opts.tcp_timeout_time_wait); // closing -> closed
EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_TIMEOUT);
session_dump(sess);
// free session
session_manager_free_session(mgr, sess);
session_manager_free(mgr);
}
#endif
#if 1
TEST(SESS_MGR_TCP_REASSEMBLY, SEQ_WRAPAROUND)
{
uint32_t len = 0;
const char *payload = NULL;
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet
printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_seq_wraparound_pkt1, sizeof(tcp_seq_wraparound_pkt1));
printf("<= Packet Parse: done\n\n");
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload == NULL);
EXPECT_TRUE(len == 0);
// C2S ACK Packet
printf("\n=> Packet Parse: TCP C2S ACK packet\n");
packet_parse(&pkt, (const char *)tcp_seq_wraparound_pkt2, sizeof(tcp_seq_wraparound_pkt2));
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload == NULL);
EXPECT_TRUE(len == 0);
// C2S Data Packet
printf("\n=> Packet Parse: TCP C2S Data packet\n");
packet_parse(&pkt, (const char *)tcp_seq_wraparound_pkt3, sizeof(tcp_seq_wraparound_pkt3));
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload != NULL);
EXPECT_TRUE(len == sizeof(tcp_seq_wraparound_pkt3_payload));
EXPECT_TRUE(memcmp((void *)payload, tcp_seq_wraparound_pkt3_payload, sizeof(tcp_seq_wraparound_pkt3_payload)) == 0);
hex_dump(payload, len);
session_consume_tcp_payload(sess, len);
// C2S Data Packet
printf("\n=> Packet Parse: TCP C2S Data packet\n");
packet_parse(&pkt, (const char *)tcp_seq_wraparound_pkt4, sizeof(tcp_seq_wraparound_pkt4));
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 4) == 0);
payload = session_peek_tcp_payload(sess, &len);
EXPECT_TRUE(payload != NULL);
EXPECT_TRUE(len == sizeof(tcp_seq_wraparound_pkt4_payload));
EXPECT_TRUE(memcmp((void *)payload, tcp_seq_wraparound_pkt4_payload, sizeof(tcp_seq_wraparound_pkt4_payload)) == 0);
hex_dump(payload, len);
session_consume_tcp_payload(sess, len);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 4 + opts.tcp_timeout_data) == NULL); // active -> closing
sess = session_manager_get_expired_session(mgr, 4 + opts.tcp_timeout_data + opts.tcp_timeout_time_wait); // closing -> closed
EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_TIMEOUT);
session_dump(sess);
// free session
session_manager_free_session(mgr, sess);
session_manager_free(mgr);
}
#endif
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -38,6 +38,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
static void build_active_tcp_session(struct session_manager *mgr, struct session *sess)

View File

@@ -38,6 +38,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
/******************************************************************************

View File

@@ -37,6 +37,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
#if 1

View File

@@ -37,6 +37,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
/******************************************************************************

View File

@@ -38,6 +38,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
/******************************************************************************

View File

@@ -37,6 +37,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
#if 1

View File

@@ -37,6 +37,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
/******************************************************************************

View File

@@ -36,6 +36,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
#if 1

View File

@@ -37,6 +37,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
#if 1

View File

@@ -37,6 +37,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
#if 1

View File

@@ -36,6 +36,12 @@ struct session_manager_options opts = {
.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 = 0,
.tcp_reassembly_max_bytes = 0,
};
#if 1

File diff suppressed because it is too large Load Diff