Refactor the session manager using session transformation 2D array & Update test case

This commit is contained in:
luwenpeng
2024-03-14 10:56:09 +08:00
parent 639614622b
commit ce00122557
47 changed files with 3403 additions and 3563 deletions

View File

@@ -4,47 +4,47 @@ device_offset = 2 # [0, 127]
[packet_io] [packet_io]
mode = dumpfile # dumpfile, marsio mode = dumpfile # dumpfile, marsio
dumpfile_dir = "/tmp/dumpfile/"
app_symbol = stellar app_symbol = stellar
dev_symbol = nf_0_fw dev_symbol = nf_0_fw
dumpfile_dir = "/tmp/dumpfile/"
nr_threads = 1 # [1, 256] nr_threads = 1 # [1, 256]
cpu_mask = [5, 6, 7, 8, 9, 10, 11, 12] cpu_mask = [5, 6, 7, 8, 9, 10, 11, 12]
[ip_reassembly] [ip_reassembly]
enable = 1 enable = 1
timeout = 10 # seconds timeout = 10000 # ms
bucket_entries = 8 bucket_entries = 8
bucket_num = 4096 bucket_num = 4096
[session_manager] [session_manager]
# max session number # max session number
max_tcp_session_num = 100 max_tcp_session_num = 40960
max_udp_session_num = 100 max_udp_session_num = 40960
# session overload evict # session overload evict
tcp_overload_evict_old_sess = 1 # 1: evict old session, 0: bypass new session 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 udp_overload_evict_old_sess = 1 # 1: evict old session, 0: bypass new session
# TCP timeout # TCP timeout
tcp_timeout_init = 5 # seconds, Range: 1-60 tcp_timeout_init = 5000 # ms, Range: 1-60,000
tcp_timeout_handshake = 10 # seconds, Range: 1-60 tcp_timeout_handshake = 10000 # ms, Range: 1-60,000
tcp_timeout_data = 3600 # seconds, Range: 1-15,999,999 tcp_timeout_data = 3600000 # ms, Range: 1-15,999,999,000
tcp_timeout_half_closed = 120 # seconds, Range: 1-604,800 tcp_timeout_half_closed = 120000 # ms, Range: 1-604,800,000
tcp_timeout_time_wait = 15 # seconds, Range: 1-600 tcp_timeout_time_wait = 15000 # ms, Range: 1-600,000
tcp_timeout_discard = 90 # seconds, Range: 1-15,999,999 tcp_timeout_discard = 90000 # ms, Range: 1-15,999,999,000
# UDP timeout # UDP timeout
udp_timeout_data = 10 # seconds, Range: 1-15,999,999 udp_timeout_data = 10000 # ms, Range: 1-15,999,999,000
# duplicate packet filter # duplicate packet filter
duplicated_packet_filter_enable = 1 duplicated_packet_filter_enable = 1
duplicated_packet_filter_capacity = 1000000 duplicated_packet_filter_capacity = 1000000
duplicated_packet_filter_timeout = 10 # seconds, Range: 1-60 duplicated_packet_filter_timeout = 10000 # ms, Range: 1-60,000
duplicated_packet_filter_error_rate = 0.00001 duplicated_packet_filter_error_rate = 0.00001
# evicted session filter # evicted session filter
evicted_session_filter_enable = 1 evicted_session_filter_enable = 1
evicted_session_filter_capacity = 1000000 evicted_session_filter_capacity = 1000000
evicted_session_filter_timeout = 10 # seconds, Range: 1-60 evicted_session_filter_timeout = 10000 # ms, Range: 1-60,000
evicted_session_filter_error_rate = 0.00001 evicted_session_filter_error_rate = 0.00001

View File

@@ -41,25 +41,16 @@ struct packet_idetify idetify = {
TEST(DABLOOMS, TEST) TEST(DABLOOMS, TEST)
{ {
struct expiry_dablooms_handle *handle = expiry_dablooms_new(config.capacity, config.error_rate, time(NULL), config.expiry_time); struct expiry_dablooms_handle *handle = expiry_dablooms_new(config.capacity, config.error_rate, 1, config.expiry_time);
EXPECT_TRUE(handle != nullptr); EXPECT_TRUE(handle != nullptr);
EXPECT_TRUE(expiry_dablooms_search(handle, (const char *)&idetify, sizeof(idetify), time(NULL)) != 1); // no exist EXPECT_TRUE(expiry_dablooms_search(handle, (const char *)&idetify, sizeof(idetify), 1) != 1); // no exist
EXPECT_TRUE(expiry_dablooms_add(handle, (const char *)&idetify, sizeof(idetify), time(NULL)) == 0); // add EXPECT_TRUE(expiry_dablooms_add(handle, (const char *)&idetify, sizeof(idetify), 1) == 0); // add
EXPECT_TRUE(expiry_dablooms_search(handle, (const char *)&idetify, sizeof(idetify), 1) == 1); // exist
for (int i = 0; i < 5; i++) EXPECT_TRUE(expiry_dablooms_search(handle, (const char *)&idetify, sizeof(idetify), 2) == 1); // exist
{ EXPECT_TRUE(expiry_dablooms_search(handle, (const char *)&idetify, sizeof(idetify), 3) == 1); // exist
if (i < config.expiry_time) EXPECT_TRUE(expiry_dablooms_search(handle, (const char *)&idetify, sizeof(idetify), 4) == 0); // not exist
{ EXPECT_TRUE(expiry_dablooms_search(handle, (const char *)&idetify, sizeof(idetify), 5) == 0); // not exist
EXPECT_TRUE(expiry_dablooms_search(handle, (const char *)&idetify, sizeof(idetify), time(NULL)) == 1); // exist
}
else
{
EXPECT_TRUE(expiry_dablooms_search(handle, (const char *)&idetify, sizeof(idetify), time(NULL)) != 1); // no exist
}
sleep(1);
printf("sleep[%02d] 1s\n", i);
}
expiry_dablooms_free(handle); expiry_dablooms_free(handle);
} }

View File

@@ -306,7 +306,7 @@ static int parse_session_manager_options(toml_table_t *table, struct session_man
CONFIG_LOG_ERROR("config file missing session_manager.duplicated_packet_filter_capacity"); CONFIG_LOG_ERROR("config file missing session_manager.duplicated_packet_filter_capacity");
return -1; return -1;
} }
opts->duplicated_packet_filter_capacity = atoll(ptr); opts->duplicated_packet_filter_capacity = atoi(ptr);
ptr = toml_raw_in(session_manager, "duplicated_packet_filter_timeout"); ptr = toml_raw_in(session_manager, "duplicated_packet_filter_timeout");
if (ptr == NULL) if (ptr == NULL)
@@ -314,7 +314,7 @@ static int parse_session_manager_options(toml_table_t *table, struct session_man
CONFIG_LOG_ERROR("config file missing session_manager.duplicated_packet_filter_timeout"); CONFIG_LOG_ERROR("config file missing session_manager.duplicated_packet_filter_timeout");
return -1; return -1;
} }
opts->duplicated_packet_filter_timeout = atoll(ptr); opts->duplicated_packet_filter_timeout = atoi(ptr);
ptr = toml_raw_in(session_manager, "duplicated_packet_filter_error_rate"); ptr = toml_raw_in(session_manager, "duplicated_packet_filter_error_rate");
if (ptr == NULL) if (ptr == NULL)

View File

@@ -66,7 +66,7 @@ static inline int duplicated_packet_key_get(const struct packet *packet, struct
* Public API * Public API
******************************************************************************/ ******************************************************************************/
struct duplicated_packet_filter *duplicated_packet_filter_new(const struct duplicated_packet_filter_options *opts, uint64_t now_sec) struct duplicated_packet_filter *duplicated_packet_filter_new(const struct duplicated_packet_filter_options *opts, uint64_t now)
{ {
struct duplicated_packet_filter *filter = (struct duplicated_packet_filter *)calloc(1, sizeof(struct duplicated_packet_filter)); struct duplicated_packet_filter *filter = (struct duplicated_packet_filter *)calloc(1, sizeof(struct duplicated_packet_filter));
if (filter == NULL) if (filter == NULL)
@@ -80,7 +80,7 @@ struct duplicated_packet_filter *duplicated_packet_filter_new(const struct dupli
return filter; return filter;
} }
filter->dablooms = expiry_dablooms_new(filter->opts.capacity, filter->opts.error_rate, now_sec, filter->opts.timeout_sec); filter->dablooms = expiry_dablooms_new(filter->opts.capacity, filter->opts.error_rate, now, filter->opts.timeout_sec);
if (filter->dablooms == NULL) if (filter->dablooms == NULL)
{ {
free(filter); free(filter);
@@ -106,7 +106,7 @@ void duplicated_packet_filter_free(struct duplicated_packet_filter *filter)
// return 1: found // return 1: found
// reutrn 0: no found // reutrn 0: no found
int duplicated_packet_filter_lookup(struct duplicated_packet_filter *filter, const struct packet *packet, uint64_t now_sec) int duplicated_packet_filter_lookup(struct duplicated_packet_filter *filter, const struct packet *packet, uint64_t now)
{ {
if (filter->opts.enable == 0) if (filter->opts.enable == 0)
{ {
@@ -119,7 +119,7 @@ int duplicated_packet_filter_lookup(struct duplicated_packet_filter *filter, con
return 0; return 0;
} }
if (expiry_dablooms_search(filter->dablooms, (const char *)&key, sizeof(struct duplicated_packet_key), now_sec) == 1) if (expiry_dablooms_search(filter->dablooms, (const char *)&key, sizeof(struct duplicated_packet_key), now) == 1)
{ {
return 1; return 1;
} }
@@ -127,7 +127,7 @@ int duplicated_packet_filter_lookup(struct duplicated_packet_filter *filter, con
return 0; return 0;
} }
void duplicated_packet_filter_add(struct duplicated_packet_filter *filter, const struct packet *packet, uint64_t now_sec) void duplicated_packet_filter_add(struct duplicated_packet_filter *filter, const struct packet *packet, uint64_t now)
{ {
if (filter->opts.enable == 0) if (filter->opts.enable == 0)
{ {
@@ -140,5 +140,5 @@ void duplicated_packet_filter_add(struct duplicated_packet_filter *filter, const
return; return;
} }
expiry_dablooms_add(filter->dablooms, (const char *)&key, sizeof(struct duplicated_packet_key), now_sec); expiry_dablooms_add(filter->dablooms, (const char *)&key, sizeof(struct duplicated_packet_key), now);
} }

View File

@@ -20,13 +20,13 @@ struct duplicated_packet_filter_options
struct duplicated_packet_filter; struct duplicated_packet_filter;
struct duplicated_packet_filter *duplicated_packet_filter_new(const struct duplicated_packet_filter_options *opts, uint64_t now_sec); struct duplicated_packet_filter *duplicated_packet_filter_new(const struct duplicated_packet_filter_options *opts, uint64_t now);
void duplicated_packet_filter_free(struct duplicated_packet_filter *filter); void duplicated_packet_filter_free(struct duplicated_packet_filter *filter);
// return 1: found // return 1: found
// reutrn 0: no found // reutrn 0: no found
int duplicated_packet_filter_lookup(struct duplicated_packet_filter *filter, const struct packet *pkt, uint64_t now_sec); int duplicated_packet_filter_lookup(struct duplicated_packet_filter *filter, const struct packet *pkt, uint64_t now);
void duplicated_packet_filter_add(struct duplicated_packet_filter *filter, const struct packet *pkt, uint64_t now_sec); void duplicated_packet_filter_add(struct duplicated_packet_filter *filter, const struct packet *pkt, uint64_t now);
#ifdef __cpluscplus #ifdef __cpluscplus
} }

View File

@@ -16,7 +16,7 @@ struct evicted_session_filter
* Public API * Public API
******************************************************************************/ ******************************************************************************/
struct evicted_session_filter *evicted_session_filter_new(const struct evicted_session_filter_options *opts, uint64_t now_sec) struct evicted_session_filter *evicted_session_filter_new(const struct evicted_session_filter_options *opts, uint64_t now)
{ {
struct evicted_session_filter *filter = (struct evicted_session_filter *)calloc(1, sizeof(struct evicted_session_filter)); struct evicted_session_filter *filter = (struct evicted_session_filter *)calloc(1, sizeof(struct evicted_session_filter));
if (filter == NULL) if (filter == NULL)
@@ -30,7 +30,7 @@ struct evicted_session_filter *evicted_session_filter_new(const struct evicted_s
return filter; return filter;
} }
filter->dablooms = expiry_dablooms_new(filter->opts.capacity, filter->opts.error_rate, now_sec, filter->opts.timeout_sec); filter->dablooms = expiry_dablooms_new(filter->opts.capacity, filter->opts.error_rate, now, filter->opts.timeout_sec);
if (filter->dablooms == NULL) if (filter->dablooms == NULL)
{ {
free(filter); free(filter);
@@ -56,14 +56,14 @@ void evicted_session_filter_free(struct evicted_session_filter *filter)
// return 1: found // return 1: found
// reutrn 0: no found // reutrn 0: no found
int evicted_session_filter_lookup(struct evicted_session_filter *filter, const struct tuple6 *key, uint64_t now_sec) int evicted_session_filter_lookup(struct evicted_session_filter *filter, const struct tuple6 *key, uint64_t now)
{ {
if (filter->opts.enable == 0) if (filter->opts.enable == 0)
{ {
return 0; return 0;
} }
if (expiry_dablooms_search(filter->dablooms, (const char *)key, sizeof(struct tuple6), now_sec) == 1) if (expiry_dablooms_search(filter->dablooms, (const char *)key, sizeof(struct tuple6), now) == 1)
{ {
return 1; return 1;
} }
@@ -71,7 +71,7 @@ int evicted_session_filter_lookup(struct evicted_session_filter *filter, const s
return 0; return 0;
} }
void evicted_session_filter_add(struct evicted_session_filter *filter, const struct tuple6 *key, uint64_t now_sec) void evicted_session_filter_add(struct evicted_session_filter *filter, const struct tuple6 *key, uint64_t now)
{ {
if (filter->opts.enable == 0) if (filter->opts.enable == 0)
{ {
@@ -81,6 +81,6 @@ void evicted_session_filter_add(struct evicted_session_filter *filter, const str
struct tuple6 reverse_key; struct tuple6 reverse_key;
tuple6_reverse(key, &reverse_key); tuple6_reverse(key, &reverse_key);
expiry_dablooms_add(filter->dablooms, (const char *)key, sizeof(struct tuple6), now_sec); expiry_dablooms_add(filter->dablooms, (const char *)key, sizeof(struct tuple6), now);
expiry_dablooms_add(filter->dablooms, (const char *)&reverse_key, sizeof(struct tuple6), now_sec); expiry_dablooms_add(filter->dablooms, (const char *)&reverse_key, sizeof(struct tuple6), now);
} }

View File

@@ -16,13 +16,13 @@ struct evicted_session_filter_options
double error_rate; double error_rate;
}; };
struct evicted_session_filter *evicted_session_filter_new(const struct evicted_session_filter_options *opts, uint64_t now_sec); struct evicted_session_filter *evicted_session_filter_new(const struct evicted_session_filter_options *opts, uint64_t now);
void evicted_session_filter_free(struct evicted_session_filter *filter); void evicted_session_filter_free(struct evicted_session_filter *filter);
// return 1: found // return 1: found
// reutrn 0: no found // reutrn 0: no found
int evicted_session_filter_lookup(struct evicted_session_filter *filter, const struct tuple6 *key, uint64_t now_sec); int evicted_session_filter_lookup(struct evicted_session_filter *filter, const struct tuple6 *key, uint64_t now);
void evicted_session_filter_add(struct evicted_session_filter *filter, const struct tuple6 *key, uint64_t now_sec); void evicted_session_filter_add(struct evicted_session_filter *filter, const struct tuple6 *key, uint64_t now);
#ifdef __cpluscplus #ifdef __cpluscplus
} }

View File

@@ -1,3 +1,4 @@
#include <time.h>
#include <string.h> #include <string.h>
#include "id_generator.h" #include "id_generator.h"
@@ -55,14 +56,18 @@ int id_generator_init(uint8_t device_base, uint8_t device_offset)
* | 1bit | 12bit device_id | 8bit thread_id | 28bit timestamp in sec | 15bit sequence per thread | * | 1bit | 12bit device_id | 8bit thread_id | 28bit timestamp in sec | 15bit sequence per thread |
* +------+------------------+----------------+------------------------+---------------------------+ * +------+------------------+----------------+------------------------+---------------------------+
*/ */
uint64_t id_generator_alloc(uint64_t now_sec, uint64_t thread_index) uint64_t id_generator_alloc()
{ {
#define MAX_ID_PER_THREAD (32768) #define MAX_ID_PER_THREAD (32768)
#define MAX_ID_BASE_TIME (268435456L) #define MAX_ID_BASE_TIME (268435456L)
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts); // must be realtime
uint64_t thread_index = stellar_get_current_thread_index();
uint64_t global_id = 0; uint64_t global_id = 0;
uint64_t id_per_thread = (global_id_generator.thread_volatile[thread_index]++) % MAX_ID_PER_THREAD; uint64_t id_per_thread = (global_id_generator.thread_volatile[thread_index]++) % MAX_ID_PER_THREAD;
uint64_t id_base_time = now_sec % MAX_ID_BASE_TIME; uint64_t id_base_time = ts.tv_sec % MAX_ID_BASE_TIME;
global_id = (global_id_generator.device_id << 51) | global_id = (global_id_generator.device_id << 51) |
(thread_index << 43) | (thread_index << 43) |
(id_base_time << 15) | (id_base_time << 15) |

View File

@@ -22,7 +22,7 @@ extern "C"
* return -1: failed * return -1: failed
*/ */
int id_generator_init(uint8_t device_base, uint8_t device_offset); int id_generator_init(uint8_t device_base, uint8_t device_offset);
uint64_t id_generator_alloc(uint64_t now_sec, uint64_t thread_index); uint64_t id_generator_alloc();
#ifdef __cpluscplus #ifdef __cpluscplus
} }

View File

@@ -365,7 +365,7 @@ static inline void ip_frag_pkt_free(struct ip_frag_pkt *frag)
* ip flow * ip flow
******************************************************************************/ ******************************************************************************/
static inline void ip_flow_init(struct ip_flow *flow, const struct ip_flow_key *key, uint64_t now_sec) static inline void ip_flow_init(struct ip_flow *flow, const struct ip_flow_key *key, uint64_t now)
{ {
static const struct ip_frag_pkt zero_frag = { static const struct ip_frag_pkt zero_frag = {
.data = NULL, .data = NULL,
@@ -376,7 +376,7 @@ static inline void ip_flow_init(struct ip_flow *flow, const struct ip_flow_key *
flow->lru.tqe_next = NULL; flow->lru.tqe_next = NULL;
flow->lru.tqe_prev = NULL; flow->lru.tqe_prev = NULL;
flow->key = *key; flow->key = *key;
flow->create_time = now_sec; flow->create_time = now;
flow->expected_total_size = UINT32_MAX; flow->expected_total_size = UINT32_MAX;
flow->received_frag_size = 0; flow->received_frag_size = 0;
flow->next_fill_idx = IP_MIN_FRAG_NUM; flow->next_fill_idx = IP_MIN_FRAG_NUM;
@@ -478,11 +478,11 @@ static inline void ip_reassembly_del_flow(struct ip_reassembly *mgr, struct ip_f
mgr->entry_used--; mgr->entry_used--;
} }
static inline void ip_reassembly_reuse_flow(struct ip_reassembly *mgr, struct ip_flow *flow, const struct ip_flow_key *key, uint64_t now_sec) static inline void ip_reassembly_reuse_flow(struct ip_reassembly *mgr, struct ip_flow *flow, const struct ip_flow_key *key, uint64_t now)
{ {
ip_reassembly_del_flow(mgr, flow); ip_reassembly_del_flow(mgr, flow);
ip_flow_free(flow); ip_flow_free(flow);
ip_flow_init(flow, key, now_sec); ip_flow_init(flow, key, now);
ip_reassembly_add_flow(mgr, flow); ip_reassembly_add_flow(mgr, flow);
} }
@@ -491,7 +491,7 @@ static inline void ip_reassembly_reuse_flow(struct ip_reassembly *mgr, struct ip
* free : the first empty entry in the bucket * free : the first empty entry in the bucket
* expired: the first timed-out entry in the bucket * expired: the first timed-out entry in the bucket
*/ */
static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const struct ip_flow_key *key, struct ip_flow **free, struct ip_flow **expired, uint64_t now_sec) static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const struct ip_flow_key *key, struct ip_flow **free, struct ip_flow **expired, uint64_t now)
{ {
ip_reassembly_stat_inc(mgr, find, key); ip_reassembly_stat_inc(mgr, find, key);
@@ -532,7 +532,7 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
{ {
empty = (empty == NULL) ? (p1 + i) : empty; empty = (empty == NULL) ? (p1 + i) : empty;
} }
else if (timeout + p1[i].create_time <= now_sec) else if (timeout + p1[i].create_time <= now)
{ {
old = (old == NULL) ? (p1 + i) : old; old = (old == NULL) ? (p1 + i) : old;
} }
@@ -547,7 +547,7 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
{ {
empty = (empty == NULL) ? (p2 + i) : empty; empty = (empty == NULL) ? (p2 + i) : empty;
} }
else if (timeout + p2[i].create_time <= now_sec) else if (timeout + p2[i].create_time <= now)
{ {
old = (old == NULL) ? (p2 + i) : old; old = (old == NULL) ? (p2 + i) : old;
} }
@@ -558,19 +558,19 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
return NULL; return NULL;
} }
static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, const struct ip_flow_key *key, uint64_t now_sec) static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, const struct ip_flow_key *key, uint64_t now)
{ {
struct ip_flow *flow = NULL; struct ip_flow *flow = NULL;
struct ip_flow *free = NULL; struct ip_flow *free = NULL;
struct ip_flow *expired = NULL; struct ip_flow *expired = NULL;
flow = ip_reassembly_find_flow(mgr, key, &free, &expired, now_sec); flow = ip_reassembly_find_flow(mgr, key, &free, &expired, now);
if (flow == NULL) if (flow == NULL)
{ {
if (expired) if (expired)
{ {
IP_REASSEMBLE_DEBUG1("add ip flow success: reuse expired entry", key); IP_REASSEMBLE_DEBUG1("add ip flow success: reuse expired entry", key);
ip_reassembly_reuse_flow(mgr, expired, key, now_sec); ip_reassembly_reuse_flow(mgr, expired, key, now);
ip_reassembly_stat_inc(mgr, timeout, key); ip_reassembly_stat_inc(mgr, timeout, key);
mgr->last = expired; mgr->last = expired;
@@ -580,7 +580,7 @@ static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, cons
if (free) if (free)
{ {
IP_REASSEMBLE_DEBUG1("add ip flow success: use free entry", key); IP_REASSEMBLE_DEBUG1("add ip flow success: use free entry", key);
ip_flow_init(free, key, now_sec); ip_flow_init(free, key, now);
ip_reassembly_add_flow(mgr, free); ip_reassembly_add_flow(mgr, free);
mgr->last = free; mgr->last = free;
@@ -595,10 +595,10 @@ static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, cons
else else
{ {
// expired // expired
if (mgr->timeout + flow->create_time <= now_sec) if (mgr->timeout + flow->create_time <= now)
{ {
IP_REASSEMBLE_DEBUG1("add ip flow success: reuse expired entry", key); IP_REASSEMBLE_DEBUG1("add ip flow success: reuse expired entry", key);
ip_reassembly_reuse_flow(mgr, flow, key, now_sec); ip_reassembly_reuse_flow(mgr, flow, key, now);
ip_reassembly_stat_inc(mgr, timeout, key); ip_reassembly_stat_inc(mgr, timeout, key);
mgr->last = flow; mgr->last = flow;
@@ -814,13 +814,13 @@ void ip_reassembly_free(struct ip_reassembly *mgr)
} }
} }
void ip_reassembly_expire(struct ip_reassembly *mgr, uint64_t now_sec) void ip_reassembly_expire(struct ip_reassembly *mgr, uint64_t now)
{ {
struct ip_flow *flow = NULL; struct ip_flow *flow = NULL;
uint64_t timeout = mgr->timeout; uint64_t timeout = mgr->timeout;
TAILQ_FOREACH(flow, &mgr->lru, lru) TAILQ_FOREACH(flow, &mgr->lru, lru)
if (timeout + flow->create_time <= now_sec) if (timeout + flow->create_time <= now)
{ {
IP_REASSEMBLE_DEBUG1("expire ip flow: discarding old fragmented packets", &flow->key); IP_REASSEMBLE_DEBUG1("expire ip flow: discarding old fragmented packets", &flow->key);
ip_reassembly_del_flow(mgr, flow); ip_reassembly_del_flow(mgr, flow);
@@ -846,7 +846,7 @@ struct ip_reassembly_stat *ip_reassembly_get_stat(struct ip_reassembly *mgr)
* The returned packet should be freed by calling the packet_free() function * The returned packet should be freed by calling the packet_free() function
*/ */
struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec) struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now)
{ {
struct packet *pkt1; struct packet *pkt1;
struct packet *pkt2; struct packet *pkt2;
@@ -864,10 +864,10 @@ struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct pack
if (layer->type == LAYER_TYPE_IPV4) if (layer->type == LAYER_TYPE_IPV4)
{ {
pkt1 = ipv4_reassembly_packet(mgr, pkt, now_sec); pkt1 = ipv4_reassembly_packet(mgr, pkt, now);
if (pkt1 && pkt1->frag_layer) if (pkt1 && pkt1->frag_layer)
{ {
pkt2 = ip_reassembly_packet(mgr, pkt1, now_sec); pkt2 = ip_reassembly_packet(mgr, pkt1, now);
packet_free(pkt1); packet_free(pkt1);
return pkt2; return pkt2;
} }
@@ -876,10 +876,10 @@ struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct pack
} }
else if (layer->type == LAYER_TYPE_IPV6) else if (layer->type == LAYER_TYPE_IPV6)
{ {
pkt1 = ipv6_reassembly_packet(mgr, pkt, now_sec); pkt1 = ipv6_reassembly_packet(mgr, pkt, now);
if (pkt1 && pkt1->frag_layer) if (pkt1 && pkt1->frag_layer)
{ {
pkt2 = ip_reassembly_packet(mgr, pkt1, now_sec); pkt2 = ip_reassembly_packet(mgr, pkt1, now);
packet_free(pkt1); packet_free(pkt1);
return pkt2; return pkt2;
} }
@@ -892,7 +892,7 @@ struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct pack
} }
} }
struct packet *ipv4_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec) struct packet *ipv4_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now)
{ {
const struct layer *layer = pkt->frag_layer; const struct layer *layer = pkt->frag_layer;
const struct ip *hdr = (const struct ip *)layer->hdr_ptr; const struct ip *hdr = (const struct ip *)layer->hdr_ptr;
@@ -911,7 +911,7 @@ struct packet *ipv4_reassembly_packet(struct ip_reassembly *mgr, const struct pa
key.ip_id = ipv4_hdr_get_ipid(hdr); key.ip_id = ipv4_hdr_get_ipid(hdr);
key.proto = ipv4_hdr_get_proto(hdr); key.proto = ipv4_hdr_get_proto(hdr);
struct ip_flow *flow = ip_reassembly_update_flow(mgr, &key, now_sec); struct ip_flow *flow = ip_reassembly_update_flow(mgr, &key, now);
if (flow == NULL) if (flow == NULL)
{ {
return NULL; return NULL;
@@ -978,7 +978,7 @@ struct packet *ipv4_reassembly_packet(struct ip_reassembly *mgr, const struct pa
* +-----------------+-----------------+--------+--------+-//-+--------+ * +-----------------+-----------------+--------+--------+-//-+--------+
*/ */
struct packet *ipv6_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec) struct packet *ipv6_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now)
{ {
const struct layer *layer = pkt->frag_layer; const struct layer *layer = pkt->frag_layer;
const struct ip6_hdr *hdr = (const struct ip6_hdr *)layer->hdr_ptr; const struct ip6_hdr *hdr = (const struct ip6_hdr *)layer->hdr_ptr;
@@ -1003,7 +1003,7 @@ struct packet *ipv6_reassembly_packet(struct ip_reassembly *mgr, const struct pa
key.ip_id = ipv6_frag_get_ident(frag_hdr); key.ip_id = ipv6_frag_get_ident(frag_hdr);
key.proto = 0; // only first fragment has the upper layer protocol key.proto = 0; // only first fragment has the upper layer protocol
struct ip_flow *flow = ip_reassembly_update_flow(mgr, &key, now_sec); struct ip_flow *flow = ip_reassembly_update_flow(mgr, &key, now);
if (flow == NULL) if (flow == NULL)
{ {
return NULL; return NULL;

View File

@@ -16,7 +16,7 @@ struct ip_reassembly_options
{ {
bool enable; bool enable;
uint32_t timeout; // seconds uint32_t timeout;
uint32_t bucket_entries; uint32_t bucket_entries;
uint32_t bucket_num; uint32_t bucket_num;
}; };
@@ -52,16 +52,16 @@ struct ip_reassembly_stat
struct ip_reassembly *ip_reassembly_new(const struct ip_reassembly_options *opts); struct ip_reassembly *ip_reassembly_new(const struct ip_reassembly_options *opts);
void ip_reassembly_free(struct ip_reassembly *mgr); void ip_reassembly_free(struct ip_reassembly *mgr);
void ip_reassembly_expire(struct ip_reassembly *mgr, uint64_t now_sec); void ip_reassembly_expire(struct ip_reassembly *mgr, uint64_t now);
struct ip_reassembly_stat *ip_reassembly_get_stat(struct ip_reassembly *mgr); struct ip_reassembly_stat *ip_reassembly_get_stat(struct ip_reassembly *mgr);
/* /*
* Returns the reassembled packet, or NULL if the packet is not reassembled * Returns the reassembled packet, or NULL if the packet is not reassembled
* The returned packet should be freed by calling the packet_free() function * The returned packet should be freed by calling the packet_free() function
*/ */
struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec); struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now);
struct packet *ipv4_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec); struct packet *ipv4_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now);
struct packet *ipv6_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec); struct packet *ipv6_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now);
#ifdef __cpluscplus #ifdef __cpluscplus
} }

View File

@@ -246,8 +246,7 @@ void packet_io_dumpfile_inject(struct packet_io_dumpfile *handle, uint16_t threa
ATOMIC_ADD(&handle->stat.inject_pkts, 1); ATOMIC_ADD(&handle->stat.inject_pkts, 1);
ATOMIC_ADD(&handle->stat.inject_bytes, packet_get_len(pkt)); ATOMIC_ADD(&handle->stat.inject_bytes, packet_get_len(pkt));
struct pcap_pkt *pcap_pkt = (struct pcap_pkt *)packet_get_user_data(pkt); assert(packet_get_user_data(pkt) == NULL);
assert(pcap_pkt == NULL);
packet_free(pkt); packet_free(pkt);
} }

View File

@@ -5,8 +5,10 @@ add_library(session_manager
session_timer.cpp session_timer.cpp
session_queue.cpp session_queue.cpp
session_manager.cpp session_manager.cpp
session_transition.cpp
) )
target_include_directories(session_manager PUBLIC ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(session_manager PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(session_manager timeout duplicated_packet_filter evicted_session_filter log id_generator timestamp) 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)
add_subdirectory(test) add_subdirectory(test)

View File

@@ -158,28 +158,6 @@ uint64_t session_get_last_time(const struct session *sess)
return sess->last_time; return sess->last_time;
} }
// session tcp state
void session_set_tcp_state(struct session *sess, enum tcp_state state)
{
sess->tcp_state = state;
}
enum tcp_state session_get_tcp_state(const struct session *sess)
{
return sess->tcp_state;
}
// session udp state
void session_set_udp_state(struct session *sess, enum udp_state state)
{
sess->udp_state = state;
}
enum udp_state session_get_udp_state(const struct session *sess)
{
return sess->udp_state;
}
// session user data // session user data
void session_set_user_data(struct session *sess, void *user_data) void session_set_user_data(struct session *sess, void *user_data)
{ {
@@ -197,11 +175,19 @@ void *session_get_user_data(const struct session *sess)
void session_set_c2s_1st_pkt(struct session *sess, const struct packet *pkt) void session_set_c2s_1st_pkt(struct session *sess, const struct packet *pkt)
{ {
if (sess->c2s_1st_pkt)
{
return;
}
sess->c2s_1st_pkt = packet_dup(pkt); sess->c2s_1st_pkt = packet_dup(pkt);
} }
void session_set_s2c_1st_pkt(struct session *sess, const struct packet *pkt) void session_set_s2c_1st_pkt(struct session *sess, const struct packet *pkt)
{ {
if (sess->s2c_1st_pkt)
{
return;
}
sess->s2c_1st_pkt = packet_dup(pkt); sess->s2c_1st_pkt = packet_dup(pkt);
} }
@@ -341,7 +327,7 @@ void session_free_ex_data(struct session *sess, uint8_t idx)
sess->ex_data[idx] = NULL; sess->ex_data[idx] = NULL;
} }
void session_free(struct session *sess) void session_clean(struct session *sess)
{ {
if (sess) if (sess)
{ {
@@ -402,100 +388,22 @@ void session_run_expirecb(struct session *sess)
* session dump * session dump
******************************************************************************/ ******************************************************************************/
static void tcp_state_to_str(enum tcp_state state, char *buffer, size_t buffer_len)
{
if (state == 0)
{
return;
}
int nused = 0;
if (state & TCP_SYN_RECVED)
{
nused += snprintf(buffer + nused, buffer_len - nused, "TCP_SYN_RECVED ");
}
if (state & TCP_SYNACK_RECVED)
{
nused += snprintf(buffer + nused, buffer_len - nused, "TCP_SYNACK_RECVED ");
}
if (state & TCP_C2S_ACK_RECVED)
{
nused += snprintf(buffer + nused, buffer_len - nused, "TCP_C2S_ACK_RECVED ");
}
if (state & TCP_S2C_ACK_RECVED)
{
nused += snprintf(buffer + nused, buffer_len - nused, "TCP_S2C_ACK_RECVED ");
}
if (state & TCP_C2S_DATA_RECVED)
{
nused += snprintf(buffer + nused, buffer_len - nused, "TCP_C2S_DATA_RECVED ");
}
if (state & TCP_S2C_DATA_RECVED)
{
nused += snprintf(buffer + nused, buffer_len - nused, "TCP_S2C_DATA_RECVED ");
}
if (state & TCP_C2S_FIN_RECVED)
{
nused += snprintf(buffer + nused, buffer_len - nused, "TCP_C2S_FIN_RECVED ");
}
if (state & TCP_S2C_FIN_RECVED)
{
nused += snprintf(buffer + nused, buffer_len - nused, "TCP_S2C_FIN_RECVED ");
}
if (state & TCP_C2S_RST_RECVED)
{
nused += snprintf(buffer + nused, buffer_len - nused, "TCP_C2S_RST_RECVED ");
}
if (state & TCP_S2C_RST_RECVED)
{
nused += snprintf(buffer + nused, buffer_len - nused, "TCP_S2C_RST_RECVED ");
}
}
static void udp_state_to_str(enum udp_state state, char *buffer, size_t buffer_len)
{
if (state == 0)
{
return;
}
int nused = 0;
if (state & UDP_C2S_RECVED)
{
snprintf(buffer + nused, buffer_len - nused, "UDP_C2S_RECVED ");
}
if (state & UDP_S2C_RECVED)
{
snprintf(buffer + nused, buffer_len - nused, "UDP_S2C_RECVED ");
}
}
const char *session_closing_reason_to_str(enum closing_reason reason) const char *session_closing_reason_to_str(enum closing_reason reason)
{ {
switch (reason) switch (reason)
{ {
case CLOSING_BY_TIMEOUT: case CLOSING_BY_TIMEOUT:
return "CLOSING BY TIMEOUT"; return "closing by timeout";
case CLOSING_BY_EVICTED: case CLOSING_BY_EVICTED:
return "CLOSING BY EVICTED"; return "closing by evicted";
case CLOSING_BY_CLIENT_FIN: case CLOSING_BY_CLIENT_FIN:
return "CLOSING BY CLIENT FIN"; return "closing by client FIN";
case CLOSING_BY_CLIENT_RST: case CLOSING_BY_CLIENT_RST:
return "CLOSING BY CLIENT RST"; return "closing by client RST";
case CLOSING_BY_SERVER_FIN: case CLOSING_BY_SERVER_FIN:
return "CLOSING BY SERVER FIN"; return "closing by server FIN";
case CLOSING_BY_SERVER_RST: case CLOSING_BY_SERVER_RST:
return "CLOSING BY SERVER RST"; return "closing by server RST";
default: default:
return "unknown"; return "unknown";
} }
@@ -571,24 +479,12 @@ void session_dump(struct session *sess)
printf("session type : %s\n", session_type_to_str(session_get_type(sess))); printf("session type : %s\n", session_type_to_str(session_get_type(sess)));
printf("session dup traffic flag : %s\n", dup_traffic_flag_to_str(session_get_dup_traffic_flag(sess))); printf("session dup traffic flag : %s\n", dup_traffic_flag_to_str(session_get_dup_traffic_flag(sess)));
printf("session closing reason : %s\n", session_closing_reason_to_str(session_get_closing_reason(sess))); printf("session closing reason : %s\n", session_closing_reason_to_str(session_get_closing_reason(sess)));
printf("session c2s packets : %" PRIu64 "\n", session_get_c2s_packets(sess)); printf("session C2S packets : %" PRIu64 "\n", session_get_c2s_packets(sess));
printf("session c2s bytes : %" PRIu64 "\n", session_get_c2s_bytes(sess)); printf("session C2S bytes : %" PRIu64 "\n", session_get_c2s_bytes(sess));
printf("session s2c packets : %" PRIu64 "\n", session_get_s2c_packets(sess)); printf("session S2C packets : %" PRIu64 "\n", session_get_s2c_packets(sess));
printf("session s2c bytes : %" PRIu64 "\n", session_get_s2c_bytes(sess)); printf("session S2C bytes : %" PRIu64 "\n", session_get_s2c_bytes(sess));
printf("session create time : %" PRIu64 "\n", session_get_new_time(sess)); printf("session create time : %" PRIu64 "\n", session_get_new_time(sess));
printf("session last time : %" PRIu64 "\n", session_get_last_time(sess)); printf("session last time : %" PRIu64 "\n", session_get_last_time(sess));
if (session_get_type(sess) == SESSION_TYPE_TCP)
{
memset(buffer, 0, sizeof(buffer));
tcp_state_to_str(session_get_tcp_state(sess), buffer, sizeof(buffer));
printf("session tcp state : %s\n", buffer);
}
else if (session_get_type(sess) == SESSION_TYPE_UDP)
{
memset(buffer, 0, sizeof(buffer));
udp_state_to_str(session_get_udp_state(sess), buffer, sizeof(buffer));
printf("session udp state : %s\n", buffer);
}
printf("session current packet ptr : %p\n", (void *)session_get0_cur_pkt(sess)); printf("session current packet ptr : %p\n", (void *)session_get0_cur_pkt(sess));
printf("session current packet dir : %s\n", session_dir_to_str(session_get_cur_dir(sess))); printf("session current packet dir : %s\n", session_dir_to_str(session_get_cur_dir(sess)));
printf("session ex data: \n"); printf("session ex data: \n");

View File

@@ -11,30 +11,6 @@ extern "C"
#include "tuple.h" #include "tuple.h"
#include "packet.h" #include "packet.h"
enum tcp_state
{
// HANDSHAKE
TCP_SYN_RECVED = 1 << 0,
TCP_SYNACK_RECVED = 1 << 1,
TCP_C2S_ACK_RECVED = 1 << 2,
TCP_S2C_ACK_RECVED = 1 << 3,
// ESTABLISHED
TCP_C2S_DATA_RECVED = 1 << 4,
TCP_S2C_DATA_RECVED = 1 << 5,
// FIN
TCP_C2S_FIN_RECVED = 1 << 6,
TCP_S2C_FIN_RECVED = 1 << 7,
// RST
TCP_C2S_RST_RECVED = 1 << 8,
TCP_S2C_RST_RECVED = 1 << 9,
};
enum udp_state
{
UDP_C2S_RECVED = 1 << 0,
UDP_S2C_RECVED = 1 << 1,
};
enum session_state enum session_state
{ {
SESSION_STATE_INIT = 0, SESSION_STATE_INIT = 0,
@@ -42,7 +18,7 @@ enum session_state
SESSION_STATE_ACTIVE = 2, SESSION_STATE_ACTIVE = 2,
SESSION_STATE_CLOSING = 3, SESSION_STATE_CLOSING = 3,
SESSION_STATE_CLOSED = 4, SESSION_STATE_CLOSED = 4,
SESSION_STATE_MAX = 5, MAX_STATE = 5,
}; };
enum session_type enum session_type
@@ -122,14 +98,6 @@ void session_set_last_time(struct session *sess, uint64_t timestamp);
uint64_t session_get_new_time(const struct session *sess); uint64_t session_get_new_time(const struct session *sess);
uint64_t session_get_last_time(const struct session *sess); uint64_t session_get_last_time(const struct session *sess);
// session tcp state
void session_set_tcp_state(struct session *sess, enum tcp_state state);
enum tcp_state session_get_tcp_state(const struct session *sess);
// session udp state
void session_set_udp_state(struct session *sess, enum udp_state state);
enum udp_state session_get_udp_state(const struct session *sess);
// session user data // session user data
void session_set_user_data(struct session *sess, void *user_data); void session_set_user_data(struct session *sess, void *user_data);
void *session_get_user_data(const struct session *sess); void *session_get_user_data(const struct session *sess);
@@ -181,7 +149,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. * 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_free_ex_data(struct session *sess, uint8_t idx);
void session_free(struct session *sess); void session_clean(struct session *sess);
/****************************************************************************** /******************************************************************************
* session expire * session expire

File diff suppressed because it is too large Load Diff

View File

@@ -23,59 +23,69 @@ struct session_manager_options
uint8_t udp_overload_evict_old_sess; // 1: evict old session, 0: bypass new session uint8_t udp_overload_evict_old_sess; // 1: evict old session, 0: bypass new session
// TCP timeout // TCP timeout
uint64_t tcp_timeout_init; // seconds, Range: 1-60 uint64_t tcp_timeout_init; // ms, Range: 1-60,000
uint64_t tcp_timeout_handshake; // seconds, Range: 1-60 uint64_t tcp_timeout_handshake; // ms, Range: 1-60,000
uint64_t tcp_timeout_data; // seconds, Range: 1-15,999,999 uint64_t tcp_timeout_data; // ms, Range: 1-15,999,999,000
uint64_t tcp_timeout_half_closed; // seconds, Range: 1-604,800 uint64_t tcp_timeout_half_closed; // ms, Range: 1-604,800,000
uint64_t tcp_timeout_time_wait; // seconds, Range: 1-600 uint64_t tcp_timeout_time_wait; // ms, Range: 1-600,000
uint64_t tcp_timeout_discard; // seconds, Range: 1-15,999,999 uint64_t tcp_timeout_discard; // ms, Range: 1-15,999,999,000
// UDP timeout // UDP timeout
uint64_t udp_timeout_data; // seconds, Range: 1-15,999,999 uint64_t udp_timeout_data; // ms, Range: 1-15,999,999,000
// duplicate packet filter // duplicate packet filter
uint8_t duplicated_packet_filter_enable; uint8_t duplicated_packet_filter_enable;
uint32_t duplicated_packet_filter_capacity; uint32_t duplicated_packet_filter_capacity;
uint32_t duplicated_packet_filter_timeout; // seconds, Range: 1-60 uint32_t duplicated_packet_filter_timeout; // ms, Range: 1-60,000
double duplicated_packet_filter_error_rate; double duplicated_packet_filter_error_rate;
// evicted session filter // evicted session filter
uint8_t evicted_session_filter_enable; uint8_t evicted_session_filter_enable;
uint32_t evicted_session_filter_capacity; uint32_t evicted_session_filter_capacity;
uint32_t evicted_session_filter_timeout; // seconds, Range: 1-60 uint32_t evicted_session_filter_timeout; // ms, Range: 1-60,000
double evicted_session_filter_error_rate; double evicted_session_filter_error_rate;
}; };
struct session_stat
{
uint64_t nr_sess_used;
uint64_t nr_sess_init;
uint64_t nr_sess_opening;
uint64_t nr_sess_active;
uint64_t nr_sess_closing;
uint64_t nr_sess_closed;
uint64_t nr_new_sess_evicted;
uint64_t nr_old_sess_evicted;
};
struct packet_stat
{
uint64_t nr_pkts;
uint64_t nr_bytes;
};
struct session_manager_stat struct session_manager_stat
{ {
uint64_t tcp_sess_num; struct packet_stat dup_pkt;
uint64_t tcp_opening_sess_num; struct packet_stat evc_pkt;
uint64_t tcp_active_sess_num;
uint64_t tcp_closing_sess_num;
uint64_t udp_sess_num; struct session_stat tcp_sess;
uint64_t udp_opening_sess_num; struct session_stat udp_sess;
uint64_t udp_active_sess_num;
uint64_t udp_closing_sess_num;
uint64_t tcp_overload_evict_old_sess_num;
uint64_t tcp_overload_evict_new_sess_num;
uint64_t udp_overload_evict_old_sess_num;
uint64_t udp_overload_evict_new_sess_num;
}; };
struct session_manager; struct session_manager;
struct session_manager *session_manager_new(struct session_manager_options *opts); struct session_manager *session_manager_new(struct session_manager_options *opts, uint64_t now);
void session_manager_free(struct session_manager *mgr); void session_manager_free(struct session_manager *mgr);
struct session *session_manager_new_session(struct session_manager *mgr, const struct packet *pkt); struct session *session_manager_new_session(struct session_manager *mgr, const struct packet *pkt, uint64_t now);
void session_manager_free_session(struct session_manager *mgr, struct session *sess); void session_manager_free_session(struct session_manager *mgr, struct session *sess);
struct session *session_manager_lookup_session(struct session_manager *mgr, const struct packet *pkt); struct session *session_manager_lookup_session(struct session_manager *mgr, const struct packet *pkt);
int session_manager_update_session(struct session_manager *mgr, struct session *sess, const struct packet *pkt); int session_manager_update_session(struct session_manager *mgr, struct session *sess, const struct packet *pkt, uint64_t now);
// return session need free by session_manager_free_session() // return session need free by session_manager_free_session()
struct session *session_manager_get_expired_session(struct session_manager *mgr); struct session *session_manager_get_expired_session(struct session_manager *mgr, uint64_t now);
struct session *session_manager_get_evicted_session(struct session_manager *mgr); struct session *session_manager_get_evicted_session(struct session_manager *mgr);
// return 0: have already timeout session // return 0: have already timeout session

View File

@@ -43,10 +43,6 @@ struct session
uint64_t create_time; uint64_t create_time;
uint64_t last_time; uint64_t last_time;
// session l4 state
enum tcp_state tcp_state;
enum udp_state udp_state;
// session packet // session packet
struct packet *c2s_1st_pkt; struct packet *c2s_1st_pkt;
struct packet *s2c_1st_pkt; struct packet *s2c_1st_pkt;

View File

@@ -12,8 +12,8 @@ struct session_table
void *arg; void *arg;
uint64_t count; uint64_t count;
struct session *least_recently_unused; struct session *head; // Least recently used
struct session *least_recently_used; struct session *tail; // Most recently used
}; };
/****************************************************************************** /******************************************************************************
@@ -45,58 +45,54 @@ static int HASH_KEYCMP_OVERWRITE(const void *key_a, const void *key_b, size_t le
return -1; return -1;
} }
static void session_table_add_session_to_linklist(struct session_table *table, struct session *sess) // add session to the tail of the list
static void add_session_to_list(struct session_table *table, struct session *sess)
{ {
if (table == NULL || sess == NULL) if (table == NULL || sess == NULL)
{ {
return; return;
} }
if (table->least_recently_used == NULL)
{
table->least_recently_unused = sess;
table->least_recently_used = sess;
sess->prev_ptr = NULL;
sess->next_ptr = NULL; sess->next_ptr = NULL;
sess->prev_ptr = NULL;
if (table->head == NULL && table->tail == NULL)
{
table->head = sess;
table->tail = sess;
} }
else else
{ {
sess->next_ptr = table->least_recently_used; table->tail->next_ptr = sess;
table->least_recently_used->prev_ptr = sess; sess->prev_ptr = table->tail;
sess->prev_ptr = NULL; table->tail = sess;
table->least_recently_used = sess;
} }
} }
static void session_table_del_session_from_linklist(struct session_table *table, struct session *sess) static void del_session_from_list(struct session_table *table, struct session *sess)
{ {
if (table == NULL || sess == NULL) if (table == NULL || sess == NULL)
{ {
return; return;
} }
if (sess->prev_ptr == NULL && sess->next_ptr == NULL) if (sess->prev_ptr)
{
table->least_recently_unused = NULL;
table->least_recently_used = NULL;
}
else if (sess->prev_ptr == NULL && sess->next_ptr != NULL)
{
table->least_recently_used = sess->next_ptr;
sess->next_ptr->prev_ptr = NULL;
}
else if (sess->prev_ptr != NULL && sess->next_ptr == NULL)
{
table->least_recently_unused = sess->prev_ptr;
sess->prev_ptr->next_ptr = NULL;
}
else
{ {
sess->prev_ptr->next_ptr = sess->next_ptr; sess->prev_ptr->next_ptr = sess->next_ptr;
}
else
{
table->head = sess->next_ptr;
}
if (sess->next_ptr)
{
sess->next_ptr->prev_ptr = sess->prev_ptr; sess->next_ptr->prev_ptr = sess->prev_ptr;
} }
sess->prev_ptr = NULL; else
sess->next_ptr = NULL; {
table->tail = sess->prev_ptr;
}
} }
/****************************************************************************** /******************************************************************************
@@ -107,8 +103,8 @@ struct session_table *session_table_new()
{ {
struct session_table *table = (struct session_table *)calloc(1, sizeof(struct session_table)); struct session_table *table = (struct session_table *)calloc(1, sizeof(struct session_table));
table->count = 0; table->count = 0;
table->least_recently_unused = NULL; table->head = NULL;
table->least_recently_used = NULL; table->tail = NULL;
return table; return table;
} }
@@ -153,33 +149,33 @@ void session_table_set_freecb(struct session_table *table, session_free_cb free_
} }
} }
int session_table_add_session(struct session_table *table, const struct tuple6 *tuple, struct session *sess) int session_table_add(struct session_table *table, const struct tuple6 *tuple, struct session *sess)
{ {
if (table == NULL || sess == NULL) if (table == NULL || sess == NULL)
{ {
return -1; return -1;
} }
if (session_table_find_session(table, tuple)) if (session_table_find_tuple(table, tuple))
{ {
return -1; return -1;
} }
HASH_ADD(hh, table->root, tuple, sizeof(sess->tuple), sess); HASH_ADD(hh, table->root, tuple, sizeof(sess->tuple), sess);
session_table_add_session_to_linklist(table, sess); add_session_to_list(table, sess);
table->count++; table->count++;
return 0; return 0;
} }
void session_table_del_session(struct session_table *table, const struct tuple6 *tuple) void session_table_del(struct session_table *table, const struct tuple6 *tuple)
{ {
if (table == NULL) if (table == NULL)
{ {
return; return;
} }
struct session *sess = session_table_find_session(table, tuple); struct session *sess = session_table_find_tuple(table, tuple);
if (sess == NULL) if (sess == NULL)
{ {
return; return;
@@ -190,11 +186,11 @@ void session_table_del_session(struct session_table *table, const struct tuple6
{ {
table->free_cb(sess, table->arg); table->free_cb(sess, table->arg);
} }
session_table_del_session_from_linklist(table, sess); del_session_from_list(table, sess);
table->count--; table->count--;
} }
struct session *session_table_find_session(struct session_table *table, const struct tuple6 *tuple) struct session *session_table_find_tuple(struct session_table *table, const struct tuple6 *tuple)
{ {
if (table == NULL) if (table == NULL)
{ {
@@ -213,29 +209,29 @@ struct session *session_table_find_session(struct session_table *table, const st
if (sess) if (sess)
{ {
session_table_del_session_from_linklist(table, sess); del_session_from_list(table, sess);
session_table_add_session_to_linklist(table, sess); add_session_to_list(table, sess);
} }
return sess; return sess;
} }
struct session *session_table_find_least_recently_unused_session(struct session_table *table) struct session *session_table_find_lru(struct session_table *table)
{ {
if (table == NULL) if (table == NULL)
{ {
return NULL; return NULL;
} }
return table->least_recently_unused; return table->head;
} }
struct session *session_table_find_least_recently_used_session(struct session_table *table) struct session *session_table_find_mru(struct session_table *table)
{ {
if (table == NULL) if (table == NULL)
{ {
return NULL; return NULL;
} }
return table->least_recently_used; return table->tail;
} }

View File

@@ -17,11 +17,11 @@ typedef void (*session_free_cb)(struct session *sess, void *arg);
void session_table_set_freecb(struct session_table *table, session_free_cb free_cb, void *arg); void session_table_set_freecb(struct session_table *table, session_free_cb free_cb, void *arg);
// return 0: success // return 0: success
// return -1: failed // return -1: failed
int session_table_add_session(struct session_table *table, const struct tuple6 *tuple, struct session *sess); int session_table_add(struct session_table *table, const struct tuple6 *tuple, struct session *sess);
void session_table_del_session(struct session_table *table, const struct tuple6 *tuple); void session_table_del(struct session_table *table, const struct tuple6 *tuple);
struct session *session_table_find_session(struct session_table *table, const struct tuple6 *tuple); struct session *session_table_find_tuple(struct session_table *table, const struct tuple6 *tuple);
struct session *session_table_find_least_recently_unused_session(struct session_table *table); struct session *session_table_find_lru(struct session_table *table);
struct session *session_table_find_least_recently_used_session(struct session_table *table); struct session *session_table_find_mru(struct session_table *table);
#ifdef __cpluscplus #ifdef __cpluscplus
} }

View File

@@ -42,19 +42,19 @@ void session_timer_free(struct session_timer *timer)
} }
} }
void session_timer_add_session(struct session_timer *timer, struct session *sess) void session_timer_add(struct session_timer *timer, struct session *sess)
{ {
struct timeout *timeout = &sess->timeout; struct timeout *timeout = &sess->timeout;
timeouts_add(timer->timeouts, timeout, sess->expire_abs_ts); timeouts_add(timer->timeouts, timeout, sess->expire_abs_ts);
} }
void session_timer_del_session(struct session_timer *timer, struct session *sess) void session_timer_del(struct session_timer *timer, struct session *sess)
{ {
struct timeout *timeout = &sess->timeout; struct timeout *timeout = &sess->timeout;
timeouts_del(timer->timeouts, timeout); timeouts_del(timer->timeouts, timeout);
} }
struct session *session_timer_expire_session(struct session_timer *timer, uint64_t abs_current_ts) struct session *session_timer_expire(struct session_timer *timer, uint64_t abs_current_ts)
{ {
timeouts_update(timer->timeouts, abs_current_ts); timeouts_update(timer->timeouts, abs_current_ts);

View File

@@ -11,13 +11,13 @@ extern "C"
struct session_timer; struct session_timer;
struct session_timer *session_timer_new(); struct session_timer *session_timer_new();
void session_timer_free(struct session_timer *timer); void session_timer_free(struct session_timer *timer);
void session_timer_add_session(struct session_timer *timer, struct session *sess); void session_timer_add(struct session_timer *timer, struct session *sess);
void session_timer_del_session(struct session_timer *timer, struct session *sess); void session_timer_del(struct session_timer *timer, struct session *sess);
/* /*
* return one session which timeout, or NULL if no session timeout. * return one session which timeout, or NULL if no session timeout.
* if return session, the session will be removed from timer. * if return session, the session will be removed from timer.
*/ */
struct session *session_timer_expire_session(struct session_timer *timer, uint64_t abs_current_ts); struct session *session_timer_expire(struct session_timer *timer, uint64_t abs_current_ts);
// return 0: have already timeout session // return 0: have already timeout session
// return >0: next expire interval // return >0: next expire interval
uint64_t session_timer_next_expire_interval(struct session_timer *timer); uint64_t session_timer_next_expire_interval(struct session_timer *timer);

View File

@@ -0,0 +1,155 @@
#include <stdio.h>
#include <assert.h>
#include "session_transition.h"
#define MAX_TRANSITION_PER_STATE 4
struct session_transition
{
int inputs_mask;
enum session_state next_state;
} fsm[MAX_STATE][MAX_TRANSITION_PER_STATE];
/*
* session transition
*
* SESSION_STATE_INIT -> SESSION_STATE_INIT ( NONE )
* SESSION_STATE_INIT -> SESSION_STATE_OPENING ( TCP_SYN | TCP_SYN_ACK | UDP_DATA )
*
* SESSION_STATE_OPENING -> SESSION_STATE_OPENING ( NONE )
* SESSION_STATE_OPENING -> SESSION_STATE_ACTIVE ( TCP_DATA | UDP_DATA )
* SESSION_STATE_OPENING -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT )
* SESSION_STATE_OPENING -> SESSION_STATE_CLOSED ( LRU_EVICT )
*
* SESSION_STATE_ACTIVE -> SESSION_STATE_ACTIVE ( NONE )
* SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT )
* SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSED ( LRU_EVICT )
*
* SESSION_STATE_CLOSING -> SESSION_STATE_CLOSING ( NONE )
* SESSION_STATE_CLOSING -> SESSION_STATE_CLOSED ( TIMEOUT | LRU_EVICT )
*/
static void session_inputs_to_str(int inputs, char *buff, int len)
{
int nused = 0;
if (inputs & TCP_SYN)
{
nused += snprintf(buff + nused, len - nused, "TCP_SYN ");
}
if (inputs & TCP_SYN_ACK)
{
nused += snprintf(buff + nused, len - nused, "TCP_SYN_ACK ");
}
if (inputs & TCP_FIN)
{
nused += snprintf(buff + nused, len - nused, "TCP_FIN ");
}
if (inputs & TCP_RST)
{
nused += snprintf(buff + nused, len - nused, "TCP_RST ");
}
if (inputs & TCP_DATA)
{
nused += snprintf(buff + nused, len - nused, "TCP_DATA ");
}
if (inputs & UDP_DATA)
{
nused += snprintf(buff + nused, len - nused, "UDP_DATA ");
}
if (inputs & TIMEOUT)
{
nused += snprintf(buff + nused, len - nused, "TIMEOUT ");
}
if (inputs & LRU_EVICT)
{
nused += snprintf(buff + nused, len - nused, "LRU_EVICT ");
}
}
void session_transition_init()
{
// SESSION_STATE_INIT -> SESSION_STATE_OPENING ( TCP_SYN | TCP_SYN_ACK | UDP_DATA )
// SESSION_STATE_INIT -> SESSION_STATE_INIT ( NONE )
fsm[SESSION_STATE_INIT][0].inputs_mask = TCP_SYN | TCP_SYN_ACK | UDP_DATA;
fsm[SESSION_STATE_INIT][0].next_state = SESSION_STATE_OPENING;
fsm[SESSION_STATE_INIT][1].inputs_mask = NONE;
fsm[SESSION_STATE_INIT][1].next_state = SESSION_STATE_INIT;
// SESSION_STATE_OPENING -> SESSION_STATE_ACTIVE ( TCP_DATA | UDP_DATA )
// SESSION_STATE_OPENING -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT )
// SESSION_STATE_OPENING -> SESSION_STATE_CLOSED ( LRU_EVICT )
// SESSION_STATE_OPENING -> SESSION_STATE_OPENING ( NONE )
fsm[SESSION_STATE_OPENING][0].inputs_mask = TCP_DATA | UDP_DATA;
fsm[SESSION_STATE_OPENING][0].next_state = SESSION_STATE_ACTIVE;
fsm[SESSION_STATE_OPENING][1].inputs_mask = TCP_FIN | TCP_RST | TIMEOUT;
fsm[SESSION_STATE_OPENING][1].next_state = SESSION_STATE_CLOSING;
fsm[SESSION_STATE_OPENING][2].inputs_mask = LRU_EVICT;
fsm[SESSION_STATE_OPENING][2].next_state = SESSION_STATE_CLOSED;
fsm[SESSION_STATE_OPENING][3].inputs_mask = NONE;
fsm[SESSION_STATE_OPENING][3].next_state = SESSION_STATE_OPENING;
// SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSING ( TCP_FIN | TCP_RST | TIMEOUT )
// SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSED ( LRU_EVICT )
// SESSION_STATE_ACTIVE -> SESSION_STATE_ACTIVE ( NONE )
fsm[SESSION_STATE_ACTIVE][0].inputs_mask = TCP_FIN | TCP_RST | TIMEOUT;
fsm[SESSION_STATE_ACTIVE][0].next_state = SESSION_STATE_CLOSING;
fsm[SESSION_STATE_ACTIVE][1].inputs_mask = LRU_EVICT;
fsm[SESSION_STATE_ACTIVE][1].next_state = SESSION_STATE_CLOSED;
fsm[SESSION_STATE_ACTIVE][2].inputs_mask = NONE;
fsm[SESSION_STATE_ACTIVE][2].next_state = SESSION_STATE_ACTIVE;
// SESSION_STATE_CLOSING -> SESSION_STATE_CLOSED ( TIMEOUT | LRU_EVICT )
// SESSION_STATE_CLOSING -> SESSION_STATE_CLOSING ( NONE )
fsm[SESSION_STATE_CLOSING][0].inputs_mask = TIMEOUT | LRU_EVICT;
fsm[SESSION_STATE_CLOSING][0].next_state = SESSION_STATE_CLOSED;
fsm[SESSION_STATE_CLOSING][1].inputs_mask = NONE;
fsm[SESSION_STATE_CLOSING][1].next_state = SESSION_STATE_CLOSING;
}
enum session_state session_transition_run(enum session_state curr_state, int inputs)
{
struct session_transition *list = fsm[curr_state];
for (int i = 0; i < MAX_TRANSITION_PER_STATE; i++)
{
int mask = list[i].inputs_mask;
if (mask & inputs)
{
return list[i].next_state;
}
if (mask == NONE)
{
return list[i].next_state;
}
}
assert(0);
return curr_state;
}
void session_transition_log(struct session *sess, enum session_state curr_state, enum session_state next_state, int inputs)
{
if (curr_state == next_state)
{
return;
}
char buff[128] = {0};
char reason[128] = {0};
tuple6_to_str(session_get0_key(sess), buff, sizeof(buff));
session_inputs_to_str(inputs, reason, sizeof(reason));
SESSION_TRANSITION_LOG_DEBUG("%s session %lu %s (%s) %s -> %s",
session_type_to_str(session_get_type(sess)), session_get_id(sess), buff, reason,
session_state_to_str(curr_state), session_state_to_str(next_state));
}

View File

@@ -0,0 +1,41 @@
#ifndef _SESSION_TRANSITION_H
#define _SESSION_TRANSITION_H
#ifdef __cpluscplus
extern "C"
{
#endif
#include "log.h"
#include "session.h"
#define SESSION_TRANSITION_LOG_DEBUG(format, ...) LOG_DEBUG("session transition", format, ##__VA_ARGS__)
enum session_inputs
{
NONE = 0,
// packet
TCP_SYN = 1 << 0,
TCP_SYN_ACK = 1 << 1,
TCP_FIN = 1 << 2, // Only Fist FIN
TCP_RST = 1 << 3,
TCP_DATA = 1 << 4,
UDP_DATA = 1 << 5,
// session timeout
TIMEOUT = 1 << 6,
// session table full evict
LRU_EVICT = 1 << 7,
};
void session_transition_init();
enum session_state session_transition_run(enum session_state curr_state, int inputs);
void session_transition_log(struct session *sess, enum session_state curr_state, enum session_state next_state, int inputs);
#ifdef __cpluscplus
}
#endif
#endif

View File

@@ -21,103 +21,94 @@ target_link_libraries(gtest_session_queue session_manager gtest)
# gtest state machine (TCP) # gtest state machine (TCP)
############################################################################### ###############################################################################
#add_executable(gtest_state_tcp_init_to_opening gtest_state_tcp_init_to_opening.cpp) add_executable(gtest_state_tcp_init_to_opening gtest_state_tcp_init_to_opening.cpp)
#target_link_libraries(gtest_state_tcp_init_to_opening session_manager gtest) target_link_libraries(gtest_state_tcp_init_to_opening session_manager gtest)
#
#add_executable(gtest_state_tcp_opening_to_active gtest_state_tcp_opening_to_active.cpp) add_executable(gtest_state_tcp_opening_to_active gtest_state_tcp_opening_to_active.cpp)
#target_link_libraries(gtest_state_tcp_opening_to_active session_manager gtest) target_link_libraries(gtest_state_tcp_opening_to_active session_manager gtest)
#
#add_executable(gtest_state_tcp_active_to_closing gtest_state_tcp_active_to_closing.cpp) add_executable(gtest_state_tcp_active_to_closing gtest_state_tcp_active_to_closing.cpp)
#target_link_libraries(gtest_state_tcp_active_to_closing session_manager gtest) target_link_libraries(gtest_state_tcp_active_to_closing session_manager gtest)
#
#add_executable(gtest_state_tcp_opening_to_closing gtest_state_tcp_opening_to_closing.cpp) add_executable(gtest_state_tcp_opening_to_closing gtest_state_tcp_opening_to_closing.cpp)
#target_link_libraries(gtest_state_tcp_opening_to_closing session_manager gtest) target_link_libraries(gtest_state_tcp_opening_to_closing session_manager gtest)
#
#add_executable(gtest_state_tcp_init_to_opening_to_active_to_closing_to_closed gtest_state_tcp_init_to_opening_to_active_to_closing_to_closed.cpp) add_executable(gtest_state_tcp_init_to_opening_to_active_to_closing_to_closed gtest_state_tcp_init_to_opening_to_active_to_closing_to_closed.cpp)
#target_link_libraries(gtest_state_tcp_init_to_opening_to_active_to_closing_to_closed session_manager gtest) target_link_libraries(gtest_state_tcp_init_to_opening_to_active_to_closing_to_closed session_manager gtest)
############################################################################### ###############################################################################
# gtest state machine (UDP) # gtest state machine (UDP)
############################################################################### ###############################################################################
#add_executable(gtest_state_udp_init_to_opening_to_closing gtest_state_udp_init_to_opening_to_closing.cpp) add_executable(gtest_state_udp_init_to_opening_to_closing gtest_state_udp_init_to_opening_to_closing.cpp)
#target_link_libraries(gtest_state_udp_init_to_opening_to_closing session_manager gtest) target_link_libraries(gtest_state_udp_init_to_opening_to_closing session_manager gtest)
#
#add_executable(gtest_state_udp_init_to_opening_to_active_to_closing gtest_state_udp_init_to_opening_to_active_to_closing.cpp) add_executable(gtest_state_udp_init_to_opening_to_active_to_closing gtest_state_udp_init_to_opening_to_active_to_closing.cpp)
#target_link_libraries(gtest_state_udp_init_to_opening_to_active_to_closing session_manager gtest) target_link_libraries(gtest_state_udp_init_to_opening_to_active_to_closing session_manager gtest)
############################################################################### ###############################################################################
# gtest timeout (TCP) # gtest timeout (TCP)
############################################################################### ###############################################################################
#add_executable(gtest_timeout_tcp_init gtest_timeout_tcp_init.cpp) add_executable(gtest_timeout_tcp_init gtest_timeout_tcp_init.cpp)
#target_link_libraries(gtest_timeout_tcp_init session_manager gtest) target_link_libraries(gtest_timeout_tcp_init session_manager gtest)
#
#add_executable(gtest_timeout_tcp_handshake gtest_timeout_tcp_handshake.cpp) add_executable(gtest_timeout_tcp_handshake gtest_timeout_tcp_handshake.cpp)
#target_link_libraries(gtest_timeout_tcp_handshake session_manager gtest) target_link_libraries(gtest_timeout_tcp_handshake session_manager gtest)
#
#add_executable(gtest_timeout_tcp_data gtest_timeout_tcp_data.cpp) add_executable(gtest_timeout_tcp_data gtest_timeout_tcp_data.cpp)
#target_link_libraries(gtest_timeout_tcp_data session_manager gtest) target_link_libraries(gtest_timeout_tcp_data session_manager gtest)
#
#add_executable(gtest_timeout_tcp_half_closed gtest_timeout_tcp_half_closed.cpp)
#target_link_libraries(gtest_timeout_tcp_half_closed session_manager gtest)
############################################################################### ###############################################################################
# gtest timeout (UDP) # gtest timeout (UDP)
############################################################################### ###############################################################################
#add_executable(gtest_timeout_udp_data gtest_timeout_udp_data.cpp) add_executable(gtest_timeout_udp_data gtest_timeout_udp_data.cpp)
#target_link_libraries(gtest_timeout_udp_data session_manager gtest) target_link_libraries(gtest_timeout_udp_data session_manager gtest)
############################################################################### ###############################################################################
# gtest filter # gtest filter
############################################################################### ###############################################################################
#add_executable(gtest_filter_tcp_dupkt gtest_filter_tcp_dupkt.cpp) add_executable(gtest_filter_tcp_dupkt gtest_filter_tcp_dupkt.cpp)
#target_link_libraries(gtest_filter_tcp_dupkt session_manager gtest) target_link_libraries(gtest_filter_tcp_dupkt session_manager gtest)
#
#add_executable(gtest_filter_udp_eviction gtest_filter_udp_eviction.cpp)
#target_link_libraries(gtest_filter_udp_eviction session_manager gtest)
############################################################################### ###############################################################################
# gtest overload # gtest overload
############################################################################### ###############################################################################
#add_executable(gtest_overload_evict_tcp_sess gtest_overload_evict_tcp_sess.cpp) add_executable(gtest_overload_evict_tcp_sess gtest_overload_evict_tcp_sess.cpp)
#target_link_libraries(gtest_overload_evict_tcp_sess session_manager gtest) target_link_libraries(gtest_overload_evict_tcp_sess session_manager gtest)
#
#add_executable(gtest_overload_evict_udp_sess gtest_overload_evict_udp_sess.cpp) add_executable(gtest_overload_evict_udp_sess gtest_overload_evict_udp_sess.cpp)
#target_link_libraries(gtest_overload_evict_udp_sess session_manager gtest) target_link_libraries(gtest_overload_evict_udp_sess session_manager gtest)
############################################################################### ###############################################################################
# gtest # gtest
############################################################################### ###############################################################################
#include(GoogleTest) include(GoogleTest)
#gtest_discover_tests(gtest_session) gtest_discover_tests(gtest_session)
#gtest_discover_tests(gtest_session_pool) gtest_discover_tests(gtest_session_pool)
#gtest_discover_tests(gtest_session_table) gtest_discover_tests(gtest_session_table)
#gtest_discover_tests(gtest_session_timer) gtest_discover_tests(gtest_session_timer)
#gtest_discover_tests(gtest_session_queue) gtest_discover_tests(gtest_session_queue)
#
#gtest_discover_tests(gtest_state_tcp_init_to_opening) gtest_discover_tests(gtest_state_tcp_init_to_opening)
#gtest_discover_tests(gtest_state_tcp_opening_to_active) gtest_discover_tests(gtest_state_tcp_opening_to_active)
#gtest_discover_tests(gtest_state_tcp_active_to_closing) gtest_discover_tests(gtest_state_tcp_active_to_closing)
#gtest_discover_tests(gtest_state_tcp_opening_to_closing) gtest_discover_tests(gtest_state_tcp_opening_to_closing)
#
#gtest_discover_tests(gtest_state_tcp_init_to_opening_to_active_to_closing_to_closed) gtest_discover_tests(gtest_state_tcp_init_to_opening_to_active_to_closing_to_closed)
#gtest_discover_tests(gtest_state_udp_init_to_opening_to_closing) gtest_discover_tests(gtest_state_udp_init_to_opening_to_closing)
#gtest_discover_tests(gtest_state_udp_init_to_opening_to_active_to_closing) gtest_discover_tests(gtest_state_udp_init_to_opening_to_active_to_closing)
#
#gtest_discover_tests(gtest_timeout_tcp_init) gtest_discover_tests(gtest_timeout_tcp_init)
#gtest_discover_tests(gtest_timeout_tcp_handshake) gtest_discover_tests(gtest_timeout_tcp_handshake)
#gtest_discover_tests(gtest_timeout_tcp_data) gtest_discover_tests(gtest_timeout_tcp_data)
#gtest_discover_tests(gtest_timeout_tcp_half_closed) gtest_discover_tests(gtest_timeout_udp_data)
#
#gtest_discover_tests(gtest_timeout_udp_data) gtest_discover_tests(gtest_filter_tcp_dupkt)
#
#gtest_discover_tests(gtest_filter_tcp_dupkt) gtest_discover_tests(gtest_overload_evict_tcp_sess)
#gtest_discover_tests(gtest_filter_udp_eviction) gtest_discover_tests(gtest_overload_evict_udp_sess)
#
#gtest_discover_tests(gtest_overload_evict_tcp_sess)
#gtest_discover_tests(gtest_overload_evict_udp_sess)

View File

@@ -1,4 +1,51 @@
#include "test_utils.h" #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,
};
static void packet_set_ip_id(struct packet *pkt, uint16_t ip_id)
{
const struct layer *ipv4_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, ip_id);
}
#if 1 #if 1
TEST(TCP_DUPKT_FILTER_ENABLE, SYN_DUP) TEST(TCP_DUPKT_FILTER_ENABLE, SYN_DUP)
@@ -6,277 +53,311 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SYN_DUP)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n"); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
__session_dispatch(sess); stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->dup_pkt.nr_pkts == 0);
EXPECT_TRUE(stat->dup_pkt.nr_bytes == 0);
// C2S SYN dup Packet // C2S SYN dup Packet
printf("=> packet parse: TCP C2S SYN dup packet\n"); printf("\n=> Packet Parse: TCP C2S SYN dup packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess == NULL); // lookup session
__session_dispatch(sess); sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == -1);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_YES);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->dup_pkt.nr_pkts == 1);
EXPECT_TRUE(stat->dup_pkt.nr_bytes == sizeof(tcp_pkt1_c2s_syn));
// C2S SYN retransmission Packet // C2S SYN retransmission Packet
printf("=> packet parse: TCP C2S SYN retransmission packet\n"); printf("\n=> Packet Parse: TCP C2S SYN retransmission packet\n");
char tcp_pkt_c2s_syn_retransmission[1500] = {0}; char syn_retransmission[1500] = {0};
memcpy(tcp_pkt_c2s_syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); memcpy(syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
packet_parse(&pkt, (const char *)tcp_pkt_c2s_syn_retransmission, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
const struct layer *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4); packet_set_ip_id(&pkt, 0x1234);
EXPECT_TRUE(ipv4_layer); printf("<= Packet Parse: done\n\n");
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234);
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_YES);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // lookup session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); sess = session_manager_lookup_session(mgr, &pkt);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_YES);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->dup_pkt.nr_pkts == 1);
EXPECT_TRUE(stat->dup_pkt.nr_bytes == sizeof(tcp_pkt1_c2s_syn));
session_manager_free(mgr); session_manager_free(mgr);
} }
#endif #endif
#if 1 #if 1
TEST(TCP_DUPKT_FILTER_ENABLE, S2C_DUP) TEST(TCP_DUPKT_FILTER_ENABLE, SYNACK_DUP)
{ {
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// S2C SYNACK Packet // S2C SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
__session_dispatch(sess); stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->dup_pkt.nr_pkts == 0);
EXPECT_TRUE(stat->dup_pkt.nr_bytes == 0);
// S2C SYNACK dup Packet // S2C SYNACK dup Packet
printf("=> packet parse: TCP S2C SYNACK dup packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK dup packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess == NULL); // lookup session
__session_dispatch(sess); sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == -1);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_YES);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->dup_pkt.nr_pkts == 1);
EXPECT_TRUE(stat->dup_pkt.nr_bytes == sizeof(tcp_pkt2_s2c_syn_ack));
// S2C SYNACK retransmission Packet // S2C SYNACK retransmission Packet
printf("=> packet parse: TCP S2C SYNACK retransmission packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK retransmission packet\n");
char tcp_pkt_s2c_synack_retransmission[1500] = {0}; char synack_retransmission[1500] = {0};
memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); memcpy(synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack));
const struct layer *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4); packet_set_ip_id(&pkt, 0x1234);
EXPECT_TRUE(ipv4_layer); printf("<= Packet Parse: done\n\n");
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234); // lookup session
printf("<= packet parse\n\n"); sess = session_manager_lookup_session(mgr, &pkt);
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_YES); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_YES);
__session_dispatch(sess); stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(stat->dup_pkt.nr_pkts == 1);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(stat->dup_pkt.nr_bytes == sizeof(tcp_pkt2_s2c_syn_ack));
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
#endif #endif
#if 1 #if 1
TEST(TCP_DUPKT_FILTER_ENABLE, SKIP_FILTER) TEST(TCP_DUPKT_FILTER_ENABLE, SKIP)
{ {
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
const struct layer *ipv4_layer; struct session_manager_stat *stat = NULL;
struct ip *hdr; char syn_retransmission[1500] = {0};
char tcp_pkt_c2s_syn_retransmission[1500] = {0};
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n"); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
__session_dispatch(sess); stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->dup_pkt.nr_pkts == 0);
EXPECT_TRUE(stat->dup_pkt.nr_bytes == 0);
// C2S SYN retransmission Packet // C2S SYN retransmission Packet
printf("=> packet parse: TCP C2S SYN retransmission packet\n"); printf("\n=> Packet Parse: TCP C2S SYN retransmission packet\n");
memcpy(tcp_pkt_c2s_syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); memcpy(syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
packet_parse(&pkt, (const char *)tcp_pkt_c2s_syn_retransmission, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4); packet_set_ip_id(&pkt, 0x1234);
EXPECT_TRUE(ipv4_layer); printf("<= Packet Parse: done\n\n");
hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234); // lookup session
printf("<= packet parse\n\n"); sess = session_manager_lookup_session(mgr, &pkt);
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
__session_dispatch(sess); stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->dup_pkt.nr_pkts == 0);
EXPECT_TRUE(stat->dup_pkt.nr_bytes == 0);
// C2S SYN retransmission Packet // C2S SYN retransmission Packet
printf("=> packet parse: TCP C2S SYN retransmission packet\n"); printf("\n=> Packet Parse: TCP C2S SYN retransmission packet\n");
memcpy(tcp_pkt_c2s_syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); memcpy(syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
packet_parse(&pkt, (const char *)tcp_pkt_c2s_syn_retransmission, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4); packet_set_ip_id(&pkt, 0x1235);
EXPECT_TRUE(ipv4_layer); printf("<= Packet Parse: done\n\n");
hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1235); // lookup session
printf("<= packet parse\n\n"); sess = session_manager_lookup_session(mgr, &pkt);
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
__session_dispatch(sess); stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->dup_pkt.nr_pkts == 0);
EXPECT_TRUE(stat->dup_pkt.nr_bytes == 0);
// C2S SYN dup Packet // C2S SYN dup Packet
printf("=> packet parse: TCP C2S SYN dup packet\n"); printf("\n=> Packet Parse: TCP C2S SYN dup packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // lookup session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); sess = session_manager_lookup_session(mgr, &pkt);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->dup_pkt.nr_pkts == 0);
EXPECT_TRUE(stat->dup_pkt.nr_bytes == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
#endif #endif
#if 1 #if 1
TEST(TCP_DUPKT_FILTER_DISABLE, C2S_DUPKT) TEST(TCP_DUPKT_FILTER_DISABLE, SYN_DUP)
{ {
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
struct session_manager_options _opts; struct session_manager_options _opts;
memcpy(&_opts, &opts, sizeof(struct session_manager_options)); memcpy(&_opts, &opts, sizeof(struct session_manager_options));
_opts.tcp_dupkt_filter_enable = 0; _opts.duplicated_packet_filter_enable = 0;
timestamp_update(); mgr = session_manager_new(&_opts, 1);
mgr = session_manager_new(&_opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n"); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
__session_dispatch(sess); stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->dup_pkt.nr_pkts == 0);
EXPECT_TRUE(stat->dup_pkt.nr_bytes == 0);
// C2S SYN dup Packet // C2S SYN dup Packet
printf("=> packet parse: TCP C2S SYN dup packet\n"); printf("\n=> Packet Parse: TCP C2S SYN dup packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
__session_dispatch(sess);
// C2S SYN retransmission Packet // lookup session
printf("=> packet parse: TCP C2S SYN retransmission packet\n"); sess = session_manager_lookup_session(mgr, &pkt);
char tcp_pkt_c2s_syn_retransmission[1500] = {0};
memcpy(tcp_pkt_c2s_syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
packet_parse(&pkt, (const char *)tcp_pkt_c2s_syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
const struct layer *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234);
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
__session_dispatch(sess); stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(stat->dup_pkt.nr_pkts == 0);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(stat->dup_pkt.nr_bytes == 0);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
#endif #endif
#if 1 #if 1
TEST(TCP_DUPKT_FILTER_DISABLE, S2C_DUP) TEST(TCP_DUPKT_FILTER_DISABLE, SYNACK_DUP)
{ {
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
struct session_manager_options _opts; struct session_manager_options _opts;
memcpy(&_opts, &opts, sizeof(struct session_manager_options)); memcpy(&_opts, &opts, sizeof(struct session_manager_options));
_opts.tcp_dupkt_filter_enable = 0; _opts.duplicated_packet_filter_enable = 0;
timestamp_update(); mgr = session_manager_new(&_opts, 1);
mgr = session_manager_new(&_opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// S2C SYNACK Packet // S2C SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
__session_dispatch(sess); stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->dup_pkt.nr_pkts == 0);
EXPECT_TRUE(stat->dup_pkt.nr_bytes == 0);
// S2C SYNACK dup Packet // S2C SYNACK dup Packet
printf("=> packet parse: TCP S2C SYNACK dup packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK dup packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
__session_dispatch(sess);
// S2C SYNACK retransmission Packet // lookup session
printf("=> packet parse: TCP S2C SYNACK retransmission packet\n"); sess = session_manager_lookup_session(mgr, &pkt);
char tcp_pkt_s2c_synack_retransmission[1500] = {0};
memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack));
const struct layer *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234);
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
__session_dispatch(sess); stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(stat->dup_pkt.nr_pkts == 0);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(stat->dup_pkt.nr_bytes == 0);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
session_manager_free(mgr); session_manager_free(mgr);
} }

View File

@@ -1,136 +0,0 @@
#include "test_utils.h"
#if 1
TEST(UDP_EVICTION_FILTER_ENABLE, HIT_FILTER_THEN_EVICT_SESS)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL);
// C2S REQ Packet
printf("=> packet parse: UDP C2S REQ packet\n");
packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
__session_dispatch(sess);
// wait session timeout
__session_manager_check_counter(mgr, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// C2S REQ Packet
printf("=> packet parse: UDP C2S REQ packet\n");
packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess == NULL);
__session_dispatch(sess);
session_manager_free(mgr);
}
#endif
#if 1
TEST(UDP_EVICTION_FILTER_ENABLE, MISS_FILTER_THEN_NEW_SESS)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_options _opts;
memcpy(&_opts, &opts, sizeof(struct session_manager_options));
_opts.udp_eviction_filter_timeout = 2;
timestamp_update();
mgr = session_manager_new(&_opts);
EXPECT_TRUE(mgr != NULL);
// C2S REQ Packet
printf("=> packet parse: UDP C2S REQ packet\n");
packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
__session_dispatch(sess);
// wait session timeout
__session_manager_check_counter(mgr, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// wait udp eviction filter timeout
sleep(_opts.udp_eviction_filter_timeout);
timestamp_update();
// C2S REQ Packet
printf("=> packet parse: UDP C2S REQ packet\n");
packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess); // add new udp session
__session_dispatch(sess);
__session_manager_check_counter(mgr, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
session_manager_free(mgr);
}
#endif
#if 1
TEST(UDP_EVICTION_FILTER_DISABLE, MISS_FILTER_THEN_NEW_SESS)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_options _opts;
memcpy(&_opts, &opts, sizeof(struct session_manager_options));
_opts.udp_eviction_filter_enable = 0;
timestamp_update();
mgr = session_manager_new(&_opts);
EXPECT_TRUE(mgr != NULL);
// C2S REQ Packet
printf("=> packet parse: UDP C2S REQ packet\n");
packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
__session_dispatch(sess);
// wait session timeout
__session_manager_check_counter(mgr, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// C2S REQ Packet
printf("=> packet parse: UDP C2S REQ packet\n");
packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess); // add new udp session
__session_dispatch(sess);
__session_manager_check_counter(mgr, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
session_manager_free(mgr);
}
#endif
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -1,150 +1,155 @@
#include "test_utils.h" #include <gtest/gtest.h>
static void overwrite_ipv4_saddr(struct packet *pkt, uint32_t saddr) #include "session.h"
#include "session_manager.h"
#include "stellar.h"
#include "ipv4_utils.h"
#include "test_packets.h"
struct session_manager_options opts = {
// max session number
.max_tcp_session_num = RX_BURST_MAX * 2,
.max_udp_session_num = RX_BURST_MAX * 2,
// 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,
};
static void packet_set_tcp_src_addr(struct packet *pkt, uint32_t addr)
{ {
const struct layer *ipv4_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_IPV4); const struct layer *ipv4_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer); EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_src_addr(hdr, saddr); ipv4_hdr_set_src_addr(hdr, addr);
} }
#if 1 #if 1
TEST(OVERLOAD, EVICT_TCP_OLD_SESS) TEST(TCP_OVERLOAD, EVICT_TCP_OLD_SESS)
{ {
struct tuple6 key;
struct packet pkt; struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
char buffer[1500] = {0}; struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
for (uint64_t i = 0; i < opts.max_tcp_session_num; i++)
{
// C2S SYN Packet // C2S SYN Packet
printf("\n====================== new session (%lu) ======================\n\n", i + 1); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
printf("=> packet parse: TCP C2S SYN packet\n");
memcpy(buffer, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
packet_parse(&pkt, (const char *)buffer, sizeof(tcp_pkt1_c2s_syn));
overwrite_ipv4_saddr(&pkt, i + 1);
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
__session_dispatch(sess);
session_manager_print_stat(mgr);
if (i == opts.max_tcp_session_num - 1)
{
__session_manager_check_counter(mgr,
i, 0, 1, // tcp_opening_sess_num, tcp_active_sess_num, tcp_closing_sess_num,
0, 0, 0, // udp_opening_sess_num, udp_active_sess_num, udp_closing_sess_num,
0, 1, // tcp_overload_evict_new_sess_num, tcp_overload_evict_old_sess_num,
0, 0); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num,
}
else
{
__session_manager_check_counter(mgr,
i + 1, 0, 0, // tcp_opening_sess_num, tcp_active_sess_num, tcp_closing_sess_num,
0, 0, 0, // udp_opening_sess_num, udp_active_sess_num, udp_closing_sess_num,
0, 0, // tcp_overload_evict_new_sess_num, tcp_overload_evict_old_sess_num,
0, 0); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num,
}
}
printf("\n====================== evicted session ======================\n\n");
// evicted oldest session
sess = session_manager_get_evicted_session(mgr);
EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSING);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_EVICTED);
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
overwrite_ipv4_saddr(&pkt, 1); printf("<= Packet Parse: done\n\n");
memset(&key, 0, sizeof(struct tuple6));
packet_get_innermost_tuple6(&pkt, &key);
EXPECT_TRUE(tuple6_cmp(session_get0_key(sess), &key) == 0);
__session_dispatch(sess);
session_manager_print_stat(mgr);
printf("\n====================== expired session ======================\n\n"); // new session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); for (uint32_t i = 0; i < opts.max_tcp_session_num; i++)
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); {
packet_set_tcp_src_addr(&pkt, i);
printf("\n====================== end status ======================\n\n"); EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1));
}
printf("=> Session Manager: after add %lu new sessions\n", opts.max_tcp_session_num);
session_manager_print_stat(mgr); session_manager_print_stat(mgr);
__session_manager_check_counter(mgr, stat = session_manager_get_stat(mgr);
0, 0, 0, // tcp_opening_sess_num, tcp_active_sess_num, tcp_closing_sess_num, EXPECT_TRUE(stat);
0, 0, 0, // udp_opening_sess_num, udp_active_sess_num, udp_closing_sess_num, EXPECT_TRUE(stat->tcp_sess.nr_sess_used == opts.max_tcp_session_num);
0, 1, // tcp_overload_evict_new_sess_num, tcp_overload_evict_old_sess_num, EXPECT_TRUE(stat->tcp_sess.nr_sess_init == 0);
0, 0); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num, EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == RX_BURST_MAX);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closed == RX_BURST_MAX); // have evicted, have't free
EXPECT_TRUE(stat->tcp_sess.nr_new_sess_evicted == 0);
EXPECT_TRUE(stat->tcp_sess.nr_old_sess_evicted == RX_BURST_MAX);
EXPECT_TRUE(stat->evc_pkt.nr_pkts == 0);
EXPECT_TRUE(stat->evc_pkt.nr_bytes == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
#endif #endif
#if 1 #if 1
TEST(OVERLOAD, EVICT_TCP_NEW_SESS) TEST(TCP_OVERLOAD, EVICT_TCP_NEW_SESS)
{ {
struct packet pkt; struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
char buffer[1500] = {0}; struct session_manager_stat *stat = NULL;
struct session_manager_options _opts; struct session_manager_options _opts;
memcpy(&_opts, &opts, sizeof(struct session_manager_options)); memcpy(&_opts, &opts, sizeof(struct session_manager_options));
_opts.tcp_overload_evict_old_sess = 0; _opts.tcp_overload_evict_old_sess = 0;
timestamp_update(); mgr = session_manager_new(&_opts, 1);
mgr = session_manager_new(&_opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
for (uint64_t i = 0; i <= _opts.max_tcp_session_num; i++)
{
// C2S SYN Packet // C2S SYN Packet
printf("\n====================== new session (%lu) ======================\n\n", i + 1); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
printf("=> packet parse: TCP C2S SYN packet\n"); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
memcpy(buffer, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); printf("<= Packet Parse: done\n\n");
packet_parse(&pkt, (const char *)buffer, sizeof(tcp_pkt1_c2s_syn));
overwrite_ipv4_saddr(&pkt, i + 1);
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
if (i == _opts.max_tcp_session_num) // new session
for (uint32_t i = 0; i < opts.max_tcp_session_num; i++)
{ {
EXPECT_TRUE(sess == NULL); packet_set_tcp_src_addr(&pkt, i);
__session_manager_check_counter(mgr, EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1));
i, 0, 0, // tcp_opening_sess_num, tcp_active_sess_num, tcp_closing_sess_num,
0, 0, 0, // udp_opening_sess_num, udp_active_sess_num, udp_closing_sess_num,
1, 0, // tcp_overload_evict_new_sess_num, tcp_overload_evict_old_sess_num,
0, 0); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num,
} }
else printf("=> Session Manager: after add %lu new sessions\n", opts.max_tcp_session_num);
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == opts.max_tcp_session_num);
EXPECT_TRUE(stat->tcp_sess.nr_sess_init == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == opts.max_tcp_session_num);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closed == 0);
EXPECT_TRUE(stat->tcp_sess.nr_new_sess_evicted == 0);
EXPECT_TRUE(stat->tcp_sess.nr_old_sess_evicted == 0);
EXPECT_TRUE(stat->evc_pkt.nr_pkts == 0);
EXPECT_TRUE(stat->evc_pkt.nr_bytes == 0);
// table full, evict new session
for (uint32_t i = 0; i < RX_BURST_MAX; i++)
{ {
EXPECT_TRUE(sess); packet_set_tcp_src_addr(&pkt, opts.max_tcp_session_num + i);
__session_manager_check_counter(mgr, EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
i + 1, 0, 0, // tcp_opening_sess_num, tcp_active_sess_num, tcp_closing_sess_num, EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1) == NULL);
0, 0, 0, // udp_opening_sess_num, udp_active_sess_num, udp_closing_sess_num,
0, 0, // tcp_overload_evict_new_sess_num, tcp_overload_evict_old_sess_num,
0, 0); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num,
} }
printf("=> Session Manager: after evicte new session\n");
__session_dispatch(sess);
session_manager_print_stat(mgr); session_manager_print_stat(mgr);
} stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == opts.max_tcp_session_num);
EXPECT_TRUE(stat->tcp_sess.nr_sess_init == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == opts.max_tcp_session_num);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closed == 0);
EXPECT_TRUE(stat->tcp_sess.nr_new_sess_evicted == RX_BURST_MAX);
EXPECT_TRUE(stat->tcp_sess.nr_old_sess_evicted == 0);
EXPECT_TRUE(stat->evc_pkt.nr_pkts == RX_BURST_MAX);
EXPECT_TRUE(stat->evc_pkt.nr_bytes == RX_BURST_MAX * sizeof(tcp_pkt1_c2s_syn));
printf("\n====================== expired session ======================\n\n");
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
printf("\n====================== end status ======================\n\n");
session_manager_print_stat(mgr);
__session_manager_check_counter(mgr,
0, 0, 0, // tcp_opening_sess_num, tcp_active_sess_num, tcp_closing_sess_num,
0, 0, 0, // udp_opening_sess_num, udp_active_sess_num, udp_closing_sess_num,
1, 0, // tcp_overload_evict_new_sess_num, tcp_overload_evict_old_sess_num,
0, 0); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num,
session_manager_free(mgr); session_manager_free(mgr);
} }
#endif #endif

View File

@@ -1,150 +1,213 @@
#include "test_utils.h" #include <gtest/gtest.h>
static void overwrite_ipv4_saddr(struct packet *pkt, uint32_t saddr) #include "session.h"
#include "session_manager.h"
#include "stellar.h"
#include "ipv4_utils.h"
#include "test_packets.h"
struct session_manager_options opts = {
// max session number
.max_tcp_session_num = RX_BURST_MAX * 2,
.max_udp_session_num = RX_BURST_MAX * 2,
// 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,
};
static void packet_set_tcp_src_addr(struct packet *pkt, uint32_t addr)
{ {
const struct layer *ipv4_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_IPV4); const struct layer *ipv4_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer); EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_src_addr(hdr, saddr); ipv4_hdr_set_src_addr(hdr, addr);
} }
#if 1 #if 1
TEST(OVERLOAD, EVICT_UDP_OLD_SESS) TEST(UDP_OVERLOAD, EVICT_OLD_SESS)
{ {
struct tuple6 key;
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
char buffer[1500] = {0}; struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
for (uint64_t i = 0; i < opts.max_udp_session_num; i++)
{
// C2S REQ Packet // C2S REQ Packet
printf("\n====================== new session (%lu) ======================\n\n", i + 1); printf("\n=> Packet Parse: UDP C2S REQ packet\n");
printf("=> packet parse: UDP C2S REQ packet\n"); packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
memcpy(buffer, udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req)); printf("<= Packet Parse: done\n\n");
packet_parse(&pkt, (const char *)buffer, sizeof(udp_pkt1_dns_req));
overwrite_ipv4_saddr(&pkt, i + 1);
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
__session_dispatch(sess); // new session
session_manager_print_stat(mgr); for (uint32_t i = 0; i < opts.max_udp_session_num; i++)
if (i == opts.max_udp_session_num - 1)
{ {
__session_manager_check_counter(mgr, packet_set_tcp_src_addr(&pkt, i);
0, 0, 0, // tcp_opening_sess_num, tcp_active_sess_num, tcp_closing_sess_num, EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1));
i, 0, 1, // udp_opening_sess_num, udp_active_sess_num, udp_closing_sess_num, }
0, 0, // tcp_overload_evict_new_sess_num, tcp_overload_evict_old_sess_num, printf("=> Session Manager: after add %lu new sessions\n", opts.max_udp_session_num);
0, 1); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num, session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->udp_sess.nr_sess_used == opts.max_udp_session_num);
EXPECT_TRUE(stat->udp_sess.nr_sess_init == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_opening == RX_BURST_MAX);
EXPECT_TRUE(stat->udp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closing == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closed == RX_BURST_MAX); // have evicted, have't free
EXPECT_TRUE(stat->udp_sess.nr_new_sess_evicted == 0);
EXPECT_TRUE(stat->udp_sess.nr_old_sess_evicted == RX_BURST_MAX);
EXPECT_TRUE(stat->evc_pkt.nr_pkts == 0);
EXPECT_TRUE(stat->evc_pkt.nr_bytes == 0);
// evicted session
while (1)
{
sess = session_manager_get_evicted_session(mgr);
if (sess)
{
session_manager_free_session(mgr, sess);
} }
else else
{ {
__session_manager_check_counter(mgr, break;
0, 0, 0, // tcp_opening_sess_num, tcp_active_sess_num, tcp_closing_sess_num,
i + 1, 0, 0, // udp_opening_sess_num, udp_active_sess_num, udp_closing_sess_num,
0, 0, // tcp_overload_evict_new_sess_num, tcp_overload_evict_old_sess_num,
0, 0); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num,
} }
} }
printf("\n====================== evicted session ======================\n\n");
// evicted oldest session
sess = session_manager_get_evicted_session(mgr);
EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSING);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_EVICTED);
packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req)); for (uint32_t i = 0; i < RX_BURST_MAX; i++)
overwrite_ipv4_saddr(&pkt, 1); {
memset(&key, 0, sizeof(struct tuple6)); packet_set_tcp_src_addr(&pkt, i);
packet_get_innermost_tuple6(&pkt, &key); EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
EXPECT_TRUE(tuple6_cmp(session_get0_key(sess), &key) == 0); EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1) == NULL); // hit evicted session, can't renew session
__session_dispatch(sess); }
printf("=> Session Manager: after readd %d evicted sessions\n", RX_BURST_MAX);
session_manager_print_stat(mgr); session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->udp_sess.nr_sess_used == RX_BURST_MAX);
EXPECT_TRUE(stat->udp_sess.nr_sess_init == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_opening == RX_BURST_MAX);
EXPECT_TRUE(stat->udp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closing == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closed == 0);
EXPECT_TRUE(stat->udp_sess.nr_new_sess_evicted == 0);
EXPECT_TRUE(stat->udp_sess.nr_old_sess_evicted == RX_BURST_MAX);
EXPECT_TRUE(stat->evc_pkt.nr_pkts == RX_BURST_MAX);
EXPECT_TRUE(stat->evc_pkt.nr_bytes == RX_BURST_MAX * sizeof(udp_pkt1_dns_req));
printf("\n====================== expired session ======================\n\n"); // evicted session timeout
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); packet_set_tcp_src_addr(&pkt, 0);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1 + opts.evicted_session_filter_timeout));
printf("\n====================== end status ======================\n\n"); printf("=> Session Manager: after evicted session timeout\n");
session_manager_print_stat(mgr); session_manager_print_stat(mgr);
__session_manager_check_counter(mgr, stat = session_manager_get_stat(mgr);
0, 0, 0, // tcp_opening_sess_num, tcp_active_sess_num, tcp_closing_sess_num, EXPECT_TRUE(stat);
0, 0, 0, // udp_opening_sess_num, udp_active_sess_num, udp_closing_sess_num, EXPECT_TRUE(stat->udp_sess.nr_sess_used == RX_BURST_MAX + 1);
0, 0, // tcp_overload_evict_new_sess_num, tcp_overload_evict_old_sess_num, EXPECT_TRUE(stat->udp_sess.nr_sess_init == 0);
0, 1); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num, EXPECT_TRUE(stat->udp_sess.nr_sess_opening == RX_BURST_MAX);
EXPECT_TRUE(stat->udp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closing == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closed == 1); // have evicted, have't free
EXPECT_TRUE(stat->udp_sess.nr_new_sess_evicted == 0);
EXPECT_TRUE(stat->udp_sess.nr_old_sess_evicted == RX_BURST_MAX + 1);
EXPECT_TRUE(stat->evc_pkt.nr_pkts == RX_BURST_MAX);
EXPECT_TRUE(stat->evc_pkt.nr_bytes == RX_BURST_MAX * sizeof(udp_pkt1_dns_req));
session_manager_free(mgr); session_manager_free(mgr);
} }
#endif #endif
#if 1 #if 1
TEST(OVERLOAD, EVICT_UDP_NEW_SESS) TEST(UDP_OVERLOAD, EVICT_NEW_SESS)
{ {
struct packet pkt; struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
char buffer[1500] = {0}; struct session_manager_stat *stat = NULL;
struct session_manager_options _opts; struct session_manager_options _opts;
memcpy(&_opts, &opts, sizeof(struct session_manager_options)); memcpy(&_opts, &opts, sizeof(struct session_manager_options));
_opts.udp_overload_evict_old_sess = 0; _opts.udp_overload_evict_old_sess = 0;
timestamp_update(); mgr = session_manager_new(&_opts, 1);
mgr = session_manager_new(&_opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
for (uint64_t i = 0; i <= _opts.max_udp_session_num; i++)
{
// C2S REQ Packet // C2S REQ Packet
printf("\n====================== new session (%lu) ======================\n\n", i + 1); printf("\n=> Packet Parse: UDP C2S REQ packet\n");
printf("=> packet parse: UDP C2S REQ packet\n"); packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
memcpy(buffer, udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req)); printf("<= Packet Parse: done\n\n");
packet_parse(&pkt, (const char *)buffer, sizeof(udp_pkt1_dns_req));
overwrite_ipv4_saddr(&pkt, i + 1);
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
if (i == _opts.max_udp_session_num) // new session
for (uint32_t i = 0; i < opts.max_udp_session_num; i++)
{ {
EXPECT_TRUE(sess == NULL); packet_set_tcp_src_addr(&pkt, i);
__session_manager_check_counter(mgr, EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1));
0, 0, 0, // tcp_opening_sess_num, tcp_active_sess_num, tcp_closing_sess_num,
i, 0, 0, // udp_opening_sess_num, udp_active_sess_num, udp_closing_sess_num,
0, 0, // tcp_overload_evict_new_sess_num, tcp_overload_evict_old_sess_num,
1, 0); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num,
} }
else printf("=> Session Manager: after add %lu new sessions\n", opts.max_udp_session_num);
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->udp_sess.nr_sess_used == opts.max_udp_session_num);
EXPECT_TRUE(stat->udp_sess.nr_sess_init == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_opening == opts.max_udp_session_num);
EXPECT_TRUE(stat->udp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closing == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closed == 0);
EXPECT_TRUE(stat->udp_sess.nr_new_sess_evicted == 0);
EXPECT_TRUE(stat->udp_sess.nr_old_sess_evicted == 0);
EXPECT_TRUE(stat->evc_pkt.nr_pkts == 0);
EXPECT_TRUE(stat->evc_pkt.nr_bytes == 0);
// evicted session
EXPECT_TRUE(session_manager_get_evicted_session(mgr) == NULL);
// table full, evict new session
for (uint32_t i = 0; i < RX_BURST_MAX; i++)
{ {
EXPECT_TRUE(sess); packet_set_tcp_src_addr(&pkt, opts.max_udp_session_num + i);
__session_manager_check_counter(mgr, EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
0, 0, 0, // tcp_opening_sess_num, tcp_active_sess_num, tcp_closing_sess_num, EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1) == NULL);
i + 1, 0, 0, // udp_opening_sess_num, udp_active_sess_num, udp_closing_sess_num,
0, 0, // tcp_overload_evict_new_sess_num, tcp_overload_evict_old_sess_num,
0, 0); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num,
} }
printf("=> Session Manager: after readd %d evicted session\n", RX_BURST_MAX);
__session_dispatch(sess);
session_manager_print_stat(mgr); session_manager_print_stat(mgr);
} stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->udp_sess.nr_sess_used == opts.max_udp_session_num);
EXPECT_TRUE(stat->udp_sess.nr_sess_init == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_opening == opts.max_udp_session_num);
EXPECT_TRUE(stat->udp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closing == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closed == 0);
EXPECT_TRUE(stat->udp_sess.nr_new_sess_evicted == RX_BURST_MAX);
EXPECT_TRUE(stat->udp_sess.nr_old_sess_evicted == 0);
EXPECT_TRUE(stat->evc_pkt.nr_pkts == RX_BURST_MAX);
EXPECT_TRUE(stat->evc_pkt.nr_bytes == RX_BURST_MAX * sizeof(udp_pkt1_dns_req));
printf("\n====================== expired session ======================\n\n");
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
printf("\n====================== end status ======================\n\n");
session_manager_print_stat(mgr);
__session_manager_check_counter(mgr,
0, 0, 0, // tcp_opening_sess_num, tcp_active_sess_num, tcp_closing_sess_num,
0, 0, 0, // udp_opening_sess_num, udp_active_sess_num, udp_closing_sess_num,
0, 0, // tcp_overload_evict_new_sess_num, tcp_overload_evict_old_sess_num,
1, 0); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num,
session_manager_free(mgr); session_manager_free(mgr);
} }
#endif #endif

View File

@@ -89,37 +89,37 @@ TEST(SESSION_TABLE, OP_SESSION)
session_set_id(sess3, 3); session_set_id(sess3, 3);
session_set_key(sess3, &tuple_3); session_set_key(sess3, &tuple_3);
EXPECT_TRUE(session_table_add_session(sess_table, &tuple_1, sess1) == 0); EXPECT_TRUE(session_table_add(sess_table, &tuple_1, sess1) == 0);
EXPECT_TRUE(session_table_get_count(sess_table) == 1); EXPECT_TRUE(session_table_get_count(sess_table) == 1);
EXPECT_TRUE(session_table_add_session(sess_table, &tuple_2, sess2) == 0); EXPECT_TRUE(session_table_add(sess_table, &tuple_2, sess2) == 0);
EXPECT_TRUE(session_table_get_count(sess_table) == 2); EXPECT_TRUE(session_table_get_count(sess_table) == 2);
EXPECT_TRUE(session_table_add_session(sess_table, &tuple_3, sess3) == 0); EXPECT_TRUE(session_table_add(sess_table, &tuple_3, sess3) == 0);
EXPECT_TRUE(session_table_get_count(sess_table) == 3); EXPECT_TRUE(session_table_get_count(sess_table) == 3);
// Search // Search
EXPECT_TRUE(session_table_find_session(sess_table, &tuple_1) == sess1); EXPECT_TRUE(session_table_find_tuple(sess_table, &tuple_1) == sess1);
EXPECT_TRUE(session_table_find_session(sess_table, &tuple_2) == sess2); EXPECT_TRUE(session_table_find_tuple(sess_table, &tuple_2) == sess2);
EXPECT_TRUE(session_table_find_session(sess_table, &tuple_3) == sess3); EXPECT_TRUE(session_table_find_tuple(sess_table, &tuple_3) == sess3);
EXPECT_TRUE(session_table_find_session(sess_table, &reversed_tuple_1) == sess1); EXPECT_TRUE(session_table_find_tuple(sess_table, &reversed_tuple_1) == sess1);
EXPECT_TRUE(session_table_find_session(sess_table, &reversed_tuple_2) == sess2); EXPECT_TRUE(session_table_find_tuple(sess_table, &reversed_tuple_2) == sess2);
EXPECT_TRUE(session_table_find_session(sess_table, &reversed_tuple_3) == sess3); EXPECT_TRUE(session_table_find_tuple(sess_table, &reversed_tuple_3) == sess3);
// Delete // Delete
session_table_del_session(sess_table, &tuple_1); session_table_del(sess_table, &tuple_1);
EXPECT_TRUE(session_table_get_count(sess_table) == 2); EXPECT_TRUE(session_table_get_count(sess_table) == 2);
EXPECT_TRUE(session_table_find_session(sess_table, &tuple_1) == NULL); EXPECT_TRUE(session_table_find_tuple(sess_table, &tuple_1) == NULL);
EXPECT_TRUE(session_table_find_session(sess_table, &reversed_tuple_1) == NULL); EXPECT_TRUE(session_table_find_tuple(sess_table, &reversed_tuple_1) == NULL);
session_table_del_session(sess_table, &reversed_tuple_2); session_table_del(sess_table, &reversed_tuple_2);
EXPECT_TRUE(session_table_get_count(sess_table) == 1); EXPECT_TRUE(session_table_get_count(sess_table) == 1);
EXPECT_TRUE(session_table_find_session(sess_table, &tuple_2) == NULL); EXPECT_TRUE(session_table_find_tuple(sess_table, &tuple_2) == NULL);
EXPECT_TRUE(session_table_find_session(sess_table, &reversed_tuple_2) == NULL); EXPECT_TRUE(session_table_find_tuple(sess_table, &reversed_tuple_2) == NULL);
session_table_del_session(sess_table, &tuple_3); session_table_del(sess_table, &tuple_3);
EXPECT_TRUE(session_table_get_count(sess_table) == 0); EXPECT_TRUE(session_table_get_count(sess_table) == 0);
EXPECT_TRUE(session_table_find_session(sess_table, &tuple_3) == NULL); EXPECT_TRUE(session_table_find_tuple(sess_table, &tuple_3) == NULL);
EXPECT_TRUE(session_table_find_session(sess_table, &reversed_tuple_3) == NULL); EXPECT_TRUE(session_table_find_tuple(sess_table, &reversed_tuple_3) == NULL);
// Destroy // Destroy
session_table_free(sess_table); session_table_free(sess_table);
@@ -147,46 +147,46 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
// Add Session // Add Session
EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == NULL); EXPECT_TRUE(session_table_find_lru(sess_table) == NULL);
EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == NULL); EXPECT_TRUE(session_table_find_mru(sess_table) == NULL);
sess1 = session_pool_pop(sess_pool); sess1 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess1 != NULL); EXPECT_TRUE(sess1 != NULL);
session_set_id(sess1, 1); session_set_id(sess1, 1);
session_set_key(sess1, &tuple_1); session_set_key(sess1, &tuple_1);
EXPECT_TRUE(session_table_add_session(sess_table, &tuple_1, sess1) == 0); EXPECT_TRUE(session_table_add(sess_table, &tuple_1, sess1) == 0);
EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == sess1); EXPECT_TRUE(session_table_find_lru(sess_table) == sess1);
EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == sess1); EXPECT_TRUE(session_table_find_mru(sess_table) == sess1);
sess2 = session_pool_pop(sess_pool); sess2 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess2 != NULL); EXPECT_TRUE(sess2 != NULL);
session_set_id(sess2, 2); session_set_id(sess2, 2);
session_set_key(sess2, &tuple_2); session_set_key(sess2, &tuple_2);
EXPECT_TRUE(session_table_add_session(sess_table, &tuple_2, sess2) == 0); EXPECT_TRUE(session_table_add(sess_table, &tuple_2, sess2) == 0);
EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == sess1); EXPECT_TRUE(session_table_find_lru(sess_table) == sess1);
EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == sess2); EXPECT_TRUE(session_table_find_mru(sess_table) == sess2);
sess3 = session_pool_pop(sess_pool); sess3 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess3 != NULL); EXPECT_TRUE(sess3 != NULL);
session_set_id(sess3, 3); session_set_id(sess3, 3);
session_set_key(sess3, &tuple_3); session_set_key(sess3, &tuple_3);
EXPECT_TRUE(session_table_add_session(sess_table, &tuple_3, sess3) == 0); EXPECT_TRUE(session_table_add(sess_table, &tuple_3, sess3) == 0);
EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == sess1); EXPECT_TRUE(session_table_find_lru(sess_table) == sess1);
EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == sess3); EXPECT_TRUE(session_table_find_mru(sess_table) == sess3);
// Delete Session // Delete Session
session_table_del_session(sess_table, &tuple_1); session_table_del(sess_table, &tuple_1);
EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == sess2); EXPECT_TRUE(session_table_find_lru(sess_table) == sess2);
EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == sess3); EXPECT_TRUE(session_table_find_mru(sess_table) == sess3);
session_table_del_session(sess_table, &tuple_2); session_table_del(sess_table, &tuple_2);
EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == sess3); EXPECT_TRUE(session_table_find_lru(sess_table) == sess3);
EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == sess3); EXPECT_TRUE(session_table_find_mru(sess_table) == sess3);
session_table_del_session(sess_table, &tuple_3); session_table_del(sess_table, &tuple_3);
EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == NULL); EXPECT_TRUE(session_table_find_lru(sess_table) == NULL);
EXPECT_TRUE(session_table_find_least_recently_used_session(sess_table) == NULL); EXPECT_TRUE(session_table_find_mru(sess_table) == NULL);
// Destroy // Destroy
session_table_free(sess_table); session_table_free(sess_table);

View File

@@ -18,8 +18,8 @@ TEST(SESSION_TIMER, ADD_DEL)
session_set_id(&sess, 1); session_set_id(&sess, 1);
session_set_expirecb(&sess, session_expire, NULL, 1000); session_set_expirecb(&sess, session_expire, NULL, 1000);
session_timer_add_session(timer, &sess); session_timer_add(timer, &sess);
session_timer_del_session(timer, &sess); session_timer_del(timer, &sess);
session_timer_free(timer); session_timer_free(timer);
} }
@@ -43,16 +43,16 @@ TEST(SESSION_TIMER, EXPIRE)
session_set_expirecb(&sess2, session_expire, NULL, 5); session_set_expirecb(&sess2, session_expire, NULL, 5);
session_set_expirecb(&sess3, session_expire, NULL, 10); session_set_expirecb(&sess3, session_expire, NULL, 10);
session_timer_add_session(timer, &sess1); session_timer_add(timer, &sess1);
session_timer_add_session(timer, &sess2); session_timer_add(timer, &sess2);
session_timer_add_session(timer, &sess3); session_timer_add(timer, &sess3);
for (uint64_t abs_current_ts = 0; abs_current_ts < 15; abs_current_ts++) for (uint64_t abs_current_ts = 0; abs_current_ts < 15; abs_current_ts++)
{ {
printf("current timestamp %lu\n", abs_current_ts); printf("current timestamp %lu\n", abs_current_ts);
do do
{ {
sess = session_timer_expire_session(timer, abs_current_ts); sess = session_timer_expire(timer, abs_current_ts);
if (sess != NULL) if (sess != NULL)
{ {
session_run_expirecb(sess); session_run_expirecb(sess);
@@ -82,9 +82,9 @@ TEST(SESSION_TIMER, BEFORE_EXPIRE_DEL)
session_set_expirecb(&sess2, session_expire, NULL, 5); session_set_expirecb(&sess2, session_expire, NULL, 5);
session_set_expirecb(&sess3, session_expire, NULL, 10); session_set_expirecb(&sess3, session_expire, NULL, 10);
session_timer_add_session(timer, &sess1); session_timer_add(timer, &sess1);
session_timer_add_session(timer, &sess2); session_timer_add(timer, &sess2);
session_timer_add_session(timer, &sess3); session_timer_add(timer, &sess3);
for (uint64_t abs_current_ts = 0; abs_current_ts < 15; abs_current_ts++) for (uint64_t abs_current_ts = 0; abs_current_ts < 15; abs_current_ts++)
{ {
@@ -92,11 +92,11 @@ TEST(SESSION_TIMER, BEFORE_EXPIRE_DEL)
if (abs_current_ts == 2) if (abs_current_ts == 2)
{ {
printf("delete timer 2\n"); printf("delete timer 2\n");
session_timer_del_session(timer, &sess2); session_timer_del(timer, &sess2);
} }
do do
{ {
sess = session_timer_expire_session(timer, abs_current_ts); sess = session_timer_expire(timer, abs_current_ts);
if (sess != NULL) if (sess != NULL)
{ {
session_run_expirecb(sess); session_run_expirecb(sess);
@@ -126,9 +126,9 @@ TEST(SESSION_TIMER, BEFORE_EXPIRE_UPDATE)
session_set_expirecb(&sess2, session_expire, NULL, 5); session_set_expirecb(&sess2, session_expire, NULL, 5);
session_set_expirecb(&sess3, session_expire, NULL, 10); session_set_expirecb(&sess3, session_expire, NULL, 10);
session_timer_add_session(timer, &sess1); session_timer_add(timer, &sess1);
session_timer_add_session(timer, &sess2); session_timer_add(timer, &sess2);
session_timer_add_session(timer, &sess3); session_timer_add(timer, &sess3);
for (uint64_t abs_current_ts = 0; abs_current_ts < 15; abs_current_ts++) for (uint64_t abs_current_ts = 0; abs_current_ts < 15; abs_current_ts++)
{ {
@@ -136,13 +136,13 @@ TEST(SESSION_TIMER, BEFORE_EXPIRE_UPDATE)
if (abs_current_ts == 2) if (abs_current_ts == 2)
{ {
printf("update timer 2\n"); printf("update timer 2\n");
session_timer_del_session(timer, &sess2); session_timer_del(timer, &sess2);
session_set_expirecb(&sess2, session_expire, NULL, 8); session_set_expirecb(&sess2, session_expire, NULL, 8);
session_timer_add_session(timer, &sess2); session_timer_add(timer, &sess2);
} }
do do
{ {
sess = session_timer_expire_session(timer, abs_current_ts); sess = session_timer_expire(timer, abs_current_ts);
if (sess != NULL) if (sess != NULL)
{ {
session_run_expirecb(sess); session_run_expirecb(sess);
@@ -169,26 +169,26 @@ TEST(SESSION_TIMER, NEXT_EXPIRE_INTERVAL)
EXPECT_TRUE(session_timer_next_expire_interval(timer) == UINT64_MAX); EXPECT_TRUE(session_timer_next_expire_interval(timer) == UINT64_MAX);
session_timer_add_session(timer, &sess1); session_timer_add(timer, &sess1);
session_timer_add_session(timer, &sess2); session_timer_add(timer, &sess2);
EXPECT_TRUE(session_timer_next_expire_interval(timer) < UINT64_MAX); EXPECT_TRUE(session_timer_next_expire_interval(timer) < UINT64_MAX);
EXPECT_TRUE(session_timer_expire_session(timer, 900) == NULL); EXPECT_TRUE(session_timer_expire(timer, 900) == NULL);
EXPECT_TRUE(session_timer_next_expire_interval(timer) <= 1000 - 900); EXPECT_TRUE(session_timer_next_expire_interval(timer) <= 1000 - 900);
EXPECT_TRUE(session_timer_expire_session(timer, 950) == NULL); EXPECT_TRUE(session_timer_expire(timer, 950) == NULL);
EXPECT_TRUE(session_timer_next_expire_interval(timer) <= 1000 - 950); EXPECT_TRUE(session_timer_next_expire_interval(timer) <= 1000 - 950);
EXPECT_TRUE(session_timer_expire_session(timer, 980) == NULL); EXPECT_TRUE(session_timer_expire(timer, 980) == NULL);
EXPECT_TRUE(session_timer_next_expire_interval(timer) <= 1000 - 980); EXPECT_TRUE(session_timer_next_expire_interval(timer) <= 1000 - 980);
EXPECT_TRUE(session_timer_expire_session(timer, 990) == NULL); EXPECT_TRUE(session_timer_expire(timer, 990) == NULL);
EXPECT_TRUE(session_timer_next_expire_interval(timer) <= 1000 - 990); EXPECT_TRUE(session_timer_next_expire_interval(timer) <= 1000 - 990);
EXPECT_TRUE(session_timer_expire_session(timer, 1010)); EXPECT_TRUE(session_timer_expire(timer, 1010));
EXPECT_TRUE(session_timer_next_expire_interval(timer) == 0); EXPECT_TRUE(session_timer_next_expire_interval(timer) == 0);
EXPECT_TRUE(session_timer_expire_session(timer, 1010)); EXPECT_TRUE(session_timer_expire(timer, 1010));
EXPECT_TRUE(session_timer_next_expire_interval(timer) == UINT64_MAX); EXPECT_TRUE(session_timer_next_expire_interval(timer) == UINT64_MAX);
session_timer_free(timer); session_timer_free(timer);

View File

@@ -1,80 +1,70 @@
// TCP state machine test: active -> closing // TCP state machine test: active -> closing
#include <gtest/gtest.h>
#include "test_utils.h" #include "session.h"
#include "session_manager.h"
#include "tcp_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,
};
static void build_active_tcp_session(struct session_manager *mgr, struct session *sess) static void build_active_tcp_session(struct session_manager *mgr, struct session *sess)
{ {
char buffer[1024] = {0};
struct packet pkt; struct packet pkt;
// C2S SYN Packet // C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n"); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == 0);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 78);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYN_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// C2S DATA Packet // C2S DATA Packet
printf("=> packet parse: TCP C2S DATA packet\n"); printf("\n=> Packet Parse: TCP C2S DATA packet\n");
packet_parse(&pkt, (const char *)tcp_pkt4_c2s_http_req, sizeof(tcp_pkt4_c2s_http_req)); packet_parse(&pkt, (const char *)tcp_pkt4_c2s_http_req, sizeof(tcp_pkt4_c2s_http_req));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_ACTIVE);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == 0);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 78 + 145);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_DATA_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
} }
/****************************************************************************** /******************************************************************************
@@ -88,55 +78,35 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_FIN_FIN)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet & C2S DATA Packet // C2S SYN Packet & C2S DATA Packet
build_active_tcp_session(mgr, sess); build_active_tcp_session(mgr, sess);
// C2S FIN Packet // C2S FIN Packet
printf("=> packet parse: TCP C2S FIN packet\n"); printf("\n=> Packet Parse: TCP C2S FIN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin)); packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_ACTIVE);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_FIN);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 78 + 145 + 66);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_C2S_FIN_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// S2C FIN Packet // S2C FIN Packet
printf("=> packet parse: TCP S2C FIN packet\n"); printf("\n=> Packet Parse: TCP S2C FIN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin)); packet_parse(&pkt, (const char *)tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -150,19 +120,40 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_FIN_FIN)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 66); EXPECT_TRUE(session_get_s2c_bytes(sess) == 66);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 3);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_S2C_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_C2S_FIN_RECVED | TCP_S2C_FIN_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 1);
__session_manager_check_counter(mgr, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_CLIENT_FIN); sess = session_manager_get_expired_session(mgr, 3 + opts.tcp_timeout_time_wait);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_FIN);
session_dump(sess);
// free session
session_manager_free_session(mgr, sess);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -179,17 +170,16 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_C2S_RST)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet & C2S DATA Packet // C2S SYN Packet & C2S DATA Packet
build_active_tcp_session(mgr, sess); build_active_tcp_session(mgr, sess);
// C2S RST Packet // C2S RST Packet
printf("=> packet parse: TCP C2S RST packet\n"); printf("\n=> Packet Parse: TCP C2S RST packet\n");
char tcp_pkt_c2s_rst[1500] = {0}; char tcp_pkt_c2s_rst[1500] = {0};
memcpy(tcp_pkt_c2s_rst, tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin)); memcpy(tcp_pkt_c2s_rst, tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin));
packet_parse(&pkt, (const char *)tcp_pkt_c2s_rst, sizeof(tcp_pkt9_c2s_fin)); packet_parse(&pkt, (const char *)tcp_pkt_c2s_rst, sizeof(tcp_pkt9_c2s_fin));
@@ -198,9 +188,13 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_C2S_RST)
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr; struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
tcp_hdr_set_flags(hdr, 0); tcp_hdr_set_flags(hdr, 0);
tcp_hdr_set_rst_flag(hdr, true); tcp_hdr_set_rst_flag(hdr, true);
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -214,19 +208,40 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_C2S_RST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0); EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 3);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_C2S_RST_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 1);
__session_manager_check_counter(mgr, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_CLIENT_RST); sess = session_manager_get_expired_session(mgr, 3 + opts.tcp_timeout_time_wait);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_RST);
session_dump(sess);
// free session
session_manager_free_session(mgr, sess);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -243,17 +258,16 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_S2C_RST)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet & C2S DATA Packet // C2S SYN Packet & C2S DATA Packet
build_active_tcp_session(mgr, sess); build_active_tcp_session(mgr, sess);
// S2C RST Packet // S2C RST Packet
printf("=> packet parse: TCP S2C RST packet\n"); printf("\n=> Packet Parse: TCP S2C RST packet\n");
char tcp_pkt_s2c_rst[1500] = {0}; char tcp_pkt_s2c_rst[1500] = {0};
memcpy(tcp_pkt_s2c_rst, tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin)); memcpy(tcp_pkt_s2c_rst, tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin));
packet_parse(&pkt, (const char *)tcp_pkt_s2c_rst, sizeof(tcp_pkt10_s2c_fin)); packet_parse(&pkt, (const char *)tcp_pkt_s2c_rst, sizeof(tcp_pkt10_s2c_fin));
@@ -262,9 +276,13 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_S2C_RST)
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr; struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
tcp_hdr_set_flags(hdr, 0); tcp_hdr_set_flags(hdr, 0);
tcp_hdr_set_rst_flag(hdr, true); tcp_hdr_set_rst_flag(hdr, true);
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -278,19 +296,40 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_S2C_RST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 66); EXPECT_TRUE(session_get_s2c_bytes(sess) == 66);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 3);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_S2C_RST_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 1);
__session_manager_check_counter(mgr, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_SERVER_RST); sess = session_manager_get_expired_session(mgr, 3 + opts.tcp_timeout_time_wait);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_SERVER_RST);
session_dump(sess);
// free session
session_manager_free_session(mgr, sess);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -305,18 +344,41 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_DATA_TIMEOUT)
{ {
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet & C2S DATA Packet // C2S SYN Packet & C2S DATA Packet
build_active_tcp_session(mgr, sess); build_active_tcp_session(mgr, sess);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0); // check stat
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); session_manager_print_stat(mgr);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_data) == NULL);
sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_data + opts.tcp_timeout_time_wait);
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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -333,27 +395,30 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_C2S_HALF_CLOSED_TIMEOUT)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet & C2S DATA Packet // C2S SYN Packet & C2S DATA Packet
build_active_tcp_session(mgr, sess); build_active_tcp_session(mgr, sess);
// C2S FIN Packet // C2S FIN Packet
printf("=> packet parse: TCP C2S FIN packet\n"); printf("\n=> Packet Parse: TCP C2S FIN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin)); packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_ACTIVE); EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP); EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_FIN); EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_FIN);
@@ -361,19 +426,40 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_C2S_HALF_CLOSED_TIMEOUT)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0); EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 3);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_C2S_FIN_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 1);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_CLIENT_FIN); sess = session_manager_get_expired_session(mgr, 3 + opts.tcp_timeout_time_wait);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_FIN);
session_dump(sess);
// free session
session_manager_free_session(mgr, sess);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -390,27 +476,30 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_S2C_HALF_CLOSED_TIMEOUT)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet & C2S DATA Packet // C2S SYN Packet & C2S DATA Packet
build_active_tcp_session(mgr, sess); build_active_tcp_session(mgr, sess);
// S2C FIN Packet // S2C FIN Packet
printf("=> packet parse: TCP S2C FIN packet\n"); printf("\n=> Packet Parse: TCP S2C FIN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin)); packet_parse(&pkt, (const char *)tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_ACTIVE); EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP); EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_SERVER_FIN); EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_SERVER_FIN);
@@ -418,19 +507,40 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_S2C_HALF_CLOSED_TIMEOUT)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 66); EXPECT_TRUE(session_get_s2c_bytes(sess) == 66);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 3);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_S2C_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_S2C_FIN_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 1);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_SERVER_FIN); sess = session_manager_get_expired_session(mgr, 3 + opts.tcp_timeout_time_wait);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_SERVER_FIN);
session_dump(sess);
// free session
session_manager_free_session(mgr, sess);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }

View File

@@ -1,6 +1,44 @@
// TCP state machine test: init -> opening // TCP state machine test: init -> opening
#include <gtest/gtest.h>
#include "test_utils.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,
};
/****************************************************************************** /******************************************************************************
* case: TCP init -> opening (by SYN) * case: TCP init -> opening (by SYN)
@@ -13,17 +51,20 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n"); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
@@ -38,20 +79,42 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0); EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 1);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYN_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess)); EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 1 + opts.tcp_timeout_init) == NULL); // opening -> closing
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 1 + opts.tcp_timeout_init + 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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -68,17 +131,20 @@ TEST(TCP_INIT_TO_OPENING, BY_SYNACK)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// SYNACK Packet // S2C SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
@@ -93,20 +159,42 @@ TEST(TCP_INIT_TO_OPENING, BY_SYNACK)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 0); EXPECT_TRUE(session_get_c2s_packets(sess) == 0);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 1);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYNACK_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_s2c_1st_pkt(sess)); EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_s2c_1st_pkt(sess));
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 1 + opts.tcp_timeout_handshake) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 1 + opts.tcp_timeout_handshake + opts.tcp_timeout_time_wait);
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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -123,53 +211,32 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_SYNACK)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n"); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0); // S2C SYNACK Packet
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); printf("\n=> Packet Parse: TCP S2C SYNACK packet\n");
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == 0);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 78);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYN_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -183,20 +250,42 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_SYNACK)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess)); EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_handshake) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_handshake + opts.tcp_timeout_time_wait);
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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -213,88 +302,43 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_SYNACK_ACK)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n"); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0); // S2C SYNACK Packet
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); printf("\n=> Packet Parse: TCP S2C SYNACK packet\n");
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == 0);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 78);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYN_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); // C2S ACK Packet
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); printf("\n=> Packet Parse: TCP C2S ACK packet\n");
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == 0);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 78);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// ACK Packet
printf("=> packet parse: TCP C2S ACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt3_c2s_ack, sizeof(tcp_pkt3_c2s_ack)); packet_parse(&pkt, (const char *)tcp_pkt3_c2s_ack, sizeof(tcp_pkt3_c2s_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -308,19 +352,41 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_SYNACK_ACK)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 3);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED | TCP_C2S_ACK_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 3 + opts.tcp_timeout_data) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 3 + opts.tcp_timeout_data + opts.tcp_timeout_time_wait);
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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -339,59 +405,37 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_RETRANSMISSION)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n"); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == 0);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 78);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYN_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// C2S SYN Packet retransmission // C2S SYN Packet retransmission
printf("=> packet parse: TCP C2S SYN retransmission packet\n"); printf("\n=> Packet Parse: TCP C2S SYN retransmission packet\n");
char tcp_pkt_c2s_syn_retransmission[1500] = {0}; char syn_retransmission[1500] = {0};
memcpy(tcp_pkt_c2s_syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); memcpy(syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
packet_parse(&pkt, (const char *)tcp_pkt_c2s_syn_retransmission, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
const struct layer *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4); const struct layer *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234); ipv4_hdr_set_ipid(hdr, 0x1234);
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -405,20 +449,42 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_RETRANSMISSION)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0); EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYN_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess)); EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_init) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_init + opts.tcp_timeout_time_wait);
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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -437,49 +503,24 @@ TEST(TCP_INIT_TO_OPENING, BY_SYNACK_RETRANSMISSION)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// SYNACK Packet // S2C SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "93.184.216.34:80 -> 192.168.38.105:60111, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == 0);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 0);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 0);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYNACK_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_s2c_1st_pkt(sess));
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// SYNACK Packet retransmission // SYNACK Packet retransmission
printf("=> packet parse: TCP S2C SYNACK retransmission packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK retransmission packet\n");
char tcp_pkt_s2c_synack_retransmission[1500] = {0}; char tcp_pkt_s2c_synack_retransmission[1500] = {0};
memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack));
@@ -487,9 +528,13 @@ TEST(TCP_INIT_TO_OPENING, BY_SYNACK_RETRANSMISSION)
EXPECT_TRUE(ipv4_layer); EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234); ipv4_hdr_set_ipid(hdr, 0x1234);
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -503,20 +548,42 @@ TEST(TCP_INIT_TO_OPENING, BY_SYNACK_RETRANSMISSION)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 74); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 0); EXPECT_TRUE(session_get_c2s_packets(sess) == 0);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYNACK_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_s2c_1st_pkt(sess)); EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_s2c_1st_pkt(sess));
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_handshake) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_handshake + opts.tcp_timeout_time_wait);
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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -533,53 +600,32 @@ TEST(TCP_INIT_TO_OPENING, BY_C2S_ASMMETRIC)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n"); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0); // C2S ACK Packet
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); printf("\n=> Packet Parse: TCP C2S ACK packet\n");
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == 0);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 78);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYN_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// ACK Packet
printf("=> packet parse: TCP C2S ACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt3_c2s_ack, sizeof(tcp_pkt3_c2s_ack)); packet_parse(&pkt, (const char *)tcp_pkt3_c2s_ack, sizeof(tcp_pkt3_c2s_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -593,20 +639,42 @@ TEST(TCP_INIT_TO_OPENING, BY_C2S_ASMMETRIC)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0); EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess)); EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_data) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_data + opts.tcp_timeout_time_wait);
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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -623,53 +691,32 @@ TEST(TCP_INIT_TO_OPENING, BY_S2C_ASMMETRIC)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// SYNACK Packet // S2C SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0); // S2C ACK Packet
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); printf("\n=> Packet Parse: TCP S2C ACK packet\n");
EXPECT_STREQ(buffer, "93.184.216.34:80 -> 192.168.38.105:60111, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == 0);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 0);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 0);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYNACK_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_s2c_1st_pkt(sess));
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// ACK Packet
printf("=> packet parse: TCP S2C ACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt5_s2c_ack, sizeof(tcp_pkt5_s2c_ack)); packet_parse(&pkt, (const char *)tcp_pkt5_s2c_ack, sizeof(tcp_pkt5_s2c_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -683,20 +730,42 @@ TEST(TCP_INIT_TO_OPENING, BY_S2C_ASMMETRIC)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66);
EXPECT_TRUE(session_get_c2s_packets(sess) == 0); EXPECT_TRUE(session_get_c2s_packets(sess) == 0);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYNACK_RECVED | TCP_S2C_ACK_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_s2c_1st_pkt(sess)); EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_s2c_1st_pkt(sess));
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_data) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_data + opts.tcp_timeout_time_wait);
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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }

View File

@@ -1,6 +1,43 @@
// TCP state machine test: init -> opening -> active -> closing -> closed // TCP state machine test: init -> opening -> active -> closing -> closed
#include <gtest/gtest.h>
#include "test_utils.h" #include "session.h"
#include "session_manager.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,
};
#if 1 #if 1
TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST) TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST)
@@ -9,17 +46,20 @@ TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n"); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
@@ -35,28 +75,23 @@ TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0); EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 1);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYN_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// S2C SYNACK Packet // S2C SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
@@ -71,27 +106,23 @@ TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// C2S ACK Packet // C2S ACK Packet
printf("=> packet parse: TCP C2S ACK packet\n"); printf("\n=> Packet Parse: TCP C2S ACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt3_c2s_ack, sizeof(tcp_pkt3_c2s_ack)); packet_parse(&pkt, (const char *)tcp_pkt3_c2s_ack, sizeof(tcp_pkt3_c2s_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
@@ -106,27 +137,23 @@ TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 3);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED | TCP_C2S_ACK_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// C2S REQ Packet // C2S REQ Packet
printf("=> packet parse: TCP C2S REQ packet\n"); printf("\n=> Packet Parse: TCP C2S REQ packet\n");
packet_parse(&pkt, (const char *)tcp_pkt4_c2s_http_req, sizeof(tcp_pkt4_c2s_http_req)); packet_parse(&pkt, (const char *)tcp_pkt4_c2s_http_req, sizeof(tcp_pkt4_c2s_http_req));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 4) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
@@ -141,27 +168,23 @@ TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 4);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_DATA_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// S2C ACK Packet // S2C ACK Packet
printf("=> packet parse: TCP S2C ACK packet\n"); printf("\n=> Packet Parse: TCP S2C ACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt5_s2c_ack, sizeof(tcp_pkt5_s2c_ack)); packet_parse(&pkt, (const char *)tcp_pkt5_s2c_ack, sizeof(tcp_pkt5_s2c_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 5) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
@@ -176,27 +199,23 @@ TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 5);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED | TCP_C2S_ACK_RECVED | TCP_S2C_ACK_RECVED | TCP_C2S_DATA_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// S2C HTTP Resp Packet1 // S2C HTTP Resp Packet1
printf("=> packet parse: TCP S2C Resp packet1\n"); printf("\n=> Packet Parse: TCP S2C Resp packet1\n");
packet_parse(&pkt, (const char *)tcp_pkt6_s2c_http_resq_1, sizeof(tcp_pkt6_s2c_http_resq_1)); packet_parse(&pkt, (const char *)tcp_pkt6_s2c_http_resq_1, sizeof(tcp_pkt6_s2c_http_resq_1));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 6) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
@@ -211,27 +230,23 @@ TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66 + 1354); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66 + 1354);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1 + 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1 + 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 6);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED | TCP_C2S_ACK_RECVED | TCP_S2C_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_S2C_DATA_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// S2C HTTP Resp Packet2 // S2C HTTP Resp Packet2
printf("=> packet parse: TCP S2C Resp packet2\n"); printf("\n=> Packet Parse: TCP S2C Resp packet2\n");
packet_parse(&pkt, (const char *)tcp_pkt7_s2c_http_resp_2, sizeof(tcp_pkt7_s2c_http_resp_2)); packet_parse(&pkt, (const char *)tcp_pkt7_s2c_http_resp_2, sizeof(tcp_pkt7_s2c_http_resp_2));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 7) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
@@ -246,27 +261,23 @@ TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66 + 1354 + 385); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66 + 1354 + 385);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1 + 1 + 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1 + 1 + 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 7);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED | TCP_C2S_ACK_RECVED | TCP_S2C_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_S2C_DATA_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// C2S ACK Packet // C2S ACK Packet
printf("=> packet parse: TCP C2S ACK packet\n"); printf("\n=> Packet Parse: TCP C2S ACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt8_c2s_ack, sizeof(tcp_pkt8_c2s_ack)); packet_parse(&pkt, (const char *)tcp_pkt8_c2s_ack, sizeof(tcp_pkt8_c2s_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 8) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
@@ -281,34 +292,30 @@ TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66 + 1354 + 385); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66 + 1354 + 385);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1 + 1 + 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1 + 1 + 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 8);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED | TCP_C2S_ACK_RECVED | TCP_S2C_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_S2C_DATA_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// C2S FIN Packet // C2S FIN Packet
printf("=> packet parse: TCP C2S FIN packet\n"); printf("\n=> Packet Parse: TCP C2S FIN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin)); packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 9) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_ACTIVE); EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP); EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_FIN); EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_FIN);
@@ -316,27 +323,23 @@ TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66 + 1354 + 385); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66 + 1354 + 385);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1 + 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1 + 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1 + 1 + 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1 + 1 + 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 9);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED | TCP_C2S_ACK_RECVED | TCP_S2C_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_S2C_DATA_RECVED | TCP_C2S_FIN_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// S2C FIN Packet // S2C FIN Packet
printf("=> packet parse: TCP S2C FIN packet\n"); printf("\n=> Packet Parse: TCP S2C FIN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin)); packet_parse(&pkt, (const char *)tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 10) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
@@ -351,27 +354,23 @@ TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66 + 1354 + 385 + 66); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66 + 1354 + 385 + 66);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1 + 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1 + 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1 + 1 + 1 + 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1 + 1 + 1 + 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 10);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED | TCP_C2S_ACK_RECVED | TCP_S2C_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_S2C_DATA_RECVED | TCP_C2S_FIN_RECVED | TCP_S2C_FIN_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// C2S ACK Packet // C2S ACK Packet
printf("=> packet parse: TCP C2S ACK packet\n"); printf("\n=> Packet Parse: TCP C2S ACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt11_c2s_ack, sizeof(tcp_pkt11_c2s_ack)); packet_parse(&pkt, (const char *)tcp_pkt11_c2s_ack, sizeof(tcp_pkt11_c2s_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 11) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
@@ -386,19 +385,39 @@ TEST(TCP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING_TO_CLOSED, TEST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66 + 1354 + 385 + 66); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 66 + 1354 + 385 + 66);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1 + 1 + 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1 + 1 + 1 + 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1 + 1 + 1 + 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1 + 1 + 1 + 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 11);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED | TCP_C2S_ACK_RECVED | TCP_S2C_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_S2C_DATA_RECVED | TCP_C2S_FIN_RECVED | TCP_S2C_FIN_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 1);
__session_manager_check_counter(mgr, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_CLIENT_FIN); sess = session_manager_get_expired_session(mgr, 11 + opts.tcp_timeout_time_wait);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_FIN);
session_dump(sess);
// free session
session_manager_free_session(mgr, sess);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }

View File

@@ -1,6 +1,43 @@
// TCP state machine test: opening -> active // TCP state machine test: opening -> active
#include <gtest/gtest.h>
#include "test_utils.h" #include "session.h"
#include "session_manager.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,
};
/****************************************************************************** /******************************************************************************
* case: TCP opening -> active (by C2S DATA) * case: TCP opening -> active (by C2S DATA)
@@ -13,53 +50,32 @@ TEST(TCP_OPENING_TO_ACTIVE, BY_SYN_C2S_DATA)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n"); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == 0);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 78);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYN_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// C2S DATA Packet // C2S DATA Packet
printf("=> packet parse: TCP C2S DATA packet\n"); printf("\n=> Packet Parse: TCP C2S DATA packet\n");
packet_parse(&pkt, (const char *)tcp_pkt4_c2s_http_req, sizeof(tcp_pkt4_c2s_http_req)); packet_parse(&pkt, (const char *)tcp_pkt4_c2s_http_req, sizeof(tcp_pkt4_c2s_http_req));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -73,19 +89,41 @@ TEST(TCP_OPENING_TO_ACTIVE, BY_SYN_C2S_DATA)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0); EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_DATA_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_data) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_data + opts.tcp_timeout_time_wait);
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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -102,53 +140,32 @@ TEST(TCP_OPENING_TO_ACTIVE, BY_SYNACK_S2C_DATA)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// SYNACK Packet // S2C SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "93.184.216.34:80 -> 192.168.38.105:60111, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == 0);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 0);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 0);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYNACK_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_s2c_1st_pkt(sess));
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// S2C DATA Packet // S2C DATA Packet
printf("=> packet parse: TCP S2C DATA packet\n"); printf("\n=> Packet Parse: TCP S2C DATA packet\n");
packet_parse(&pkt, (const char *)tcp_pkt6_s2c_http_resq_1, sizeof(tcp_pkt6_s2c_http_resq_1)); packet_parse(&pkt, (const char *)tcp_pkt6_s2c_http_resq_1, sizeof(tcp_pkt6_s2c_http_resq_1));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -162,19 +179,41 @@ TEST(TCP_OPENING_TO_ACTIVE, BY_SYNACK_S2C_DATA)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 1354); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74 + 1354);
EXPECT_TRUE(session_get_c2s_packets(sess) == 0); EXPECT_TRUE(session_get_c2s_packets(sess) == 0);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYNACK_RECVED | TCP_S2C_ACK_RECVED | TCP_S2C_DATA_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_data) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_data + opts.tcp_timeout_time_wait);
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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }

View File

@@ -1,47 +1,44 @@
// TCP state machine test: opening -> closing // TCP state machine test: opening -> closing
#include <gtest/gtest.h>
#include "test_utils.h" #include "session.h"
#include "session_manager.h"
static void build_opening_tcp_session(struct session_manager *mgr, struct session *sess) #include "tcp_utils.h"
{ #include "test_packets.h"
char buffer[1024] = {0};
struct packet pkt;
// C2S SYN Packet struct session_manager_options opts = {
printf("=> packet parse: TCP C2S SYN packet\n"); // max session number
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); .max_tcp_session_num = 256,
printf("<= packet parse\n\n"); .max_udp_session_num = 256,
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0); // session overload
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); .tcp_overload_evict_old_sess = 1, // 1: evict old session, 0: bypass new session
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); .udp_overload_evict_old_sess = 1, // 1: evict old session, 0: bypass new session
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == 0);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 78);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == TCP_SYN_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
__session_dispatch(sess); // 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,
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // udp timeout
.udp_timeout_data = 7,
sleep(1); // duplicate packet filter
timestamp_update(); .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,
};
/****************************************************************************** /******************************************************************************
* case: TCP opening -> closing (by FIN-FIN) * case: TCP opening -> closing (by FIN-FIN)
@@ -54,55 +51,43 @@ TEST(TCP_OPENING_TO_CLOSING, BY_FIN_FIN)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
build_opening_tcp_session(mgr, sess); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
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);
// C2S FIN Packet // C2S FIN Packet
printf("=> packet parse: TCP C2S FIN packet\n"); printf("\n=> Packet Parse: TCP C2S FIN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin)); packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_FIN);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 78 + 66);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_FIN_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// S2C FIN Packet // S2C FIN Packet
printf("=> packet parse: TCP S2C FIN packet\n"); printf("\n=> Packet Parse: TCP S2C FIN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin)); packet_parse(&pkt, (const char *)tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -116,19 +101,40 @@ TEST(TCP_OPENING_TO_CLOSING, BY_FIN_FIN)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 66); EXPECT_TRUE(session_get_s2c_bytes(sess) == 66);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 3);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_S2C_ACK_RECVED | TCP_C2S_FIN_RECVED | TCP_S2C_FIN_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 1);
__session_manager_check_counter(mgr, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_CLIENT_FIN); sess = session_manager_get_expired_session(mgr, 3 + opts.tcp_timeout_time_wait);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_FIN);
session_dump(sess);
// free session
session_manager_free_session(mgr, sess);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -145,17 +151,24 @@ TEST(TCP_OPENING_TO_CLOSING, BY_C2S_RST)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
build_opening_tcp_session(mgr, sess); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
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);
// C2S RST Packet // C2S RST Packet
printf("=> packet parse: TCP C2S RST packet\n"); printf("\n=> Packet Parse: TCP C2S RST packet\n");
char tcp_pkt_c2s_rst[1500] = {0}; char tcp_pkt_c2s_rst[1500] = {0};
memcpy(tcp_pkt_c2s_rst, tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin)); memcpy(tcp_pkt_c2s_rst, tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin));
packet_parse(&pkt, (const char *)tcp_pkt_c2s_rst, sizeof(tcp_pkt9_c2s_fin)); packet_parse(&pkt, (const char *)tcp_pkt_c2s_rst, sizeof(tcp_pkt9_c2s_fin));
@@ -164,9 +177,13 @@ TEST(TCP_OPENING_TO_CLOSING, BY_C2S_RST)
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr; struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
tcp_hdr_set_flags(hdr, 0); tcp_hdr_set_flags(hdr, 0);
tcp_hdr_set_rst_flag(hdr, true); tcp_hdr_set_rst_flag(hdr, true);
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -180,19 +197,40 @@ TEST(TCP_OPENING_TO_CLOSING, BY_C2S_RST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0); EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_RST_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 1);
__session_manager_check_counter(mgr, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_CLIENT_RST); sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_time_wait);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_RST);
session_dump(sess);
// free session
session_manager_free_session(mgr, sess);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -209,17 +247,24 @@ TEST(TCP_OPENING_TO_CLOSING, BY_S2C_RST)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
build_opening_tcp_session(mgr, sess); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
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);
// S2C RST Packet // S2C RST Packet
printf("=> packet parse: TCP S2C RST packet\n"); printf("\n=> Packet Parse: TCP S2C RST packet\n");
char tcp_pkt_s2c_rst[1500] = {0}; char tcp_pkt_s2c_rst[1500] = {0};
memcpy(tcp_pkt_s2c_rst, tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin)); memcpy(tcp_pkt_s2c_rst, tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin));
packet_parse(&pkt, (const char *)tcp_pkt_s2c_rst, sizeof(tcp_pkt10_s2c_fin)); packet_parse(&pkt, (const char *)tcp_pkt_s2c_rst, sizeof(tcp_pkt10_s2c_fin));
@@ -228,9 +273,13 @@ TEST(TCP_OPENING_TO_CLOSING, BY_S2C_RST)
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr; struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
tcp_hdr_set_flags(hdr, 0); tcp_hdr_set_flags(hdr, 0);
tcp_hdr_set_rst_flag(hdr, true); tcp_hdr_set_rst_flag(hdr, true);
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -244,19 +293,40 @@ TEST(TCP_OPENING_TO_CLOSING, BY_S2C_RST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 66); EXPECT_TRUE(session_get_s2c_bytes(sess) == 66);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_S2C_RST_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 1);
__session_manager_check_counter(mgr, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_SERVER_RST); sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_time_wait);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_SERVER_RST);
session_dump(sess);
// free session
session_manager_free_session(mgr, sess);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -269,20 +339,52 @@ TEST(TCP_OPENING_TO_CLOSING, BY_S2C_RST)
#if 1 #if 1
TEST(TCP_OPENING_TO_CLOSING, BY_INIT_TIMEOUT) TEST(TCP_OPENING_TO_CLOSING, BY_INIT_TIMEOUT)
{ {
struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
build_opening_tcp_session(mgr, sess); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= Packet Parse: done\n\n");
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // lookup session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); // new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 1 + opts.tcp_timeout_init) == NULL);
sess = session_manager_get_expired_session(mgr, 1 + opts.tcp_timeout_init + opts.tcp_timeout_time_wait);
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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -299,21 +401,32 @@ TEST(TCP_OPENING_TO_CLOSING, BY_HANDSHAKE_TIMEOUT)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
build_opening_tcp_session(mgr, sess); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
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);
// S2C SYNACK Packet // S2C SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -327,20 +440,41 @@ TEST(TCP_OPENING_TO_CLOSING, BY_HANDSHAKE_TIMEOUT)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess)); session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_handshake) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_handshake + opts.tcp_timeout_time_wait);
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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -357,56 +491,43 @@ TEST(TCP_OPENING_TO_CLOSING, BY_DATA_TIMEOUT)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
build_opening_tcp_session(mgr, sess); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
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);
// S2C SYNACK Packet // S2C SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); // C2S ACK Packet
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); printf("\n=> Packet Parse: TCP C2S ACK packet\n");
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == 0);
EXPECT_TRUE(session_get_c2s_bytes(sess) == 78);
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// ACK Packet
printf("=> packet parse: TCP C2S ACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt3_c2s_ack, sizeof(tcp_pkt3_c2s_ack)); packet_parse(&pkt, (const char *)tcp_pkt3_c2s_ack, sizeof(tcp_pkt3_c2s_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -420,56 +541,89 @@ TEST(TCP_OPENING_TO_CLOSING, BY_DATA_TIMEOUT)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 74); EXPECT_TRUE(session_get_s2c_bytes(sess) == 74);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 3);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_SYNACK_RECVED | TCP_C2S_ACK_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 3 + opts.tcp_timeout_data) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 3 + opts.tcp_timeout_data + opts.tcp_timeout_time_wait);
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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
#endif #endif
/****************************************************************************** /******************************************************************************
* case: TCP opening -> closing (by C2S half closed timeout) * case: TCP opening -> closing (by C2S half FIN)
******************************************************************************/ ******************************************************************************/
#if 1 #if 1
TEST(TCP_OPENING_TO_CLOSING, BY_C2S_HALF_CLOSED_TIMEOUT) TEST(TCP_OPENING_TO_CLOSING, BY_C2S_HALF_FIN)
{ {
char buffer[1024] = {0}; char buffer[1024] = {0};
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
build_opening_tcp_session(mgr, sess); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
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);
// C2S FIN Packet // C2S FIN Packet
printf("=> packet parse: TCP C2S FIN packet\n"); printf("\n=> Packet Parse: TCP C2S FIN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin)); packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING); EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP); EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_FIN); EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_FIN);
@@ -477,56 +631,88 @@ TEST(TCP_OPENING_TO_CLOSING, BY_C2S_HALF_CLOSED_TIMEOUT)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0); EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_C2S_ACK_RECVED | TCP_C2S_FIN_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 1);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_CLIENT_FIN); sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_time_wait);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_CLIENT_FIN);
session_dump(sess);
// free session
session_manager_free_session(mgr, sess);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
#endif #endif
/****************************************************************************** /******************************************************************************
* case: TCP opening -> closing (by S2C half closed timeout) * case: TCP opening -> closing (by S2C half FIN)
******************************************************************************/ ******************************************************************************/
#if 1 #if 1
TEST(TCP_OPENING_TO_CLOSING, BY_S2C_HALF_CLOSED_TIMEOUT) TEST(TCP_OPENING_TO_CLOSING, BY_S2C_HALF_FIN)
{ {
char buffer[1024] = {0}; char buffer[1024] = {0};
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
build_opening_tcp_session(mgr, sess); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
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);
// S2C FIN Packet // S2C FIN Packet
printf("=> packet parse: TCP S2C FIN packet\n"); printf("\n=> Packet Parse: TCP S2C FIN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin)); packet_parse(&pkt, (const char *)tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0"); EXPECT_STREQ(buffer, "192.168.38.105:60111 -> 93.184.216.34:80, proto: 6, domain: 0");
EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_key_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_OPENING); EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSING);
EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP); EXPECT_TRUE(session_get_type(sess) == SESSION_TYPE_TCP);
EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO); EXPECT_TRUE(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_SERVER_FIN); EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_SERVER_FIN);
@@ -534,19 +720,40 @@ TEST(TCP_OPENING_TO_CLOSING, BY_S2C_HALF_CLOSED_TIMEOUT)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 66); EXPECT_TRUE(session_get_s2c_bytes(sess) == 66);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_tcp_state(sess) == (TCP_SYN_RECVED | TCP_S2C_ACK_RECVED | TCP_S2C_FIN_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 1);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_SERVER_FIN); sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_time_wait);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_SERVER_FIN);
session_dump(sess);
// free session
session_manager_free_session(mgr, sess);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->tcp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->tcp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }

View File

@@ -1,14 +1,43 @@
// UDP state machine test: init -> opening -> active -> closing // UDP state machine test: init -> opening -> active -> closing
#include <gtest/gtest.h>
#include "test_utils.h" #include "session.h"
#include "session_manager.h"
/****************************************************************************** #include "test_packets.h"
* case: UDP init -> opening (by C2S Packet)
* struct session_manager_options opts = {
* case UDP opening -> active (by S2C Packet) // max session number
* .max_tcp_session_num = 256,
* case UDP active -> closing (by timeout) .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,
};
#if 1 #if 1
TEST(UDP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING, TEST) TEST(UDP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING, TEST)
@@ -17,17 +46,20 @@ TEST(UDP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING, TEST)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S REQ Packet // C2S REQ Packet
printf("=> packet parse: UDP C2S REQ packet\n"); printf("\n=> Packet Parse: UDP C2S REQ packet\n");
packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req)); packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
@@ -42,28 +74,23 @@ TEST(UDP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING, TEST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0); EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 1);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_udp_state(sess) == UDP_C2S_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess));
__session_dispatch(sess);
__session_manager_check_counter(mgr, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
sleep(1);
timestamp_update();
// S2C RESP Packet // S2C RESP Packet
printf("=> packet parse: UDP S2C RESP packet\n"); printf("\n=> Packet Parse: UDP S2C RESP packet\n");
packet_parse(&pkt, (const char *)udp_pkt2_dns_resp, sizeof(udp_pkt2_dns_resp)); packet_parse(&pkt, (const char *)udp_pkt2_dns_resp, sizeof(udp_pkt2_dns_resp));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer)); tuple6_to_str(session_get0_key(sess), buffer, sizeof(buffer));
@@ -77,19 +104,41 @@ TEST(UDP_INIT_TO_OPENING_TO_ACTIVE_TO_CLOSING, TEST)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 550); EXPECT_TRUE(session_get_s2c_bytes(sess) == 550);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_udp_state(sess) == (UDP_C2S_RECVED | UDP_S2C_RECVED));
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->udp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->udp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_active == 1);
EXPECT_TRUE(stat->udp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.udp_timeout_data) == NULL); // active -> closing
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 2 + opts.udp_timeout_data + opts.udp_timeout_data); // 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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->udp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }

View File

@@ -1,10 +1,46 @@
// UDP state machine test: init -> opening // UDP state machine test: init -> opening -> closing
#include <gtest/gtest.h>
#include "test_utils.h" #include "session.h"
#include "session_manager.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,
};
/****************************************************************************** /******************************************************************************
* case: UDP init -> opening (by C2S Packet) * case: UDP init -> opening (by C2S Packet)
*
* case: UDP opening -> closing (by timeout) * case: UDP opening -> closing (by timeout)
* ******************************************************************************/ * ******************************************************************************/
@@ -15,17 +51,20 @@ TEST(UDP_INIT_TO_OPENING_TO_CLOSING, BY_C2S)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S REQ Packet // C2S REQ Packet
printf("=> packet parse: UDP C2S REQ packet\n"); printf("\n=> Packet Parse: UDP C2S REQ packet\n");
packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req)); packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
@@ -40,20 +79,41 @@ TEST(UDP_INIT_TO_OPENING_TO_CLOSING, BY_C2S)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 0); EXPECT_TRUE(session_get_s2c_bytes(sess) == 0);
EXPECT_TRUE(session_get_c2s_packets(sess) == 1); EXPECT_TRUE(session_get_c2s_packets(sess) == 1);
EXPECT_TRUE(session_get_s2c_packets(sess) == 0); EXPECT_TRUE(session_get_s2c_packets(sess) == 0);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 1);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_C2S);
EXPECT_TRUE(session_get_udp_state(sess) == UDP_C2S_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_c2s_1st_pkt(sess)); session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->udp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->udp_sess.nr_sess_opening == 1);
EXPECT_TRUE(stat->udp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 1 + opts.udp_timeout_data) == NULL); // opening -> closing
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 1 + opts.udp_timeout_data + opts.udp_timeout_data); // 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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->udp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }
@@ -61,7 +121,6 @@ TEST(UDP_INIT_TO_OPENING_TO_CLOSING, BY_C2S)
/****************************************************************************** /******************************************************************************
* case: UDP init -> opening (by S2C Packet) * case: UDP init -> opening (by S2C Packet)
*
* case: UDP opening -> closing (by timeout) * case: UDP opening -> closing (by timeout)
******************************************************************************/ ******************************************************************************/
@@ -72,17 +131,20 @@ TEST(UDP_INIT_TO_OPENING_TO_CLOSING, BY_S2C)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// S2C RESP Packet // S2C RESP Packet
printf("=> packet parse: UDP S2C RESP packet\n"); printf("\n=> Packet Parse: UDP S2C RESP packet\n");
packet_parse(&pkt, (const char *)udp_pkt2_dns_resp, sizeof(udp_pkt2_dns_resp)); packet_parse(&pkt, (const char *)udp_pkt2_dns_resp, sizeof(udp_pkt2_dns_resp));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_id(sess) != 0); EXPECT_TRUE(session_get_id(sess) != 0);
@@ -97,20 +159,44 @@ TEST(UDP_INIT_TO_OPENING_TO_CLOSING, BY_S2C)
EXPECT_TRUE(session_get_s2c_bytes(sess) == 550); EXPECT_TRUE(session_get_s2c_bytes(sess) == 550);
EXPECT_TRUE(session_get_c2s_packets(sess) == 0); EXPECT_TRUE(session_get_c2s_packets(sess) == 0);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1); EXPECT_TRUE(session_get_s2c_packets(sess) == 1);
EXPECT_TRUE(session_get_new_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec()); EXPECT_TRUE(session_get_last_time(sess) == 1);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt); EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C); EXPECT_TRUE(session_get_cur_dir(sess) == SESSION_DIR_S2C);
EXPECT_TRUE(session_get_udp_state(sess) == UDP_S2C_RECVED);
EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) == NULL); EXPECT_TRUE(session_get0_c2s_1st_pkt(sess) == NULL);
EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL); EXPECT_TRUE(session_get0_s2c_1st_pkt(sess) != NULL);
EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_s2c_1st_pkt(sess)); EXPECT_TRUE(session_get0_1st_pkt(sess) == session_get0_s2c_1st_pkt(sess));
session_dump(sess);
__session_dispatch(sess); // check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->udp_sess.nr_sess_used == 1);
EXPECT_TRUE(stat->udp_sess.nr_sess_opening == 1);
EXPECT_TRUE(stat->udp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closing == 0);
__session_manager_check_counter(mgr, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0); // expire session
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT); EXPECT_TRUE(session_manager_get_expired_session(mgr, 1 + opts.udp_timeout_data) == NULL); // opening -> closing
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); sess = session_manager_get_expired_session(mgr, 1 + opts.udp_timeout_data + opts.udp_timeout_data); // 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);
// check stat
session_manager_print_stat(mgr);
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->udp_sess.nr_sess_used == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_opening == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_active == 0);
EXPECT_TRUE(stat->udp_sess.nr_sess_closing == 0);
session_manager_free(mgr); session_manager_free(mgr);
} }

View File

@@ -1,4 +1,42 @@
#include "test_utils.h" #include <gtest/gtest.h>
#include "session.h"
#include "session_manager.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,
};
#if 1 #if 1
TEST(TIMEOUT, TCP_TIMEOUT_DATA) TEST(TIMEOUT, TCP_TIMEOUT_DATA)
@@ -7,31 +45,40 @@ TEST(TIMEOUT, TCP_TIMEOUT_DATA)
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n"); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// C2S DATA Packet // C2S DATA Packet
printf("=> packet parse: TCP C2S DATA packet\n"); printf("\n=> Packet Parse: TCP C2S DATA packet\n");
packet_parse(&pkt, (const char *)tcp_pkt4_c2s_http_req, sizeof(tcp_pkt4_c2s_http_req)); packet_parse(&pkt, (const char *)tcp_pkt4_c2s_http_req, sizeof(tcp_pkt4_c2s_http_req));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_data) == NULL);
__session_manager_check_tcp_timeout_data(mgr, &opts); sess = session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_data + opts.tcp_timeout_time_wait);
__session_manager_check_tcp_timeout_time_wait(mgr, &opts); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 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); session_manager_free(mgr);
} }

View File

@@ -1,88 +0,0 @@
#include "test_utils.h"
#if 1
TEST(TIMEOUT, TCP_TIMEOUT_HALF_CLOSED1)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
// C2S FIN Packet
printf("=> packet parse: TCP C2S FIN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
__session_manager_check_tcp_timeout_half_closed(mgr, &opts, SESSION_STATE_OPENING);
__session_manager_check_tcp_timeout_time_wait(mgr, &opts);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
session_manager_free(mgr);
}
#endif
#if 1
TEST(TIMEOUT, TCP_TIMEOUT_HALF_CLOSED2)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
// C2S DATA Packet
printf("=> packet parse: TCP C2S DATA packet\n");
packet_parse(&pkt, (const char *)tcp_pkt4_c2s_http_req, sizeof(tcp_pkt4_c2s_http_req));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
// C2S FIN Packet
printf("=> packet parse: TCP C2S FIN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
__session_manager_check_tcp_timeout_half_closed(mgr, &opts, SESSION_STATE_ACTIVE);
__session_manager_check_tcp_timeout_time_wait(mgr, &opts);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
session_manager_free(mgr);
}
#endif
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -1,4 +1,43 @@
#include "test_utils.h" #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,
};
#if 1 #if 1
TEST(TIMEOUT, TCP_TIMEOUT_HANDSHAKE) TEST(TIMEOUT, TCP_TIMEOUT_HANDSHAKE)
@@ -7,24 +46,29 @@ TEST(TIMEOUT, TCP_TIMEOUT_HANDSHAKE)
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// SYNACK Packet // S2C SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n"); printf("\n=> Packet Parse: TCP S2C SYNACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 1 + opts.tcp_timeout_handshake) == NULL);
__session_manager_check_tcp_timeout_handshake(mgr, &opts); sess = session_manager_get_expired_session(mgr, 1 + opts.tcp_timeout_handshake + opts.tcp_timeout_time_wait);
__session_manager_check_tcp_timeout_time_wait(mgr, &opts); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 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); session_manager_free(mgr);
} }

View File

@@ -1,60 +1,74 @@
#include "test_utils.h" #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,
};
#if 1 #if 1
TEST(TIMEOUT, TCP_TIMEOUT_INIT1) TEST(TIMEOUT, TCP_TIMEOUT_INIT)
{ {
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet // C2S SYN Packet
printf("=> packet parse: TCP C2S SYN packet\n"); printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); // expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 1 + opts.tcp_timeout_init) == NULL); // opening -> closing
__session_manager_check_tcp_timeout_init(mgr, &opts); sess = session_manager_get_expired_session(mgr, 1 + opts.tcp_timeout_init + opts.tcp_timeout_time_wait); // closing -> closed
__session_manager_check_tcp_timeout_time_wait(mgr, &opts);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
session_manager_free(mgr);
}
#endif
#if 1
TEST(TIMEOUT, TCP_TIMEOUT_INIT2)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL);
// S2C SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0); EXPECT_TRUE(session_get_closing_reason(sess) == CLOSING_BY_TIMEOUT);
session_dump(sess);
__session_manager_check_tcp_timeout_init(mgr, &opts); // free session
__session_manager_check_tcp_timeout_time_wait(mgr, &opts); session_manager_free_session(mgr, sess);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
session_manager_free(mgr); session_manager_free(mgr);
} }

View File

@@ -1,4 +1,42 @@
#include "test_utils.h" #include <gtest/gtest.h>
#include "session.h"
#include "session_manager.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,
};
#if 1 #if 1
TEST(TIMEOUT, UDP_TIMEOUT_DATA1) TEST(TIMEOUT, UDP_TIMEOUT_DATA1)
@@ -7,24 +45,29 @@ TEST(TIMEOUT, UDP_TIMEOUT_DATA1)
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S REQ Packet // C2S REQ Packet
printf("=> packet parse: UDP C2S REQ packet\n"); printf("\n=> Packet Parse: UDP C2S REQ packet\n");
packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req)); packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
__session_manager_check_counter(mgr, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0); // expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 1 + opts.udp_timeout_data) == NULL); // opening -> closing
__session_manager_check_udp_timeout_data(mgr, &opts, SESSION_STATE_OPENING); sess = session_manager_get_expired_session(mgr, 1 + opts.udp_timeout_data + opts.udp_timeout_data); // closing -> closed
EXPECT_TRUE(sess);
EXPECT_TRUE(session_manager_get_expired_session(mgr) == NULL); EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 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); session_manager_free(mgr);
} }
@@ -37,31 +80,40 @@ TEST(TIMEOUT, UDP_TIMEOUT_DATA2)
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
timestamp_update(); mgr = session_manager_new(&opts, 1);
mgr = session_manager_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// C2S REQ Packet // C2S REQ Packet
printf("=> packet parse: UDP C2S REQ packet\n"); printf("\n=> Packet Parse: UDP C2S REQ packet\n");
packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req)); packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// new session
sess = session_manager_new_session(mgr, &pkt, 1);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// S2C RESP Packet // S2C RESP Packet
printf("=> packet parse: UDP S2C RESP packet\n"); printf("\n=> Packet Parse: UDP S2C RESP packet\n");
packet_parse(&pkt, (const char *)udp_pkt2_dns_resp, sizeof(udp_pkt2_dns_resp)); packet_parse(&pkt, (const char *)udp_pkt2_dns_resp, sizeof(udp_pkt2_dns_resp));
printf("<= packet parse\n\n"); printf("<= Packet Parse: done\n\n");
sess = session_manager_update_session(mgr, &pkt);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess); EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0); // expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.udp_timeout_data) == NULL); // active -> closing
__session_manager_check_udp_timeout_data(mgr, &opts, SESSION_STATE_ACTIVE); sess = session_manager_get_expired_session(mgr, 2 + opts.udp_timeout_data + opts.udp_timeout_data); // closing -> closed
EXPECT_TRUE(sess);
EXPECT_TRUE(session_manager_get_expired_session(mgr) == NULL); EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSED);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 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); session_manager_free(mgr);
} }

View File

@@ -1,353 +0,0 @@
#ifndef _TEST_STATE_MACHINE_H
#define _TEST_STATE_MACHINE_H
#ifdef __cpluscplus
extern "C"
{
#endif
#include <gtest/gtest.h>
#include "session_private.h"
#include "timestamp.h"
#include "session_manager.h"
#include "tcp_utils.h"
#include "ipv4_utils.h"
#include "test_packets.h"
struct session_manager_options opts = {
// max session number
.max_tcp_session_num = 3,
.max_udp_session_num = 3,
// 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 = 2,
.tcp_timeout_handshake = 2,
.tcp_timeout_data = 2,
.tcp_timeout_half_closed = 2,
.tcp_timeout_time_wait = 2,
.tcp_timeout_discard = 2,
// udp timeout
.udp_timeout_data = 2,
// 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,
};
__attribute__((unused)) static void __session_dispatch(struct session *sess)
{
if (sess == NULL)
{
return;
}
printf("\n");
printf("=> session dispatch: %p\n", sess);
session_dump(sess);
printf("<= session dispatch\n");
printf("\n");
session_set0_cur_pkt(sess, NULL);
session_set_cur_dir(sess, SESSION_DIR_NONE);
}
__attribute__((unused)) static void __session_manager_wait(struct session_manager *mgr, enum closing_reason reason)
{
struct session *sess;
for (int i = 0; i < 5; i++)
{
timestamp_update();
sess = session_manager_get_expired_session(mgr);
__session_dispatch(sess);
if (sess && session_get_state(sess) == SESSION_STATE_CLOSING)
{
EXPECT_TRUE(session_get_closing_reason(sess) == reason);
}
sess = session_manager_get_evicted_session(mgr);
__session_dispatch(sess);
if (sess && session_get_state(sess) == SESSION_STATE_CLOSING)
{
EXPECT_TRUE(session_get_closing_reason(sess) == reason);
}
sleep(1);
}
}
__attribute__((unused)) static void __session_manager_check_counter(struct session_manager *mgr,
uint64_t tcp_opening_sess_num, uint64_t tcp_active_sess_num, uint64_t tcp_closing_sess_num,
uint64_t udp_opening_sess_num, uint64_t udp_active_sess_num, uint64_t udp_closing_sess_num,
uint64_t tcp_overload_evict_new_sess_num, uint64_t tcp_overload_evict_old_sess_num,
uint64_t udp_overload_evict_new_sess_num, uint64_t udp_overload_evict_old_sess_num)
{
struct session_manager_stat *stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat->tcp_sess_num == tcp_opening_sess_num + tcp_active_sess_num + tcp_closing_sess_num);
EXPECT_TRUE(stat->tcp_opening_sess_num == tcp_opening_sess_num);
EXPECT_TRUE(stat->tcp_active_sess_num == tcp_active_sess_num);
EXPECT_TRUE(stat->tcp_closing_sess_num == tcp_closing_sess_num);
EXPECT_TRUE(stat->udp_sess_num == udp_opening_sess_num + udp_active_sess_num + udp_closing_sess_num);
EXPECT_TRUE(stat->udp_opening_sess_num == udp_opening_sess_num);
EXPECT_TRUE(stat->udp_active_sess_num == udp_active_sess_num);
EXPECT_TRUE(stat->udp_closing_sess_num == udp_closing_sess_num);
EXPECT_TRUE(stat->tcp_overload_evict_new_sess_num == tcp_overload_evict_new_sess_num);
EXPECT_TRUE(stat->tcp_overload_evict_old_sess_num == tcp_overload_evict_old_sess_num);
EXPECT_TRUE(stat->udp_overload_evict_new_sess_num == udp_overload_evict_new_sess_num);
EXPECT_TRUE(stat->udp_overload_evict_old_sess_num == udp_overload_evict_old_sess_num);
}
__attribute__((unused)) static void __session_manager_check_tcp_timeout_init(struct session_manager *mgr, struct session_manager_options *opts)
{
struct session *sess;
uint64_t interval;
uint64_t timeout_time = timestamp_get_sec() + opts->tcp_timeout_init;
printf("\n=> tcp_timeout_init\n");
for (uint64_t i = 0; i <= opts->tcp_timeout_init; i++)
{
timestamp_update();
sess = session_manager_get_expired_session(mgr);
interval = session_manager_get_expire_interval(mgr);
if (i == opts->tcp_timeout_init)
{
printf("timeout_time: %lu, curr_time: %lu, session expired\n",
timeout_time, timestamp_get_sec());
__session_manager_check_counter(mgr, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
EXPECT_TRUE(sess != NULL);
break;
}
else
{
printf("timeout_time: %lu, curr_time: %lu, interval : %lu, session not expire\n",
timeout_time, timestamp_get_sec(), interval);
EXPECT_TRUE(interval <= opts->tcp_timeout_init);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
EXPECT_TRUE(sess == NULL);
}
sleep(1);
}
printf("<= tcp_timeout_init\n\n");
}
__attribute__((unused)) static void __session_manager_check_tcp_timeout_handshake(struct session_manager *mgr, struct session_manager_options *opts)
{
struct session *sess;
uint64_t interval;
uint64_t timeout_time = timestamp_get_sec() + opts->tcp_timeout_handshake;
printf("\n=> tcp_timeout_handshake\n");
for (uint64_t i = 0; i <= opts->tcp_timeout_handshake; i++)
{
timestamp_update();
sess = session_manager_get_expired_session(mgr);
interval = session_manager_get_expire_interval(mgr);
if (i == opts->tcp_timeout_handshake)
{
printf("timeout_time: %lu, curr_time: %lu, session expired\n",
timeout_time, timestamp_get_sec());
__session_manager_check_counter(mgr, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
EXPECT_TRUE(sess != NULL);
break;
}
else
{
printf("timeout_time: %lu, curr_time: %lu, interval : %lu, session not expire\n",
timeout_time, timestamp_get_sec(), interval);
EXPECT_TRUE(interval <= opts->tcp_timeout_handshake);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
EXPECT_TRUE(sess == NULL);
}
sleep(1);
}
printf("<= tcp_timeout_handshake\n\n");
}
__attribute__((unused)) static void __session_manager_check_tcp_timeout_data(struct session_manager *mgr, struct session_manager_options *opts)
{
struct session *sess;
uint64_t interval;
uint64_t timeout_time = timestamp_get_sec() + opts->tcp_timeout_data;
printf("\n=> tcp_timeout_data\n");
for (uint64_t i = 0; i <= opts->tcp_timeout_data; i++)
{
timestamp_update();
sess = session_manager_get_expired_session(mgr);
interval = session_manager_get_expire_interval(mgr);
if (i == opts->tcp_timeout_data)
{
printf("timeout_time: %lu, curr_time: %lu, session expired\n",
timeout_time, timestamp_get_sec());
__session_manager_check_counter(mgr, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
EXPECT_TRUE(sess != NULL);
break;
}
else
{
printf("timeout_time: %lu, curr_time: %lu, interval : %lu, session not expire\n",
timeout_time, timestamp_get_sec(), interval);
EXPECT_TRUE(interval <= opts->tcp_timeout_data);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
EXPECT_TRUE(sess == NULL);
}
sleep(1);
}
printf("<= tcp_timeout_data\n\n");
}
__attribute__((unused)) static void __session_manager_check_tcp_timeout_half_closed(struct session_manager *mgr, struct session_manager_options *opts, enum session_state curr_state)
{
EXPECT_TRUE(curr_state == SESSION_STATE_OPENING || curr_state == SESSION_STATE_ACTIVE);
struct session *sess;
uint64_t interval;
uint64_t timeout_time = timestamp_get_sec() + opts->tcp_timeout_half_closed;
printf("\n=> tcp_timeout_half_closed\n");
for (uint64_t i = 0; i <= opts->tcp_timeout_half_closed; i++)
{
timestamp_update();
sess = session_manager_get_expired_session(mgr);
interval = session_manager_get_expire_interval(mgr);
if (i == opts->tcp_timeout_half_closed)
{
printf("timeout_time: %lu, curr_time: %lu, session expired\n",
timeout_time, timestamp_get_sec());
__session_manager_check_counter(mgr, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
EXPECT_TRUE(sess != NULL);
break;
}
else
{
printf("timeout_time: %lu, curr_time: %lu, interval : %lu, session not expire\n",
timeout_time, timestamp_get_sec(), interval);
EXPECT_TRUE(interval <= opts->tcp_timeout_half_closed);
if (curr_state == SESSION_STATE_OPENING)
{
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
if (curr_state == SESSION_STATE_ACTIVE)
{
__session_manager_check_counter(mgr, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0);
}
EXPECT_TRUE(sess == NULL);
}
sleep(1);
}
printf("<= tcp_timeout_half_closed\n\n");
}
__attribute__((unused)) static void __session_manager_check_tcp_timeout_time_wait(struct session_manager *mgr, struct session_manager_options *opts)
{
struct session *sess;
uint64_t interval;
uint64_t timeout_time = timestamp_get_sec() + opts->tcp_timeout_time_wait;
printf("\n=> tcp_timeout_time_wait\n");
for (uint64_t i = 0; i <= opts->tcp_timeout_time_wait; i++)
{
timestamp_update();
sess = session_manager_get_expired_session(mgr);
interval = session_manager_get_expire_interval(mgr);
if (i == opts->tcp_timeout_time_wait)
{
printf("timeout_time: %lu, curr_time: %lu, session expired\n",
timeout_time, timestamp_get_sec());
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
EXPECT_TRUE(sess == NULL);
break;
}
else
{
printf("timeout_time: %lu, curr_time: %lu, interval : %lu, session not expire\n",
timeout_time, timestamp_get_sec(), interval);
EXPECT_TRUE(interval <= opts->tcp_timeout_init);
__session_manager_check_counter(mgr, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0);
EXPECT_TRUE(sess == NULL);
}
sleep(1);
}
printf("<= tcp_timeout_time_wait\n\n");
}
__attribute__((unused)) static void __session_manager_check_udp_timeout_data(struct session_manager *mgr, struct session_manager_options *opts, enum session_state curr_state)
{
EXPECT_TRUE(curr_state == SESSION_STATE_OPENING || curr_state == SESSION_STATE_ACTIVE);
struct session *sess;
uint64_t interval;
uint64_t timeout_time = timestamp_get_sec() + opts->udp_timeout_data;
printf("\n=> udp_timeout_data\n");
for (uint64_t i = 0; i <= opts->udp_timeout_data; i++)
{
timestamp_update();
sess = session_manager_get_expired_session(mgr);
interval = session_manager_get_expire_interval(mgr);
if (i == opts->udp_timeout_data)
{
printf("timeout_time: %lu, curr_time: %lu, session expired\n",
timeout_time, timestamp_get_sec());
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0);
EXPECT_TRUE(sess != NULL);
break;
}
else
{
printf("timeout_time: %lu, curr_time: %lu, interval : %lu, session not expire\n",
timeout_time, timestamp_get_sec(), interval);
EXPECT_TRUE(interval <= opts->udp_timeout_data);
if (curr_state == SESSION_STATE_OPENING)
{
__session_manager_check_counter(mgr, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
}
if (curr_state == SESSION_STATE_ACTIVE)
{
__session_manager_check_counter(mgr, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0);
}
EXPECT_TRUE(sess == NULL);
}
sleep(1);
}
printf("<= udp_timeout_data\n\n");
}
#ifdef __cpluscplus
}
#endif
#endif

View File

@@ -1,4 +1,4 @@
add_executable(stellar stellar.cpp) add_executable(stellar stellar.cpp)
target_link_libraries(stellar id_generator session_manager pthread config packet_io) target_link_libraries(stellar timestamp id_generator session_manager pthread config packet_io)
install(TARGETS stellar RUNTIME DESTINATION bin COMPONENT Program) install(TARGETS stellar RUNTIME DESTINATION bin COMPONENT Program)

View File

@@ -137,7 +137,7 @@ static void *main_loop(void *arg)
int nr_recv; int nr_recv;
int need_drop_pkt = 1; // TODO int need_drop_pkt = 1; // TODO
uint64_t now_sec = 0; uint64_t now = 0;
uint16_t thr_idx = threads_ctx->index; uint16_t thr_idx = threads_ctx->index;
if (packet_io_init(packet_io, thr_idx) != 0) if (packet_io_init(packet_io, thr_idx) != 0)
@@ -152,7 +152,7 @@ static void *main_loop(void *arg)
while (ATOMIC_READ(&threads_ctx->need_exit) == 0) while (ATOMIC_READ(&threads_ctx->need_exit) == 0)
{ {
now_sec = timestamp_get_sec(); // TODO now = timestamp_get_msec(); // TODO
nr_recv = packet_io_ingress(packet_io, thr_idx, packets, RX_BURST_MAX); nr_recv = packet_io_ingress(packet_io, thr_idx, packets, RX_BURST_MAX);
if (nr_recv == 0) if (nr_recv == 0)
{ {
@@ -166,7 +166,7 @@ static void *main_loop(void *arg)
// call plugin_manager_dispatch_raw_pkt(); // call plugin_manager_dispatch_raw_pkt();
if (packet_is_fragment(pkt)) if (packet_is_fragment(pkt))
{ {
struct packet *defraged_pkt = ip_reassembly_packet(ip_reass, pkt, now_sec); struct packet *defraged_pkt = ip_reassembly_packet(ip_reass, pkt, now);
if (defraged_pkt == NULL) if (defraged_pkt == NULL)
{ {
continue; continue;
@@ -183,19 +183,17 @@ static void *main_loop(void *arg)
sess = session_manager_lookup_session(sess_mgr, pkt); sess = session_manager_lookup_session(sess_mgr, pkt);
if (sess == NULL) if (sess == NULL)
{ {
sess = session_manager_new_session(sess_mgr, pkt); sess = session_manager_new_session(sess_mgr, pkt, now);
if (sess == NULL) if (sess == NULL)
{ {
continue; continue;
} }
plug_mgr_ctx = plugin_manager_new_ctx(); plug_mgr_ctx = plugin_manager_new_ctx();
session_set_id(sess, id_generator_alloc(now_sec, thr_idx));
session_set_user_data(sess, plug_mgr_ctx); session_set_user_data(sess, plug_mgr_ctx);
} }
else else
{ {
session_manager_update_session(sess_mgr, sess, pkt); session_manager_update_session(sess_mgr, sess, pkt, now);
} }
plugin_manager_dispatch(plug_mgr, sess, pkt); plugin_manager_dispatch(plug_mgr, sess, pkt);
} }
@@ -232,7 +230,7 @@ static void *main_loop(void *arg)
} }
} }
while ((expired_sess = session_manager_get_expired_session(sess_mgr))) while ((expired_sess = session_manager_get_expired_session(sess_mgr, now)))
{ {
plug_mgr_ctx = session_get_user_data(expired_sess); plug_mgr_ctx = session_get_user_data(expired_sess);
plugin_manager_free_ctx(plug_mgr_ctx); plugin_manager_free_ctx(plug_mgr_ctx);
@@ -253,6 +251,7 @@ static void *main_loop(void *arg)
static int thread_context_init(struct stellar_context *ctx, uint8_t nr_threads) static int thread_context_init(struct stellar_context *ctx, uint8_t nr_threads)
{ {
uint64_t now = timestamp_get_msec();
for (uint8_t i = 0; i < nr_threads; i++) for (uint8_t i = 0; i < nr_threads; i++)
{ {
struct thread_context *threads_ctx = &ctx->threads_ctx[i]; struct thread_context *threads_ctx = &ctx->threads_ctx[i];
@@ -260,7 +259,7 @@ static int thread_context_init(struct stellar_context *ctx, uint8_t nr_threads)
threads_ctx->need_exit = 0; threads_ctx->need_exit = 0;
threads_ctx->is_runing = 0; threads_ctx->is_runing = 0;
threads_ctx->sess_mgr = session_manager_new(sess_mgr_opts); threads_ctx->sess_mgr = session_manager_new(sess_mgr_opts, now);
if (threads_ctx->sess_mgr == NULL) if (threads_ctx->sess_mgr == NULL)
{ {
STELLAR_LOG_ERROR("unable to create session manager"); STELLAR_LOG_ERROR("unable to create session manager");

View File

@@ -9,7 +9,7 @@ extern "C"
#include <stdint.h> #include <stdint.h>
#define MAX_THREAD_NUM 256 #define MAX_THREAD_NUM 256
#define RX_BURST_MAX 128 #define RX_BURST_MAX 64
#define ATOMIC_INC(x) __atomic_fetch_add(x, 1, __ATOMIC_RELAXED) #define ATOMIC_INC(x) __atomic_fetch_add(x, 1, __ATOMIC_RELAXED)
#define ATOMIC_DEC(x) __atomic_fetch_sub(x, 1, __ATOMIC_RELAXED) #define ATOMIC_DEC(x) __atomic_fetch_sub(x, 1, __ATOMIC_RELAXED)