Update timeout and timestamp

* Timeout using CLOCK_MONOTONIC
    * Session start/last timestamps use CLOCK_REALTIME
    * Session ID generator uses CLOCK_REALTIME
This commit is contained in:
luwenpeng
2024-04-16 18:34:41 +08:00
parent d878849c3a
commit f5f09e5e23
15 changed files with 259 additions and 112 deletions

View File

@@ -1,3 +1,4 @@
#include <time.h>
#include <stdlib.h>
#include <assert.h>
@@ -234,24 +235,47 @@ static inline bool before(uint32_t seq1, uint32_t seq2)
return (int32_t)(seq1 - seq2) < 0;
}
static void tcp_clean(struct session *sess)
static void tcp_clean(struct session_manager *mgr, struct session *sess)
{
tcp_reassembly_free(sess->tcp_halfs[SESSION_DIRECTION_C2S].assembler);
tcp_reassembly_free(sess->tcp_halfs[SESSION_DIRECTION_S2C].assembler);
struct tcp_reassembly *c2s_ssembler = sess->tcp_halfs[SESSION_DIRECTION_C2S].assembler;
struct tcp_reassembly *s2c_ssembler = sess->tcp_halfs[SESSION_DIRECTION_S2C].assembler;
struct tcp_segment *seg;
if (c2s_ssembler)
{
while ((seg = tcp_reassembly_expire(c2s_ssembler, UINT64_MAX)))
{
session_inc_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_SEGS_RELEASED, 1);
session_inc_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_PLDS_RELEASED, seg->len);
mgr->stat.nr_tcp_seg_released++;
tcp_segment_free(seg);
}
tcp_reassembly_free(c2s_ssembler);
}
if (s2c_ssembler)
{
while ((seg = tcp_reassembly_expire(s2c_ssembler, UINT64_MAX)))
{
session_inc_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_SEGS_RELEASED, 1);
session_inc_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_PLDS_RELEASED, seg->len);
mgr->stat.nr_tcp_seg_released++;
tcp_segment_free(seg);
}
tcp_reassembly_free(s2c_ssembler);
}
}
static int tcp_init(struct session *sess, uint8_t tcp_reassembly_enable, uint64_t tcp_reassembly_max_timeout, uint64_t tcp_reassembly_max_segments)
static int tcp_init(struct session_manager *mgr, struct session *sess)
{
if (!tcp_reassembly_enable)
if (!mgr->opts.tcp_reassembly_enable)
{
return 0;
}
sess->tcp_halfs[SESSION_DIRECTION_C2S].assembler = tcp_reassembly_new(tcp_reassembly_max_timeout, tcp_reassembly_max_segments);
sess->tcp_halfs[SESSION_DIRECTION_S2C].assembler = tcp_reassembly_new(tcp_reassembly_max_timeout, tcp_reassembly_max_segments);
sess->tcp_halfs[SESSION_DIRECTION_C2S].assembler = tcp_reassembly_new(mgr->opts.tcp_reassembly_max_timeout, mgr->opts.tcp_reassembly_max_segments);
sess->tcp_halfs[SESSION_DIRECTION_S2C].assembler = tcp_reassembly_new(mgr->opts.tcp_reassembly_max_timeout, mgr->opts.tcp_reassembly_max_segments);
if (sess->tcp_halfs[SESSION_DIRECTION_C2S].assembler == NULL || sess->tcp_halfs[SESSION_DIRECTION_S2C].assembler == NULL)
{
tcp_clean(sess);
tcp_clean(mgr, sess);
return -1;
}
@@ -479,15 +503,18 @@ static int duplicated_packet_bypass(struct session_manager *mgr, struct session
* Session Manager
******************************************************************************/
static void session_update(struct session *sess, enum session_state next_state, const struct packet *pkt, const struct tuple6 *key, enum session_direction dir, uint64_t now)
static void session_update(struct session *sess, enum session_state next_state, const struct packet *pkt, const struct tuple6 *key, enum session_direction dir)
{
struct timespec real;
clock_gettime(CLOCK_REALTIME, &real); // must be realtime
if (session_get_state(sess) == SESSION_STATE_INIT)
{
session_set_id(sess, id_generator_alloc());
session_set_tuple(sess, key);
session_set_tuple_direction(sess, dir);
tuple6_to_str(key, sess->tuple_str, sizeof(sess->tuple_str));
session_set_timestamp(sess, SESSION_TIMESTAMP_START, now);
session_set_timestamp(sess, SESSION_TIMESTAMP_START, real.tv_sec);
switch (key->ip_proto)
{
case IPPROTO_TCP:
@@ -512,7 +539,7 @@ static void session_update(struct session *sess, enum session_state next_state,
session_set_current_packet(sess, pkt);
session_set_current_direction(sess, dir);
session_set_timestamp(sess, SESSION_TIMESTAMP_LAST, now);
session_set_timestamp(sess, SESSION_TIMESTAMP_LAST, real.tv_sec);
session_set_state(sess, next_state);
}
@@ -588,10 +615,10 @@ static struct session *session_manager_new_tcp_session(struct session_manager *m
sess->mgr_stat = &mgr->stat;
enum session_state next_state = session_transition_run(SESSION_STATE_INIT, TCP_SYN);
session_update(sess, next_state, pkt, key, dir, now);
session_update(sess, next_state, pkt, key, dir);
session_transition_log(sess, SESSION_STATE_INIT, next_state, TCP_SYN);
if (tcp_init(sess, mgr->opts.tcp_reassembly_enable, mgr->opts.tcp_reassembly_max_timeout, mgr->opts.tcp_reassembly_max_segments) == -1)
if (tcp_init(mgr, sess) == -1)
{
assert(0);
session_pool_push(mgr->sess_pool, sess);
@@ -634,7 +661,7 @@ static struct session *session_manager_new_udp_session(struct session_manager *m
enum session_direction 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_update(sess, next_state, pkt, key, dir, now);
session_update(sess, next_state, pkt, key, dir);
session_transition_log(sess, SESSION_STATE_INIT, next_state, UDP_DATA);
session_timer_update(mgr->sess_timer, sess, now + mgr->opts.udp_data_timeout);
@@ -663,7 +690,7 @@ static int session_manager_update_tcp_session(struct session_manager *mgr, struc
enum session_state next_state = session_transition_run(curr_state, inputs);
// update session
session_update(sess, next_state, pkt, key, dir, now);
session_update(sess, next_state, pkt, key, dir);
session_transition_log(sess, curr_state, next_state, inputs);
// update tcp
@@ -741,7 +768,7 @@ static int session_manager_update_udp_session(struct session_manager *mgr, struc
enum session_direction 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_update(sess, next_state, pkt, key, dir, now);
session_update(sess, next_state, pkt, key, dir);
session_transition_log(sess, curr_state, next_state, UDP_DATA);
if (session_get_state(sess) == SESSION_STATE_DISCARD)
@@ -894,7 +921,7 @@ void session_manager_free_session(struct session_manager *mgr, struct session *s
switch (session_get_type(sess))
{
case SESSION_TYPE_TCP:
tcp_clean(sess);
tcp_clean(mgr, sess);
session_table_del(mgr->tcp_sess_table, session_get_tuple(sess));
SESS_MGR_STAT_DEC(&mgr->stat, session_get_state(sess), tcp);
mgr->stat.nr_tcp_sess_used--;