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]
mode = dumpfile # dumpfile, marsio
dumpfile_dir = "/tmp/dumpfile/"
app_symbol = stellar
dev_symbol = nf_0_fw
dumpfile_dir = "/tmp/dumpfile/"
nr_threads = 1 # [1, 256]
cpu_mask = [5, 6, 7, 8, 9, 10, 11, 12]
[ip_reassembly]
enable = 1
timeout = 10 # seconds
timeout = 10000 # ms
bucket_entries = 8
bucket_num = 4096
[session_manager]
# max session number
max_tcp_session_num = 100
max_udp_session_num = 100
max_tcp_session_num = 40960
max_udp_session_num = 40960
# session overload evict
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 = 5 # seconds, Range: 1-60
tcp_timeout_handshake = 10 # seconds, Range: 1-60
tcp_timeout_data = 3600 # seconds, Range: 1-15,999,999
tcp_timeout_half_closed = 120 # seconds, Range: 1-604,800
tcp_timeout_time_wait = 15 # seconds, Range: 1-600
tcp_timeout_discard = 90 # seconds, Range: 1-15,999,999
tcp_timeout_init = 5000 # ms, Range: 1-60,000
tcp_timeout_handshake = 10000 # ms, Range: 1-60,000
tcp_timeout_data = 3600000 # ms, Range: 1-15,999,999,000
tcp_timeout_half_closed = 120000 # ms, Range: 1-604,800,000
tcp_timeout_time_wait = 15000 # ms, Range: 1-600,000
tcp_timeout_discard = 90000 # ms, Range: 1-15,999,999,000
# 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
duplicated_packet_filter_enable = 1
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
# evicted session filter
evicted_session_filter_enable = 1
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

View File

@@ -41,25 +41,16 @@ struct packet_idetify idetify = {
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(expiry_dablooms_search(handle, (const char *)&idetify, sizeof(idetify), time(NULL)) != 1); // no exist
EXPECT_TRUE(expiry_dablooms_add(handle, (const char *)&idetify, sizeof(idetify), time(NULL)) == 0); // add
for (int i = 0; i < 5; i++)
{
if (i < config.expiry_time)
{
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);
}
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), 1) == 0); // add
EXPECT_TRUE(expiry_dablooms_search(handle, (const char *)&idetify, sizeof(idetify), 1) == 1); // exist
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
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
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");
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");
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");
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");
if (ptr == NULL)

View File

@@ -66,7 +66,7 @@ static inline int duplicated_packet_key_get(const struct packet *packet, struct
* 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));
if (filter == NULL)
@@ -80,7 +80,7 @@ struct duplicated_packet_filter *duplicated_packet_filter_new(const struct dupli
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)
{
free(filter);
@@ -106,7 +106,7 @@ void duplicated_packet_filter_free(struct duplicated_packet_filter *filter)
// return 1: 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)
{
@@ -119,7 +119,7 @@ int duplicated_packet_filter_lookup(struct duplicated_packet_filter *filter, con
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;
}
@@ -127,7 +127,7 @@ int duplicated_packet_filter_lookup(struct duplicated_packet_filter *filter, con
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)
{
@@ -140,5 +140,5 @@ void duplicated_packet_filter_add(struct duplicated_packet_filter *filter, const
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 *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);
// return 1: found
// reutrn 0: no found
int duplicated_packet_filter_lookup(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_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);
#ifdef __cpluscplus
}

View File

@@ -16,7 +16,7 @@ struct evicted_session_filter
* 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));
if (filter == NULL)
@@ -30,7 +30,7 @@ struct evicted_session_filter *evicted_session_filter_new(const struct evicted_s
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)
{
free(filter);
@@ -56,14 +56,14 @@ void evicted_session_filter_free(struct evicted_session_filter *filter)
// return 1: 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)
{
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;
}
@@ -71,7 +71,7 @@ int evicted_session_filter_lookup(struct evicted_session_filter *filter, const s
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)
{
@@ -81,6 +81,6 @@ void evicted_session_filter_add(struct evicted_session_filter *filter, const str
struct tuple6 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 *)&reverse_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);
}

View File

@@ -16,13 +16,13 @@ struct evicted_session_filter_options
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);
// return 1: found
// reutrn 0: no found
int evicted_session_filter_lookup(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_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);
#ifdef __cpluscplus
}

View File

@@ -1,3 +1,4 @@
#include <time.h>
#include <string.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 |
* +------+------------------+----------------+------------------------+---------------------------+
*/
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_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 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) |
(thread_index << 43) |
(id_base_time << 15) |

View File

@@ -22,7 +22,7 @@ extern "C"
* return -1: failed
*/
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
}

View File

@@ -365,7 +365,7 @@ static inline void ip_frag_pkt_free(struct ip_frag_pkt *frag)
* 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 = {
.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_prev = NULL;
flow->key = *key;
flow->create_time = now_sec;
flow->create_time = now;
flow->expected_total_size = UINT32_MAX;
flow->received_frag_size = 0;
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--;
}
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_flow_free(flow);
ip_flow_init(flow, key, now_sec);
ip_flow_init(flow, key, now);
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
* 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);
@@ -532,7 +532,7 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
{
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;
}
@@ -547,7 +547,7 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
{
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;
}
@@ -558,19 +558,19 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
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 *free = 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 (expired)
{
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);
mgr->last = expired;
@@ -580,7 +580,7 @@ static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, cons
if (free)
{
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);
mgr->last = free;
@@ -595,10 +595,10 @@ static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, cons
else
{
// 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_reassembly_reuse_flow(mgr, flow, key, now_sec);
ip_reassembly_reuse_flow(mgr, flow, key, now);
ip_reassembly_stat_inc(mgr, timeout, key);
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;
uint64_t timeout = mgr->timeout;
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_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
*/
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 *pkt2;
@@ -864,10 +864,10 @@ struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct pack
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)
{
pkt2 = ip_reassembly_packet(mgr, pkt1, now_sec);
pkt2 = ip_reassembly_packet(mgr, pkt1, now);
packet_free(pkt1);
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)
{
pkt1 = ipv6_reassembly_packet(mgr, pkt, now_sec);
pkt1 = ipv6_reassembly_packet(mgr, pkt, now);
if (pkt1 && pkt1->frag_layer)
{
pkt2 = ip_reassembly_packet(mgr, pkt1, now_sec);
pkt2 = ip_reassembly_packet(mgr, pkt1, now);
packet_free(pkt1);
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 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.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)
{
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 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.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)
{
return NULL;

View File

@@ -16,7 +16,7 @@ struct ip_reassembly_options
{
bool enable;
uint32_t timeout; // seconds
uint32_t timeout;
uint32_t bucket_entries;
uint32_t bucket_num;
};
@@ -52,16 +52,16 @@ struct ip_reassembly_stat
struct ip_reassembly *ip_reassembly_new(const struct ip_reassembly_options *opts);
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);
/*
* Returns the reassembled packet, or NULL if the packet is not reassembled
* 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 *ipv4_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_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);
struct packet *ipv6_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now);
#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_bytes, packet_get_len(pkt));
struct pcap_pkt *pcap_pkt = (struct pcap_pkt *)packet_get_user_data(pkt);
assert(pcap_pkt == NULL);
assert(packet_get_user_data(pkt) == NULL);
packet_free(pkt);
}

View File

@@ -5,8 +5,10 @@ add_library(session_manager
session_timer.cpp
session_queue.cpp
session_manager.cpp
session_transition.cpp
)
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)

View File

@@ -158,28 +158,6 @@ uint64_t session_get_last_time(const struct session *sess)
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
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)
{
if (sess->c2s_1st_pkt)
{
return;
}
sess->c2s_1st_pkt = packet_dup(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);
}
@@ -341,7 +327,7 @@ void session_free_ex_data(struct session *sess, uint8_t idx)
sess->ex_data[idx] = NULL;
}
void session_free(struct session *sess)
void session_clean(struct session *sess)
{
if (sess)
{
@@ -402,100 +388,22 @@ void session_run_expirecb(struct session *sess)
* 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)
{
switch (reason)
{
case CLOSING_BY_TIMEOUT:
return "CLOSING BY TIMEOUT";
return "closing by timeout";
case CLOSING_BY_EVICTED:
return "CLOSING BY EVICTED";
return "closing by evicted";
case CLOSING_BY_CLIENT_FIN:
return "CLOSING BY CLIENT FIN";
return "closing by client FIN";
case CLOSING_BY_CLIENT_RST:
return "CLOSING BY CLIENT RST";
return "closing by client RST";
case CLOSING_BY_SERVER_FIN:
return "CLOSING BY SERVER FIN";
return "closing by server FIN";
case CLOSING_BY_SERVER_RST:
return "CLOSING BY SERVER RST";
return "closing by server RST";
default:
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 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 c2s packets : %" PRIu64 "\n", session_get_c2s_packets(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 bytes : %" PRIu64 "\n", session_get_s2c_bytes(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 S2C packets : %" PRIu64 "\n", session_get_s2c_packets(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 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 dir : %s\n", session_dir_to_str(session_get_cur_dir(sess)));
printf("session ex data: \n");

View File

@@ -11,30 +11,6 @@ extern "C"
#include "tuple.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
{
SESSION_STATE_INIT = 0,
@@ -42,7 +18,7 @@ enum session_state
SESSION_STATE_ACTIVE = 2,
SESSION_STATE_CLOSING = 3,
SESSION_STATE_CLOSED = 4,
SESSION_STATE_MAX = 5,
MAX_STATE = 5,
};
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_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
void session_set_user_data(struct session *sess, void *user_data);
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.
*/
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

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
// TCP timeout
uint64_t tcp_timeout_init; // seconds, Range: 1-60
uint64_t tcp_timeout_handshake; // seconds, Range: 1-60
uint64_t tcp_timeout_data; // seconds, Range: 1-15,999,999
uint64_t tcp_timeout_half_closed; // seconds, Range: 1-604,800
uint64_t tcp_timeout_time_wait; // seconds, Range: 1-600
uint64_t tcp_timeout_discard; // seconds, Range: 1-15,999,999
uint64_t tcp_timeout_init; // ms, Range: 1-60,000
uint64_t tcp_timeout_handshake; // ms, Range: 1-60,000
uint64_t tcp_timeout_data; // ms, Range: 1-15,999,999,000
uint64_t tcp_timeout_half_closed; // ms, Range: 1-604,800,000
uint64_t tcp_timeout_time_wait; // ms, Range: 1-600,000
uint64_t tcp_timeout_discard; // ms, Range: 1-15,999,999,000
// 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
uint8_t duplicated_packet_filter_enable;
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;
// evicted session filter
uint8_t evicted_session_filter_enable;
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;
};
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
{
uint64_t tcp_sess_num;
uint64_t tcp_opening_sess_num;
uint64_t tcp_active_sess_num;
uint64_t tcp_closing_sess_num;
struct packet_stat dup_pkt;
struct packet_stat evc_pkt;
uint64_t udp_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_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_stat tcp_sess;
struct session_stat udp_sess;
};
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);
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);
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()
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);
// return 0: have already timeout session

View File

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

View File

@@ -12,8 +12,8 @@ struct session_table
void *arg;
uint64_t count;
struct session *least_recently_unused;
struct session *least_recently_used;
struct session *head; // 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;
}
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)
{
return;
}
if (table->least_recently_used == NULL)
sess->next_ptr = NULL;
sess->prev_ptr = NULL;
if (table->head == NULL && table->tail == NULL)
{
table->least_recently_unused = sess;
table->least_recently_used = sess;
sess->prev_ptr = NULL;
sess->next_ptr = NULL;
table->head = sess;
table->tail = sess;
}
else
{
sess->next_ptr = table->least_recently_used;
table->least_recently_used->prev_ptr = sess;
sess->prev_ptr = NULL;
table->least_recently_used = sess;
table->tail->next_ptr = sess;
sess->prev_ptr = table->tail;
table->tail = 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)
{
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;
sess->prev_ptr->next_ptr = sess->next_ptr;
}
else
{
sess->prev_ptr->next_ptr = sess->next_ptr;
table->head = sess->next_ptr;
}
if (sess->next_ptr)
{
sess->next_ptr->prev_ptr = sess->prev_ptr;
}
sess->prev_ptr = NULL;
sess->next_ptr = NULL;
else
{
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));
table->count = 0;
table->least_recently_unused = NULL;
table->least_recently_used = NULL;
table->head = NULL;
table->tail = NULL;
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)
{
return -1;
}
if (session_table_find_session(table, tuple))
if (session_table_find_tuple(table, tuple))
{
return -1;
}
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++;
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)
{
return;
}
struct session *sess = session_table_find_session(table, tuple);
struct session *sess = session_table_find_tuple(table, tuple);
if (sess == NULL)
{
return;
@@ -190,11 +186,11 @@ void session_table_del_session(struct session_table *table, const struct tuple6
{
table->free_cb(sess, table->arg);
}
session_table_del_session_from_linklist(table, sess);
del_session_from_list(table, sess);
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)
{
@@ -213,29 +209,29 @@ struct session *session_table_find_session(struct session_table *table, const st
if (sess)
{
session_table_del_session_from_linklist(table, sess);
session_table_add_session_to_linklist(table, sess);
del_session_from_list(table, sess);
add_session_to_list(table, 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)
{
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)
{
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);
// return 0: success
// return -1: failed
int session_table_add_session(struct session_table *table, const struct tuple6 *tuple, struct session *sess);
void session_table_del_session(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_least_recently_unused_session(struct session_table *table);
struct session *session_table_find_least_recently_used_session(struct session_table *table);
int session_table_add(struct session_table *table, const struct tuple6 *tuple, struct session *sess);
void session_table_del(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_lru(struct session_table *table);
struct session *session_table_find_mru(struct session_table *table);
#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;
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;
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);

View File

@@ -11,13 +11,13 @@ extern "C"
struct session_timer;
struct session_timer *session_timer_new();
void session_timer_free(struct session_timer *timer);
void session_timer_add_session(struct session_timer *timer, struct session *sess);
void session_timer_del_session(struct session_timer *timer, struct session *sess);
void session_timer_add(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.
* 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: next expire interval
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)
###############################################################################
#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)
#
#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)
#
#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)
#
#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)
#
#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)
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)
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)
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)
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)
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)
###############################################################################
# gtest state machine (UDP)
###############################################################################
#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)
#
#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)
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)
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)
###############################################################################
# gtest timeout (TCP)
###############################################################################
#add_executable(gtest_timeout_tcp_init gtest_timeout_tcp_init.cpp)
#target_link_libraries(gtest_timeout_tcp_init session_manager gtest)
#
#add_executable(gtest_timeout_tcp_handshake gtest_timeout_tcp_handshake.cpp)
#target_link_libraries(gtest_timeout_tcp_handshake session_manager gtest)
#
#add_executable(gtest_timeout_tcp_data gtest_timeout_tcp_data.cpp)
#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)
add_executable(gtest_timeout_tcp_init gtest_timeout_tcp_init.cpp)
target_link_libraries(gtest_timeout_tcp_init session_manager gtest)
add_executable(gtest_timeout_tcp_handshake gtest_timeout_tcp_handshake.cpp)
target_link_libraries(gtest_timeout_tcp_handshake session_manager gtest)
add_executable(gtest_timeout_tcp_data gtest_timeout_tcp_data.cpp)
target_link_libraries(gtest_timeout_tcp_data session_manager gtest)
###############################################################################
# gtest timeout (UDP)
###############################################################################
#add_executable(gtest_timeout_udp_data gtest_timeout_udp_data.cpp)
#target_link_libraries(gtest_timeout_udp_data session_manager gtest)
add_executable(gtest_timeout_udp_data gtest_timeout_udp_data.cpp)
target_link_libraries(gtest_timeout_udp_data session_manager gtest)
###############################################################################
# gtest filter
###############################################################################
#add_executable(gtest_filter_tcp_dupkt gtest_filter_tcp_dupkt.cpp)
#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)
add_executable(gtest_filter_tcp_dupkt gtest_filter_tcp_dupkt.cpp)
target_link_libraries(gtest_filter_tcp_dupkt session_manager gtest)
###############################################################################
# gtest overload
###############################################################################
#add_executable(gtest_overload_evict_tcp_sess gtest_overload_evict_tcp_sess.cpp)
#target_link_libraries(gtest_overload_evict_tcp_sess session_manager gtest)
#
#add_executable(gtest_overload_evict_udp_sess gtest_overload_evict_udp_sess.cpp)
#target_link_libraries(gtest_overload_evict_udp_sess session_manager gtest)
add_executable(gtest_overload_evict_tcp_sess gtest_overload_evict_tcp_sess.cpp)
target_link_libraries(gtest_overload_evict_tcp_sess session_manager gtest)
add_executable(gtest_overload_evict_udp_sess gtest_overload_evict_udp_sess.cpp)
target_link_libraries(gtest_overload_evict_udp_sess session_manager gtest)
###############################################################################
# gtest
###############################################################################
#include(GoogleTest)
#gtest_discover_tests(gtest_session)
#gtest_discover_tests(gtest_session_pool)
#gtest_discover_tests(gtest_session_table)
#gtest_discover_tests(gtest_session_timer)
#gtest_discover_tests(gtest_session_queue)
#
#gtest_discover_tests(gtest_state_tcp_init_to_opening)
#gtest_discover_tests(gtest_state_tcp_opening_to_active)
#gtest_discover_tests(gtest_state_tcp_active_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_udp_init_to_opening_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_handshake)
#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_filter_tcp_dupkt)
#gtest_discover_tests(gtest_filter_udp_eviction)
#
#gtest_discover_tests(gtest_overload_evict_tcp_sess)
#gtest_discover_tests(gtest_overload_evict_udp_sess)
include(GoogleTest)
gtest_discover_tests(gtest_session)
gtest_discover_tests(gtest_session_pool)
gtest_discover_tests(gtest_session_table)
gtest_discover_tests(gtest_session_timer)
gtest_discover_tests(gtest_session_queue)
gtest_discover_tests(gtest_state_tcp_init_to_opening)
gtest_discover_tests(gtest_state_tcp_opening_to_active)
gtest_discover_tests(gtest_state_tcp_active_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_udp_init_to_opening_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_handshake)
gtest_discover_tests(gtest_timeout_tcp_data)
gtest_discover_tests(gtest_timeout_udp_data)
gtest_discover_tests(gtest_filter_tcp_dupkt)
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
TEST(TCP_DUPKT_FILTER_ENABLE, SYN_DUP)
@@ -6,277 +53,311 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SYN_DUP)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess == NULL);
__session_dispatch(sess);
printf("<= Packet Parse: done\n\n");
// lookup session
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
printf("=> packet parse: TCP C2S SYN retransmission packet\n");
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(session_get_dup_traffic_flag(sess) == DUP_TRAFFIC_YES);
__session_dispatch(sess);
printf("\n=> Packet Parse: TCP C2S SYN retransmission packet\n");
char syn_retransmission[1500] = {0};
memcpy(syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
packet_parse(&pkt, (const char *)syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
packet_set_ip_id(&pkt, 0x1234);
printf("<= Packet Parse: done\n\n");
__session_manager_check_counter(mgr, 1, 0, 0, 0, 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);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
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);
}
#endif
#if 1
TEST(TCP_DUPKT_FILTER_ENABLE, S2C_DUP)
TEST(TCP_DUPKT_FILTER_ENABLE, SYNACK_DUP)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess == NULL);
__session_dispatch(sess);
printf("<= Packet Parse: done\n\n");
// lookup session
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
printf("=> packet parse: TCP S2C SYNACK retransmission packet\n");
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);
printf("\n=> Packet Parse: TCP S2C SYNACK retransmission packet\n");
char synack_retransmission[1500] = {0};
memcpy(synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
packet_parse(&pkt, (const char *)synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack));
packet_set_ip_id(&pkt, 0x1234);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
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);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 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);
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));
session_manager_free(mgr);
}
#endif
#if 1
TEST(TCP_DUPKT_FILTER_ENABLE, SKIP_FILTER)
TEST(TCP_DUPKT_FILTER_ENABLE, SKIP)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
const struct layer *ipv4_layer;
struct ip *hdr;
char tcp_pkt_c2s_syn_retransmission[1500] = {0};
struct session_manager_stat *stat = NULL;
char syn_retransmission[1500] = {0};
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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
printf("=> packet parse: TCP C2S SYN retransmission packet\n");
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));
ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer);
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);
printf("\n=> Packet Parse: TCP C2S SYN retransmission packet\n");
memcpy(syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
packet_parse(&pkt, (const char *)syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
packet_set_ip_id(&pkt, 0x1234);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
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);
__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
printf("=> packet parse: TCP C2S SYN retransmission packet\n");
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));
ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer);
hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1235);
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("\n=> Packet Parse: TCP C2S SYN retransmission packet\n");
memcpy(syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
packet_parse(&pkt, (const char *)syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
packet_set_ip_id(&pkt, 0x1235);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
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);
__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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
__session_dispatch(sess);
printf("<= Packet Parse: done\n\n");
__session_manager_check_counter(mgr, 1, 0, 0, 0, 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);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
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);
}
#endif
#if 1
TEST(TCP_DUPKT_FILTER_DISABLE, C2S_DUPKT)
TEST(TCP_DUPKT_FILTER_DISABLE, SYN_DUP)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
struct session_manager_options _opts;
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);
mgr = session_manager_new(&_opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
__session_dispatch(sess);
printf("<= Packet Parse: done\n\n");
// C2S SYN retransmission Packet
printf("=> packet parse: TCP C2S SYN retransmission packet\n");
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);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
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);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 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);
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);
}
#endif
#if 1
TEST(TCP_DUPKT_FILTER_DISABLE, S2C_DUP)
TEST(TCP_DUPKT_FILTER_DISABLE, SYNACK_DUP)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
struct session_manager_options _opts;
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);
mgr = session_manager_new(&_opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
EXPECT_TRUE(sess);
__session_dispatch(sess);
printf("<= Packet Parse: done\n\n");
// S2C SYNACK retransmission Packet
printf("=> packet parse: TCP S2C SYNACK retransmission packet\n");
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);
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
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);
__session_dispatch(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 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);
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);
}

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);
EXPECT_TRUE(ipv4_layer);
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
TEST(OVERLOAD, EVICT_TCP_OLD_SESS)
TEST(TCP_OVERLOAD, EVICT_TCP_OLD_SESS)
{
struct tuple6 key;
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
char buffer[1500] = {0};
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
for (uint64_t i = 0; i < opts.max_tcp_session_num; i++)
{
// C2S SYN Packet
printf("\n====================== new session (%lu) ======================\n\n", i + 1);
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);
// C2S SYN Packet
printf("\n=> Packet Parse: TCP C2S SYN packet\n");
packet_parse(&pkt, (const char *)tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
overwrite_ipv4_saddr(&pkt, 1);
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("<= Packet Parse: done\n\n");
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");
// new session
for (uint32_t i = 0; i < opts.max_tcp_session_num; i++)
{
packet_set_tcp_src_addr(&pkt, i);
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_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, 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,
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 == 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);
}
#endif
#if 1
TEST(OVERLOAD, EVICT_TCP_NEW_SESS)
TEST(TCP_OVERLOAD, EVICT_TCP_NEW_SESS)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
char buffer[1500] = {0};
struct session_manager_stat *stat = NULL;
struct session_manager_options _opts;
memcpy(&_opts, &opts, sizeof(struct session_manager_options));
_opts.tcp_overload_evict_old_sess = 0;
timestamp_update();
mgr = session_manager_new(&_opts);
mgr = session_manager_new(&_opts, 1);
EXPECT_TRUE(mgr != NULL);
for (uint64_t i = 0; i <= _opts.max_tcp_session_num; i++)
// C2S SYN Packet
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");
// new session
for (uint32_t i = 0; i < opts.max_tcp_session_num; i++)
{
// C2S SYN Packet
printf("\n====================== new session (%lu) ======================\n\n", i + 1);
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);
if (i == _opts.max_tcp_session_num)
{
EXPECT_TRUE(sess == NULL);
__session_manager_check_counter(mgr,
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
{
EXPECT_TRUE(sess);
__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,
}
__session_dispatch(sess);
session_manager_print_stat(mgr);
packet_set_tcp_src_addr(&pkt, i);
EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1));
}
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");
printf("=> Session Manager: after add %lu new sessions\n", opts.max_tcp_session_num);
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,
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++)
{
packet_set_tcp_src_addr(&pkt, opts.max_tcp_session_num + i);
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1) == NULL);
}
printf("=> Session Manager: after evicte new session\n");
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));
session_manager_free(mgr);
}
#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);
EXPECT_TRUE(ipv4_layer);
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
TEST(OVERLOAD, EVICT_UDP_OLD_SESS)
TEST(UDP_OVERLOAD, EVICT_OLD_SESS)
{
struct tuple6 key;
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
char buffer[1500] = {0};
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
for (uint64_t i = 0; i < opts.max_udp_session_num; i++)
// C2S REQ Packet
printf("\n=> Packet Parse: UDP C2S REQ packet\n");
packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
printf("<= Packet Parse: done\n\n");
// new session
for (uint32_t i = 0; i < opts.max_udp_session_num; i++)
{
// C2S REQ Packet
printf("\n====================== new session (%lu) ======================\n\n", i + 1);
printf("=> packet parse: UDP C2S REQ packet\n");
memcpy(buffer, udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
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);
packet_set_tcp_src_addr(&pkt, i);
EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1));
}
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 == 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);
__session_dispatch(sess);
session_manager_print_stat(mgr);
if (i == opts.max_udp_session_num - 1)
// evicted session
while (1)
{
sess = session_manager_get_evicted_session(mgr);
if (sess)
{
__session_manager_check_counter(mgr,
0, 0, 0, // tcp_opening_sess_num, tcp_active_sess_num, tcp_closing_sess_num,
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,
0, 1); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num,
session_manager_free_session(mgr, sess);
}
else
{
__session_manager_check_counter(mgr,
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,
break;
}
}
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));
overwrite_ipv4_saddr(&pkt, 1);
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);
for (uint32_t i = 0; i < RX_BURST_MAX; i++)
{
packet_set_tcp_src_addr(&pkt, i);
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1) == NULL); // hit evicted session, can't renew session
}
printf("=> Session Manager: after readd %d evicted sessions\n", RX_BURST_MAX);
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");
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
printf("\n====================== end status ======================\n\n");
// evicted session timeout
packet_set_tcp_src_addr(&pkt, 0);
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1 + opts.evicted_session_filter_timeout));
printf("=> Session Manager: after evicted session timeout\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,
0, 1); // udp_overload_evict_new_sess_num, udp_overload_evict_old_sess_num,
stat = session_manager_get_stat(mgr);
EXPECT_TRUE(stat);
EXPECT_TRUE(stat->udp_sess.nr_sess_used == RX_BURST_MAX + 1);
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 == 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);
}
#endif
#if 1
TEST(OVERLOAD, EVICT_UDP_NEW_SESS)
TEST(UDP_OVERLOAD, EVICT_NEW_SESS)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
char buffer[1500] = {0};
struct session_manager_stat *stat = NULL;
struct session_manager_options _opts;
memcpy(&_opts, &opts, sizeof(struct session_manager_options));
_opts.udp_overload_evict_old_sess = 0;
timestamp_update();
mgr = session_manager_new(&_opts);
mgr = session_manager_new(&_opts, 1);
EXPECT_TRUE(mgr != NULL);
for (uint64_t i = 0; i <= _opts.max_udp_session_num; i++)
// C2S REQ Packet
printf("\n=> Packet Parse: UDP C2S REQ packet\n");
packet_parse(&pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
printf("<= Packet Parse: done\n\n");
// new session
for (uint32_t i = 0; i < opts.max_udp_session_num; i++)
{
// C2S REQ Packet
printf("\n====================== new session (%lu) ======================\n\n", i + 1);
printf("=> packet parse: UDP C2S REQ packet\n");
memcpy(buffer, udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
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)
{
EXPECT_TRUE(sess == NULL);
__session_manager_check_counter(mgr,
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
{
EXPECT_TRUE(sess);
__session_manager_check_counter(mgr,
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,
}
__session_dispatch(sess);
session_manager_print_stat(mgr);
packet_set_tcp_src_addr(&pkt, i);
EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1));
}
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");
printf("=> Session Manager: after add %lu new sessions\n", opts.max_udp_session_num);
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,
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++)
{
packet_set_tcp_src_addr(&pkt, opts.max_udp_session_num + i);
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
EXPECT_TRUE(session_manager_new_session(mgr, &pkt, 1) == NULL);
}
printf("=> Session Manager: after readd %d evicted session\n", RX_BURST_MAX);
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));
session_manager_free(mgr);
}
#endif

View File

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

View File

@@ -18,8 +18,8 @@ TEST(SESSION_TIMER, ADD_DEL)
session_set_id(&sess, 1);
session_set_expirecb(&sess, session_expire, NULL, 1000);
session_timer_add_session(timer, &sess);
session_timer_del_session(timer, &sess);
session_timer_add(timer, &sess);
session_timer_del(timer, &sess);
session_timer_free(timer);
}
@@ -43,16 +43,16 @@ TEST(SESSION_TIMER, EXPIRE)
session_set_expirecb(&sess2, session_expire, NULL, 5);
session_set_expirecb(&sess3, session_expire, NULL, 10);
session_timer_add_session(timer, &sess1);
session_timer_add_session(timer, &sess2);
session_timer_add_session(timer, &sess3);
session_timer_add(timer, &sess1);
session_timer_add(timer, &sess2);
session_timer_add(timer, &sess3);
for (uint64_t abs_current_ts = 0; abs_current_ts < 15; abs_current_ts++)
{
printf("current timestamp %lu\n", abs_current_ts);
do
{
sess = session_timer_expire_session(timer, abs_current_ts);
sess = session_timer_expire(timer, abs_current_ts);
if (sess != NULL)
{
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(&sess3, session_expire, NULL, 10);
session_timer_add_session(timer, &sess1);
session_timer_add_session(timer, &sess2);
session_timer_add_session(timer, &sess3);
session_timer_add(timer, &sess1);
session_timer_add(timer, &sess2);
session_timer_add(timer, &sess3);
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)
{
printf("delete timer 2\n");
session_timer_del_session(timer, &sess2);
session_timer_del(timer, &sess2);
}
do
{
sess = session_timer_expire_session(timer, abs_current_ts);
sess = session_timer_expire(timer, abs_current_ts);
if (sess != NULL)
{
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(&sess3, session_expire, NULL, 10);
session_timer_add_session(timer, &sess1);
session_timer_add_session(timer, &sess2);
session_timer_add_session(timer, &sess3);
session_timer_add(timer, &sess1);
session_timer_add(timer, &sess2);
session_timer_add(timer, &sess3);
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)
{
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_timer_add_session(timer, &sess2);
session_timer_add(timer, &sess2);
}
do
{
sess = session_timer_expire_session(timer, abs_current_ts);
sess = session_timer_expire(timer, abs_current_ts);
if (sess != NULL)
{
session_run_expirecb(sess);
@@ -169,26 +169,26 @@ TEST(SESSION_TIMER, NEXT_EXPIRE_INTERVAL)
EXPECT_TRUE(session_timer_next_expire_interval(timer) == UINT64_MAX);
session_timer_add_session(timer, &sess1);
session_timer_add_session(timer, &sess2);
session_timer_add(timer, &sess1);
session_timer_add(timer, &sess2);
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_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_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_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_expire_session(timer, 1010));
EXPECT_TRUE(session_timer_expire(timer, 1010));
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);
session_timer_free(timer);

View File

@@ -1,80 +1,70 @@
// 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)
{
char buffer[1024] = {0};
struct packet pkt;
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
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_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();
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
}
/******************************************************************************
@@ -88,55 +78,35 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_FIN_FIN)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet & C2S DATA Packet
build_active_tcp_session(mgr, sess);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
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_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();
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_packets(sess) == 1 + 1 + 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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 3);
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_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_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);
__session_manager_wait(mgr, CLOSING_BY_CLIENT_FIN);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
sess = session_manager_get_expired_session(mgr, 3 + 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_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);
}
@@ -179,17 +170,16 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_C2S_RST)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet & C2S DATA Packet
build_active_tcp_session(mgr, sess);
// 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};
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));
@@ -198,9 +188,13 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_C2S_RST)
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
tcp_hdr_set_flags(hdr, 0);
tcp_hdr_set_rst_flag(hdr, true);
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 3);
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_RST_RECVED));
EXPECT_TRUE(session_get0_c2s_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);
__session_manager_wait(mgr, CLOSING_BY_CLIENT_RST);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
sess = session_manager_get_expired_session(mgr, 3 + 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_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);
}
@@ -243,17 +258,16 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_S2C_RST)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet & C2S DATA Packet
build_active_tcp_session(mgr, sess);
// 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};
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));
@@ -262,9 +276,13 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_S2C_RST)
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
tcp_hdr_set_flags(hdr, 0);
tcp_hdr_set_rst_flag(hdr, true);
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_packets(sess) == 1 + 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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 3);
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_C2S_ACK_RECVED | TCP_C2S_DATA_RECVED | TCP_S2C_RST_RECVED));
EXPECT_TRUE(session_get0_c2s_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);
__session_manager_wait(mgr, CLOSING_BY_SERVER_RST);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
sess = session_manager_get_expired_session(mgr, 3 + 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_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);
}
@@ -305,18 +344,41 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_DATA_TIMEOUT)
{
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet & C2S DATA Packet
build_active_tcp_session(mgr, sess);
__session_manager_check_counter(mgr, 0, 1, 0, 0, 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);
// 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);
// 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);
}
@@ -333,27 +395,30 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_C2S_HALF_CLOSED_TIMEOUT)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet & C2S DATA Packet
build_active_tcp_session(mgr, sess);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
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_ACTIVE);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSING);
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);
@@ -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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 3);
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_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);
__session_manager_wait(mgr, CLOSING_BY_CLIENT_FIN);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
sess = session_manager_get_expired_session(mgr, 3 + 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_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);
}
@@ -390,27 +476,30 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_S2C_HALF_CLOSED_TIMEOUT)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// C2S SYN Packet & C2S DATA Packet
build_active_tcp_session(mgr, sess);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
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_ACTIVE);
EXPECT_TRUE(session_get_state(sess) == SESSION_STATE_CLOSING);
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_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_c2s_packets(sess) == 1 + 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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 3);
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_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_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);
__session_manager_wait(mgr, CLOSING_BY_SERVER_FIN);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
sess = session_manager_get_expired_session(mgr, 3 + 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_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);
}

View File

@@ -1,6 +1,44 @@
// 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)
@@ -13,17 +51,20 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 1);
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_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 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
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);
}
@@ -68,17 +131,20 @@ TEST(TCP_INIT_TO_OPENING, BY_SYNACK)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n");
// S2C SYNACK Packet
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 1);
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_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 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);
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);
}
@@ -123,53 +211,32 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_SYNACK)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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();
// SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n");
// S2C SYNACK Packet
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
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_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_handshake) == NULL);
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);
}
@@ -213,88 +302,43 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_SYNACK_ACK)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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();
// SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n");
// S2C SYNACK Packet
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
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) == 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");
// C2S ACK Packet
printf("\n=> Packet Parse: TCP C2S ACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt3_c2s_ack, sizeof(tcp_pkt3_c2s_ack));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_packets(sess) == 1 + 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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 3);
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_SYNACK_RECVED | TCP_C2S_ACK_RECVED));
EXPECT_TRUE(session_get0_c2s_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 3 + opts.tcp_timeout_data) == NULL);
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);
}
@@ -339,59 +405,37 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_RETRANSMISSION)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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
printf("=> packet parse: TCP C2S SYN retransmission packet\n");
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));
printf("\n=> Packet Parse: TCP C2S SYN retransmission packet\n");
char syn_retransmission[1500] = {0};
memcpy(syn_retransmission, tcp_pkt1_c2s_syn, 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);
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);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
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_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_init) == NULL);
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);
}
@@ -437,49 +503,24 @@ TEST(TCP_INIT_TO_OPENING, BY_SYNACK_RETRANSMISSION)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n");
// S2C SYNACK Packet
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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
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};
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));
@@ -487,9 +528,13 @@ TEST(TCP_INIT_TO_OPENING, BY_SYNACK_RETRANSMISSION)
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);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_packets(sess) == 0);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
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_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_handshake) == NULL);
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);
}
@@ -533,53 +600,32 @@ TEST(TCP_INIT_TO_OPENING, BY_C2S_ASMMETRIC)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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();
// ACK Packet
printf("=> packet parse: TCP C2S ACK packet\n");
// C2S ACK Packet
printf("\n=> Packet Parse: TCP C2S ACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt3_c2s_ack, sizeof(tcp_pkt3_c2s_ack));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
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));
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_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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);
}
@@ -623,53 +691,32 @@ TEST(TCP_INIT_TO_OPENING, BY_S2C_ASMMETRIC)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n");
// S2C SYNACK Packet
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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();
// ACK Packet
printf("=> packet parse: TCP S2C ACK packet\n");
// S2C ACK Packet
printf("\n=> Packet Parse: TCP S2C ACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt5_s2c_ack, sizeof(tcp_pkt5_s2c_ack));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_packets(sess) == 0);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
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 | TCP_S2C_ACK_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_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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);
}

View File

@@ -1,6 +1,43 @@
// 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
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 session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 1);
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();
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
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);
__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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_packets(sess) == 1 + 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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 3);
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_SYNACK_RECVED | TCP_C2S_ACK_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();
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 4) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_packets(sess) == 1 + 1 + 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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 4);
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_SYNACK_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();
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 5) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_packets(sess) == 1 + 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_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 5);
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 | 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_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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 6) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_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_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 6);
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 | 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_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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 7) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_packets(sess) == 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_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 7);
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 | 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_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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 8) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_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_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 8);
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_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_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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 9) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
memset(buffer, 0, 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_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_dup_traffic_flag(sess) == DUP_TRAFFIC_NO);
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_c2s_packets(sess) == 1 + 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_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 9);
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_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_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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 10) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_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_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 10);
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 | 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_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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 11) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_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_new_time(sess) < timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 11);
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_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_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);
__session_manager_wait(mgr, CLOSING_BY_CLIENT_FIN);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
sess = session_manager_get_expired_session(mgr, 11 + 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_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);
}

View File

@@ -1,6 +1,43 @@
// 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)
@@ -13,53 +50,32 @@ TEST(TCP_OPENING_TO_ACTIVE, BY_SYN_C2S_DATA)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
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_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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);
}
@@ -102,53 +140,32 @@ TEST(TCP_OPENING_TO_ACTIVE, BY_SYNACK_S2C_DATA)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n");
// S2C SYNACK Packet
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_packets(sess) == 0);
EXPECT_TRUE(session_get_s2c_packets(sess) == 1 + 1);
EXPECT_TRUE(session_get_new_time(sess) < timestamp_get_sec());
EXPECT_TRUE(session_get_last_time(sess) == timestamp_get_sec());
EXPECT_TRUE(session_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
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 | TCP_S2C_ACK_RECVED | TCP_S2C_DATA_RECVED));
EXPECT_TRUE(session_get0_c2s_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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);
}

View File

@@ -1,47 +1,44 @@
// 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)
{
char buffer[1024] = {0};
struct packet pkt;
#include "tcp_utils.h"
#include "test_packets.h"
// 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);
struct session_manager_options opts = {
// max session number
.max_tcp_session_num = 256,
.max_udp_session_num = 256,
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 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
__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);
timestamp_update();
}
// 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 -> closing (by FIN-FIN)
@@ -54,55 +51,43 @@ TEST(TCP_OPENING_TO_CLOSING, BY_FIN_FIN)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
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) == 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();
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_packets(sess) == 1 + 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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 3);
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_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_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);
__session_manager_wait(mgr, CLOSING_BY_CLIENT_FIN);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
sess = session_manager_get_expired_session(mgr, 3 + 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_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);
}
@@ -145,17 +151,24 @@ TEST(TCP_OPENING_TO_CLOSING, BY_C2S_RST)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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
printf("=> packet parse: TCP C2S RST packet\n");
printf("\n=> Packet Parse: TCP C2S RST packet\n");
char tcp_pkt_c2s_rst[1500] = {0};
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));
@@ -164,9 +177,13 @@ TEST(TCP_OPENING_TO_CLOSING, BY_C2S_RST)
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
tcp_hdr_set_flags(hdr, 0);
tcp_hdr_set_rst_flag(hdr, true);
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
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_RST_RECVED));
EXPECT_TRUE(session_get0_c2s_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);
__session_manager_wait(mgr, CLOSING_BY_CLIENT_RST);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
sess = session_manager_get_expired_session(mgr, 2 + 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_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);
}
@@ -209,17 +247,24 @@ TEST(TCP_OPENING_TO_CLOSING, BY_S2C_RST)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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
printf("=> packet parse: TCP S2C RST packet\n");
printf("\n=> Packet Parse: TCP S2C RST packet\n");
char tcp_pkt_s2c_rst[1500] = {0};
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));
@@ -228,9 +273,13 @@ TEST(TCP_OPENING_TO_CLOSING, BY_S2C_RST)
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
tcp_hdr_set_flags(hdr, 0);
tcp_hdr_set_rst_flag(hdr, true);
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
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_S2C_RST_RECVED));
EXPECT_TRUE(session_get0_c2s_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);
__session_manager_wait(mgr, CLOSING_BY_SERVER_RST);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
sess = session_manager_get_expired_session(mgr, 2 + 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_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);
}
@@ -269,20 +339,52 @@ TEST(TCP_OPENING_TO_CLOSING, BY_S2C_RST)
#if 1
TEST(TCP_OPENING_TO_CLOSING, BY_INIT_TIMEOUT)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// lookup session
EXPECT_TRUE(session_manager_lookup_session(mgr, &pkt) == NULL);
// 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);
}
@@ -299,21 +401,32 @@ TEST(TCP_OPENING_TO_CLOSING, BY_HANDSHAKE_TIMEOUT)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
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_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.tcp_timeout_handshake) == NULL);
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);
}
@@ -357,56 +491,43 @@ TEST(TCP_OPENING_TO_CLOSING, BY_DATA_TIMEOUT)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
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) == 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");
// C2S ACK Packet
printf("\n=> Packet Parse: TCP C2S ACK packet\n");
packet_parse(&pkt, (const char *)tcp_pkt3_c2s_ack, sizeof(tcp_pkt3_c2s_ack));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 3) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_c2s_packets(sess) == 1 + 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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 3);
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_SYNACK_RECVED | TCP_C2S_ACK_RECVED));
EXPECT_TRUE(session_get0_c2s_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 3 + opts.tcp_timeout_data) == NULL);
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);
}
#endif
/******************************************************************************
* case: TCP opening -> closing (by C2S half closed timeout)
* case: TCP opening -> closing (by C2S half FIN)
******************************************************************************/
#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};
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
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_state(sess) == SESSION_STATE_CLOSING);
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);
@@ -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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
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_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);
__session_manager_wait(mgr, CLOSING_BY_CLIENT_FIN);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
sess = session_manager_get_expired_session(mgr, 2 + 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_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);
}
#endif
/******************************************************************************
* case: TCP opening -> closing (by S2C half closed timeout)
* case: TCP opening -> closing (by S2C half FIN)
******************************************************************************/
#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};
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
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_state(sess) == SESSION_STATE_CLOSING);
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_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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
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_S2C_ACK_RECVED | TCP_S2C_FIN_RECVED));
EXPECT_TRUE(session_get0_c2s_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);
__session_manager_wait(mgr, CLOSING_BY_SERVER_FIN);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
sess = session_manager_get_expired_session(mgr, 2 + 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_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);
}

View File

@@ -1,14 +1,43 @@
// UDP state machine test: init -> opening -> active -> closing
#include <gtest/gtest.h>
#include "test_utils.h"
#include "session.h"
#include "session_manager.h"
/******************************************************************************
* case: UDP init -> opening (by C2S Packet)
*
* case UDP opening -> active (by S2C Packet)
*
* case UDP active -> closing (by timeout)
******************************************************************************/
#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
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 session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 1);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
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_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
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
EXPECT_TRUE(sess);
// update session
EXPECT_TRUE(session_manager_update_session(mgr, sess, &pkt, 2) == 0);
EXPECT_TRUE(session_get_id(sess) != 0);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 2);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
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_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.udp_timeout_data) == NULL); // active -> closing
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);
}

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 opening -> closing (by timeout)
* ******************************************************************************/
@@ -15,17 +51,20 @@ TEST(UDP_INIT_TO_OPENING_TO_CLOSING, BY_C2S)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 1);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
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_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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 1 + opts.udp_timeout_data) == NULL); // opening -> closing
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);
}
@@ -61,7 +121,6 @@ TEST(UDP_INIT_TO_OPENING_TO_CLOSING, BY_C2S)
/******************************************************************************
* case: UDP init -> opening (by S2C Packet)
*
* case: UDP opening -> closing (by timeout)
******************************************************************************/
@@ -72,17 +131,20 @@ TEST(UDP_INIT_TO_OPENING_TO_CLOSING, BY_S2C)
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
struct session_manager_stat *stat = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
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_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_get_new_time(sess) == 1);
EXPECT_TRUE(session_get_last_time(sess) == 1);
EXPECT_TRUE(session_get0_cur_pkt(sess) == &pkt);
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_s2c_1st_pkt(sess) != NULL);
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);
__session_manager_wait(mgr, CLOSING_BY_TIMEOUT);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 1 + opts.udp_timeout_data) == NULL); // opening -> closing
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);
}

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
TEST(TIMEOUT, TCP_TIMEOUT_DATA)
@@ -7,31 +45,40 @@ TEST(TIMEOUT, TCP_TIMEOUT_DATA)
struct session *sess = NULL;
struct session_manager *mgr = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
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);
__session_manager_check_tcp_timeout_data(mgr, &opts);
__session_manager_check_tcp_timeout_time_wait(mgr, &opts);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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);
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
TEST(TIMEOUT, TCP_TIMEOUT_HANDSHAKE)
@@ -7,24 +46,29 @@ TEST(TIMEOUT, TCP_TIMEOUT_HANDSHAKE)
struct session *sess = NULL;
struct session_manager *mgr = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// SYNACK Packet
printf("=> packet parse: TCP S2C SYNACK packet\n");
// S2C SYNACK Packet
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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
__session_manager_check_tcp_timeout_handshake(mgr, &opts);
__session_manager_check_tcp_timeout_time_wait(mgr, &opts);
__session_manager_check_counter(mgr, 0, 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);
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);
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
TEST(TIMEOUT, TCP_TIMEOUT_INIT1)
TEST(TIMEOUT, TCP_TIMEOUT_INIT)
{
struct packet pkt;
struct session *sess = NULL;
struct session_manager *mgr = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
__session_manager_check_tcp_timeout_init(mgr, &opts);
__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);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 1 + opts.tcp_timeout_init) == NULL); // opening -> closing
sess = session_manager_get_expired_session(mgr, 1 + opts.tcp_timeout_init + opts.tcp_timeout_time_wait); // closing -> closed
EXPECT_TRUE(sess);
__session_manager_check_counter(mgr, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
__session_manager_check_tcp_timeout_init(mgr, &opts);
__session_manager_check_tcp_timeout_time_wait(mgr, &opts);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
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);
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
TEST(TIMEOUT, UDP_TIMEOUT_DATA1)
@@ -7,24 +45,29 @@ TEST(TIMEOUT, UDP_TIMEOUT_DATA1)
struct session *sess = NULL;
struct session_manager *mgr = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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);
__session_manager_check_counter(mgr, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
__session_manager_check_udp_timeout_data(mgr, &opts, SESSION_STATE_OPENING);
EXPECT_TRUE(session_manager_get_expired_session(mgr) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 1 + opts.udp_timeout_data) == NULL); // opening -> closing
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);
session_manager_free(mgr);
}
@@ -37,31 +80,40 @@ TEST(TIMEOUT, UDP_TIMEOUT_DATA2)
struct session *sess = NULL;
struct session_manager *mgr = NULL;
timestamp_update();
mgr = session_manager_new(&opts);
mgr = session_manager_new(&opts, 1);
EXPECT_TRUE(mgr != NULL);
// 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
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 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));
printf("<= packet parse\n\n");
sess = session_manager_update_session(mgr, &pkt);
printf("<= Packet Parse: done\n\n");
// lookup session
sess = session_manager_lookup_session(mgr, &pkt);
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);
__session_manager_check_udp_timeout_data(mgr, &opts, SESSION_STATE_ACTIVE);
EXPECT_TRUE(session_manager_get_expired_session(mgr) == NULL);
__session_manager_check_counter(mgr, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
// expire session
EXPECT_TRUE(session_manager_get_expired_session(mgr, 2 + opts.udp_timeout_data) == NULL); // active -> closing
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);
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)
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)

View File

@@ -137,7 +137,7 @@ static void *main_loop(void *arg)
int nr_recv;
int need_drop_pkt = 1; // TODO
uint64_t now_sec = 0;
uint64_t now = 0;
uint16_t thr_idx = threads_ctx->index;
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)
{
now_sec = timestamp_get_sec(); // TODO
now = timestamp_get_msec(); // TODO
nr_recv = packet_io_ingress(packet_io, thr_idx, packets, RX_BURST_MAX);
if (nr_recv == 0)
{
@@ -166,7 +166,7 @@ static void *main_loop(void *arg)
// call plugin_manager_dispatch_raw_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)
{
continue;
@@ -183,19 +183,17 @@ static void *main_loop(void *arg)
sess = session_manager_lookup_session(sess_mgr, pkt);
if (sess == NULL)
{
sess = session_manager_new_session(sess_mgr, pkt);
sess = session_manager_new_session(sess_mgr, pkt, now);
if (sess == NULL)
{
continue;
}
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);
}
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);
}
@@ -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);
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)
{
uint64_t now = timestamp_get_msec();
for (uint8_t i = 0; i < nr_threads; 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->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)
{
STELLAR_LOG_ERROR("unable to create session manager");

View File

@@ -9,7 +9,7 @@ extern "C"
#include <stdint.h>
#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_DEC(x) __atomic_fetch_sub(x, 1, __ATOMIC_RELAXED)