Modify the configuration items of evicted_session_filter && duplicated_packet_filter

This commit is contained in:
luwenpeng
2024-04-08 11:28:45 +08:00
parent 151b6f8f1d
commit c8beafe081
21 changed files with 148 additions and 204 deletions

View File

@@ -15,18 +15,17 @@
struct session_manager
{
struct session_manager_options opts;
struct list_head evicte_queue;
struct session_pool *sess_pool;
struct session_timer *sess_timer;
struct session_table *tcp_sess_table;
struct session_table *udp_sess_table;
struct session_timer *sess_timer;
struct list_head evicte_queue;
struct duplicated_packet_filter *dup_pkt_filter;
struct evicted_session_filter *evicte_sess_filter;
struct session_manager_stat stat;
struct session_manager_options opts;
};
#define EVICTE_SESSION_BURST (RX_BURST_MAX)
@@ -40,6 +39,7 @@ int check_options(const struct session_manager_options *opts)
return -1;
}
// max session number
if (opts->max_tcp_session_num < EVICTE_SESSION_BURST * 2)
{
SESSION_LOG_ERROR("invalid max_tcp_session_num: %lu, supported range: [%u, %lu]", opts->max_tcp_session_num, EVICTE_SESSION_BURST * 2, UINT64_MAX);
@@ -50,6 +50,10 @@ int check_options(const struct session_manager_options *opts)
SESSION_LOG_ERROR("invalid max_udp_session_num: %lu, supported range: [%u, %lu]", opts->max_udp_session_num, EVICTE_SESSION_BURST * 2, UINT64_MAX);
return -1;
}
// session overload (skip)
// TCP timeout
if (opts->tcp_init_timeout < 1 || opts->tcp_init_timeout > 60000)
{
SESSION_LOG_ERROR("invalid tcp_init_timeout: %lu, supported range: [1, 60000]", opts->tcp_init_timeout);
@@ -85,12 +89,70 @@ int check_options(const struct session_manager_options *opts)
SESSION_LOG_ERROR("invalid tcp_unverified_rst_timeout: %lu, supported range: [1, 600000]", opts->tcp_unverified_rst_timeout);
return -1;
}
// UDP timeout
if (opts->udp_data_timeout < 1 || opts->udp_data_timeout > 15999999000)
{
SESSION_LOG_ERROR("invalid udp_data_timeout: %lu, supported range: [1, 15999999000]", opts->udp_data_timeout);
return -1;
}
// duplicate packet filter
if (opts->duplicated_packet_filter_enable)
{
if (opts->duplicated_packet_filter_capacity == 0)
{
// UINT32_MAX = 4294967295
SESSION_LOG_ERROR("invalid duplicated_packet_filter_capacity: %u, supported range: [1, 4294967295]", opts->duplicated_packet_filter_capacity);
return -1;
}
if (opts->duplicated_packet_filter_timeout < 1 || opts->duplicated_packet_filter_timeout > 60000)
{
SESSION_LOG_ERROR("invalid duplicated_packet_filter_timeout: %u, supported range: [1, 60000]", opts->duplicated_packet_filter_timeout);
return -1;
}
if (opts->duplicated_packet_filter_error_rate < 0.0 || opts->duplicated_packet_filter_error_rate > 1.0)
{
SESSION_LOG_ERROR("invalid duplicated_packet_filter_error_rate: %f, supported range: [0.0, 1.0]", opts->duplicated_packet_filter_error_rate);
return -1;
}
}
// evicted session filter
if (opts->evicted_session_filter_enable)
{
if (opts->evicted_session_filter_capacity == 0)
{
// UINT32_MAX = 4294967295
SESSION_LOG_ERROR("invalid evicted_session_filter_capacity: %u, supported range: [1, 4294967295]", opts->evicted_session_filter_capacity);
return -1;
}
if (opts->evicted_session_filter_timeout < 1 || opts->evicted_session_filter_timeout > 60000)
{
SESSION_LOG_ERROR("invalid evicted_session_filter_timeout: %u, supported range: [1, 60000]", opts->evicted_session_filter_timeout);
return -1;
}
if (opts->evicted_session_filter_error_rate < 0.0 || opts->evicted_session_filter_error_rate > 1.0)
{
SESSION_LOG_ERROR("invalid evicted_session_filter_error_rate: %f, supported range: [0.0, 1.0]", opts->evicted_session_filter_error_rate);
return -1;
}
}
// TCP reassembly
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: %u, supported range: [1, 60000]", opts->tcp_reassembly_max_timeout);
return -1;
}
if (opts->tcp_reassembly_max_segments < 2 || opts->tcp_reassembly_max_segments > 32)
{
SESSION_LOG_ERROR("invalid tcp_reassembly_max_segments: %u, supported range: [2, 32]", opts->tcp_reassembly_max_segments);
return -1;
}
}
return 0;
}
@@ -126,10 +188,11 @@ static int tcp_pcb_init(struct tcp_pcb *pcb, uint64_t max_timeout, uint64_t max_
return 0;
}
static void tcp_half_update(struct tcp_half *half, const struct pkt_layer *tcp_layer, uint64_t now)
static void tcp_pcb_update(struct tcp_pcb *pcb, enum session_dir dir, const struct pkt_layer *tcp_layer, uint64_t now)
{
struct tcp_segment *seg;
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
struct tcp_half *half = (dir == SESSION_DIR_C2S) ? &pcb->c2s : &pcb->s2c;
uint8_t flags = tcp_hdr_get_flags(hdr);
half->flags |= flags;
@@ -351,7 +414,7 @@ static int session_manager_self_protection(struct session_manager *mgr, struct s
// on pre new session
static int session_manager_filter_evicted_session(struct session_manager *mgr, struct session *sess, const struct packet *pkt, const struct tuple6 *key, uint64_t now)
{
if (evicted_session_filter_lookup(mgr->evicte_sess_filter, key, now))
if (mgr->opts.evicted_session_filter_enable && evicted_session_filter_lookup(mgr->evicte_sess_filter, key, now))
{
mgr->stat.evc_pkt.nr_pkts++;
mgr->stat.evc_pkt.nr_bytes += packet_get_len(pkt);
@@ -364,6 +427,11 @@ static int session_manager_filter_evicted_session(struct session_manager *mgr, s
// on pre update session
static int session_manager_filter_duplicated_packet(struct session_manager *mgr, struct session *sess, const struct packet *pkt, const struct tuple6 *key, uint64_t now)
{
if (mgr->opts.duplicated_packet_filter_enable == 0)
{
return 0;
}
enum session_dir dir = identify_direction_by_history(sess, key);
if ((dir == SESSION_DIR_C2S && session_get_metric(sess, SESSION_METRIC_C2S_PACKETS) < 3) ||
(dir == SESSION_DIR_S2C && session_get_metric(sess, SESSION_METRIC_S2C_PACKETS) < 3) ||
@@ -501,7 +569,10 @@ static void session_manager_evicte_session(struct session_manager *mgr, struct s
SESSION_LOG_DEBUG("evicte udp old session: %lu", session_get_id(sess));
mgr->stat.udp_sess.nr_old_sess_evicted++;
session_table_del(mgr->udp_sess_table, session_get_tuple(sess));
evicted_session_filter_add(mgr->evicte_sess_filter, session_get_tuple(sess), now);
if (mgr->opts.evicted_session_filter_enable)
{
evicted_session_filter_add(mgr->evicte_sess_filter, session_get_tuple(sess), now);
}
break;
default:
assert(0);
@@ -542,8 +613,7 @@ static struct session *session_manager_new_tcp_session(struct session_manager *m
session_pool_push(mgr->sess_pool, sess);
return NULL;
}
struct tcp_half *curr = (dir == SESSION_DIR_C2S) ? &sess->tcp_pcb.c2s : &sess->tcp_pcb.s2c;
tcp_half_update(curr, tcp_layer, now);
tcp_pcb_update(&sess->tcp_pcb, dir, tcp_layer, now);
enum session_state next_state = session_transition_run(SESSION_STATE_INIT, TCP_SYN);
session_update(sess, next_state, pkt, key, dir, now);
@@ -554,7 +624,12 @@ static struct session *session_manager_new_tcp_session(struct session_manager *m
session_timer_update(mgr->sess_timer, sess, now + timeout);
session_table_add(mgr->tcp_sess_table, key, sess);
duplicated_packet_filter_add(mgr->dup_pkt_filter, pkt, now);
uint64_t curr_dir_pkts = (dir == SESSION_DIR_C2S) ? session_get_metric(sess, SESSION_METRIC_C2S_PACKETS) : session_get_metric(sess, SESSION_METRIC_S2C_PACKETS);
if (curr_dir_pkts < 3 && mgr->opts.duplicated_packet_filter_enable)
{
duplicated_packet_filter_add(mgr->dup_pkt_filter, pkt, now);
}
mgr->stat.tcp_sess.nr_sess_used++;
return sess;
@@ -613,9 +688,12 @@ static int session_manager_update_tcp_session(struct session_manager *mgr, struc
session_transition_log(sess, curr_state, next_state, inputs);
// update tcp pcb
struct tcp_half *curr = (dir == SESSION_DIR_C2S) ? &sess->tcp_pcb.c2s : &sess->tcp_pcb.s2c;
struct tcp_half *peer = (dir == SESSION_DIR_C2S) ? &sess->tcp_pcb.s2c : &sess->tcp_pcb.c2s;
tcp_half_update(curr, tcp_layer, now);
tcp_pcb_update(&sess->tcp_pcb, dir, tcp_layer, now);
if (mgr->opts.duplicated_packet_filter_enable)
{
duplicated_packet_filter_add(mgr->dup_pkt_filter, pkt, now);
}
// set closing reason
if (next_state == SESSION_STATE_CLOSING && !session_get_closing_reason(sess))
@@ -631,6 +709,8 @@ static int session_manager_update_tcp_session(struct session_manager *mgr, struc
}
// update timeout
struct tcp_half *curr = (dir == SESSION_DIR_C2S) ? &sess->tcp_pcb.c2s : &sess->tcp_pcb.s2c;
struct tcp_half *peer = (dir == SESSION_DIR_C2S) ? &sess->tcp_pcb.s2c : &sess->tcp_pcb.c2s;
uint64_t timeout = 0;
switch (next_state)
{
@@ -704,34 +784,32 @@ struct session_manager *session_manager_new(struct session_manager_options *opts
{
return NULL;
}
memcpy(&mgr->opts, opts, sizeof(struct session_manager_options));
// duplicated packet filter
struct duplicated_packet_filter_options duplicated_packet_filter_opts = {
.enable = opts->duplicated_packet_filter_enable,
.capacity = opts->duplicated_packet_filter_capacity,
.timeout = opts->duplicated_packet_filter_timeout,
.error_rate = opts->duplicated_packet_filter_error_rate,
};
// evicted session filter
struct evicted_session_filter_options evicted_session_filter_opts = {
.enable = opts->evicted_session_filter_enable,
.capacity = opts->evicted_session_filter_capacity,
.timeout = opts->evicted_session_filter_timeout,
.error_rate = opts->evicted_session_filter_error_rate,
};
mgr->sess_pool = session_pool_new(mgr->opts.max_tcp_session_num + mgr->opts.max_udp_session_num);
mgr->tcp_sess_table = session_table_new();
mgr->udp_sess_table = session_table_new();
mgr->sess_timer = session_timer_new(now);
mgr->dup_pkt_filter = duplicated_packet_filter_new(&duplicated_packet_filter_opts, now);
mgr->evicte_sess_filter = evicted_session_filter_new(&evicted_session_filter_opts, now);
if (mgr->sess_pool == NULL || mgr->tcp_sess_table == NULL || mgr->udp_sess_table == NULL || mgr->sess_timer == NULL || mgr->dup_pkt_filter == NULL || mgr->evicte_sess_filter == NULL)
if (mgr->sess_pool == NULL || mgr->tcp_sess_table == NULL || mgr->udp_sess_table == NULL || mgr->sess_timer == NULL)
{
goto error;
}
if (mgr->opts.evicted_session_filter_enable)
{
mgr->evicte_sess_filter = evicted_session_filter_new(mgr->opts.evicted_session_filter_capacity, mgr->opts.evicted_session_filter_timeout, mgr->opts.evicted_session_filter_error_rate, now);
if (mgr->evicte_sess_filter == NULL)
{
goto error;
}
}
if (mgr->opts.duplicated_packet_filter_enable)
{
mgr->dup_pkt_filter = duplicated_packet_filter_new(mgr->opts.duplicated_packet_filter_capacity, mgr->opts.duplicated_packet_filter_timeout, mgr->opts.duplicated_packet_filter_error_rate, now);
if (mgr->dup_pkt_filter == NULL)
{
goto error;
}
}
INIT_LIST_HEAD(&mgr->evicte_queue);
session_filter_init();
@@ -766,8 +844,14 @@ void session_manager_free(struct session_manager *mgr)
{
session_manager_free_session(mgr, sess);
}
evicted_session_filter_free(mgr->evicte_sess_filter);
duplicated_packet_filter_free(mgr->dup_pkt_filter);
if (mgr->opts.evicted_session_filter_enable)
{
evicted_session_filter_free(mgr->evicte_sess_filter);
}
if (mgr->opts.duplicated_packet_filter_enable)
{
duplicated_packet_filter_free(mgr->dup_pkt_filter);
}
session_timer_free(mgr->sess_timer);
session_table_free(mgr->udp_sess_table);
session_table_free(mgr->tcp_sess_table);