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:
@@ -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--;
|
||||
|
||||
Reference in New Issue
Block a user