session manager support tcp reassembly
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user