reactor packet I/O & duplicated packet filter & evicted session filter

This commit is contained in:
luwenpeng
2024-03-09 19:28:14 +08:00
parent ee35a26a9d
commit 512dfddd03
79 changed files with 1974 additions and 2093 deletions

View File

@@ -37,14 +37,14 @@ tcp_timeout_discard = 90 # seconds, Range: 1-15,999,999
# UDP timeout # UDP timeout
udp_timeout_data = 10 # seconds, Range: 1-15,999,999 udp_timeout_data = 10 # seconds, Range: 1-15,999,999
# TCP duplicate packet filter # duplicate packet filter
tcp_dupkt_filter_enable = 1 duplicated_packet_filter_enable = 1
tcp_dupkt_filter_capacity = 1000000 duplicated_packet_filter_capacity = 1000000
tcp_dupkt_filter_timeout = 10 # seconds, Range: 1-60 duplicated_packet_filter_timeout = 10 # seconds, Range: 1-60
tcp_dupkt_filter_error_rate = 0.00001 duplicated_packet_filter_error_rate = 0.00001
# UDP eviction filter # evicted session filter
udp_eviction_filter_enable = 1 evicted_session_filter_enable = 1
udp_eviction_filter_capacity = 1000000 evicted_session_filter_capacity = 1000000
udp_eviction_filter_timeout = 10 # seconds, Range: 1-60 evicted_session_filter_timeout = 10 # seconds, Range: 1-60
udp_eviction_filter_error_rate = 0.00001 evicted_session_filter_error_rate = 0.00001

View File

@@ -6,8 +6,8 @@ add_subdirectory(packet)
add_subdirectory(packet_io) add_subdirectory(packet_io)
add_subdirectory(id_generator) add_subdirectory(id_generator)
add_subdirectory(ip_reassembly) add_subdirectory(ip_reassembly)
add_subdirectory(dupkt_filter) add_subdirectory(duplicated_packet_filter)
add_subdirectory(eviction_filter) add_subdirectory(evicted_session_filter)
add_subdirectory(session) add_subdirectory(session)
add_subdirectory(config) add_subdirectory(config)
add_subdirectory(stellar) add_subdirectory(stellar)

View File

@@ -1,7 +1,3 @@
###############################################################################
# config
###############################################################################
add_library(config config.cpp) add_library(config config.cpp)
target_include_directories(config PUBLIC ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(config PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(config toml packet_io ip_reassembly session_manager) target_link_libraries(config toml packet_io ip_reassembly session_manager)

View File

@@ -7,53 +7,53 @@
// return 0: success // return 0: success
// retuun -1: failed // retuun -1: failed
static int parse_device_options(struct device_options *dev_opts, toml_table_t *conf_file_handle) static int parse_device_options(toml_table_t *table, struct device_options *opts)
{ {
const char *ptr; const char *ptr;
toml_table_t *device_table; toml_table_t *device;
device_table = toml_table_in(conf_file_handle, "device"); device = toml_table_in(table, "device");
if (device_table == NULL) if (device == NULL)
{ {
CONFIG_LOG_ERROR("config file missing device section"); CONFIG_LOG_ERROR("config file missing device section");
return -1; return -1;
} }
ptr = toml_raw_in(device_table, "device_base"); ptr = toml_raw_in(device, "device_base");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing device.device_base"); CONFIG_LOG_ERROR("config file missing device.device_base");
return -1; return -1;
} }
dev_opts->device_base = atoi(ptr); opts->device_base = atoi(ptr);
ptr = toml_raw_in(device_table, "device_offset"); ptr = toml_raw_in(device, "device_offset");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing device.device_offset"); CONFIG_LOG_ERROR("config file missing device.device_offset");
return -1; return -1;
} }
dev_opts->device_offset = atoi(ptr); opts->device_offset = atoi(ptr);
return 0; return 0;
} }
// return 0: success // return 0: success
// retuun -1: failed // retuun -1: failed
static int parse_packet_io_options(struct packet_io_options *pkt_io_opts, toml_table_t *conf_file_handle) static int parse_packet_io_options(toml_table_t *table, struct packet_io_options *opts)
{ {
const char *ptr; const char *ptr;
toml_table_t *packet_io_table; toml_table_t *packet_io;
toml_array_t *mask_array; toml_array_t *mask_array;
packet_io_table = toml_table_in(conf_file_handle, "packet_io"); packet_io = toml_table_in(table, "packet_io");
if (packet_io_table == NULL) if (packet_io == NULL)
{ {
CONFIG_LOG_ERROR("config file missing packet_io section"); CONFIG_LOG_ERROR("config file missing packet_io section");
return -1; return -1;
} }
ptr = toml_raw_in(packet_io_table, "mode"); ptr = toml_raw_in(packet_io, "mode");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing packet_io.mode"); CONFIG_LOG_ERROR("config file missing packet_io.mode");
@@ -61,11 +61,11 @@ static int parse_packet_io_options(struct packet_io_options *pkt_io_opts, toml_t
} }
if (strcmp(ptr, "dumpfile") == 0) if (strcmp(ptr, "dumpfile") == 0)
{ {
pkt_io_opts->mode = PACKET_IO_DUMPFILE; opts->mode = PACKET_IO_DUMPFILE;
} }
else if (strcmp(ptr, "marsio") == 0) else if (strcmp(ptr, "marsio") == 0)
{ {
pkt_io_opts->mode = PACKET_IO_MARSIO; opts->mode = PACKET_IO_MARSIO;
} }
else else
{ {
@@ -73,37 +73,37 @@ static int parse_packet_io_options(struct packet_io_options *pkt_io_opts, toml_t
return -1; return -1;
} }
if (pkt_io_opts->mode == PACKET_IO_DUMPFILE) if (opts->mode == PACKET_IO_DUMPFILE)
{ {
ptr = toml_raw_in(packet_io_table, "dumpfile_dir"); ptr = toml_raw_in(packet_io, "dumpfile_dir");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing packet_io.dumpfile_dir"); CONFIG_LOG_ERROR("config file missing packet_io.dumpfile_dir");
return -1; return -1;
} }
// skip "" // skip ""
strncpy(pkt_io_opts->dumpfile_dir, ptr + 1, strlen(ptr) - 2); strncpy(opts->dumpfile_dir, ptr + 1, strlen(ptr) - 2);
} }
else else
{ {
ptr = toml_raw_in(packet_io_table, "app_symbol"); ptr = toml_raw_in(packet_io, "app_symbol");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing packet_io.app_symbol"); CONFIG_LOG_ERROR("config file missing packet_io.app_symbol");
return -1; return -1;
} }
strncpy(pkt_io_opts->app_symbol, ptr, sizeof(pkt_io_opts->app_symbol) - 1); strncpy(opts->app_symbol, ptr, sizeof(opts->app_symbol) - 1);
ptr = toml_raw_in(packet_io_table, "dev_symbol"); ptr = toml_raw_in(packet_io, "dev_symbol");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing packet_io.dev_symbol"); CONFIG_LOG_ERROR("config file missing packet_io.dev_symbol");
return -1; return -1;
} }
strncpy(pkt_io_opts->dev_symbol, ptr, sizeof(pkt_io_opts->dev_symbol) - 1); strncpy(opts->dev_symbol, ptr, sizeof(opts->dev_symbol) - 1);
} }
ptr = toml_raw_in(packet_io_table, "nr_threads"); ptr = toml_raw_in(packet_io, "nr_threads");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing packet_io.nr_threads"); CONFIG_LOG_ERROR("config file missing packet_io.nr_threads");
@@ -114,15 +114,15 @@ static int parse_packet_io_options(struct packet_io_options *pkt_io_opts, toml_t
CONFIG_LOG_ERROR("config file invalid packet_io.nr_threads %d, range [1, %d]", atoi(ptr), MAX_THREAD_NUM); CONFIG_LOG_ERROR("config file invalid packet_io.nr_threads %d, range [1, %d]", atoi(ptr), MAX_THREAD_NUM);
return -1; return -1;
} }
pkt_io_opts->nr_threads = atoi(ptr); opts->nr_threads = atoi(ptr);
mask_array = toml_array_in(packet_io_table, "cpu_mask"); mask_array = toml_array_in(packet_io, "cpu_mask");
if (mask_array == NULL) if (mask_array == NULL)
{ {
CONFIG_LOG_ERROR("config file missing packet_io.cpu_mask"); CONFIG_LOG_ERROR("config file missing packet_io.cpu_mask");
return -1; return -1;
} }
for (uint8_t i = 0; i < pkt_io_opts->nr_threads; i++) for (uint8_t i = 0; i < opts->nr_threads; i++)
{ {
ptr = toml_raw_at(mask_array, i); ptr = toml_raw_at(mask_array, i);
if (ptr == NULL) if (ptr == NULL)
@@ -130,7 +130,7 @@ static int parse_packet_io_options(struct packet_io_options *pkt_io_opts, toml_t
CONFIG_LOG_ERROR("config file missing packet_io.cpu_mask[%d]", i); CONFIG_LOG_ERROR("config file missing packet_io.cpu_mask[%d]", i);
return -1; return -1;
} }
pkt_io_opts->cpu_mask[i] = atoi(ptr); opts->cpu_mask[i] = atoi(ptr);
} }
return 0; return 0;
@@ -138,269 +138,269 @@ static int parse_packet_io_options(struct packet_io_options *pkt_io_opts, toml_t
// return 0: success // return 0: success
// retuun -1: failed // retuun -1: failed
static int parse_ip_reassembly_options(struct ip_reassembly_options *ip_reass_opts, toml_table_t *conf_file_handle) static int parse_ip_reassembly_options(toml_table_t *table, struct ip_reassembly_options *opts)
{ {
const char *ptr; const char *ptr;
toml_table_t *ip_reass_table; toml_table_t *ip_reassembly;
ip_reass_table = toml_table_in(conf_file_handle, "ip_reassembly"); ip_reassembly = toml_table_in(table, "ip_reassembly");
if (ip_reass_table == NULL) if (ip_reassembly == NULL)
{ {
CONFIG_LOG_ERROR("config file missing ip_reassembly section"); CONFIG_LOG_ERROR("config file missing ip_reassembly section");
return -1; return -1;
} }
ptr = toml_raw_in(ip_reass_table, "enable"); ptr = toml_raw_in(ip_reassembly, "enable");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing ip_reassembly.enable"); CONFIG_LOG_ERROR("config file missing ip_reassembly.enable");
return -1; return -1;
} }
ip_reass_opts->enable = atoi(ptr); opts->enable = atoi(ptr);
ptr = toml_raw_in(ip_reass_table, "timeout"); ptr = toml_raw_in(ip_reassembly, "timeout");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing ip_reassembly.timeout"); CONFIG_LOG_ERROR("config file missing ip_reassembly.timeout");
return -1; return -1;
} }
ip_reass_opts->timeout = atoi(ptr); opts->timeout = atoi(ptr);
ptr = toml_raw_in(ip_reass_table, "bucket_entries"); ptr = toml_raw_in(ip_reassembly, "bucket_entries");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing ip_reassembly.bucket_entries"); CONFIG_LOG_ERROR("config file missing ip_reassembly.bucket_entries");
return -1; return -1;
} }
ip_reass_opts->bucket_entries = atoi(ptr); opts->bucket_entries = atoi(ptr);
ptr = toml_raw_in(ip_reass_table, "bucket_num"); ptr = toml_raw_in(ip_reassembly, "bucket_num");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing ip_reassembly.bucket_num"); CONFIG_LOG_ERROR("config file missing ip_reassembly.bucket_num");
return -1; return -1;
} }
ip_reass_opts->bucket_num = atoi(ptr); opts->bucket_num = atoi(ptr);
return 0; return 0;
} }
// return 0: success // return 0: success
// retuun -1: failed // retuun -1: failed
static int parse_session_manager_options(struct session_manager_options *sess_mgr_opts, toml_table_t *conf_file_handle) static int parse_session_manager_options(toml_table_t *table, struct session_manager_options *opts)
{ {
const char *ptr; const char *ptr;
toml_table_t *sess_mgr_table; toml_table_t *session_manager;
sess_mgr_table = toml_table_in(conf_file_handle, "session_manager"); session_manager = toml_table_in(table, "session_manager");
if (sess_mgr_table == NULL) if (session_manager == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager section"); CONFIG_LOG_ERROR("config file missing session_manager section");
return -1; return -1;
} }
// max session number // max session number
ptr = toml_raw_in(sess_mgr_table, "max_tcp_session_num"); ptr = toml_raw_in(session_manager, "max_tcp_session_num");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.max_tcp_session_num"); CONFIG_LOG_ERROR("config file missing session_manager.max_tcp_session_num");
return -1; return -1;
} }
sess_mgr_opts->max_tcp_session_num = atoll(ptr); opts->max_tcp_session_num = atoll(ptr);
ptr = toml_raw_in(sess_mgr_table, "max_udp_session_num"); ptr = toml_raw_in(session_manager, "max_udp_session_num");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.max_udp_session_num"); CONFIG_LOG_ERROR("config file missing session_manager.max_udp_session_num");
return -1; return -1;
} }
sess_mgr_opts->max_udp_session_num = atoll(ptr); opts->max_udp_session_num = atoll(ptr);
// session overload (1: evict old session, 0: bypass new session) // session overload (1: evict old session, 0: bypass new session)
ptr = toml_raw_in(sess_mgr_table, "tcp_overload_evict_old_sess"); ptr = toml_raw_in(session_manager, "tcp_overload_evict_old_sess");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.tcp_overload_evict_old_sess"); CONFIG_LOG_ERROR("config file missing session_manager.tcp_overload_evict_old_sess");
return -1; return -1;
} }
sess_mgr_opts->tcp_overload_evict_old_sess = atoi(ptr); opts->tcp_overload_evict_old_sess = atoi(ptr);
ptr = toml_raw_in(sess_mgr_table, "udp_overload_evict_old_sess"); ptr = toml_raw_in(session_manager, "udp_overload_evict_old_sess");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.udp_overload_evict_old_sess"); CONFIG_LOG_ERROR("config file missing session_manager.udp_overload_evict_old_sess");
return -1; return -1;
} }
sess_mgr_opts->udp_overload_evict_old_sess = atoi(ptr); opts->udp_overload_evict_old_sess = atoi(ptr);
// TCP timeout // TCP timeout
ptr = toml_raw_in(sess_mgr_table, "tcp_timeout_init"); ptr = toml_raw_in(session_manager, "tcp_timeout_init");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_init"); CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_init");
return -1; return -1;
} }
sess_mgr_opts->tcp_timeout_init = atoll(ptr); opts->tcp_timeout_init = atoll(ptr);
ptr = toml_raw_in(sess_mgr_table, "tcp_timeout_handshake"); ptr = toml_raw_in(session_manager, "tcp_timeout_handshake");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_handshake"); CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_handshake");
return -1; return -1;
} }
sess_mgr_opts->tcp_timeout_handshake = atoll(ptr); opts->tcp_timeout_handshake = atoll(ptr);
ptr = toml_raw_in(sess_mgr_table, "tcp_timeout_data"); ptr = toml_raw_in(session_manager, "tcp_timeout_data");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_data"); CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_data");
return -1; return -1;
} }
sess_mgr_opts->tcp_timeout_data = atoll(ptr); opts->tcp_timeout_data = atoll(ptr);
ptr = toml_raw_in(sess_mgr_table, "tcp_timeout_half_closed"); ptr = toml_raw_in(session_manager, "tcp_timeout_half_closed");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_half_closed"); CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_half_closed");
return -1; return -1;
} }
sess_mgr_opts->tcp_timeout_half_closed = atoll(ptr); opts->tcp_timeout_half_closed = atoll(ptr);
ptr = toml_raw_in(sess_mgr_table, "tcp_timeout_time_wait"); ptr = toml_raw_in(session_manager, "tcp_timeout_time_wait");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_time_wait"); CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_time_wait");
return -1; return -1;
} }
sess_mgr_opts->tcp_timeout_time_wait = atoll(ptr); opts->tcp_timeout_time_wait = atoll(ptr);
ptr = toml_raw_in(sess_mgr_table, "tcp_timeout_discard"); ptr = toml_raw_in(session_manager, "tcp_timeout_discard");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_discard"); CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_discard");
return -1; return -1;
} }
sess_mgr_opts->tcp_timeout_discard = atoll(ptr); opts->tcp_timeout_discard = atoll(ptr);
// UDP timeout // UDP timeout
ptr = toml_raw_in(sess_mgr_table, "udp_timeout_data"); ptr = toml_raw_in(session_manager, "udp_timeout_data");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.udp_timeout_data"); CONFIG_LOG_ERROR("config file missing session_manager.udp_timeout_data");
return -1; return -1;
} }
sess_mgr_opts->udp_timeout_data = atoll(ptr); opts->udp_timeout_data = atoll(ptr);
// TCP duplicate packet filter // duplicate packet filter
ptr = toml_raw_in(sess_mgr_table, "tcp_dupkt_filter_enable"); ptr = toml_raw_in(session_manager, "duplicated_packet_filter_enable");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.tcp_dupkt_filter_enable"); CONFIG_LOG_ERROR("config file missing session_manager.duplicated_packet_filter_enable");
return -1; return -1;
} }
sess_mgr_opts->tcp_dupkt_filter_enable = atoi(ptr); opts->duplicated_packet_filter_enable = atoi(ptr);
ptr = toml_raw_in(sess_mgr_table, "tcp_dupkt_filter_capacity"); ptr = toml_raw_in(session_manager, "duplicated_packet_filter_capacity");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.tcp_dupkt_filter_capacity"); CONFIG_LOG_ERROR("config file missing session_manager.duplicated_packet_filter_capacity");
return -1; return -1;
} }
sess_mgr_opts->tcp_dupkt_filter_capacity = atoll(ptr); opts->duplicated_packet_filter_capacity = atoll(ptr);
ptr = toml_raw_in(sess_mgr_table, "tcp_dupkt_filter_timeout"); ptr = toml_raw_in(session_manager, "duplicated_packet_filter_timeout");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.tcp_dupkt_filter_timeout"); CONFIG_LOG_ERROR("config file missing session_manager.duplicated_packet_filter_timeout");
return -1; return -1;
} }
sess_mgr_opts->tcp_dupkt_filter_timeout = atoll(ptr); opts->duplicated_packet_filter_timeout = atoll(ptr);
ptr = toml_raw_in(sess_mgr_table, "tcp_dupkt_filter_error_rate"); ptr = toml_raw_in(session_manager, "duplicated_packet_filter_error_rate");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.tcp_dupkt_filter_error_rate"); CONFIG_LOG_ERROR("config file missing session_manager.duplicated_packet_filter_error_rate");
return -1; return -1;
} }
sess_mgr_opts->tcp_dupkt_filter_error_rate = atof(ptr); opts->duplicated_packet_filter_error_rate = atof(ptr);
// UDP eviction filter // eviction filter
ptr = toml_raw_in(sess_mgr_table, "udp_eviction_filter_enable"); ptr = toml_raw_in(session_manager, "evicted_session_filter_enable");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.udp_eviction_filter_enable"); CONFIG_LOG_ERROR("config file missing session_manager.evicted_session_filter_enable");
return -1; return -1;
} }
sess_mgr_opts->udp_eviction_filter_enable = atoi(ptr); opts->evicted_session_filter_enable = atoi(ptr);
ptr = toml_raw_in(sess_mgr_table, "udp_eviction_filter_capacity"); ptr = toml_raw_in(session_manager, "evicted_session_filter_capacity");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.udp_eviction_filter_capacity"); CONFIG_LOG_ERROR("config file missing session_manager.evicted_session_filter_capacity");
return -1; return -1;
} }
sess_mgr_opts->udp_eviction_filter_capacity = atoll(ptr); opts->evicted_session_filter_capacity = atoi(ptr);
ptr = toml_raw_in(sess_mgr_table, "udp_eviction_filter_timeout"); ptr = toml_raw_in(session_manager, "evicted_session_filter_timeout");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.udp_eviction_filter_timeout"); CONFIG_LOG_ERROR("config file missing session_manager.evicted_session_filter_timeout");
return -1; return -1;
} }
sess_mgr_opts->udp_eviction_filter_timeout = atoll(ptr); opts->evicted_session_filter_timeout = atoi(ptr);
ptr = toml_raw_in(sess_mgr_table, "udp_eviction_filter_error_rate"); ptr = toml_raw_in(session_manager, "evicted_session_filter_error_rate");
if (ptr == NULL) if (ptr == NULL)
{ {
CONFIG_LOG_ERROR("config file missing session_manager.udp_eviction_filter_error_rate"); CONFIG_LOG_ERROR("config file missing session_manager.evicted_session_filter_error_rate");
return -1; return -1;
} }
sess_mgr_opts->udp_eviction_filter_error_rate = atof(ptr); opts->evicted_session_filter_error_rate = atof(ptr);
return 0; return 0;
} }
// return 0: success // return 0: success
// retuun -1: failed // retuun -1: failed
int config_load(struct config *cfg, const char *cfg_file) int parse_config_file(const char *file, struct config *config)
{ {
int ret = -1; int ret = -1;
char errbuf[200]; char errbuf[200];
FILE *fp = NULL; FILE *fp = NULL;
toml_table_t *conf_file_handle = NULL; toml_table_t *table = NULL;
memset(cfg, 0, sizeof(*cfg)); memset(config, 0, sizeof(*config));
fp = fopen(cfg_file, "r"); fp = fopen(file, "r");
if (fp == NULL) if (fp == NULL)
{ {
CONFIG_LOG_ERROR("open config file %s failed, %s", cfg_file, strerror(errno)); CONFIG_LOG_ERROR("open config file %s failed, %s", file, strerror(errno));
goto error_out; goto error_out;
} }
conf_file_handle = toml_parse_file(fp, errbuf, sizeof(errbuf)); table = toml_parse_file(fp, errbuf, sizeof(errbuf));
if (conf_file_handle == NULL) if (table == NULL)
{ {
CONFIG_LOG_ERROR("parse config file %s failed, %s", cfg_file, errbuf); CONFIG_LOG_ERROR("parse config file %s failed, %s", file, errbuf);
goto error_out; goto error_out;
} }
if (parse_device_options(&cfg->dev_opts, conf_file_handle) != 0) if (parse_device_options(table, &config->dev_opts) != 0)
{ {
goto error_out; goto error_out;
} }
if (parse_packet_io_options(&cfg->pkt_io_opts, conf_file_handle) != 0) if (parse_packet_io_options(table, &config->pkt_io_opts) != 0)
{ {
goto error_out; goto error_out;
} }
if (parse_ip_reassembly_options(&cfg->ip_reass_opts, conf_file_handle) != 0) if (parse_ip_reassembly_options(table, &config->ip_reass_opts) != 0)
{ {
goto error_out; goto error_out;
} }
if (parse_session_manager_options(&cfg->sess_mgr_opts, conf_file_handle) != 0) if (parse_session_manager_options(table, &config->sess_mgr_opts) != 0)
{ {
goto error_out; goto error_out;
} }
@@ -408,9 +408,9 @@ int config_load(struct config *cfg, const char *cfg_file)
ret = 0; ret = 0;
error_out: error_out:
if (conf_file_handle) if (table)
{ {
toml_free(conf_file_handle); toml_free(table);
} }
if (fp) if (fp)
@@ -421,17 +421,17 @@ error_out:
return ret; return ret;
} }
void config_dump(struct config *cfg) void print_config_options(struct config *config)
{ {
if (cfg == NULL) if (config == NULL)
{ {
return; return;
} }
struct device_options *dev_opts = &cfg->dev_opts; struct device_options *dev_opts = &config->dev_opts;
struct packet_io_options *pkt_io_opts = &cfg->pkt_io_opts; struct packet_io_options *pkt_io_opts = &config->pkt_io_opts;
struct ip_reassembly_options *ip_reass_opts = &cfg->ip_reass_opts; struct ip_reassembly_options *ip_reass_opts = &config->ip_reass_opts;
struct session_manager_options *sess_mgr_opts = &cfg->sess_mgr_opts; struct session_manager_options *sess_mgr_opts = &config->sess_mgr_opts;
// device config // device config
CONFIG_LOG_DEBUG("device->device_base : %d", dev_opts->device_base); CONFIG_LOG_DEBUG("device->device_base : %d", dev_opts->device_base);
@@ -476,13 +476,13 @@ void config_dump(struct config *cfg)
CONFIG_LOG_DEBUG("session_manager->udp_timeout_data : %ld", sess_mgr_opts->udp_timeout_data); CONFIG_LOG_DEBUG("session_manager->udp_timeout_data : %ld", sess_mgr_opts->udp_timeout_data);
CONFIG_LOG_DEBUG("session_manager->tcp_dupkt_filter_enable : %d", sess_mgr_opts->tcp_dupkt_filter_enable); CONFIG_LOG_DEBUG("session_manager->duplicated_packet_filter_enable : %d", sess_mgr_opts->duplicated_packet_filter_enable);
CONFIG_LOG_DEBUG("session_manager->tcp_dupkt_filter_capacity : %ld", sess_mgr_opts->tcp_dupkt_filter_capacity); CONFIG_LOG_DEBUG("session_manager->duplicated_packet_filter_capacity : %d", sess_mgr_opts->duplicated_packet_filter_capacity);
CONFIG_LOG_DEBUG("session_manager->tcp_dupkt_filter_timeout : %ld", sess_mgr_opts->tcp_dupkt_filter_timeout); CONFIG_LOG_DEBUG("session_manager->duplicated_packet_filter_timeout : %d", sess_mgr_opts->duplicated_packet_filter_timeout);
CONFIG_LOG_DEBUG("session_manager->tcp_dupkt_filter_error_rate : %f", sess_mgr_opts->tcp_dupkt_filter_error_rate); CONFIG_LOG_DEBUG("session_manager->duplicated_packet_filter_error_rate : %f", sess_mgr_opts->duplicated_packet_filter_error_rate);
CONFIG_LOG_DEBUG("session_manager->udp_eviction_filter_enable : %d", sess_mgr_opts->udp_eviction_filter_enable); CONFIG_LOG_DEBUG("session_manager->evicted_session_filter_enable : %d", sess_mgr_opts->evicted_session_filter_enable);
CONFIG_LOG_DEBUG("session_manager->udp_eviction_filter_capacity : %ld", sess_mgr_opts->udp_eviction_filter_capacity); CONFIG_LOG_DEBUG("session_manager->evicted_session_filter_capacity : %d", sess_mgr_opts->evicted_session_filter_capacity);
CONFIG_LOG_DEBUG("session_manager->udp_eviction_filter_timeout : %ld", sess_mgr_opts->udp_eviction_filter_timeout); CONFIG_LOG_DEBUG("session_manager->evicted_session_filter_timeout : %d", sess_mgr_opts->evicted_session_filter_timeout);
CONFIG_LOG_DEBUG("session_manager->udp_eviction_filter_error_rate : %f", sess_mgr_opts->udp_eviction_filter_error_rate); CONFIG_LOG_DEBUG("session_manager->evicted_session_filter_error_rate : %f", sess_mgr_opts->evicted_session_filter_error_rate);
} }

View File

@@ -6,21 +6,12 @@ extern "C"
{ {
#endif #endif
#include "stellar.h"
#include "packet_io.h" #include "packet_io.h"
#include "ip_reassembly.h" #include "ip_reassembly.h"
#include "session_manager.h" #include "session_manager.h"
#define CONFIG_LOG_ERROR(format, ...) LOG_ERROR("config", format, ##__VA_ARGS__) #define CONFIG_LOG_ERROR(format, ...) LOG_ERROR("config", format, ##__VA_ARGS__)
#ifndef CONFIG_LOG_ERROR
#define CONFIG_LOG_ERROR(format, ...) \
fprintf(stderr, "ERROR (config), " format "\n", ##__VA_ARGS__);
#endif
#define CONFIG_LOG_DEBUG(format, ...) LOG_DEBUG("config", format, ##__VA_ARGS__) #define CONFIG_LOG_DEBUG(format, ...) LOG_DEBUG("config", format, ##__VA_ARGS__)
#ifndef CONFIG_LOG_DEBUG
#define CONFIG_LOG_DEBUG(format, ...) \
fprintf(stderr, "DEBUG (config), " format "\n", ##__VA_ARGS__);
#endif
struct device_options struct device_options
{ {
@@ -36,8 +27,10 @@ struct config
struct session_manager_options sess_mgr_opts; struct session_manager_options sess_mgr_opts;
}; };
int config_load(struct config *cfg, const char *cfg_file); // return 0: success
void config_dump(struct config *cfg); // retuun -1: failed
int parse_config_file(const char *file, struct config *config);
void print_config_options(struct config *config);
#ifdef __cpluscplus #ifdef __cpluscplus
} }

View File

@@ -8,9 +8,8 @@ extern "C"
#include <stdint.h> #include <stdint.h>
#define CRC32_UPD(crc, n) \ #define CRC32_UPD(crc, n) \
(crc32c_tables[(n)][(crc) & 0xFF] ^ \ (crc32c_tables[(n)][(crc) & 0xFF] ^ crc32c_tables[(n)-1][((crc) >> 8) & 0xFF])
crc32c_tables[(n)-1][((crc) >> 8) & 0xFF])
static const uint32_t crc32c_tables[8][256] = { static const uint32_t crc32c_tables[8][256] = {
{0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB, {0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,

View File

@@ -1,9 +0,0 @@
###############################################################################
# dupkt_filter
###############################################################################
add_library(dupkt_filter dupkt_filter.cpp)
target_include_directories(dupkt_filter PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(dupkt_filter packet timestamp dablooms)
add_subdirectory(test)

View File

@@ -1,153 +0,0 @@
#include <string.h>
#include "timestamp.h"
#include "dablooms.h"
#include "tcp_utils.h"
#include "ipv4_utils.h"
#include "dupkt_filter.h"
struct dupkt_filter_key
{
// TCP
uint32_t seq;
uint32_t ack;
uint16_t src_port; /* host order */
uint16_t dst_port; /* host order */
uint16_t l4_checksum;
// IPv4
uint16_t ip_id;
uint32_t src_addr; /* host order */
uint32_t dst_addr; /* host order */
} __attribute__((__packed__));
struct dupkt_filter
{
uint8_t enable;
unsigned int capacity;
double error_rate;
int timeout_s;
struct expiry_dablooms_handle *handle;
};
/******************************************************************************
* Private API
******************************************************************************/
// return 0: success
// reutrn -1: error
static inline int packet_get_dupkt_filter_key(const struct packet *packet, struct dupkt_filter_key *key)
{
const struct layer_record *ipv4_layer = packet_get_innermost_layer(packet, LAYER_TYPE_IPV4);
if (ipv4_layer == NULL)
{
return -1;
}
const struct layer_record *tcp_layer = packet_get_innermost_layer(packet, LAYER_TYPE_TCP);
if (tcp_layer == NULL)
{
return -1;
}
memset(key, 0, sizeof(struct dupkt_filter_key));
const struct ip *iphdr = (const struct ip *)ipv4_layer->hdr_ptr;
key->ip_id = ipv4_hdr_get_ipid(iphdr);
key->src_addr = ipv4_hdr_get_src_addr(iphdr);
key->dst_addr = ipv4_hdr_get_dst_addr(iphdr);
const struct tcphdr *tcphdr = (const struct tcphdr *)tcp_layer->hdr_ptr;
key->seq = tcp_hdr_get_seq(tcphdr);
key->ack = tcp_hdr_get_ack(tcphdr);
key->src_port = tcp_hdr_get_src_port(tcphdr);
key->dst_port = tcp_hdr_get_dst_port(tcphdr);
key->l4_checksum = tcp_hdr_get_checksum(tcphdr);
return 0;
}
/******************************************************************************
* Public API
******************************************************************************/
struct dupkt_filter *dupkt_filter_new(uint8_t enable, unsigned int capacity, double error_rate, int timeout_s)
{
struct dupkt_filter *filter = (struct dupkt_filter *)calloc(1, sizeof(struct dupkt_filter));
if (filter == NULL)
{
return NULL;
}
filter->enable = enable;
filter->capacity = capacity;
filter->error_rate = error_rate;
filter->timeout_s = timeout_s;
if (filter->enable == 0)
{
return filter;
}
filter->handle = expiry_dablooms_new(filter->capacity, filter->error_rate, timestamp_get_sec(), filter->timeout_s);
if (filter->handle == NULL)
{
free(filter);
return NULL;
}
return filter;
}
void dupkt_filter_free(struct dupkt_filter *filter)
{
if (filter)
{
if (filter->handle)
{
expiry_dablooms_free(filter->handle);
filter->handle = NULL;
}
free(filter);
filter = NULL;
}
}
// return 1: found
// reutrn 0: no found
int dupkt_filter_lookup(struct dupkt_filter *filter, const struct packet *packet)
{
if (filter->enable == 0)
{
return 0;
}
struct dupkt_filter_key key;
if (packet_get_dupkt_filter_key(packet, &key) == -1)
{
return 0;
}
if (expiry_dablooms_search(filter->handle, (const char *)&key, sizeof(struct dupkt_filter_key), timestamp_get_sec()) == 1)
{
return 1;
}
return 0;
}
void dupkt_filter_add(struct dupkt_filter *filter, const struct packet *packet)
{
if (filter->enable == 0)
{
return;
}
struct dupkt_filter_key key;
if (packet_get_dupkt_filter_key(packet, &key) == -1)
{
return;
}
expiry_dablooms_add(filter->handle, (const char *)&key, sizeof(struct dupkt_filter_key), timestamp_get_sec());
}

View File

@@ -1,25 +0,0 @@
#ifndef _DUPKT_FILTER_H
#define _DUPKT_FILTER_H
#ifdef __cpluscplus
extern "C"
{
#endif
// Duplicated Packet Filter for IPv4-based TCP Packet
#include "packet.h"
struct dupkt_filter *dupkt_filter_new(uint8_t enable, unsigned int capacity, double error_rate, int timeout_s);
void dupkt_filter_free(struct dupkt_filter *filter);
// return 1: found
// reutrn 0: no found
int dupkt_filter_lookup(struct dupkt_filter *filter, const struct packet *packet);
void dupkt_filter_add(struct dupkt_filter *filter, const struct packet *packet);
#ifdef __cpluscplus
}
#endif
#endif

View File

@@ -1,9 +0,0 @@
###############################################################################
# gtest
###############################################################################
add_executable(gtest_dupkt_filter gtest_dupkt_filter.cpp)
target_link_libraries(gtest_dupkt_filter dupkt_filter gtest)
include(GoogleTest)
gtest_discover_tests(gtest_dupkt_filter)

View File

@@ -0,0 +1,5 @@
add_library(duplicated_packet_filter duplicated_packet_filter.cpp)
target_include_directories(duplicated_packet_filter PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(duplicated_packet_filter packet dablooms)
add_subdirectory(test)

View File

@@ -0,0 +1,144 @@
#include <string.h>
#include "dablooms.h"
#include "tcp_utils.h"
#include "ipv4_utils.h"
#include "duplicated_packet_filter.h"
struct duplicated_packet_key
{
// TCP
uint32_t seq;
uint32_t ack;
uint16_t src_port; /* host order */
uint16_t dst_port; /* host order */
uint16_t l4_checksum;
// IPv4
uint16_t ip_id;
uint32_t src_addr; /* host order */
uint32_t dst_addr; /* host order */
} __attribute__((__packed__));
struct duplicated_packet_filter
{
struct duplicated_packet_filter_options opts;
struct expiry_dablooms_handle *dablooms;
};
/******************************************************************************
* Private API
******************************************************************************/
// return 0: success
// reutrn -1: error
static inline int duplicated_packet_key_get(const struct packet *packet, struct duplicated_packet_key *key)
{
const struct layer *ipv4_layer = packet_get_innermost_layer(packet, LAYER_TYPE_IPV4);
if (ipv4_layer == NULL)
{
return -1;
}
const struct layer *tcp_layer = packet_get_innermost_layer(packet, LAYER_TYPE_TCP);
if (tcp_layer == NULL)
{
return -1;
}
memset(key, 0, sizeof(struct duplicated_packet_key));
const struct ip *iphdr = (const struct ip *)ipv4_layer->hdr_ptr;
key->ip_id = ipv4_hdr_get_ipid(iphdr);
key->src_addr = ipv4_hdr_get_src_addr(iphdr);
key->dst_addr = ipv4_hdr_get_dst_addr(iphdr);
const struct tcphdr *tcphdr = (const struct tcphdr *)tcp_layer->hdr_ptr;
key->seq = tcp_hdr_get_seq(tcphdr);
key->ack = tcp_hdr_get_ack(tcphdr);
key->src_port = tcp_hdr_get_src_port(tcphdr);
key->dst_port = tcp_hdr_get_dst_port(tcphdr);
key->l4_checksum = tcp_hdr_get_checksum(tcphdr);
return 0;
}
/******************************************************************************
* 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 *filter = (struct duplicated_packet_filter *)calloc(1, sizeof(struct duplicated_packet_filter));
if (filter == NULL)
{
return NULL;
}
memcpy(&filter->opts, opts, sizeof(struct duplicated_packet_filter_options));
if (filter->opts.enable == 0)
{
return filter;
}
filter->dablooms = expiry_dablooms_new(filter->opts.capacity, filter->opts.error_rate, now_sec, filter->opts.timeout_sec);
if (filter->dablooms == NULL)
{
free(filter);
return NULL;
}
return filter;
}
void duplicated_packet_filter_free(struct duplicated_packet_filter *filter)
{
if (filter)
{
if (filter->dablooms)
{
expiry_dablooms_free(filter->dablooms);
filter->dablooms = NULL;
}
free(filter);
filter = NULL;
}
}
// 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)
{
if (filter->opts.enable == 0)
{
return 0;
}
struct duplicated_packet_key key;
if (duplicated_packet_key_get(packet, &key) == -1)
{
return 0;
}
if (expiry_dablooms_search(filter->dablooms, (const char *)&key, sizeof(struct duplicated_packet_key), now_sec) == 1)
{
return 1;
}
return 0;
}
void duplicated_packet_filter_add(struct duplicated_packet_filter *filter, const struct packet *packet, uint64_t now_sec)
{
if (filter->opts.enable == 0)
{
return;
}
struct duplicated_packet_key key;
if (duplicated_packet_key_get(packet, &key) == -1)
{
return;
}
expiry_dablooms_add(filter->dablooms, (const char *)&key, sizeof(struct duplicated_packet_key), now_sec);
}

View File

@@ -0,0 +1,35 @@
#ifndef _DUPLICATED_PACKET_H_
#define _DUPLICATED_PACKET_H_
#ifdef __cpluscplus
extern "C"
{
#endif
// Duplicated Packet Filter for IPv4-Based TCP Packet
#include "packet.h"
struct duplicated_packet_filter_options
{
uint8_t enable;
uint32_t capacity;
uint32_t timeout_sec;
double error_rate;
};
struct duplicated_packet_filter;
struct duplicated_packet_filter *duplicated_packet_filter_new(const struct duplicated_packet_filter_options *opts, uint64_t now_sec);
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);
#ifdef __cpluscplus
}
#endif
#endif

View File

@@ -0,0 +1,5 @@
add_executable(gtest_duplicated_packet_filter gtest_duplicated_packet_filter.cpp)
target_link_libraries(gtest_duplicated_packet_filter duplicated_packet_filter gtest)
include(GoogleTest)
gtest_discover_tests(gtest_duplicated_packet_filter)

View File

@@ -1,7 +1,6 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "dupkt_filter.h" #include "duplicated_packet_filter.h"
#include "timestamp.h"
/****************************************************************************** /******************************************************************************
* [Protocols in frame: eth:ethertype:ip:ipv6:tcp] * [Protocols in frame: eth:ethertype:ip:ipv6:tcp]
@@ -65,49 +64,29 @@ unsigned char data[] = {
0x81, 0x80, 0x5c, 0x76, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, 0x00, 0xf7, 0x57, 0x00, 0x00, 0x02, 0x04, 0x04, 0xc4, 0x01, 0x03, 0x03, 0x08, 0x01, 0x01, 0x81, 0x80, 0x5c, 0x76, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x20, 0x00, 0xf7, 0x57, 0x00, 0x00, 0x02, 0x04, 0x04, 0xc4, 0x01, 0x03, 0x03, 0x08, 0x01, 0x01,
0x04, 0x02}; 0x04, 0x02};
struct config struct duplicated_packet_filter_options opts = {
{
uint8_t enable;
unsigned int capacity;
double error_rate;
int timeout_s;
} config = {
.enable = 1, .enable = 1,
.capacity = 1000000, .capacity = 1000000,
.timeout_sec = 2,
.error_rate = 0.00001, .error_rate = 0.00001,
.timeout_s = 3,
}; };
TEST(DUPKT_FILTER, TEST) TEST(DUPLICATED_PACKET_FILTER, TEST)
{ {
timestamp_update();
struct packet pkt; struct packet pkt;
packet_parse(&pkt, (const char *)data, sizeof(data)); packet_parse(&pkt, (const char *)data, sizeof(data));
struct dupkt_filter *filter = dupkt_filter_new(config.enable, config.capacity, config.error_rate, config.timeout_s); struct duplicated_packet_filter *filter = duplicated_packet_filter_new(&opts, 1);
EXPECT_TRUE(filter != nullptr); EXPECT_TRUE(filter != nullptr);
EXPECT_TRUE(dupkt_filter_lookup(filter, &pkt) == 0); // no found EXPECT_TRUE(duplicated_packet_filter_lookup(filter, &pkt, 1) == 0); // no found
dupkt_filter_add(filter, &pkt); // add duplicated_packet_filter_add(filter, &pkt, 1); // add
EXPECT_TRUE(duplicated_packet_filter_lookup(filter, &pkt, 1) == 1); // found
EXPECT_TRUE(duplicated_packet_filter_lookup(filter, &pkt, 2) == 1); // found
EXPECT_TRUE(duplicated_packet_filter_lookup(filter, &pkt, 3) == 0); // not found
EXPECT_TRUE(duplicated_packet_filter_lookup(filter, &pkt, 4) == 0); // not found
for (int i = 0; i < 5; i++) duplicated_packet_filter_free(filter);
{
timestamp_update();
if (i < config.timeout_s)
{
EXPECT_TRUE(dupkt_filter_lookup(filter, &pkt) == 1); // found
}
else
{
EXPECT_TRUE(dupkt_filter_lookup(filter, &pkt) == 0); // no found
}
sleep(1);
printf("sleep[%02d] 1s\n", i);
}
dupkt_filter_free(filter);
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View File

@@ -0,0 +1,5 @@
add_library(evicted_session_filter evicted_session_filter.cpp)
target_include_directories(evicted_session_filter PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(evicted_session_filter packet dablooms)
add_subdirectory(test)

View File

@@ -0,0 +1,86 @@
#include <string.h>
#include "dablooms.h"
#include "udp_utils.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "evicted_session_filter.h"
struct evicted_session_filter
{
struct evicted_session_filter_options opts;
struct expiry_dablooms_handle *dablooms;
};
/******************************************************************************
* 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 *filter = (struct evicted_session_filter *)calloc(1, sizeof(struct evicted_session_filter));
if (filter == NULL)
{
return NULL;
}
memcpy(&filter->opts, opts, sizeof(struct evicted_session_filter_options));
if (filter->opts.enable == 0)
{
return filter;
}
filter->dablooms = expiry_dablooms_new(filter->opts.capacity, filter->opts.error_rate, now_sec, filter->opts.timeout_sec);
if (filter->dablooms == NULL)
{
free(filter);
return NULL;
}
return filter;
}
void evicted_session_filter_free(struct evicted_session_filter *filter)
{
if (filter)
{
if (filter->dablooms)
{
expiry_dablooms_free(filter->dablooms);
filter->dablooms = NULL;
}
free(filter);
filter = NULL;
}
}
// 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)
{
if (filter->opts.enable == 0)
{
return 0;
}
if (expiry_dablooms_search(filter->dablooms, (const char *)key, sizeof(struct tuple6), now_sec) == 1)
{
return 1;
}
return 0;
}
void evicted_session_filter_add(struct evicted_session_filter *filter, const struct tuple6 *key, uint64_t now_sec)
{
if (filter->opts.enable == 0)
{
return;
}
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);
}

View File

@@ -0,0 +1,31 @@
#ifndef _EVICTED_SESSION_FILTER_H_
#define _EVICTED_SESSION_FILTER_H_
#ifdef __cpluscplus
extern "C"
{
#endif
#include "tuple.h"
struct evicted_session_filter_options
{
uint8_t enable;
uint32_t capacity;
uint32_t timeout_sec;
double error_rate;
};
struct evicted_session_filter *evicted_session_filter_new(const struct evicted_session_filter_options *opts, uint64_t now_sec);
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);
#ifdef __cpluscplus
}
#endif
#endif

View File

@@ -0,0 +1,5 @@
add_executable(gtest_evicted_session_filter gtest_evicted_session_filter.cpp)
target_link_libraries(gtest_evicted_session_filter evicted_session_filter gtest)
include(GoogleTest)
gtest_discover_tests(gtest_evicted_session_filter)

View File

@@ -0,0 +1,55 @@
#include <gtest/gtest.h>
#include "evicted_session_filter.h"
struct evicted_session_filter_options opts = {
.enable = 1,
.capacity = 1000000,
.timeout_sec = 2,
.error_rate = 0.00001,
};
TEST(EVICTED_SESSION_FILTER, TEST)
{
struct tuple6 c2s_key;
struct tuple6 s2c_key;
memset(&c2s_key, 0, sizeof(c2s_key));
c2s_key.ip_type = IP_TYPE_V4;
c2s_key.src_addr.v4.s_addr = inet_addr("192.168.1.2");
c2s_key.dst_addr.v4.s_addr = inet_addr("192.168.1.3");
c2s_key.src_port = 0x0303;
c2s_key.dst_port = 0x0404;
c2s_key.ip_proto = 0x05;
c2s_key.domain = 0x0606060606060606;
memset(&s2c_key, 0, sizeof(s2c_key));
s2c_key.ip_type = IP_TYPE_V4;
s2c_key.src_addr.v4.s_addr = inet_addr("192.168.1.3");
s2c_key.dst_addr.v4.s_addr = inet_addr("192.168.1.2");
s2c_key.src_port = 0x0404;
s2c_key.dst_port = 0x0303;
s2c_key.ip_proto = 0x05;
s2c_key.domain = 0x0606060606060606;
struct evicted_session_filter *filter = evicted_session_filter_new(&opts, 1);
EXPECT_TRUE(filter != nullptr);
EXPECT_TRUE(evicted_session_filter_lookup(filter, &c2s_key, 1) == 0); // no found
EXPECT_TRUE(evicted_session_filter_lookup(filter, &s2c_key, 1) == 0); // no found
evicted_session_filter_add(filter, &c2s_key, 1); // add
EXPECT_TRUE(evicted_session_filter_lookup(filter, &c2s_key, 1) == 1); // found
EXPECT_TRUE(evicted_session_filter_lookup(filter, &s2c_key, 1) == 1); // found
EXPECT_TRUE(evicted_session_filter_lookup(filter, &c2s_key, 2) == 1); // found
EXPECT_TRUE(evicted_session_filter_lookup(filter, &s2c_key, 2) == 1); // found
EXPECT_TRUE(evicted_session_filter_lookup(filter, &c2s_key, 3) == 0); // not found
EXPECT_TRUE(evicted_session_filter_lookup(filter, &s2c_key, 3) == 0); // not found
evicted_session_filter_free(filter);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -1,9 +0,0 @@
###############################################################################
# eviction_filter
###############################################################################
add_library(eviction_filter eviction_filter.cpp)
target_include_directories(eviction_filter PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(eviction_filter packet timestamp dablooms)
add_subdirectory(test)

View File

@@ -1,172 +0,0 @@
#include <string.h>
#include "timestamp.h"
#include "dablooms.h"
#include "udp_utils.h"
#include "ipv4_utils.h"
#include "ipv6_utils.h"
#include "eviction_filter.h"
struct eviction_filter_key
{
// UDP
uint16_t src_port; /* host order */
uint16_t dst_port; /* host order */
// IPv4 or IPv6
union ip_address src_addr; /* network order */
union ip_address dst_addr; /* network order */
} __attribute__((__packed__));
struct eviction_filter
{
uint8_t enable;
unsigned int capacity;
double error_rate;
int timeout_s;
struct expiry_dablooms_handle *handle;
};
/******************************************************************************
* Private API
******************************************************************************/
static void eviction_filter_key_reverse(struct eviction_filter_key *in, struct eviction_filter_key *out)
{
memset(out, 0, sizeof(struct eviction_filter_key));
out->src_port = in->dst_port;
out->dst_port = in->src_port;
out->src_addr = in->dst_addr;
out->dst_addr = in->src_addr;
}
// return 0: success
// reutrn -1: error
static inline int packet_get_eviction_filter_key(const struct packet *packet, struct eviction_filter_key *key)
{
const struct layer_record *l3_layer = packet_get_innermost_layer(packet, LAYER_TYPE_L3);
if (l3_layer == NULL)
{
return -1;
}
const struct layer_record *l4_layer = packet_get_innermost_layer(packet, LAYER_TYPE_L4);
if (l4_layer == NULL)
{
return -1;
}
if (l4_layer->type != LAYER_TYPE_UDP)
{
return -1;
}
memset(key, 0, sizeof(struct eviction_filter_key));
if (l3_layer->type == LAYER_TYPE_IPV4)
{
const struct ip *iphdr = (const struct ip *)l3_layer->hdr_ptr;
key->src_addr.v4 = ipv4_hdr_get_src_in_addr(iphdr);
key->dst_addr.v4 = ipv4_hdr_get_dst_in_addr(iphdr);
}
if (l3_layer->type == LAYER_TYPE_IPV6)
{
const struct ip6_hdr *iphdr = (const struct ip6_hdr *)l3_layer->hdr_ptr;
key->src_addr.v6 = ipv6_hdr_get_src_in6_addr(iphdr);
key->dst_addr.v6 = ipv6_hdr_get_dst_in6_addr(iphdr);
}
const struct udphdr *udphdr = (const struct udphdr *)l4_layer->hdr_ptr;
key->src_port = udp_hdr_get_src_port(udphdr);
key->dst_port = udp_hdr_get_dst_port(udphdr);
return 0;
}
/******************************************************************************
* Public API
******************************************************************************/
struct eviction_filter *eviction_filter_new(uint8_t enable, unsigned int capacity, double error_rate, int timeout_s)
{
struct eviction_filter *filter = (struct eviction_filter *)calloc(1, sizeof(struct eviction_filter));
if (filter == NULL)
{
return NULL;
}
filter->enable = enable;
filter->capacity = capacity;
filter->error_rate = error_rate;
filter->timeout_s = timeout_s;
if (filter->enable == 0)
{
return filter;
}
filter->handle = expiry_dablooms_new(filter->capacity, filter->error_rate, timestamp_get_sec(), filter->timeout_s);
if (filter->handle == NULL)
{
free(filter);
return NULL;
}
return filter;
}
void eviction_filter_free(struct eviction_filter *filter)
{
if (filter)
{
if (filter->handle)
{
expiry_dablooms_free(filter->handle);
filter->handle = NULL;
}
free(filter);
filter = NULL;
}
}
// return 1: found
// reutrn 0: no found
int eviction_filter_lookup(struct eviction_filter *filter, const struct packet *packet)
{
if (filter->enable == 0)
{
return 0;
}
struct eviction_filter_key key;
if (packet_get_eviction_filter_key(packet, &key) == -1)
{
return 0;
}
if (expiry_dablooms_search(filter->handle, (const char *)&key, sizeof(struct eviction_filter_key), timestamp_get_sec()) == 1)
{
return 1;
}
return 0;
}
void eviction_filter_add(struct eviction_filter *filter, const struct packet *packet)
{
if (filter->enable == 0)
{
return;
}
struct eviction_filter_key key;
if (packet_get_eviction_filter_key(packet, &key) == -1)
{
return;
}
expiry_dablooms_add(filter->handle, (const char *)&key, sizeof(struct eviction_filter_key), timestamp_get_sec());
struct eviction_filter_key reverse_key;
eviction_filter_key_reverse(&key, &reverse_key);
expiry_dablooms_add(filter->handle, (const char *)&reverse_key, sizeof(struct eviction_filter_key), timestamp_get_sec());
}

View File

@@ -1,25 +0,0 @@
#ifndef _EVICTION_FILTER_H
#define _EVICTION_FILTER_H
#ifdef __cpluscplus
extern "C"
{
#endif
// Eviction Filter Only for UDP Packet
#include "packet.h"
struct eviction_filter *eviction_filter_new(uint8_t enable, unsigned int capacity, double error_rate, int timeout_s);
void eviction_filter_free(struct eviction_filter *filter);
// return 1: found
// reutrn 0: no found
int eviction_filter_lookup(struct eviction_filter *filter, const struct packet *packet);
void eviction_filter_add(struct eviction_filter *filter, const struct packet *packet);
#ifdef __cpluscplus
}
#endif
#endif

View File

@@ -1,9 +0,0 @@
###############################################################################
# gtest
###############################################################################
add_executable(gtest_eviction_filter gtest_eviction_filter.cpp)
target_link_libraries(gtest_eviction_filter eviction_filter gtest)
include(GoogleTest)
gtest_discover_tests(gtest_eviction_filter)

View File

@@ -1,171 +0,0 @@
#include <gtest/gtest.h>
#include "eviction_filter.h"
#include "timestamp.h"
/*
* Frame 1: 74 bytes on wire (592 bits), 74 bytes captured (592 bits) on interface en0, id 0
* Ethernet II, Src: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea), Dst: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
* Destination: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
* Source: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea)
* Type: IPv4 (0x0800)
* Internet Protocol Version 4, Src: 192.168.38.105, Dst: 121.14.154.93
* 0100 .... = Version: 4
* .... 0101 = Header Length: 20 bytes (5)
* Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
* 0000 00.. = Differentiated Services Codepoint: Default (0)
* .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
* Total Length: 60
* Identification: 0xaef9 (44793)
* 000. .... = Flags: 0x0
* 0... .... = Reserved bit: Not set
* .0.. .... = Don't fragment: Not set
* ..0. .... = More fragments: Not set
* ...0 0000 0000 0000 = Fragment Offset: 0
* Time to Live: 64
* Protocol: UDP (17)
* Header Checksum: 0xd13a [correct]
* [Header checksum status: Good]
* [Calculated Checksum: 0xd13a]
* Source Address: 192.168.38.105
* Destination Address: 121.14.154.93
* User Datagram Protocol, Src Port: 61099, Dst Port: 53
* Source Port: 61099
* Destination Port: 53
* Length: 40
* Checksum: 0xdcf1 [correct]
* [Calculated Checksum: 0xdcf1]
* [Checksum Status: Good]
* [Stream index: 0]
* [Timestamps]
* [Time since first frame: 0.000000000 seconds]
* [Time since previous frame: 0.000000000 seconds]
* UDP payload (32 bytes)
* Domain Name System (query)
*/
unsigned char udp_pkt1_dns_req[] = {
0x48, 0x73, 0x97, 0x96, 0x38, 0x0e, 0x3c, 0xa6, 0xf6, 0x0a, 0xc5, 0xea, 0x08, 0x00, 0x45, 0x00, 0x00, 0x3c, 0xae, 0xf9, 0x00, 0x00, 0x40, 0x11, 0xd1, 0x3a,
0xc0, 0xa8, 0x26, 0x69, 0x79, 0x0e, 0x9a, 0x5d, 0xee, 0xab, 0x00, 0x35, 0x00, 0x28, 0xdc, 0xf1, 0xa5, 0xaf, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0x77, 0x77, 0x77, 0x06, 0x62, 0x61, 0x64, 0x73, 0x73, 0x6c, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01};
/*
* Frame 2: 550 bytes on wire (4400 bits), 550 bytes captured (4400 bits) on interface en0, id 0
* Ethernet II, Src: NewH3CTe_96:38:0e (48:73:97:96:38:0e), Dst: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea)
* Destination: Apple_0a:c5:ea (3c:a6:f6:0a:c5:ea)
* Source: NewH3CTe_96:38:0e (48:73:97:96:38:0e)
* Type: IPv4 (0x0800)
* Internet Protocol Version 4, Src: 121.14.154.93, Dst: 192.168.38.105
* 0100 .... = Version: 4
* .... 0101 = Header Length: 20 bytes (5)
* Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
* 0000 00.. = Differentiated Services Codepoint: Default (0)
* .... ..00 = Explicit Congestion Notification: Not ECN-Capable Transport (0)
* Total Length: 536
* Identification: 0xb578 (46456)
* 000. .... = Flags: 0x0
* 0... .... = Reserved bit: Not set
* .0.. .... = Don't fragment: Not set
* ..0. .... = More fragments: Not set
* ...0 0000 0000 0000 = Fragment Offset: 0
* Time to Live: 46
* Protocol: UDP (17)
* Header Checksum: 0xdadf [correct]
* [Header checksum status: Good]
* [Calculated Checksum: 0xdadf]
* Source Address: 121.14.154.93
* Destination Address: 192.168.38.105
* User Datagram Protocol, Src Port: 53, Dst Port: 61099
* Source Port: 53
* Destination Port: 61099
* Length: 516
* Checksum: 0x9aca [correct]
* [Calculated Checksum: 0x9aca]
* [Checksum Status: Good]
* [Stream index: 0]
* [Timestamps]
* [Time since first frame: 0.525915000 seconds]
* [Time since previous frame: 0.525915000 seconds]
* UDP payload (508 bytes)
* Domain Name System (response)
*/
unsigned char udp_pkt2_dns_resp[] = {
0x3c, 0xa6, 0xf6, 0x0a, 0xc5, 0xea, 0x48, 0x73, 0x97, 0x96, 0x38, 0x0e, 0x08, 0x00, 0x45, 0x00, 0x02, 0x18, 0xb5, 0x78, 0x00, 0x00, 0x2e, 0x11, 0xda, 0xdf,
0x79, 0x0e, 0x9a, 0x5d, 0xc0, 0xa8, 0x26, 0x69, 0x00, 0x35, 0xee, 0xab, 0x02, 0x04, 0x9a, 0xca, 0xa5, 0xaf, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0d,
0x00, 0x0e, 0x03, 0x77, 0x77, 0x77, 0x06, 0x62, 0x61, 0x64, 0x73, 0x73, 0x6c, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01,
0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0x00, 0x04, 0x68, 0x9a, 0x59, 0x69, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x14, 0x01, 0x62,
0x0c, 0x67, 0x74, 0x6c, 0x64, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01,
0xa7, 0x1a, 0x00, 0x04, 0x01, 0x65, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x63, 0xc0, 0x3e, 0xc0, 0x17,
0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x66, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04,
0x01, 0x61, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x6b, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01,
0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x68, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x64, 0xc0, 0x3e,
0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x67, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a,
0x00, 0x04, 0x01, 0x69, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x6d, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02,
0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x6c, 0xc0, 0x3e, 0xc0, 0x17, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x04, 0x01, 0x6a,
0xc0, 0x3e, 0xc0, 0x8c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x57, 0x5b, 0x00, 0x04, 0xc0, 0x05, 0x06, 0x1e, 0xc0, 0x3c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
0x70, 0x36, 0x00, 0x04, 0xc0, 0x21, 0x0e, 0x1e, 0xc0, 0x6c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x72, 0x6d, 0x00, 0x04, 0xc0, 0x1a, 0x5c, 0x1e, 0xc0, 0xbc,
0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x71, 0xdb, 0x00, 0x04, 0xc0, 0x1f, 0x50, 0x1e, 0xc0, 0x5c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x75, 0x53, 0x00, 0x04,
0xc0, 0x0c, 0x5e, 0x1e, 0xc0, 0x7c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x71, 0xdb, 0x00, 0x04, 0xc0, 0x23, 0x33, 0x1e, 0xc0, 0xcc, 0x00, 0x01, 0x00, 0x01,
0x00, 0x01, 0x78, 0x72, 0x00, 0x04, 0xc0, 0x2a, 0x5d, 0x1e, 0xc0, 0xac, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x7a, 0x75, 0x00, 0x04, 0xc0, 0x36, 0x70, 0x1e,
0xc0, 0xdc, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x73, 0x3d, 0x00, 0x04, 0xc0, 0x2b, 0xac, 0x1e, 0xc1, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x72, 0x6d,
0x00, 0x04, 0xc0, 0x30, 0x4f, 0x1e, 0xc0, 0x9c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x7a, 0x75, 0x00, 0x04, 0xc0, 0x34, 0xb2, 0x1e, 0xc0, 0xfc, 0x00, 0x01,
0x00, 0x01, 0x00, 0x01, 0x7a, 0x75, 0x00, 0x04, 0xc0, 0x29, 0xa2, 0x1e, 0xc0, 0xec, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x72, 0x6d, 0x00, 0x04, 0xc0, 0x37,
0x53, 0x1e, 0xc0, 0x8c, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x01, 0xa7, 0x1a, 0x00, 0x10, 0x20, 0x01, 0x05, 0x03, 0xa8, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x30};
struct config
{
uint8_t enable;
unsigned int capacity;
double error_rate;
int timeout_s;
} config = {
.enable = 1,
.capacity = 1000000,
.error_rate = 0.00001,
.timeout_s = 3,
};
TEST(EVICTION_FILTER, TEST)
{
timestamp_update();
struct packet c2s_pkt;
struct packet s2c_pkt;
packet_parse(&c2s_pkt, (const char *)udp_pkt1_dns_req, sizeof(udp_pkt1_dns_req));
packet_parse(&s2c_pkt, (const char *)udp_pkt2_dns_resp, sizeof(udp_pkt2_dns_resp));
struct eviction_filter *filter = eviction_filter_new(config.enable, config.capacity, config.error_rate, config.timeout_s);
EXPECT_TRUE(filter != nullptr);
EXPECT_TRUE(eviction_filter_lookup(filter, &c2s_pkt) == 0); // no found
EXPECT_TRUE(eviction_filter_lookup(filter, &s2c_pkt) == 0); // no found
eviction_filter_add(filter, &c2s_pkt); // add
for (int i = 0; i < 5; i++)
{
timestamp_update();
if (i < config.timeout_s)
{
EXPECT_TRUE(eviction_filter_lookup(filter, &c2s_pkt) == 1); // found
EXPECT_TRUE(eviction_filter_lookup(filter, &s2c_pkt) == 1); // found
}
else
{
EXPECT_TRUE(eviction_filter_lookup(filter, &c2s_pkt) == 0); // no found
EXPECT_TRUE(eviction_filter_lookup(filter, &s2c_pkt) == 0); // no found
}
sleep(1);
printf("sleep[%02d] 1s\n", i);
}
eviction_filter_free(filter);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -1,7 +1,3 @@
###############################################################################
# file
###############################################################################
add_library(file file_scan.cpp) add_library(file file_scan.cpp)
target_include_directories(file PUBLIC ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(file PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(file log) target_link_libraries(file log)

View File

@@ -8,8 +8,8 @@ extern "C"
#include "log.h" #include "log.h"
#define FILE_SCAN_LOG_ERROR(format, ...) LOG_ERROR("file_scan", format, ##__VA_ARGS__) #define FILE_SCAN_LOG_ERROR(format, ...) LOG_ERROR("file scan", format, ##__VA_ARGS__)
#define FILE_SCAN_LOG_DEBUG(format, ...) LOG_DEBUG("file_scan", format, ##__VA_ARGS__) #define FILE_SCAN_LOG_DEBUG(format, ...) LOG_DEBUG("file scan", format, ##__VA_ARGS__)
typedef int file_handle(const char *file, void *arg); typedef int file_handle(const char *file, void *arg);
int file_scan(const char *dir, file_handle *cb, void *arg); int file_scan(const char *dir, file_handle *cb, void *arg);

View File

@@ -1,8 +1,4 @@
###############################################################################
# id_generator
###############################################################################
add_library(id_generator id_generator.cpp) add_library(id_generator id_generator.cpp)
target_include_directories(id_generator PUBLIC ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(id_generator PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(id_generator PUBLIC ${CMAKE_SOURCE_DIR}/src/stellar) target_include_directories(id_generator PUBLIC ${CMAKE_SOURCE_DIR}/src/stellar)
target_link_libraries(id_generator log timestamp) target_link_libraries(id_generator log)

View File

@@ -2,7 +2,6 @@
#include "id_generator.h" #include "id_generator.h"
#include "stellar.h" #include "stellar.h"
#include "timestamp.h"
struct id_generator struct id_generator
{ {
@@ -49,11 +48,6 @@ int id_generator_init(uint8_t device_base, uint8_t device_offset)
return 0; return 0;
} }
void id_generator_free()
{
memset(&global_id_generator, 0, sizeof(struct id_generator));
}
/* /*
* 高位 --- 低位 * 高位 --- 低位
* *
@@ -61,16 +55,14 @@ void id_generator_free()
* | 1bit | 12bit device_id | 8bit thread_id | 28bit timestamp in sec | 15bit sequence per thread | * | 1bit | 12bit device_id | 8bit thread_id | 28bit timestamp in sec | 15bit sequence per thread |
* +------+------------------+----------------+------------------------+---------------------------+ * +------+------------------+----------------+------------------------+---------------------------+
*/ */
uint64_t id_generator_get() uint64_t id_generator_alloc(uint64_t now_sec, uint64_t thread_index)
{ {
#define MAX_ID_PER_THREAD (32768) #define MAX_ID_PER_THREAD (32768)
#define MAX_ID_BASE_TIME (268435456L) #define MAX_ID_BASE_TIME (268435456L)
uint64_t global_id = 0; uint64_t global_id = 0;
uint64_t thread_index = stellar_get_current_thread_index();
uint64_t id_per_thread = (global_id_generator.thread_volatile[thread_index]++) % MAX_ID_PER_THREAD; uint64_t id_per_thread = (global_id_generator.thread_volatile[thread_index]++) % MAX_ID_PER_THREAD;
uint64_t id_base_time = timestamp_get_sec() % MAX_ID_BASE_TIME; uint64_t id_base_time = now_sec % MAX_ID_BASE_TIME;
global_id = (global_id_generator.device_id << 51) | global_id = (global_id_generator.device_id << 51) |
(thread_index << 43) | (thread_index << 43) |
(id_base_time << 15) | (id_base_time << 15) |

View File

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

View File

@@ -1,9 +1,5 @@
###############################################################################
# ip_reassembly
###############################################################################
add_library(ip_reassembly ip_reassembly.cpp) add_library(ip_reassembly ip_reassembly.cpp)
target_include_directories(ip_reassembly PUBLIC ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(ip_reassembly PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(ip_reassembly timestamp packet) target_link_libraries(ip_reassembly packet)
add_subdirectory(test) add_subdirectory(test)

View File

@@ -4,12 +4,10 @@
#include <assert.h> #include <assert.h>
#include "packet.h" #include "packet.h"
#include "timestamp.h"
#include "crc32_hash.h" #include "crc32_hash.h"
#include "checksum.h" #include "checksum.h"
#include "ipv4_utils.h" #include "ipv4_utils.h"
#include "ipv6_utils.h" #include "ipv6_utils.h"
#include "packet_utils.h"
#include "ip_reassembly.h" #include "ip_reassembly.h"
#define IPV4_KEYLEN 1 #define IPV4_KEYLEN 1
@@ -303,7 +301,7 @@ static inline void ip_flow_key_zero(struct ip_flow_key *key)
static inline void ip_frag_hdr_init(struct ip_frag_hdr *hdr, const struct packet *pkt) static inline void ip_frag_hdr_init(struct ip_frag_hdr *hdr, const struct packet *pkt)
{ {
struct layer_record *layer = pkt->frag_layer; struct layer *layer = pkt->frag_layer;
if (layer->type == LAYER_TYPE_IPV6) if (layer->type == LAYER_TYPE_IPV6)
{ {
@@ -367,7 +365,7 @@ static inline void ip_frag_pkt_free(struct ip_frag_pkt *frag)
* ip flow * ip flow
******************************************************************************/ ******************************************************************************/
static inline void ip_flow_init(struct ip_flow *flow, const struct ip_flow_key *key) static inline void ip_flow_init(struct ip_flow *flow, const struct ip_flow_key *key, uint64_t now_sec)
{ {
static const struct ip_frag_pkt zero_frag = { static const struct ip_frag_pkt zero_frag = {
.data = NULL, .data = NULL,
@@ -378,7 +376,7 @@ static inline void ip_flow_init(struct ip_flow *flow, const struct ip_flow_key *
flow->lru.tqe_next = NULL; flow->lru.tqe_next = NULL;
flow->lru.tqe_prev = NULL; flow->lru.tqe_prev = NULL;
flow->key = *key; flow->key = *key;
flow->create_time = timestamp_get_sec(); flow->create_time = now_sec;
flow->expected_total_size = UINT32_MAX; flow->expected_total_size = UINT32_MAX;
flow->received_frag_size = 0; flow->received_frag_size = 0;
flow->next_fill_idx = IP_MIN_FRAG_NUM; flow->next_fill_idx = IP_MIN_FRAG_NUM;
@@ -480,11 +478,11 @@ static inline void ip_reassembly_del_flow(struct ip_reassembly *mgr, struct ip_f
mgr->entry_used--; mgr->entry_used--;
} }
static inline void ip_reassembly_reuse_flow(struct ip_reassembly *mgr, struct ip_flow *flow, const struct ip_flow_key *key) 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)
{ {
ip_reassembly_del_flow(mgr, flow); ip_reassembly_del_flow(mgr, flow);
ip_flow_free(flow); ip_flow_free(flow);
ip_flow_init(flow, key); ip_flow_init(flow, key, now_sec);
ip_reassembly_add_flow(mgr, flow); ip_reassembly_add_flow(mgr, flow);
} }
@@ -493,7 +491,7 @@ static inline void ip_reassembly_reuse_flow(struct ip_reassembly *mgr, struct ip
* free : the first empty entry in the bucket * free : the first empty entry in the bucket
* expired: the first timed-out entry in the bucket * expired: the first timed-out entry in the bucket
*/ */
static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const struct ip_flow_key *key, struct ip_flow **free, struct ip_flow **expired) 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)
{ {
ip_reassembly_stat_inc(mgr, find, key); ip_reassembly_stat_inc(mgr, find, key);
@@ -522,7 +520,6 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
struct ip_flow *empty = NULL; struct ip_flow *empty = NULL;
uint64_t timeout = mgr->timeout; uint64_t timeout = mgr->timeout;
uint32_t assoc = mgr->bucket_entries; uint32_t assoc = mgr->bucket_entries;
uint64_t tms = timestamp_get_sec();
for (uint32_t i = 0; i != assoc; i++) for (uint32_t i = 0; i != assoc; i++)
{ {
if (ip_flow_key_cmp(key, &p1[i].key) == 0) if (ip_flow_key_cmp(key, &p1[i].key) == 0)
@@ -535,7 +532,7 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
{ {
empty = (empty == NULL) ? (p1 + i) : empty; empty = (empty == NULL) ? (p1 + i) : empty;
} }
else if (timeout + p1[i].create_time <= tms) else if (timeout + p1[i].create_time <= now_sec)
{ {
old = (old == NULL) ? (p1 + i) : old; old = (old == NULL) ? (p1 + i) : old;
} }
@@ -550,7 +547,7 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
{ {
empty = (empty == NULL) ? (p2 + i) : empty; empty = (empty == NULL) ? (p2 + i) : empty;
} }
else if (timeout + p2[i].create_time <= tms) else if (timeout + p2[i].create_time <= now_sec)
{ {
old = (old == NULL) ? (p2 + i) : old; old = (old == NULL) ? (p2 + i) : old;
} }
@@ -561,19 +558,19 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
return NULL; return NULL;
} }
static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, const struct ip_flow_key *key) static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, const struct ip_flow_key *key, uint64_t now_sec)
{ {
struct ip_flow *flow = NULL; struct ip_flow *flow = NULL;
struct ip_flow *free = NULL; struct ip_flow *free = NULL;
struct ip_flow *expired = NULL; struct ip_flow *expired = NULL;
flow = ip_reassembly_find_flow(mgr, key, &free, &expired); flow = ip_reassembly_find_flow(mgr, key, &free, &expired, now_sec);
if (flow == NULL) if (flow == NULL)
{ {
if (expired) if (expired)
{ {
IP_REASSEMBLE_DEBUG1("add ip flow success: reuse expired entry", key); IP_REASSEMBLE_DEBUG1("add ip flow success: reuse expired entry", key);
ip_reassembly_reuse_flow(mgr, expired, key); ip_reassembly_reuse_flow(mgr, expired, key, now_sec);
ip_reassembly_stat_inc(mgr, timeout, key); ip_reassembly_stat_inc(mgr, timeout, key);
mgr->last = expired; mgr->last = expired;
@@ -583,7 +580,7 @@ static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, cons
if (free) if (free)
{ {
IP_REASSEMBLE_DEBUG1("add ip flow success: use free entry", key); IP_REASSEMBLE_DEBUG1("add ip flow success: use free entry", key);
ip_flow_init(free, key); ip_flow_init(free, key, now_sec);
ip_reassembly_add_flow(mgr, free); ip_reassembly_add_flow(mgr, free);
mgr->last = free; mgr->last = free;
@@ -598,10 +595,10 @@ static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, cons
else else
{ {
// expired // expired
if (mgr->timeout + flow->create_time <= timestamp_get_sec()) if (mgr->timeout + flow->create_time <= now_sec)
{ {
IP_REASSEMBLE_DEBUG1("add ip flow success: reuse expired entry", key); IP_REASSEMBLE_DEBUG1("add ip flow success: reuse expired entry", key);
ip_reassembly_reuse_flow(mgr, flow, key); ip_reassembly_reuse_flow(mgr, flow, key, now_sec);
ip_reassembly_stat_inc(mgr, timeout, key); ip_reassembly_stat_inc(mgr, timeout, key);
mgr->last = flow; mgr->last = flow;
@@ -817,14 +814,13 @@ void ip_reassembly_free(struct ip_reassembly *mgr)
} }
} }
void ip_reassembly_expire(struct ip_reassembly *mgr) void ip_reassembly_expire(struct ip_reassembly *mgr, uint64_t now_sec)
{ {
struct ip_flow *flow = NULL; struct ip_flow *flow = NULL;
uint64_t curr_ts = timestamp_get_sec();
uint64_t timeout = mgr->timeout; uint64_t timeout = mgr->timeout;
TAILQ_FOREACH(flow, &mgr->lru, lru) TAILQ_FOREACH(flow, &mgr->lru, lru)
if (timeout + flow->create_time <= curr_ts) if (timeout + flow->create_time <= now_sec)
{ {
IP_REASSEMBLE_DEBUG1("expire ip flow: discarding old fragmented packets", &flow->key); IP_REASSEMBLE_DEBUG1("expire ip flow: discarding old fragmented packets", &flow->key);
ip_reassembly_del_flow(mgr, flow); ip_reassembly_del_flow(mgr, flow);
@@ -833,34 +829,6 @@ void ip_reassembly_expire(struct ip_reassembly *mgr)
} }
} }
void ip_reassembly_print_stat(struct ip_reassembly *mgr)
{
if (mgr)
{
IP_REASSEMBLE_DEBUG("ip4_flow_find : %lu", mgr->stat.ip4_flow_find);
IP_REASSEMBLE_DEBUG("ip4_flow_add : %lu", mgr->stat.ip4_flow_add);
IP_REASSEMBLE_DEBUG("ip4_flow_del : %lu", mgr->stat.ip4_flow_del);
IP_REASSEMBLE_DEBUG("ip4_flow_timeout : %lu", mgr->stat.ip4_flow_timeout);
IP_REASSEMBLE_DEBUG("ip4_flow_fail_no_space : %lu", mgr->stat.ip4_flow_fail_no_space);
IP_REASSEMBLE_DEBUG("ip4_flow_fail_overlap : %lu", mgr->stat.ip4_flow_fail_overlap);
IP_REASSEMBLE_DEBUG("ip4_flow_fail_many_frag : %lu", mgr->stat.ip4_flow_fail_many_frag);
IP_REASSEMBLE_DEBUG("ip4_flow_fail_invalid_length : %lu", mgr->stat.ip4_flow_fail_invalid_length);
IP_REASSEMBLE_DEBUG("ip4_flow_bypass_dup_fist_frag : %lu", mgr->stat.ip4_flow_bypass_dup_fist_frag);
IP_REASSEMBLE_DEBUG("ip4_flow_bypass_dup_last_frag : %lu", mgr->stat.ip4_flow_bypass_dup_last_frag);
IP_REASSEMBLE_DEBUG("ip6_flow_find : %lu", mgr->stat.ip6_flow_find);
IP_REASSEMBLE_DEBUG("ip6_flow_add : %lu", mgr->stat.ip6_flow_add);
IP_REASSEMBLE_DEBUG("ip6_flow_del : %lu", mgr->stat.ip6_flow_del);
IP_REASSEMBLE_DEBUG("ip6_flow_timeout : %lu", mgr->stat.ip6_flow_timeout);
IP_REASSEMBLE_DEBUG("ip6_flow_fail_no_space : %lu", mgr->stat.ip6_flow_fail_no_space);
IP_REASSEMBLE_DEBUG("ip6_flow_fail_overlap : %lu", mgr->stat.ip6_flow_fail_overlap);
IP_REASSEMBLE_DEBUG("ip6_flow_fail_many_frag : %lu", mgr->stat.ip6_flow_fail_many_frag);
IP_REASSEMBLE_DEBUG("ip6_flow_fail_invalid_length : %lu", mgr->stat.ip6_flow_fail_invalid_length);
IP_REASSEMBLE_DEBUG("ip6_flow_bypass_dup_fist_frag : %lu", mgr->stat.ip6_flow_bypass_dup_fist_frag);
IP_REASSEMBLE_DEBUG("ip6_flow_bypass_dup_last_frag : %lu", mgr->stat.ip6_flow_bypass_dup_last_frag);
}
}
struct ip_reassembly_stat *ip_reassembly_get_stat(struct ip_reassembly *mgr) struct ip_reassembly_stat *ip_reassembly_get_stat(struct ip_reassembly *mgr)
{ {
if (mgr) if (mgr)
@@ -878,7 +846,7 @@ struct ip_reassembly_stat *ip_reassembly_get_stat(struct ip_reassembly *mgr)
* The returned packet should be freed by calling the packet_free() function * The returned packet should be freed by calling the packet_free() function
*/ */
struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt) struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec)
{ {
struct packet *pkt1; struct packet *pkt1;
struct packet *pkt2; struct packet *pkt2;
@@ -888,7 +856,7 @@ struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct pack
return NULL; return NULL;
} }
const struct layer_record *layer = pkt->frag_layer; const struct layer *layer = pkt->frag_layer;
if (layer == NULL) if (layer == NULL)
{ {
return NULL; return NULL;
@@ -896,10 +864,10 @@ struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct pack
if (layer->type == LAYER_TYPE_IPV4) if (layer->type == LAYER_TYPE_IPV4)
{ {
pkt1 = ipv4_reassembly_packet(mgr, pkt); pkt1 = ipv4_reassembly_packet(mgr, pkt, now_sec);
if (pkt1 && pkt1->frag_layer) if (pkt1 && pkt1->frag_layer)
{ {
pkt2 = ip_reassembly_packet(mgr, pkt1); pkt2 = ip_reassembly_packet(mgr, pkt1, now_sec);
packet_free(pkt1); packet_free(pkt1);
return pkt2; return pkt2;
} }
@@ -908,10 +876,10 @@ struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct pack
} }
else if (layer->type == LAYER_TYPE_IPV6) else if (layer->type == LAYER_TYPE_IPV6)
{ {
pkt1 = ipv6_reassembly_packet(mgr, pkt); pkt1 = ipv6_reassembly_packet(mgr, pkt, now_sec);
if (pkt1 && pkt1->frag_layer) if (pkt1 && pkt1->frag_layer)
{ {
pkt2 = ip_reassembly_packet(mgr, pkt1); pkt2 = ip_reassembly_packet(mgr, pkt1, now_sec);
packet_free(pkt1); packet_free(pkt1);
return pkt2; return pkt2;
} }
@@ -924,9 +892,9 @@ 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) struct packet *ipv4_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec)
{ {
const struct layer_record *layer = pkt->frag_layer; const struct layer *layer = pkt->frag_layer;
const struct ip *hdr = (const struct ip *)layer->hdr_ptr; const struct ip *hdr = (const struct ip *)layer->hdr_ptr;
uint16_t frag_len = ipv4_hdr_get_total_len(hdr) - ipv4_hdr_get_hdr_len(hdr); uint16_t frag_len = ipv4_hdr_get_total_len(hdr) - ipv4_hdr_get_hdr_len(hdr);
if (frag_len > layer->pld_len) if (frag_len > layer->pld_len)
@@ -943,7 +911,7 @@ struct packet *ipv4_reassembly_packet(struct ip_reassembly *mgr, const struct pa
key.ip_id = ipv4_hdr_get_ipid(hdr); key.ip_id = ipv4_hdr_get_ipid(hdr);
key.proto = ipv4_hdr_get_proto(hdr); key.proto = ipv4_hdr_get_proto(hdr);
struct ip_flow *flow = ip_reassembly_update_flow(mgr, &key); struct ip_flow *flow = ip_reassembly_update_flow(mgr, &key, now_sec);
if (flow == NULL) if (flow == NULL)
{ {
return NULL; return NULL;
@@ -1010,9 +978,9 @@ 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) struct packet *ipv6_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec)
{ {
const struct layer_record *layer = pkt->frag_layer; const struct layer *layer = pkt->frag_layer;
const struct ip6_hdr *hdr = (const struct ip6_hdr *)layer->hdr_ptr; const struct ip6_hdr *hdr = (const struct ip6_hdr *)layer->hdr_ptr;
const struct ip6_frag *frag_hdr = ipv6_hdr_get_frag_ext(hdr); const struct ip6_frag *frag_hdr = ipv6_hdr_get_frag_ext(hdr);
if (frag_hdr == NULL) if (frag_hdr == NULL)
@@ -1035,7 +1003,7 @@ struct packet *ipv6_reassembly_packet(struct ip_reassembly *mgr, const struct pa
key.ip_id = ipv6_frag_get_ident(frag_hdr); key.ip_id = ipv6_frag_get_ident(frag_hdr);
key.proto = 0; // only first fragment has the upper layer protocol key.proto = 0; // only first fragment has the upper layer protocol
struct ip_flow *flow = ip_reassembly_update_flow(mgr, &key); struct ip_flow *flow = ip_reassembly_update_flow(mgr, &key, now_sec);
if (flow == NULL) if (flow == NULL)
{ {
return NULL; return NULL;

View File

@@ -52,17 +52,16 @@ struct ip_reassembly_stat
struct ip_reassembly *ip_reassembly_new(const struct ip_reassembly_options *opts); struct ip_reassembly *ip_reassembly_new(const struct ip_reassembly_options *opts);
void ip_reassembly_free(struct ip_reassembly *mgr); void ip_reassembly_free(struct ip_reassembly *mgr);
void ip_reassembly_expire(struct ip_reassembly *mgr); void ip_reassembly_expire(struct ip_reassembly *mgr, uint64_t now_sec);
void ip_reassembly_print_stat(struct ip_reassembly *mgr);
struct ip_reassembly_stat *ip_reassembly_get_stat(struct ip_reassembly *mgr); struct ip_reassembly_stat *ip_reassembly_get_stat(struct ip_reassembly *mgr);
/* /*
* Returns the reassembled packet, or NULL if the packet is not reassembled * Returns the reassembled packet, or NULL if the packet is not reassembled
* The returned packet should be freed by calling the packet_free() function * The returned packet should be freed by calling the packet_free() function
*/ */
struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt); 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); 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); struct packet *ipv6_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec);
#ifdef __cpluscplus #ifdef __cpluscplus
} }

View File

@@ -1,7 +1,3 @@
###############################################################################
# gtest
###############################################################################
add_executable(gtest_ipv4_reassembly gtest_ipv4_reassembly.cpp) add_executable(gtest_ipv4_reassembly gtest_ipv4_reassembly.cpp)
target_link_libraries(gtest_ipv4_reassembly ip_reassembly gtest) target_link_libraries(gtest_ipv4_reassembly ip_reassembly gtest)

View File

@@ -196,7 +196,7 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
{ {
struct packet pkt; struct packet pkt;
struct packet *new_pkt; struct packet *new_pkt;
const struct layer_record *layer; const struct layer *layer;
struct ip_reassembly *mgr; struct ip_reassembly *mgr;
struct ip_reassembly_options opts = { struct ip_reassembly_options opts = {
.enable = true, .enable = true,
@@ -205,11 +205,9 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
.bucket_num = 8, .bucket_num = 8,
}; };
timestamp_update();
mgr = ip_reassembly_new(&opts); mgr = ip_reassembly_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -218,9 +216,9 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
// frag1 // frag1
packet_parse(&pkt, (const char *)frag1, sizeof(frag1)); packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
1, 1, 0, 0, // ip4: find, add, del, timeout 1, 1, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -229,9 +227,9 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
// frag2 // frag2
packet_parse(&pkt, (const char *)frag2, sizeof(frag2)); packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
2, 1, 1, 0, // ip4: find, add, del, timeout 2, 1, 1, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -291,7 +289,7 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
{ {
struct packet pkt; struct packet pkt;
struct packet *new_pkt; struct packet *new_pkt;
const struct layer_record *layer; const struct layer *layer;
struct ip_reassembly *mgr; struct ip_reassembly *mgr;
struct ip_reassembly_options opts = { struct ip_reassembly_options opts = {
.enable = true, .enable = true,
@@ -300,11 +298,9 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
.bucket_num = 8, .bucket_num = 8,
}; };
timestamp_update();
mgr = ip_reassembly_new(&opts); mgr = ip_reassembly_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -313,9 +309,9 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
// frag2 // frag2
packet_parse(&pkt, (const char *)frag2, sizeof(frag2)); packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
1, 1, 0, 0, // ip4: find, add, del, timeout 1, 1, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -324,9 +320,9 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
// frag1 // frag1
packet_parse(&pkt, (const char *)frag1, sizeof(frag1)); packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
2, 1, 1, 0, // ip4: find, add, del, timeout 2, 1, 1, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -394,11 +390,9 @@ TEST(IPV4_REASSEMBLE, EXPIRE)
.bucket_num = 8, .bucket_num = 8,
}; };
timestamp_update();
mgr = ip_reassembly_new(&opts); mgr = ip_reassembly_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -407,24 +401,20 @@ TEST(IPV4_REASSEMBLE, EXPIRE)
// frag1 // frag1
packet_parse(&pkt, (const char *)frag1, sizeof(frag1)); packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
1, 1, 0, 0, // ip4: find, add, del, timeout 1, 1, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
0, 0, 0, 0, // ip6: find, add, del, timeout 0, 0, 0, 0, // ip6: find, add, del, timeout
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
// sleep 1s
sleep(1);
timestamp_update();
// frag2 // frag2
packet_parse(&pkt, (const char *)frag2, sizeof(frag2)); packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 2);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
2, 2, 1, 1, // ip4: find, add, del, timeout 2, 2, 1, 1, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -443,7 +433,7 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
{ {
struct packet pkt; struct packet pkt;
struct packet *new_pkt; struct packet *new_pkt;
const struct layer_record *layer; const struct layer *layer;
struct ip_reassembly *mgr; struct ip_reassembly *mgr;
struct ip_reassembly_options opts = { struct ip_reassembly_options opts = {
.enable = true, .enable = true,
@@ -452,11 +442,9 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
.bucket_num = 8, .bucket_num = 8,
}; };
timestamp_update();
mgr = ip_reassembly_new(&opts); mgr = ip_reassembly_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -465,9 +453,9 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
// frag1 // frag1
packet_parse(&pkt, (const char *)frag1, sizeof(frag1)); packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
1, 1, 0, 0, // ip4: find, add, del, timeout 1, 1, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -476,9 +464,9 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
// frag1 // frag1
packet_parse(&pkt, (const char *)frag1, sizeof(frag1)); packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
2, 1, 0, 0, // ip4: find, add, del, timeout 2, 1, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 1, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 1, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -487,9 +475,9 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
// frag2 // frag2
packet_parse(&pkt, (const char *)frag2, sizeof(frag2)); packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
3, 1, 1, 0, // ip4: find, add, del, timeout 3, 1, 1, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 1, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 1, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -549,7 +537,7 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
{ {
struct packet pkt; struct packet pkt;
struct packet *new_pkt; struct packet *new_pkt;
const struct layer_record *layer; const struct layer *layer;
struct ip_reassembly *mgr; struct ip_reassembly *mgr;
struct ip_reassembly_options opts = { struct ip_reassembly_options opts = {
.enable = true, .enable = true,
@@ -558,11 +546,9 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
.bucket_num = 8, .bucket_num = 8,
}; };
timestamp_update();
mgr = ip_reassembly_new(&opts); mgr = ip_reassembly_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -571,9 +557,9 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
// frag2 // frag2
packet_parse(&pkt, (const char *)frag2, sizeof(frag2)); packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
1, 1, 0, 0, // ip4: find, add, del, timeout 1, 1, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -582,9 +568,9 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
// frag2 // frag2
packet_parse(&pkt, (const char *)frag2, sizeof(frag2)); packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
2, 1, 0, 0, // ip4: find, add, del, timeout 2, 1, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 1, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 1, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -593,9 +579,9 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
// frag1 // frag1
packet_parse(&pkt, (const char *)frag1, sizeof(frag1)); packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
3, 1, 1, 0, // ip4: find, add, del, timeout 3, 1, 1, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 1, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 1, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -663,11 +649,9 @@ TEST(IPV4_REASSEMBLE, FULL)
.bucket_num = 1, .bucket_num = 1,
}; };
timestamp_update();
mgr = ip_reassembly_new(&opts); mgr = ip_reassembly_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -680,9 +664,9 @@ TEST(IPV4_REASSEMBLE, FULL)
// flow1 // flow1
packet_set_ipv4_src_addr(&pkt, 1); packet_set_ipv4_src_addr(&pkt, 1);
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
1, 1, 0, 0, // ip4: find, add, del, timeout 1, 1, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -691,9 +675,9 @@ TEST(IPV4_REASSEMBLE, FULL)
// flow2 // flow2
packet_set_ipv4_src_addr(&pkt, 2); packet_set_ipv4_src_addr(&pkt, 2);
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
2, 2, 0, 0, // ip4: find, add, del, timeout 2, 2, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -702,9 +686,9 @@ TEST(IPV4_REASSEMBLE, FULL)
// flow3 // flow3
packet_set_ipv4_src_addr(&pkt, 3); packet_set_ipv4_src_addr(&pkt, 3);
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
3, 2, 0, 0, // ip4: find, add, del, timeout 3, 2, 0, 0, // ip4: find, add, del, timeout
1, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 1, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag

View File

@@ -607,7 +607,7 @@ TEST(IPV6_REASSEMBLE, NORMAL)
{ {
struct packet pkt; struct packet pkt;
struct packet *new_pkt; struct packet *new_pkt;
const struct layer_record *layer; const struct layer *layer;
struct ip_reassembly *mgr; struct ip_reassembly *mgr;
struct ip_reassembly_options opts = { struct ip_reassembly_options opts = {
.enable = true, .enable = true,
@@ -616,11 +616,9 @@ TEST(IPV6_REASSEMBLE, NORMAL)
.bucket_num = 8, .bucket_num = 8,
}; };
timestamp_update();
mgr = ip_reassembly_new(&opts); mgr = ip_reassembly_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -629,9 +627,9 @@ TEST(IPV6_REASSEMBLE, NORMAL)
// frag1 // frag1
packet_parse(&pkt, (const char *)frag1, sizeof(frag1)); packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -640,9 +638,9 @@ TEST(IPV6_REASSEMBLE, NORMAL)
// frag2 // frag2
packet_parse(&pkt, (const char *)frag2, sizeof(frag2)); packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -651,9 +649,9 @@ TEST(IPV6_REASSEMBLE, NORMAL)
// frag3 // frag3
packet_parse(&pkt, (const char *)frag3, sizeof(frag3)); packet_parse(&pkt, (const char *)frag3, sizeof(frag3));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -662,9 +660,9 @@ TEST(IPV6_REASSEMBLE, NORMAL)
// frag4 // frag4
packet_parse(&pkt, (const char *)frag4, sizeof(frag4)); packet_parse(&pkt, (const char *)frag4, sizeof(frag4));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -726,11 +724,9 @@ TEST(IPV6_REASSEMBLE, EXPIRE)
.bucket_num = 8, .bucket_num = 8,
}; };
timestamp_update();
mgr = ip_reassembly_new(&opts); mgr = ip_reassembly_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -739,24 +735,20 @@ TEST(IPV6_REASSEMBLE, EXPIRE)
// frag1 // frag1
packet_parse(&pkt, (const char *)frag1, sizeof(frag1)); packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
1, 1, 0, 0, // ip6: find, add, del, timeout 1, 1, 0, 0, // ip6: find, add, del, timeout
0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0); // ip6: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
// sleep 1
sleep(1);
timestamp_update();
// frag2 // frag2
packet_parse(&pkt, (const char *)frag2, sizeof(frag2)); packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 2);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -775,7 +767,7 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
{ {
struct packet pkt; struct packet pkt;
struct packet *new_pkt; struct packet *new_pkt;
const struct layer_record *layer; const struct layer *layer;
struct ip_reassembly *mgr; struct ip_reassembly *mgr;
struct ip_reassembly_options opts = { struct ip_reassembly_options opts = {
.enable = true, .enable = true,
@@ -784,11 +776,9 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
.bucket_num = 8, .bucket_num = 8,
}; };
timestamp_update();
mgr = ip_reassembly_new(&opts); mgr = ip_reassembly_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -797,9 +787,9 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
// frag1 // frag1
packet_parse(&pkt, (const char *)frag1, sizeof(frag1)); packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -808,9 +798,9 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
// frag1 // frag1
packet_parse(&pkt, (const char *)frag1, sizeof(frag1)); packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -819,9 +809,9 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
// frag2 // frag2
packet_parse(&pkt, (const char *)frag2, sizeof(frag2)); packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -830,9 +820,9 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
// frag3 // frag3
packet_parse(&pkt, (const char *)frag3, sizeof(frag3)); packet_parse(&pkt, (const char *)frag3, sizeof(frag3));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -841,9 +831,9 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
// frag4 // frag4
packet_parse(&pkt, (const char *)frag4, sizeof(frag4)); packet_parse(&pkt, (const char *)frag4, sizeof(frag4));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -897,7 +887,7 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
{ {
struct packet pkt; struct packet pkt;
struct packet *new_pkt; struct packet *new_pkt;
const struct layer_record *layer; const struct layer *layer;
struct ip_reassembly *mgr; struct ip_reassembly *mgr;
struct ip_reassembly_options opts = { struct ip_reassembly_options opts = {
.enable = true, .enable = true,
@@ -906,11 +896,9 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
.bucket_num = 8, .bucket_num = 8,
}; };
timestamp_update();
mgr = ip_reassembly_new(&opts); mgr = ip_reassembly_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -919,9 +907,9 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
// frag4 // frag4
packet_parse(&pkt, (const char *)frag4, sizeof(frag4)); packet_parse(&pkt, (const char *)frag4, sizeof(frag4));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -930,9 +918,9 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
// frag4 // frag4
packet_parse(&pkt, (const char *)frag4, sizeof(frag4)); packet_parse(&pkt, (const char *)frag4, sizeof(frag4));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -941,9 +929,9 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
// frag3 // frag3
packet_parse(&pkt, (const char *)frag3, sizeof(frag3)); packet_parse(&pkt, (const char *)frag3, sizeof(frag3));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -952,9 +940,9 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
// frag2 // frag2
packet_parse(&pkt, (const char *)frag2, sizeof(frag2)); packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -963,9 +951,9 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
// frag1 // frag1
packet_parse(&pkt, (const char *)frag1, sizeof(frag1)); packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt); EXPECT_TRUE(new_pkt);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -1028,11 +1016,9 @@ TEST(IPV6_REASSEMBLE, FULL)
.bucket_num = 1, .bucket_num = 1,
}; };
timestamp_update();
mgr = ip_reassembly_new(&opts); mgr = ip_reassembly_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -1046,9 +1032,9 @@ TEST(IPV6_REASSEMBLE, FULL)
// flow1 // flow1
memset(&src_addr, 1, sizeof(src_addr)); memset(&src_addr, 1, sizeof(src_addr));
packet_set_ipv6_src_addr(&pkt, src_addr); packet_set_ipv6_src_addr(&pkt, src_addr);
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -1058,9 +1044,9 @@ TEST(IPV6_REASSEMBLE, FULL)
// flow2 // flow2
memset(&src_addr, 2, sizeof(src_addr)); memset(&src_addr, 2, sizeof(src_addr));
packet_set_ipv6_src_addr(&pkt, src_addr); packet_set_ipv6_src_addr(&pkt, src_addr);
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -1070,9 +1056,9 @@ TEST(IPV6_REASSEMBLE, FULL)
// flow3 // flow3
memset(&src_addr, 3, sizeof(src_addr)); memset(&src_addr, 3, sizeof(src_addr));
packet_set_ipv6_src_addr(&pkt, src_addr); packet_set_ipv6_src_addr(&pkt, src_addr);
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -1099,11 +1085,9 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
.bucket_num = 8, .bucket_num = 8,
}; };
timestamp_update();
mgr = ip_reassembly_new(&opts); mgr = ip_reassembly_new(&opts);
EXPECT_TRUE(mgr != NULL); EXPECT_TRUE(mgr != NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -1112,9 +1096,9 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
// frag1 // frag1
packet_parse(&pkt, (const char *)frag1, sizeof(frag1)); packet_parse(&pkt, (const char *)frag1, sizeof(frag1));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -1123,9 +1107,9 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
// frag2 // frag2
packet_parse(&pkt, (const char *)frag2, sizeof(frag2)); packet_parse(&pkt, (const char *)frag2, sizeof(frag2));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -1137,9 +1121,9 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
memcpy(dup_frag, frag3, sizeof(frag3)); memcpy(dup_frag, frag3, sizeof(frag3));
packet_parse(&pkt, (const char *)dup_frag, sizeof(dup_frag)); packet_parse(&pkt, (const char *)dup_frag, sizeof(dup_frag));
packet_set_ipv6_frag_offset(&pkt, 2048); packet_set_ipv6_frag_offset(&pkt, 2048);
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag
@@ -1148,9 +1132,9 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
// frag4 // frag4
packet_parse(&pkt, (const char *)frag4, sizeof(frag4)); packet_parse(&pkt, (const char *)frag4, sizeof(frag4));
new_pkt = ip_reassembly_packet(mgr, &pkt); new_pkt = ip_reassembly_packet(mgr, &pkt, 1);
EXPECT_TRUE(new_pkt == NULL); EXPECT_TRUE(new_pkt == NULL);
// ip_reassembly_print_stat(mgr);
check_stat(ip_reassembly_get_stat(mgr), check_stat(ip_reassembly_get_stat(mgr),
0, 0, 0, 0, // ip4: find, add, del, timeout 0, 0, 0, 0, // ip4: find, add, del, timeout
0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag 0, 0, 0, 0, 0, 0, // ip4: nospace, overlap, many frag, invalid length, dup first frag, dup last frag

View File

@@ -8,17 +8,15 @@ extern "C"
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "timestamp.h"
#include "udp_utils.h" #include "udp_utils.h"
#include "tcp_utils.h" #include "tcp_utils.h"
#include "ipv4_utils.h" #include "ipv4_utils.h"
#include "ipv6_utils.h" #include "ipv6_utils.h"
#include "packet_utils.h"
#include "ip_reassembly.h" #include "ip_reassembly.h"
static inline void packet_set_ipv4_src_addr(struct packet *pkt, uint32_t saddr) static inline void packet_set_ipv4_src_addr(struct packet *pkt, uint32_t saddr)
{ {
const struct layer_record *ipv4_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_IPV4); const struct layer *ipv4_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer); EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_src_addr(hdr, saddr); ipv4_hdr_set_src_addr(hdr, saddr);
@@ -26,7 +24,7 @@ static inline void packet_set_ipv4_src_addr(struct packet *pkt, uint32_t saddr)
static inline void packet_set_ipv6_src_addr(struct packet *pkt, struct in6_addr saddr) static inline void packet_set_ipv6_src_addr(struct packet *pkt, struct in6_addr saddr)
{ {
const struct layer_record *ipv6_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_IPV6); const struct layer *ipv6_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_IPV6);
EXPECT_TRUE(ipv6_layer); EXPECT_TRUE(ipv6_layer);
struct ip6_hdr *hdr = (struct ip6_hdr *)ipv6_layer->hdr_ptr; struct ip6_hdr *hdr = (struct ip6_hdr *)ipv6_layer->hdr_ptr;
ipv6_hdr_set_src_in6_addr(hdr, saddr); ipv6_hdr_set_src_in6_addr(hdr, saddr);
@@ -34,7 +32,7 @@ static inline void packet_set_ipv6_src_addr(struct packet *pkt, struct in6_addr
static inline void packet_set_ipv6_frag_offset(struct packet *pkt, uint16_t offset) static inline void packet_set_ipv6_frag_offset(struct packet *pkt, uint16_t offset)
{ {
const struct layer_record *ipv6_layer = (struct layer_record *)packet_get_innermost_layer(pkt, LAYER_TYPE_IPV6); const struct layer *ipv6_layer = (struct layer *)packet_get_innermost_layer(pkt, LAYER_TYPE_IPV6);
EXPECT_TRUE(ipv6_layer); EXPECT_TRUE(ipv6_layer);
struct ip6_hdr *hdr = (struct ip6_hdr *)ipv6_layer->hdr_ptr; struct ip6_hdr *hdr = (struct ip6_hdr *)ipv6_layer->hdr_ptr;
struct ip6_frag *frag_hdr = ipv6_hdr_get_frag_ext(hdr); struct ip6_frag *frag_hdr = ipv6_hdr_get_frag_ext(hdr);

View File

@@ -1,7 +1,3 @@
###############################################################################
# log
###############################################################################
add_library(log log.cpp) add_library(log log.cpp)
target_include_directories(log PUBLIC ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(log PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(log toml) target_link_libraries(log toml)

View File

@@ -1,7 +1,3 @@
###############################################################################
# gtest
###############################################################################
add_executable(gtest_log gtest_log.cpp) add_executable(gtest_log gtest_log.cpp)
target_link_libraries(gtest_log log gtest) target_link_libraries(gtest_log log gtest)

View File

@@ -1,8 +1,4 @@
############################################################################### add_library(packet packet.cpp)
# packet
###############################################################################
add_library(packet packet.cpp packet_utils.cpp)
target_include_directories(packet PUBLIC ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(packet PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(packet PUBLIC ${CMAKE_SOURCE_DIR}/deps/uthash) target_include_directories(packet PUBLIC ${CMAKE_SOURCE_DIR}/deps/uthash)
target_link_libraries(packet tuple log) target_link_libraries(packet tuple log)

File diff suppressed because it is too large Load Diff

View File

@@ -11,10 +11,9 @@ extern "C"
#include "tuple.h" #include "tuple.h"
#include "log.h" #include "log.h"
#define PACKET_MAX_LAYERS 16 #define PACKET_MAX_LAYERS 32
#define PACKET_LOG_ERROR(format, ...) LOG_ERROR("packet", format, ##__VA_ARGS__) #define PACKET_LOG_ERROR(format, ...) LOG_ERROR("packet", format, ##__VA_ARGS__)
#define PACKET_LOG_DEBUG(format, ...) void(0) #define PACKET_LOG_DEBUG(format, ...) LOG_DEBUG("packet", format, ##__VA_ARGS__)
// #define PACKET_LOG_DEBUG(format, ...) LOG_DEBUG("packet", format, ##__VA_ARGS__)
enum layer_type enum layer_type
{ {
@@ -61,7 +60,49 @@ enum ldbc_method
LDBC_METHOD_HASH_INNERMOST_EXT_IP = 5, LDBC_METHOD_HASH_INNERMOST_EXT_IP = 5,
}; };
struct layer_record enum packet_direction
{
PACKET_DIRECTION_I2E = 0,
PACKET_DIRECTION_E2I = 1,
};
enum packet_action
{
PACKET_ACTION_FORWARD = 0,
PACKET_ACTION_DROP = 1,
};
enum packet_type
{
PACKET_TYPE_DATA = 0,
PACKET_TYPE_CTRL = 1,
};
struct metadata
{
#define MAX_SID_NUM 8
#define MAX_ROUTE_LEN 64
struct
{
uint16_t list[MAX_SID_NUM];
uint16_t used;
} sid;
struct
{
char data[MAX_ROUTE_LEN];
uint16_t len;
} route;
void *user_data;
uint64_t domain;
uint64_t session_id;
enum packet_direction direction;
enum packet_action action;
enum packet_type type;
};
struct layer
{ {
enum layer_type type; enum layer_type type;
const char *hdr_ptr; // header pointer const char *hdr_ptr; // header pointer
@@ -71,61 +112,90 @@ struct layer_record
uint16_t pld_len; // payload length uint16_t pld_len; // payload length
}; };
#define MAX_SID_NUM 8
#define MAX_ROUTE_LEN 64
struct packet struct packet
{ {
struct layer_record layers[PACKET_MAX_LAYERS]; struct layer layers[PACKET_MAX_LAYERS];
struct layer_record *frag_layer; // fragment layer struct layer *frag_layer; // fragment layer
int8_t layers_used; int8_t layers_used;
int8_t layers_size; int8_t layers_size;
const char *data_ptr; const char *data_ptr;
uint16_t data_len; uint16_t data_len;
uint64_t domain;
bool need_free; bool need_free;
// metadata struct metadata meta;
void *io_ctx;
uint16_t sid_list[MAX_SID_NUM];
uint16_t sid_used;
char route_ctx[MAX_ROUTE_LEN];
uint16_t route_len;
uint64_t session_id;
uint8_t direction;
uint8_t type;
uint8_t action;
}; };
// return innermost payload // return innermost payload
const char *packet_parse(struct packet *handler, const char *data, uint16_t len); const char *packet_parse(struct packet *pkt, const char *data, uint16_t len);
void packet_print(const struct packet *handler); void packet_print(const struct packet *pkt);
// return 0 : found // return 0: found
// return -1 : not found // return -1: not found
int packet_get_innermost_tuple2(const struct packet *handler, struct tuple2 *tuple); int packet_get_innermost_tuple2(const struct packet *pkt, struct tuple2 *tuple);
int packet_get_outermost_tuple2(const struct packet *handler, struct tuple2 *tuple); int packet_get_outermost_tuple2(const struct packet *pkt, struct tuple2 *tuple);
// return 0 : found // return 0: found
// return -1 : not found // return -1: not found
int packet_get_innermost_tuple4(const struct packet *handler, struct tuple4 *tuple); int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple);
int packet_get_outermost_tuple4(const struct packet *handler, struct tuple4 *tuple); int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple);
// return 0 : found // return 0: found
// return -1 : not found // return -1: not found
int packet_get_innermost_tuple6(const struct packet *handler, struct tuple6 *tuple); int packet_get_innermost_tuple6(const struct packet *pkt, struct tuple6 *tuple);
int packet_get_outermost_tuple6(const struct packet *handler, struct tuple6 *tuple); int packet_get_outermost_tuple6(const struct packet *pkt, struct tuple6 *tuple);
const struct layer_record *packet_get_innermost_layer(const struct packet *handler, enum layer_type type); const struct layer *packet_get_innermost_layer(const struct packet *pkt, enum layer_type type);
const struct layer_record *packet_get_outermost_layer(const struct packet *handler, enum layer_type type); const struct layer *packet_get_outermost_layer(const struct packet *pkt, enum layer_type type);
// direction 1: E2I // direction 1: E2I
// direction 0: I2E // direction 0: I2E
uint64_t packet_get_hash(const struct packet *handler, enum ldbc_method method, int direction); uint64_t packet_get_hash(const struct packet *pkt, enum ldbc_method method, int direction);
// return 0: success
// return -1: failed
int packet_set_sid(struct packet *pkt, uint16_t *sid, int num);
// return number of sid
int packet_get_sid(const struct packet *pkt, uint16_t *sid, int size);
// return 0: success
// return -1: failed
int packet_prepend_sid(struct packet *pkt, uint16_t sid);
// return 0: success
// return -1: failed
int packet_append_sid(struct packet *pkt, uint16_t sid);
// return 0: success
// return -1: failed
int packet_set_route_ctx(struct packet *pkt, const char *route, int len);
// return len of route ctx
int packet_get_route_ctx(const struct packet *pkt, char *buff, int size);
void packet_set_user_data(struct packet *pkt, void *user_data);
void *packet_get_user_data(const struct packet *pkt);
void packet_set_domain(struct packet *pkt, uint64_t domain);
uint64_t packet_get_domain(const struct packet *pkt);
void packet_set_session_id(struct packet *pkt, uint64_t session_id);
uint64_t packet_get_session_id(const struct packet *pkt);
void packet_set_direction(struct packet *pkt, enum packet_direction direction);
enum packet_direction packet_get_direction(const struct packet *pkt);
void packet_set_action(struct packet *pkt, enum packet_action action);
enum packet_action packet_get_action(const struct packet *pkt);
void packet_set_type(struct packet *pkt, enum packet_type type);
enum packet_type packet_get_type(const struct packet *pkt);
struct packet *packet_new(uint16_t pkt_len);
void packet_free(struct packet *pkt);
struct packet *packet_dup(const struct packet *pkt);
const char *packet_get_data(const struct packet *pkt);
uint16_t packet_get_len(const struct packet *pkt);
bool packet_is_fragment(const struct packet *pkt);
#ifdef __cpluscplus #ifdef __cpluscplus
} }

View File

@@ -1,202 +0,0 @@
#include "packet_utils.h"
void packet_set_io_ctx(struct packet *pkt, void *ctx)
{
pkt->io_ctx = ctx;
}
void *packet_get_io_ctx(const struct packet *pkt)
{
return pkt->io_ctx;
}
// return 0 success; return -1 failed
int packet_set_sid(struct packet *pkt, uint16_t *sid, int num)
{
if (num > MAX_SID_NUM)
{
return -1;
}
pkt->sid_used = num;
memcpy(pkt->sid_list, sid, num * sizeof(uint16_t));
return 0;
}
// return number of sid
int packet_get_sid(const struct packet *pkt, uint16_t *sid, int size)
{
if (size < pkt->sid_used)
{
return 0;
}
memcpy(sid, pkt->sid_list, pkt->sid_used * sizeof(uint16_t));
return pkt->sid_used;
}
// return 0 success; return -1 failed
int packet_prepend_sid(struct packet *pkt, uint16_t sid)
{
if (pkt->sid_used >= MAX_SID_NUM)
{
return -1;
}
memmove(pkt->sid_list + 1, pkt->sid_list, pkt->sid_used * sizeof(uint16_t));
pkt->sid_list[0] = sid;
pkt->sid_used++;
return 0;
}
// return 0 success; return -1 failed
int packet_append_sid(struct packet *pkt, uint16_t sid)
{
if (pkt->sid_used >= MAX_SID_NUM)
{
return -1;
}
pkt->sid_list[pkt->sid_used] = sid;
pkt->sid_used++;
return 0;
}
// return 0 success; return -1 failed
int packet_set_route_ctx(struct packet *pkt, const char *route, int len)
{
if (len > MAX_ROUTE_LEN)
{
return -1;
}
memcpy(pkt->route_ctx, route, len);
pkt->route_len = len;
return 0;
}
// return len of route ctx
int packet_get_route_ctx(const struct packet *pkt, char *buff, int size)
{
if (pkt->route_len > size)
{
return 0;
}
memcpy(buff, pkt->route_ctx, pkt->route_len);
return pkt->route_len;
}
void packet_set_session_id(struct packet *pkt, uint64_t session_id)
{
pkt->session_id = session_id;
}
uint64_t packet_get_session_id(const struct packet *pkt)
{
return pkt->session_id;
}
void packet_set_direction(struct packet *pkt, uint8_t direction)
{
pkt->direction = direction;
}
uint8_t packet_get_direction(const struct packet *pkt)
{
return pkt->direction;
}
void packet_set_type(struct packet *pkt, uint8_t type)
{
pkt->type = type;
}
uint8_t packet_get_type(const struct packet *pkt)
{
return pkt->type;
}
void packet_set_action(struct packet *pkt, uint8_t action)
{
pkt->action = action;
}
uint8_t packet_get_action(const struct packet *pkt)
{
return pkt->action;
}
struct packet *packet_new(uint16_t len)
{
struct packet *pkt = (struct packet *)calloc(1, sizeof(struct packet) + len);
if (pkt == NULL)
{
return NULL;
}
pkt->data_len = len;
pkt->data_ptr = (const char *)pkt + sizeof(struct packet);
pkt->need_free = true;
return pkt;
}
void packet_free(struct packet *pkt)
{
if (pkt && pkt->need_free)
{
free(pkt);
pkt = NULL;
}
}
struct packet *packet_dup(const struct packet *pkt)
{
if (pkt == NULL)
{
return NULL;
}
struct packet *pkt_dup = packet_new(pkt->data_len);
if (pkt_dup == NULL)
{
return NULL;
}
memcpy(pkt_dup, pkt, sizeof(struct packet));
memcpy((char *)pkt_dup->data_ptr, pkt->data_ptr, pkt->data_len);
pkt_dup->need_free = true;
// update layers
for (int8_t i = 0; i < pkt->layers_used; i++)
{
pkt_dup->layers[i].hdr_ptr = pkt_dup->data_ptr + pkt->layers[i].hdr_offset;
pkt_dup->layers[i].pld_ptr = pkt_dup->data_ptr + pkt->layers[i].hdr_offset + pkt->layers[i].hdr_len;
}
// update frag_layer
if (pkt->frag_layer)
{
pkt_dup->frag_layer = &pkt_dup->layers[pkt->frag_layer - pkt->layers];
}
return pkt_dup;
}
const char *packet_get_data(const struct packet *pkt)
{
return pkt->data_ptr;
}
uint16_t packet_get_len(const struct packet *pkt)
{
return pkt->data_len;
}
bool paket_is_fragment(const struct packet *pkt)
{
if (pkt->frag_layer)
{
return true;
}
else
{
return false;
}
}

View File

@@ -1,59 +0,0 @@
#ifndef _PACKET_UTILS_H
#define _PACKET_UTILS_H
#ifdef __cpluscplus
extern "C"
{
#endif
#include <stdlib.h>
#include <string.h>
#include "packet.h"
void packet_set_io_ctx(struct packet *pkt, void *ctx);
void *packet_get_io_ctx(const struct packet *pkt);
int packet_set_sid(struct packet *pkt, uint16_t *sid, int num); // return 0 success; return -1 failed
int packet_get_sid(const struct packet *pkt, uint16_t *sid, int size); // return number of sid
int packet_prepend_sid(struct packet *pkt, uint16_t sid); // return 0 success; return -1 failed
int packet_append_sid(struct packet *pkt, uint16_t sid); // return 0 success; return -1 failed
int packet_set_route_ctx(struct packet *pkt, const char *route, int len); // return 0 success; return -1 failed
int packet_get_route_ctx(const struct packet *pkt, char *buff, int size); // return len of route ctx
void packet_set_session_id(struct packet *pkt, uint64_t session_id);
uint64_t packet_get_session_id(const struct packet *pkt);
#define PACKET_DIRECTION_I2E 0
#define PACKET_DIRECTION_E2I 1
void packet_set_direction(struct packet *pkt, uint8_t direction);
uint8_t packet_get_direction(const struct packet *pkt);
#define PACKET_TYPE_DATA 0
#define PACKET_TYPE_CTRL 1
void packet_set_type(struct packet *pkt, uint8_t type);
uint8_t packet_get_type(const struct packet *pkt);
#define PACKET_ACTION_FORWARD 0
#define PACKET_ACTION_DROP 1
void packet_set_action(struct packet *pkt, uint8_t action);
uint8_t packet_get_action(const struct packet *pkt);
struct packet *packet_new(uint16_t len);
void packet_free(struct packet *pkt);
struct packet *packet_dup(const struct packet *pkt);
const char *packet_get_data(const struct packet *pkt);
uint16_t packet_get_len(const struct packet *pkt);
bool paket_is_fragment(const struct packet *pkt);
#ifdef __cpluscplus
}
#endif
#endif

View File

@@ -1,7 +1,3 @@
###############################################################################
# gtest
###############################################################################
add_executable(gtest_packet gtest_packet.cpp) add_executable(gtest_packet gtest_packet.cpp)
target_link_libraries(gtest_packet packet gtest) target_link_libraries(gtest_packet packet gtest)
@@ -17,8 +13,8 @@ target_link_libraries(gtest_ipv4_utils packet gtest)
add_executable(gtest_ipv6_utils gtest_ipv6_utils.cpp) add_executable(gtest_ipv6_utils gtest_ipv6_utils.cpp)
target_link_libraries(gtest_ipv6_utils packet gtest) target_link_libraries(gtest_ipv6_utils packet gtest)
add_executable(gtest_packet_utils gtest_packet_utils.cpp) add_executable(gtest_packet_frag gtest_packet_frag.cpp)
target_link_libraries(gtest_packet_utils packet gtest) target_link_libraries(gtest_packet_frag packet gtest)
include(GoogleTest) include(GoogleTest)
gtest_discover_tests(gtest_packet) gtest_discover_tests(gtest_packet)
@@ -26,4 +22,4 @@ gtest_discover_tests(gtest_udp_utils)
gtest_discover_tests(gtest_tcp_utils) gtest_discover_tests(gtest_tcp_utils)
gtest_discover_tests(gtest_ipv4_utils) gtest_discover_tests(gtest_ipv4_utils)
gtest_discover_tests(gtest_ipv6_utils) gtest_discover_tests(gtest_ipv6_utils)
gtest_discover_tests(gtest_packet_utils) gtest_discover_tests(gtest_packet_frag)

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "packet_utils.h" #include "packet.h"
/****************************************************************************** /******************************************************************************
* [Protocols in frame: eth:ethertype:ip:data] * [Protocols in frame: eth:ethertype:ip:data]
@@ -44,15 +44,15 @@ unsigned char data1[] = {
0x00, 0x00, 0x31, 0x32, 0x33, 0x0a, 0x00, 0x00}; 0x00, 0x00, 0x31, 0x32, 0x33, 0x0a, 0x00, 0x00};
#if 1 #if 1
TEST(PACKET_UTILS, IPV4_FRAGMENT) TEST(PACKET_FRAG, IPV4_FRAGMENT)
{ {
struct packet handler; struct packet handler;
packet_parse(&handler, (const char *)data1, sizeof(data1)); packet_parse(&handler, (const char *)data1, sizeof(data1));
EXPECT_TRUE(paket_is_fragment(&handler) == true); EXPECT_TRUE(packet_is_fragment(&handler) == true);
struct packet *dup = packet_dup(&handler); struct packet *dup = packet_dup(&handler);
EXPECT_TRUE(dup != NULL); EXPECT_TRUE(dup != NULL);
EXPECT_TRUE(paket_is_fragment(dup) == true); EXPECT_TRUE(packet_is_fragment(dup) == true);
packet_free(dup); packet_free(dup);
} }
#endif #endif
@@ -152,15 +152,15 @@ unsigned char data2[] = {
0x68, 0x68}; 0x68, 0x68};
#if 1 #if 1
TEST(PACKET_UTILS, IPV6_FRAGMENT) TEST(PACKET_FRAG, IPV6_FRAGMENT)
{ {
struct packet handler; struct packet handler;
packet_parse(&handler, (const char *)data2, sizeof(data2)); packet_parse(&handler, (const char *)data2, sizeof(data2));
EXPECT_TRUE(paket_is_fragment(&handler) == true); EXPECT_TRUE(packet_is_fragment(&handler) == true);
struct packet *dup = packet_dup(&handler); struct packet *dup = packet_dup(&handler);
EXPECT_TRUE(dup != NULL); EXPECT_TRUE(dup != NULL);
EXPECT_TRUE(paket_is_fragment(dup) == true); EXPECT_TRUE(packet_is_fragment(dup) == true);
packet_free(dup); packet_free(dup);
} }
#endif #endif
@@ -228,15 +228,15 @@ unsigned char data3[] = {
0x04, 0x02}; 0x04, 0x02};
#if 1 #if 1
TEST(PACKET_UTILS, IPV4_IPV6_NOT_FRAGMENT) TEST(PACKET_FRAG, IPV4_IPV6_NOT_FRAGMENT)
{ {
struct packet handler; struct packet handler;
packet_parse(&handler, (const char *)data3, sizeof(data3)); packet_parse(&handler, (const char *)data3, sizeof(data3));
EXPECT_TRUE(paket_is_fragment(&handler) == false); EXPECT_TRUE(packet_is_fragment(&handler) == false);
struct packet *dup = packet_dup(&handler); struct packet *dup = packet_dup(&handler);
EXPECT_TRUE(dup != NULL); EXPECT_TRUE(dup != NULL);
EXPECT_TRUE(paket_is_fragment(dup) == false); EXPECT_TRUE(packet_is_fragment(dup) == false);
packet_free(dup); packet_free(dup);
} }
#endif #endif
@@ -290,15 +290,15 @@ unsigned char data4[] = {
0x58, 0x58}; 0x58, 0x58};
#if 1 #if 1
TEST(PACKET_UTILS, IPV6_IPV6_NOT_FRAGMENT) TEST(PACKET_FRAG, IPV6_IPV6_NOT_FRAGMENT)
{ {
struct packet handler; struct packet handler;
packet_parse(&handler, (const char *)data4, sizeof(data4)); packet_parse(&handler, (const char *)data4, sizeof(data4));
EXPECT_TRUE(paket_is_fragment(&handler) == false); EXPECT_TRUE(packet_is_fragment(&handler) == false);
struct packet *dup = packet_dup(&handler); struct packet *dup = packet_dup(&handler);
EXPECT_TRUE(dup != NULL); EXPECT_TRUE(dup != NULL);
EXPECT_TRUE(paket_is_fragment(dup) == false); EXPECT_TRUE(packet_is_fragment(dup) == false);
packet_free(dup); packet_free(dup);
} }
#endif #endif

View File

@@ -1,8 +1,4 @@
############################################################################### add_library(packet_io packet_io_dumpfile.cpp packet_io_marsio.cpp lock_free_queue.cpp packet_io.cpp)
# packet_io
###############################################################################
add_library(packet_io packet_queue.cpp packet_io.cpp packet_io_dumpfile.cpp packet_io_marsio.cpp)
target_include_directories(packet_io PUBLIC ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(packet_io PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(packet_io PUBLIC ${CMAKE_SOURCE_DIR}/src/stellar) target_include_directories(packet_io PUBLIC ${CMAKE_SOURCE_DIR}/src/stellar)
target_link_libraries(packet_io mrzcpd packet file pcap) target_link_libraries(packet_io mrzcpd pcap packet file)

View File

@@ -2,11 +2,10 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include "packet_io.h" #include "stellar.h"
#include "packet_utils.h" #include "lock_free_queue.h"
#include "packet_queue.h"
struct packet_queue struct lock_free_queue
{ {
uint64_t *queue; uint64_t *queue;
uint32_t size; uint32_t size;
@@ -14,19 +13,19 @@ struct packet_queue
uint32_t tail; uint32_t tail;
}; };
struct packet_queue *packet_queue_new(uint32_t size) struct lock_free_queue *lock_free_queue_new(uint32_t size)
{ {
struct packet_queue *queue = (struct packet_queue *)calloc(1, sizeof(struct packet_queue)); struct lock_free_queue *queue = (struct lock_free_queue *)calloc(1, sizeof(struct lock_free_queue));
if (queue == NULL) if (queue == NULL)
{ {
PACKET_IO_LOG_ERROR("unable to alloc packet queue"); LOCK_FREE_QUEUE_LOG_ERROR("unable to new lock free queue");
return NULL; return NULL;
} }
queue->queue = (uint64_t *)calloc(size, sizeof(uint64_t)); queue->queue = (uint64_t *)calloc(size, sizeof(uint64_t));
if (queue->queue == NULL) if (queue->queue == NULL)
{ {
PACKET_IO_LOG_ERROR("unable to alloc packet queue buffer"); LOCK_FREE_QUEUE_LOG_ERROR("unable to new lock free queue");
free(queue); free(queue);
return NULL; return NULL;
} }
@@ -38,22 +37,17 @@ struct packet_queue *packet_queue_new(uint32_t size)
return queue; return queue;
} }
void packet_queue_free(struct packet_queue *queue) void lock_free_queue_free(struct lock_free_queue *queue)
{ {
if (queue == NULL) if (queue == NULL)
{ {
return; return;
} }
struct packet *pkt = NULL; // wait queue is empty
while (1) while (queue->head != queue->tail)
{ {
packet_queue_pop(queue, &pkt); usleep(1000);
if (pkt == NULL)
{
break;
}
packet_free(pkt);
} }
if (queue->queue) if (queue->queue)
@@ -65,13 +59,13 @@ void packet_queue_free(struct packet_queue *queue)
free(queue); free(queue);
} }
void packet_queue_push(struct packet_queue *queue, struct packet *pkt) void lock_free_queue_push(struct lock_free_queue *queue, void *data)
{ {
uint64_t wait = 1000; uint64_t wait = 1000;
retry: retry:
if (__sync_val_compare_and_swap(&queue->queue[queue->tail], 0, pkt) != 0) if (__sync_val_compare_and_swap(&queue->queue[queue->tail], 0, data) != 0)
{ {
PACKET_IO_LOG_ERROR("packet queue is full, retry later"); LOCK_FREE_QUEUE_LOG_ERROR("lock free queue is full, retry later");
usleep(wait); usleep(wait);
wait *= 2; wait *= 2;
goto retry; goto retry;
@@ -80,15 +74,15 @@ retry:
queue->tail = (queue->tail + 1) % queue->size; queue->tail = (queue->tail + 1) % queue->size;
} }
void packet_queue_pop(struct packet_queue *queue, struct packet **pkt) void lock_free_queue_pop(struct lock_free_queue *queue, void **data)
{ {
uint64_t read = ATOMIC_READ(&queue->queue[queue->head]); uint64_t read = ATOMIC_READ(&queue->queue[queue->head]);
if (read == 0) if (read == 0)
{ {
*pkt = NULL; *data = NULL;
return; return;
} }
__sync_val_compare_and_swap(&queue->queue[queue->head], read, 0); __sync_val_compare_and_swap(&queue->queue[queue->head], read, 0);
*pkt = (struct packet *)read; *data = (void *)read;
queue->head = (queue->head + 1) % queue->size; queue->head = (queue->head + 1) % queue->size;
} }

View File

@@ -0,0 +1,26 @@
#ifndef _LOCK_FREE_QUEUE_H
#define _LOCK_FREE_QUEUE_H
#ifdef __cpluscplus
extern "C"
{
#endif
#include "log.h"
#define LOCK_FREE_QUEUE_LOG_ERROR(format, ...) LOG_ERROR("lock free queue", format, ##__VA_ARGS__)
#define LOCK_FREE_QUEUE_LOG_DEBUG(format, ...) LOG_DEBUG("lock free queue", format, ##__VA_ARGS__)
struct lock_free_queue;
struct lock_free_queue *lock_free_queue_new(uint32_t size);
void lock_free_queue_free(struct lock_free_queue *queue);
void lock_free_queue_push(struct lock_free_queue *queue, void *data);
void lock_free_queue_pop(struct lock_free_queue *queue, void **data);
#ifdef __cpluscplus
}
#endif
#endif

View File

@@ -5,22 +5,26 @@
#include "packet_io_marsio.h" #include "packet_io_marsio.h"
#include "packet_io_dumpfile.h" #include "packet_io_dumpfile.h"
typedef void *new_cb(void *options); typedef void *on_new(void *options);
typedef void free_cb(void *handle); typedef void on_free(void *handle);
typedef void *stat_cb(void *handle); typedef void *on_stat(void *handle);
typedef int init_cb(void *handle, uint16_t thread_id); typedef int on_init(void *handle, uint16_t thread_id);
typedef int recv_cb(void *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts); typedef int on_recv(void *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
typedef void send_cb(void *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts); typedef void on_send(void *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
typedef void on_drop(void *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
typedef void on_inject(void *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
struct packet_io struct packet_io
{ {
void *handle; void *handle;
new_cb *on_new; on_new *new_func;
free_cb *on_free; on_free *free_func;
stat_cb *on_stat; on_stat *stat_func;
init_cb *on_init; on_init *init_func;
recv_cb *on_recv; on_recv *recv_func;
send_cb *on_send; on_send *send_func;
on_drop *drop_func;
on_inject *inject_func;
}; };
struct packet_io *packet_io_new(struct packet_io_options *opts) struct packet_io *packet_io_new(struct packet_io_options *opts)
@@ -32,40 +36,44 @@ struct packet_io *packet_io_new(struct packet_io_options *opts)
return NULL; return NULL;
} }
struct packet_io_marsio_opts marsio_opts; struct packet_io_marsio_options opts_marsio;
strncpy(marsio_opts.app_symbol, opts->app_symbol, sizeof(marsio_opts.app_symbol)); struct packet_io_dumpfile_options opts_dumpfile;
strncpy(marsio_opts.dev_symbol, opts->dev_symbol, sizeof(marsio_opts.dev_symbol)); void *opts_ptr = NULL;
memcpy(marsio_opts.cpu_mask, opts->cpu_mask, sizeof(marsio_opts.cpu_mask));
marsio_opts.nr_threads = opts->nr_threads;
struct packet_io_dumpfile_opts dumpfile_opts;
strncpy(dumpfile_opts.dumpfile_dir, opts->dumpfile_dir, sizeof(dumpfile_opts.dumpfile_dir));
dumpfile_opts.nr_threads = opts->nr_threads;
void *_opts = NULL;
if (opts->mode == PACKET_IO_MARSIO) if (opts->mode == PACKET_IO_MARSIO)
{ {
_opts = &marsio_opts; strncpy(opts_marsio.app_symbol, opts->app_symbol, sizeof(opts_marsio.app_symbol));
handle->on_new = (new_cb *)packet_io_marsio_new; strncpy(opts_marsio.dev_symbol, opts->dev_symbol, sizeof(opts_marsio.dev_symbol));
handle->on_free = (free_cb *)packet_io_marsio_free; memcpy(opts_marsio.cpu_mask, opts->cpu_mask, sizeof(opts_marsio.cpu_mask));
handle->on_stat = (stat_cb *)packet_io_marsio_stat; opts_marsio.nr_threads = opts->nr_threads;
handle->on_init = (init_cb *)packet_io_marsio_init;
handle->on_recv = (recv_cb *)packet_io_marsio_recv; opts_ptr = &opts_marsio;
handle->on_send = (send_cb *)packet_io_marsio_send; handle->new_func = (on_new *)packet_io_marsio_new;
handle->free_func = (on_free *)packet_io_marsio_free;
handle->stat_func = (on_stat *)packet_io_marsio_get_stat;
handle->init_func = (on_init *)packet_io_marsio_init;
handle->recv_func = (on_recv *)packet_io_marsio_ingress;
handle->send_func = (on_send *)packet_io_marsio_egress;
handle->drop_func = (on_drop *)packet_io_marsio_drop;
handle->inject_func = (on_inject *)packet_io_marsio_inject;
} }
else else
{ {
_opts = &dumpfile_opts; strncpy(opts_dumpfile.dumpfile_dir, opts->dumpfile_dir, sizeof(opts_dumpfile.dumpfile_dir));
handle->on_new = (new_cb *)packet_io_dumpfile_new; opts_dumpfile.nr_threads = opts->nr_threads;
handle->on_free = (free_cb *)packet_io_dumpfile_free;
handle->on_stat = (stat_cb *)packet_io_dumpfile_stat; opts_ptr = &opts_dumpfile;
handle->on_init = (init_cb *)packet_io_dumpfile_init; handle->new_func = (on_new *)packet_io_dumpfile_new;
handle->on_recv = (recv_cb *)packet_io_dumpfile_recv; handle->free_func = (on_free *)packet_io_dumpfile_free;
handle->on_send = (send_cb *)packet_io_dumpfile_send; handle->stat_func = (on_stat *)packet_io_dumpfile_get_stat;
handle->init_func = (on_init *)packet_io_dumpfile_init;
handle->recv_func = (on_recv *)packet_io_dumpfile_ingress;
handle->send_func = (on_send *)packet_io_dumpfile_egress;
handle->drop_func = (on_drop *)packet_io_dumpfile_drop;
handle->inject_func = (on_inject *)packet_io_dumpfile_inject;
} }
handle->handle = handle->on_new(_opts); handle->handle = handle->new_func(opts_ptr);
if (handle->handle == NULL) if (handle->handle == NULL)
{ {
goto error_out; goto error_out;
@@ -82,39 +90,40 @@ void packet_io_free(struct packet_io *handle)
{ {
if (handle) if (handle)
{ {
handle->on_free(handle->handle); handle->free_func(handle->handle);
free(handle); free(handle);
handle = NULL; handle = NULL;
} }
} }
void packet_io_print_stat(struct packet_io *handle)
{
struct packet_io_stat *stat = packet_io_get_stat(handle);
PACKET_IO_LOG_DEBUG("rx_pkts : %lu, rx_bytes : %lu", stat->rx_pkts, stat->rx_bytes);
PACKET_IO_LOG_DEBUG("tx_pkts : %lu, tx_bytes : %lu", stat->tx_pkts, stat->tx_bytes);
PACKET_IO_LOG_DEBUG("drop_pkts : %lu, drop_bytes : %lu", stat->drop_pkts, stat->drop_bytes);
PACKET_IO_LOG_DEBUG("inject_pkts : %lu, inject_bytes : %lu", stat->inject_pkts, stat->inject_bytes);
PACKET_IO_LOG_DEBUG("keepalive_pkts : %lu, keepalive_bytes : %lu", stat->keepalive_pkts, stat->keepalive_bytes);
}
struct packet_io_stat *packet_io_get_stat(struct packet_io *handle) struct packet_io_stat *packet_io_get_stat(struct packet_io *handle)
{ {
return (struct packet_io_stat *)handle->on_stat(handle->handle); return (struct packet_io_stat *)handle->stat_func(handle->handle);
} }
// return 0: success
// return -1: failed
int packet_io_init(struct packet_io *handle, uint16_t thread_id) int packet_io_init(struct packet_io *handle, uint16_t thread_id)
{ {
return handle->on_init(handle->handle, thread_id); return handle->init_func(handle->handle, thread_id);
} }
// return number of packets received
int packet_io_ingress(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts) int packet_io_ingress(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts)
{ {
return handle->on_recv(handle->handle, thread_id, pkts, nr_pkts); return handle->recv_func(handle->handle, thread_id, pkts, nr_pkts);
} }
void packet_io_egress(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts) void packet_io_egress(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts)
{ {
handle->on_send(handle->handle, thread_id, pkts, nr_pkts); handle->send_func(handle->handle, thread_id, pkts, nr_pkts);
}
void packet_io_drop(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts)
{
handle->drop_func(handle->handle, thread_id, pkts, nr_pkts);
}
void packet_io_inject(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts)
{
handle->inject_func(handle->handle, thread_id, pkts, nr_pkts);
} }

View File

@@ -55,13 +55,18 @@ struct packet_io_options
struct packet_io; struct packet_io;
struct packet_io *packet_io_new(struct packet_io_options *opts); struct packet_io *packet_io_new(struct packet_io_options *opts);
void packet_io_free(struct packet_io *handle); void packet_io_free(struct packet_io *handle);
void packet_io_print_stat(struct packet_io *handle);
struct packet_io_stat *packet_io_get_stat(struct packet_io *handle); struct packet_io_stat *packet_io_get_stat(struct packet_io *handle);
// return 0 if success, -1 if failed // TODO performance optimization egress for multi-packet
// return 0: success
// return -1: failed
int packet_io_init(struct packet_io *handle, uint16_t thread_id); int packet_io_init(struct packet_io *handle, uint16_t thread_id);
// return number of packets received
int packet_io_ingress(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts); int packet_io_ingress(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
void packet_io_egress(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts); void packet_io_egress(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
void packet_io_drop(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
void packet_io_inject(struct packet_io *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
#ifdef __cpluscplus #ifdef __cpluscplus
} }

View File

@@ -1,12 +1,14 @@
#include <pcap/pcap.h> #include <pcap/pcap.h>
#include <pthread.h> #include <pthread.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include "stellar.h" #include "stellar.h"
#include "file_scan.h" #include "file_scan.h"
#include "packet_io.h" #include "packet_io.h"
#include "packet_utils.h" #include "lock_free_queue.h"
#include "packet_queue.h"
#include "packet_io_dumpfile.h" #include "packet_io_dumpfile.h"
#define MAX_PACKET_QUEUE_SIZE (4096 * 1000) #define MAX_PACKET_QUEUE_SIZE (4096 * 1000)
@@ -17,12 +19,18 @@ struct packet_io_dumpfile
char dumpfile_dir[256]; char dumpfile_dir[256];
pcap_t *pcap; pcap_t *pcap;
struct packet_queue *queue[MAX_THREAD_NUM]; struct lock_free_queue *queue[MAX_THREAD_NUM];
struct packet_io_stat stat; struct packet_io_stat stat;
uint64_t io_thread_need_exit; uint64_t io_thread_need_exit;
uint64_t io_thread_is_runing; uint64_t io_thread_is_runing;
}; };
struct pcap_pkt
{
char *data;
int len;
};
/****************************************************************************** /******************************************************************************
* Private API * Private API
******************************************************************************/ ******************************************************************************/
@@ -31,19 +39,25 @@ static void pcap_handle(u_char *user, const struct pcap_pkthdr *h, const u_char
{ {
struct packet_io_dumpfile *handle = (struct packet_io_dumpfile *)user; struct packet_io_dumpfile *handle = (struct packet_io_dumpfile *)user;
struct packet *pkt = packet_new(h->caplen); // copy packet data to new memory
if (pkt == NULL) struct pcap_pkt *pcap_pkt = (struct pcap_pkt *)calloc(1, sizeof(struct pcap_pkt) + h->caplen);
if (pcap_pkt == NULL)
{ {
PACKET_IO_LOG_ERROR("unable to alloc packet"); PACKET_IO_LOG_ERROR("unable to alloc packet");
return; return;
} }
pcap_pkt->data = (char *)pcap_pkt + sizeof(struct pcap_pkt);
pcap_pkt->len = h->caplen;
memcpy((char *)pcap_pkt->data, bytes, h->caplen);
memcpy((char *)pkt->data_ptr, bytes, h->caplen); // calculate packet hash
packet_parse(pkt, pkt->data_ptr, h->caplen); struct packet pkt;
packet_parse(&pkt, pcap_pkt->data, pcap_pkt->len);
uint64_t hash = packet_get_hash(&pkt, LDBC_METHOD_HASH_INT_IP_AND_EXT_IP, 0);
uint64_t hash = packet_get_hash(pkt, LDBC_METHOD_HASH_INT_IP_AND_EXT_IP, 0); // push packet to queue
struct packet_queue *queue = handle->queue[hash % handle->nr_threads]; struct lock_free_queue *queue = handle->queue[hash % handle->nr_threads];
packet_queue_push(queue, pkt); lock_free_queue_push(queue, pcap_pkt);
if (ATOMIC_READ(&handle->io_thread_need_exit)) if (ATOMIC_READ(&handle->io_thread_need_exit))
{ {
@@ -56,7 +70,7 @@ static int dumpfile_handle(const char *file, void *arg)
{ {
struct packet_io_dumpfile *handle = (struct packet_io_dumpfile *)arg; struct packet_io_dumpfile *handle = (struct packet_io_dumpfile *)arg;
PACKET_IO_LOG_STATE("dumpfile %s inprocessing", file) PACKET_IO_LOG_STATE("dumpfile %s in-processing", file)
handle->pcap = pcap_open_offline(file, NULL); handle->pcap = pcap_open_offline(file, NULL);
if (handle->pcap == NULL) if (handle->pcap == NULL)
@@ -91,7 +105,7 @@ static void *dumpfile_thread_cycle(void *arg)
* Public API * Public API
******************************************************************************/ ******************************************************************************/
struct packet_io_dumpfile *packet_io_dumpfile_new(struct packet_io_dumpfile_opts *opts) struct packet_io_dumpfile *packet_io_dumpfile_new(struct packet_io_dumpfile_options *opts)
{ {
pthread_t tid; pthread_t tid;
struct packet_io_dumpfile *handle = (struct packet_io_dumpfile *)calloc(1, sizeof(struct packet_io_dumpfile)); struct packet_io_dumpfile *handle = (struct packet_io_dumpfile *)calloc(1, sizeof(struct packet_io_dumpfile));
@@ -106,7 +120,7 @@ struct packet_io_dumpfile *packet_io_dumpfile_new(struct packet_io_dumpfile_opts
for (uint16_t i = 0; i < handle->nr_threads; i++) for (uint16_t i = 0; i < handle->nr_threads; i++)
{ {
handle->queue[i] = packet_queue_new(MAX_PACKET_QUEUE_SIZE); handle->queue[i] = lock_free_queue_new(MAX_PACKET_QUEUE_SIZE);
if (handle->queue[i] == NULL) if (handle->queue[i] == NULL)
{ {
PACKET_IO_LOG_ERROR("unable to create packet queue"); PACKET_IO_LOG_ERROR("unable to create packet queue");
@@ -140,14 +154,14 @@ void packet_io_dumpfile_free(struct packet_io_dumpfile *handle)
for (uint16_t i = 0; i < handle->nr_threads; i++) for (uint16_t i = 0; i < handle->nr_threads; i++)
{ {
packet_queue_free(handle->queue[i]); lock_free_queue_free(handle->queue[i]);
} }
free(handle); free(handle);
handle = NULL; handle = NULL;
} }
} }
struct packet_io_stat *packet_io_dumpfile_stat(struct packet_io_dumpfile *handle) struct packet_io_stat *packet_io_dumpfile_get_stat(struct packet_io_dumpfile *handle)
{ {
return &handle->stat; return &handle->stat;
} }
@@ -157,55 +171,84 @@ int packet_io_dumpfile_init(struct packet_io_dumpfile *handle, uint16_t thread_i
return 0; return 0;
} }
int packet_io_dumpfile_recv(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts) int packet_io_dumpfile_ingress(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts)
{ {
struct packet_queue *queue = handle->queue[thread_id]; struct lock_free_queue *queue = handle->queue[thread_id];
struct packet *pkt = NULL; struct pcap_pkt *pcap_pkt = NULL;
int nr_parsed = 0; int nr_parsed = 0;
for (int i = 0; i < nr_pkts; i++) for (int i = 0; i < nr_pkts; i++)
{ {
packet_queue_pop(queue, &pkt); lock_free_queue_pop(queue, (void **)&pcap_pkt);
if (pkt == NULL) if (pcap_pkt == NULL)
{ {
break; break;
} }
else else
{ {
ATOMIC_ADD(&handle->stat.rx_pkts, 1); ATOMIC_ADD(&handle->stat.rx_pkts, 1);
ATOMIC_ADD(&handle->stat.rx_bytes, packet_get_len(pkt)); ATOMIC_ADD(&handle->stat.rx_bytes, pcap_pkt->len);
struct packet *temp = &pkts[nr_parsed++]; struct packet *pkt = &pkts[nr_parsed++];
memset(temp, 0, sizeof(struct packet)); memset(pkt, 0, sizeof(struct packet));
packet_parse(temp, pkt->data_ptr, pkt->data_len); packet_parse(pkt, pcap_pkt->data, pcap_pkt->len);
packet_set_io_ctx(temp, pkt); packet_set_user_data(pkt, pcap_pkt);
packet_set_type(temp, PACKET_TYPE_DATA); packet_set_type(pkt, PACKET_TYPE_DATA);
packet_set_action(temp, PACKET_ACTION_FORWARD); packet_set_action(pkt, PACKET_ACTION_FORWARD);
} }
} }
return nr_parsed; return nr_parsed;
} }
void packet_io_dumpfile_send(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts) // pkts from packet_io_dumpfile_ingress
void packet_io_dumpfile_egress(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts)
{ {
struct packet *pkt = NULL; struct packet *pkt = NULL;
for (int i = 0; i < nr_pkts; i++) for (int i = 0; i < nr_pkts; i++)
{ {
pkt = &pkts[i]; pkt = &pkts[i];
if (packet_get_action(pkt) == PACKET_ACTION_DROP) ATOMIC_ADD(&handle->stat.tx_pkts, 1);
{ ATOMIC_ADD(&handle->stat.tx_bytes, packet_get_len(pkt));
ATOMIC_ADD(&handle->stat.drop_pkts, 1);
ATOMIC_ADD(&handle->stat.drop_bytes, packet_get_len(pkt)); struct pcap_pkt *pcap_pkt = (struct pcap_pkt *)packet_get_user_data(pkt);
} assert(pcap_pkt != NULL);
else free(pcap_pkt);
{ }
ATOMIC_ADD(&handle->stat.tx_pkts, 1); }
ATOMIC_ADD(&handle->stat.tx_bytes, packet_get_len(pkt));
} // pkts from packet_io_dumpfile_ingress
void packet_io_dumpfile_drop(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts)
{
struct packet *pkt = NULL;
for (int i = 0; i < nr_pkts; i++)
{
pkt = &pkts[i];
ATOMIC_ADD(&handle->stat.drop_pkts, 1);
ATOMIC_ADD(&handle->stat.drop_bytes, packet_get_len(pkt));
struct pcap_pkt *pcap_pkt = (struct pcap_pkt *)packet_get_user_data(pkt);
assert(pcap_pkt != NULL);
free(pcap_pkt);
}
}
// pkts build by packet_new
void packet_io_dumpfile_inject(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts)
{
struct packet *pkt = NULL;
for (int i = 0; i < nr_pkts; i++)
{
pkt = &pkts[i];
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);
packet_free((struct packet *)packet_get_io_ctx(pkt));
packet_free(pkt); packet_free(pkt);
} }
} }

View File

@@ -8,7 +8,7 @@ extern "C"
#include "packet.h" #include "packet.h"
struct packet_io_dumpfile_opts struct packet_io_dumpfile_options
{ {
char dumpfile_dir[256]; char dumpfile_dir[256];
uint8_t nr_threads; uint8_t nr_threads;
@@ -16,13 +16,18 @@ struct packet_io_dumpfile_opts
struct packet_io_dumpfile; struct packet_io_dumpfile;
struct packet_io_dumpfile *packet_io_dumpfile_new(struct packet_io_dumpfile_opts *opts); struct packet_io_dumpfile *packet_io_dumpfile_new(struct packet_io_dumpfile_options *opts);
void packet_io_dumpfile_free(struct packet_io_dumpfile *handle); void packet_io_dumpfile_free(struct packet_io_dumpfile *handle);
struct packet_io_stat *packet_io_dumpfile_stat(struct packet_io_dumpfile *handle); struct packet_io_stat *packet_io_dumpfile_get_stat(struct packet_io_dumpfile *handle);
// return 0: success
// return -1: failed
int packet_io_dumpfile_init(struct packet_io_dumpfile *handle, uint16_t thread_id); int packet_io_dumpfile_init(struct packet_io_dumpfile *handle, uint16_t thread_id);
int packet_io_dumpfile_recv(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts); // return number of packets received
void packet_io_dumpfile_send(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts); int packet_io_dumpfile_ingress(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
void packet_io_dumpfile_egress(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
void packet_io_dumpfile_drop(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
void packet_io_dumpfile_inject(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
#ifdef __cpluscplus #ifdef __cpluscplus
} }

View File

@@ -1,10 +1,13 @@
#include <sched.h> #include <sched.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <netinet/ether.h> #include <netinet/ether.h>
#include "stellar.h" #include "stellar.h"
#include "marsio.h" #include "marsio.h"
#include "packet.h"
#include "packet_io.h" #include "packet_io.h"
#include "packet_utils.h"
#include "packet_io_marsio.h" #include "packet_io_marsio.h"
struct packet_io_marsio struct packet_io_marsio
@@ -22,21 +25,25 @@ struct packet_io_marsio
static void metadata_to_packet(marsio_buff_t *mbuff, struct packet *pkt) static void metadata_to_packet(marsio_buff_t *mbuff, struct packet *pkt)
{ {
packet_set_io_ctx(pkt, mbuff); struct metadata *meta = &pkt->meta;
pkt->sid_used = marsio_buff_get_sid_list(mbuff, pkt->sid_list, MAX_SID_NUM);
pkt->route_len = marsio_buff_get_metadata(mbuff, MR_BUFF_ROUTE_CTX, pkt->route_ctx, MAX_ROUTE_LEN); packet_set_user_data(pkt, mbuff);
marsio_buff_get_metadata(mbuff, MR_BUFF_SESSION_ID, &(pkt->session_id), sizeof(pkt->session_id)); meta->sid.used = marsio_buff_get_sid_list(mbuff, meta->sid.list, MAX_SID_NUM);
marsio_buff_get_metadata(mbuff, MR_BUFF_DIR, &(pkt->direction), sizeof(pkt->direction)); meta->route.len = marsio_buff_get_metadata(mbuff, MR_BUFF_ROUTE_CTX, meta->route.data, MAX_ROUTE_LEN);
marsio_buff_get_metadata(mbuff, MR_BUFF_SESSION_ID, &(meta->session_id), sizeof(meta->session_id));
marsio_buff_get_metadata(mbuff, MR_BUFF_DIR, &(meta->direction), sizeof(meta->direction));
packet_set_type(pkt, marsio_buff_is_ctrlbuf(mbuff) ? PACKET_TYPE_CTRL : PACKET_TYPE_DATA); packet_set_type(pkt, marsio_buff_is_ctrlbuf(mbuff) ? PACKET_TYPE_CTRL : PACKET_TYPE_DATA);
packet_set_action(pkt, PACKET_ACTION_FORWARD); packet_set_action(pkt, PACKET_ACTION_FORWARD);
} }
static void metadata_to_mbuff(marsio_buff_t *mbuff, struct packet *pkt) static void metadata_to_mbuff(marsio_buff_t *mbuff, struct packet *pkt)
{ {
marsio_buff_set_sid_list(mbuff, pkt->sid_list, pkt->sid_used); struct metadata *meta = &pkt->meta;
marsio_buff_set_metadata(mbuff, MR_BUFF_ROUTE_CTX, pkt->route_ctx, pkt->route_len);
marsio_buff_set_metadata(mbuff, MR_BUFF_SESSION_ID, &(pkt->session_id), sizeof(pkt->session_id)); marsio_buff_set_sid_list(mbuff, meta->sid.list, meta->sid.used);
marsio_buff_set_metadata(mbuff, MR_BUFF_DIR, &(pkt->direction), sizeof(pkt->direction)); marsio_buff_set_metadata(mbuff, MR_BUFF_ROUTE_CTX, meta->route.data, meta->route.len);
marsio_buff_set_metadata(mbuff, MR_BUFF_SESSION_ID, &(meta->session_id), sizeof(meta->session_id));
marsio_buff_set_metadata(mbuff, MR_BUFF_DIR, &(meta->direction), sizeof(meta->direction));
if (packet_get_type(pkt) == PACKET_TYPE_CTRL) if (packet_get_type(pkt) == PACKET_TYPE_CTRL)
{ {
marsio_buff_set_ctrlbuf(mbuff); marsio_buff_set_ctrlbuf(mbuff);
@@ -65,7 +72,7 @@ static int is_keepalive_packet(const char *data, int len)
* Public API * Public API
******************************************************************************/ ******************************************************************************/
struct packet_io_marsio *packet_io_marsio_new(struct packet_io_marsio_opts *opts) struct packet_io_marsio *packet_io_marsio_new(struct packet_io_marsio_options *opts)
{ {
int opt = 1; int opt = 1;
cpu_set_t coremask; cpu_set_t coremask;
@@ -146,7 +153,7 @@ void packet_io_marsio_free(struct packet_io_marsio *handle)
} }
} }
struct packet_io_stat *packet_io_marsio_stat(struct packet_io_marsio *handle) struct packet_io_stat *packet_io_marsio_get_stat(struct packet_io_marsio *handle)
{ {
return &handle->stat; return &handle->stat;
} }
@@ -162,7 +169,7 @@ int packet_io_marsio_init(struct packet_io_marsio *handle, uint16_t thread_id)
return 0; return 0;
} }
int packet_io_marsio_recv(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts) int packet_io_marsio_ingress(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts)
{ {
marsio_buff_t *rx_buff; marsio_buff_t *rx_buff;
marsio_buff_t *rx_buffs[RX_BURST_MAX]; marsio_buff_t *rx_buffs[RX_BURST_MAX];
@@ -197,13 +204,38 @@ int packet_io_marsio_recv(struct packet_io_marsio *handle, uint16_t thread_id, s
continue; continue;
} }
packet_parse(&pkts[nr_parsed], raw_data, raw_len);
metadata_to_packet(rx_buff, &pkts[nr_parsed++]); metadata_to_packet(rx_buff, &pkts[nr_parsed++]);
} }
return nr_parsed; return nr_parsed;
} }
void packet_io_marsio_send(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts) // pkts from packet_io_marsio_ingress
void packet_io_marsio_egress(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts)
{
struct packet *pkt;
struct metadata *meta;
marsio_buff_t *tx_buff;
for (int i = 0; i < nr_pkts; i++)
{
pkt = &pkts[i];
ATOMIC_ADD(&handle->stat.tx_pkts, 1);
ATOMIC_ADD(&handle->stat.tx_bytes, packet_get_len(pkt));
// update sid list
tx_buff = (marsio_buff_t *)packet_get_user_data(pkt);
assert(tx_buff != NULL);
meta = &pkt->meta;
marsio_buff_set_sid_list(tx_buff, meta->sid.list, meta->sid.used);
marsio_send_burst(handle->mr_path, thread_id, &tx_buff, 1);
}
}
// pkts from packet_io_marsio_ingress
void packet_io_marsio_drop(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts)
{ {
struct packet *pkt; struct packet *pkt;
marsio_buff_t *tx_buff; marsio_buff_t *tx_buff;
@@ -211,43 +243,42 @@ void packet_io_marsio_send(struct packet_io_marsio *handle, uint16_t thread_id,
for (int i = 0; i < nr_pkts; i++) for (int i = 0; i < nr_pkts; i++)
{ {
pkt = &pkts[i]; pkt = &pkts[i];
tx_buff = (marsio_buff_t *)packet_get_io_ctx(pkt); tx_buff = (marsio_buff_t *)packet_get_user_data(pkt);
if (packet_get_action(pkt) == PACKET_ACTION_DROP) assert(tx_buff != NULL);
ATOMIC_ADD(&handle->stat.drop_pkts, 1);
ATOMIC_ADD(&handle->stat.drop_bytes, packet_get_len(pkt));
marsio_buff_free(handle->mr_ins, &tx_buff, 1, 0, thread_id);
}
}
// pkts from packet_new
void packet_io_marsio_inject(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts)
{
struct packet *pkt;
marsio_buff_t *tx_buff;
for (int i = 0; i < nr_pkts; i++)
{
pkt = &pkts[i];
tx_buff = (marsio_buff_t *)packet_get_user_data(pkt);
assert(tx_buff == NULL);
if (marsio_buff_malloc_global(handle->mr_ins, &tx_buff, 1, MARSIO_SOCKET_ID_ANY, MARSIO_LCORE_ID_ANY) < 0)
{ {
if (tx_buff) PACKET_IO_LOG_ERROR("unable to alloc tx buffer");
{ continue;
ATOMIC_ADD(&handle->stat.drop_pkts, 1);
ATOMIC_ADD(&handle->stat.drop_bytes, packet_get_len(pkt));
marsio_buff_free(handle->mr_ins, &tx_buff, 1, 0, thread_id);
}
else
{
// do nothing
}
} }
else ATOMIC_ADD(&handle->stat.inject_pkts, 1);
{ ATOMIC_ADD(&handle->stat.inject_bytes, packet_get_len(pkt));
if (tx_buff == NULL)
{
if (marsio_buff_malloc_global(handle->mr_ins, &tx_buff, 1, MARSIO_SOCKET_ID_ANY, MARSIO_LCORE_ID_ANY) < 0)
{
PACKET_IO_LOG_ERROR("unable to alloc tx buffer");
goto fast_end;
}
ATOMIC_ADD(&handle->stat.inject_pkts, 1);
ATOMIC_ADD(&handle->stat.inject_bytes, packet_get_len(pkt));
char *dst = marsio_buff_append(tx_buff, packet_get_len(pkt)); char *dst = marsio_buff_append(tx_buff, packet_get_len(pkt));
memcpy(dst, packet_get_data(pkt), packet_get_len(pkt)); memcpy(dst, packet_get_data(pkt), packet_get_len(pkt));
}
ATOMIC_ADD(&handle->stat.tx_pkts, 1); ATOMIC_ADD(&handle->stat.tx_pkts, 1);
ATOMIC_ADD(&handle->stat.tx_bytes, packet_get_len(pkt)); ATOMIC_ADD(&handle->stat.tx_bytes, packet_get_len(pkt));
metadata_to_mbuff(tx_buff, pkt); metadata_to_mbuff(tx_buff, pkt);
marsio_send_burst(handle->mr_path, thread_id, &tx_buff, 1); marsio_send_burst(handle->mr_path, thread_id, &tx_buff, 1);
}
fast_end:
packet_free(pkt); packet_free(pkt);
} }
} }

View File

@@ -8,7 +8,7 @@ extern "C"
#include "packet.h" #include "packet.h"
struct packet_io_marsio_opts struct packet_io_marsio_options
{ {
char app_symbol[64]; char app_symbol[64];
char dev_symbol[64]; char dev_symbol[64];
@@ -18,13 +18,18 @@ struct packet_io_marsio_opts
struct packet_io_marsio; struct packet_io_marsio;
struct packet_io_marsio *packet_io_marsio_new(struct packet_io_marsio_opts *opts); struct packet_io_marsio *packet_io_marsio_new(struct packet_io_marsio_options *opts);
void packet_io_marsio_free(struct packet_io_marsio *handle); void packet_io_marsio_free(struct packet_io_marsio *handle);
struct packet_io_stat *packet_io_marsio_stat(struct packet_io_marsio *handle); struct packet_io_stat *packet_io_marsio_get_stat(struct packet_io_marsio *handle);
// return 0: success
// return -1: failed
int packet_io_marsio_init(struct packet_io_marsio *handle, uint16_t thread_id); int packet_io_marsio_init(struct packet_io_marsio *handle, uint16_t thread_id);
int packet_io_marsio_recv(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts); // return number of packets received
void packet_io_marsio_send(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts); int packet_io_marsio_ingress(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
void packet_io_marsio_egress(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
void packet_io_marsio_drop(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
void packet_io_marsio_inject(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
#ifdef __cpluscplus #ifdef __cpluscplus
} }

View File

@@ -1,26 +0,0 @@
#ifndef _PACKET_QUEUE_H
#define _PACKET_QUEUE_H
#ifdef __cpluscplus
extern "C"
{
#endif
#include <stdint.h>
struct packet_queue;
struct packet_queue *packet_queue_new(uint32_t size);
void packet_queue_free(struct packet_queue *queue);
int packet_queue_is_full(struct packet_queue *queue);
int packet_queue_is_empty(struct packet_queue *queue);
void packet_queue_push(struct packet_queue *queue, struct packet *pkt);
void packet_queue_pop(struct packet_queue *queue, struct packet **pkt);
#ifdef __cpluscplus
}
#endif
#endif

View File

@@ -1,7 +1,3 @@
###############################################################################
# session manager
###############################################################################
add_library(session_manager add_library(session_manager
session.cpp session.cpp
session_pool.cpp session_pool.cpp
@@ -11,6 +7,6 @@ add_library(session_manager
session_manager.cpp session_manager.cpp
) )
target_include_directories(session_manager PUBLIC ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(session_manager PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(session_manager timeout dupkt_filter eviction_filter log id_generator) target_link_libraries(session_manager timeout duplicated_packet_filter evicted_session_filter log id_generator timestamp)
add_subdirectory(test) add_subdirectory(test)

View File

@@ -1,7 +1,6 @@
#include <assert.h> #include <assert.h>
#include "session_private.h" #include "session_private.h"
#include "packet_utils.h"
#define EX_KEY_MAX_LEN 64 #define EX_KEY_MAX_LEN 64
@@ -506,6 +505,8 @@ const char *session_state_to_str(enum session_state state)
{ {
switch (state) switch (state)
{ {
case SESSION_STATE_INIT:
return "init";
case SESSION_STATE_OPENING: case SESSION_STATE_OPENING:
return "opening"; return "opening";
case SESSION_STATE_ACTIVE: case SESSION_STATE_ACTIVE:

View File

@@ -37,10 +37,12 @@ enum udp_state
enum session_state enum session_state
{ {
SESSION_STATE_OPENING = 0x1, SESSION_STATE_INIT = 0,
SESSION_STATE_ACTIVE = 0x2, SESSION_STATE_OPENING = 1,
SESSION_STATE_CLOSING = 0x3, SESSION_STATE_ACTIVE = 2,
SESSION_STATE_CLOSED = 0x4, SESSION_STATE_CLOSING = 3,
SESSION_STATE_CLOSED = 4,
SESSION_STATE_MAX = 5,
}; };
enum session_type enum session_type

View File

@@ -1,6 +1,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include "stellar.h"
#include "timestamp.h" #include "timestamp.h"
#include "session_private.h" #include "session_private.h"
#include "session_pool.h" #include "session_pool.h"
@@ -10,9 +11,8 @@
#include "session_manager.h" #include "session_manager.h"
#include "tcp_utils.h" #include "tcp_utils.h"
#include "udp_utils.h" #include "udp_utils.h"
#include "packet_utils.h" #include "duplicated_packet_filter.h"
#include "dupkt_filter.h" #include "evicted_session_filter.h"
#include "eviction_filter.h"
#include "id_generator.h" #include "id_generator.h"
struct session_manager struct session_manager
@@ -23,8 +23,8 @@ struct session_manager
struct session_timer *sess_timer; struct session_timer *sess_timer;
struct session_queue *sess_evicted_queue; struct session_queue *sess_evicted_queue;
struct dupkt_filter *tcp_dupkt_filter; struct duplicated_packet_filter *tcp_dup_pkt_filter;
struct eviction_filter *udp_eviction_filter; struct evicted_session_filter *udp_evc_sess_filter;
struct session_manager_options opts; struct session_manager_options opts;
@@ -58,6 +58,95 @@ struct session_manager
uint64_t npkts_hit_udp_evicted; // fast forward uint64_t npkts_hit_udp_evicted; // fast forward
}; };
enum packet_flag
{
NONE = 0,
TCP_SYN = 1 << 0,
TCP_SYN_ACK = 1 << 1,
TCP_FIN = 1 << 2,
TCP_RST = 1 << 3,
TCP_DATA = 1 << 4,
UDP_DATA = 1 << 5,
TIMEOUT = 1 << 6,
};
struct session_finite_state_machine
{
int flag_mask;
int next_state;
} sess_fsm[SESSION_STATE_MAX][8];
void session_finite_state_machine_init()
{
// SESSION_STATE_INIT -> SESSION_STATE_OPENING
// SESSION_STATE_INIT -> SESSION_STATE_INIT
sess_fsm[SESSION_STATE_INIT][0].flag_mask = TCP_SYN | TCP_SYN_ACK | UDP_DATA;
sess_fsm[SESSION_STATE_INIT][0].next_state = SESSION_STATE_OPENING;
sess_fsm[SESSION_STATE_INIT][1].flag_mask = NONE;
sess_fsm[SESSION_STATE_INIT][1].next_state = SESSION_STATE_INIT;
// SESSION_STATE_OPENING -> SESSION_STATE_ACTIVE
// SESSION_STATE_OPENING -> SESSION_STATE_CLOSING
// SESSION_STATE_OPENING -> SESSION_STATE_CLOSED
// SESSION_STATE_OPENING -> SESSION_STATE_OPENING
sess_fsm[SESSION_STATE_OPENING][0].flag_mask = TCP_DATA | UDP_DATA;
sess_fsm[SESSION_STATE_OPENING][0].next_state = SESSION_STATE_ACTIVE;
sess_fsm[SESSION_STATE_OPENING][1].flag_mask = TCP_FIN | TCP_RST;
sess_fsm[SESSION_STATE_OPENING][1].next_state = SESSION_STATE_CLOSING;
sess_fsm[SESSION_STATE_OPENING][2].flag_mask = TIMEOUT;
sess_fsm[SESSION_STATE_OPENING][2].next_state = SESSION_STATE_CLOSED;
sess_fsm[SESSION_STATE_OPENING][3].flag_mask = NONE;
sess_fsm[SESSION_STATE_OPENING][3].next_state = SESSION_STATE_OPENING;
// SESSION_STATE_ACTIVE -> SESSION_STATE_CLOSING
// SESSION_STATE_ACTIVE -> SESSION_STATE_ACTIVE
sess_fsm[SESSION_STATE_ACTIVE][0].flag_mask = TCP_FIN | TCP_RST | TIMEOUT;
sess_fsm[SESSION_STATE_ACTIVE][0].next_state = SESSION_STATE_CLOSING;
sess_fsm[SESSION_STATE_ACTIVE][1].flag_mask = NONE;
sess_fsm[SESSION_STATE_ACTIVE][1].next_state = SESSION_STATE_ACTIVE;
// SESSION_STATE_CLOSING -> SESSION_STATE_CLOSED
// SESSION_STATE_CLOSING -> SESSION_STATE_CLOSING
sess_fsm[SESSION_STATE_CLOSING][0].flag_mask = TIMEOUT;
sess_fsm[SESSION_STATE_CLOSING][0].next_state = SESSION_STATE_CLOSED;
sess_fsm[SESSION_STATE_CLOSING][1].flag_mask = NONE;
sess_fsm[SESSION_STATE_CLOSING][1].next_state = SESSION_STATE_CLOSING;
// SESSION_STATE_CLOSED -> SESSION_STATE_INIT
}
int session_finite_state_machine_run(enum session_state curr_state, int input_pkt_flag)
{
struct session_finite_state_machine *list = sess_fsm[curr_state];
for (int i = 0; i < 8; i++)
{
int mask = list[i].flag_mask;
if (mask & input_pkt_flag)
{
return list[i].next_state;
}
if (mask == NONE)
{
return list[i].next_state;
}
}
assert(0);
return curr_state;
}
static inline void tcp_init_timeout_cb(struct session *sess, void *arg); static inline void tcp_init_timeout_cb(struct session *sess, void *arg);
static inline void tcp_handshake_timeout_cb(struct session *sess, void *arg); static inline void tcp_handshake_timeout_cb(struct session *sess, void *arg);
static inline void tcp_data_timeout_cb(struct session *sess, void *arg); static inline void tcp_data_timeout_cb(struct session *sess, void *arg);
@@ -66,14 +155,13 @@ static inline void tcp_time_wait_timeout_cb(struct session *sess, void *arg);
static inline void udp_data_timeout_cb(struct session *sess, void *arg); static inline void udp_data_timeout_cb(struct session *sess, void *arg);
static inline int session_manager_check_options(struct session_manager_options *opts); static inline int session_manager_check_options(struct session_manager_options *opts);
static inline uint64_t session_manager_alloc_session_id(void);
static inline int session_manager_update_tcp_filter(struct session_manager *mgr, struct session *sess, const struct packet *pkt, enum session_dir curr_dir); static inline int session_manager_update_tcp_filter(struct session_manager *mgr, struct session *sess, const struct packet *pkt, enum session_dir curr_dir);
static inline enum session_dir judge_direction_by_tuple6(const struct tuple6 *key); static inline enum session_dir judge_direction_by_tuple6(const struct tuple6 *key);
static inline enum session_dir judge_direction_by_session(const struct session *sess, const struct tuple6 *key); static inline enum session_dir judge_direction_by_session(const struct session *sess, const struct tuple6 *key);
static inline void session_update_tcp_state(struct session *sess, const struct layer_record *tcp_layer, enum session_dir curr_dir); static inline void session_update_tcp_state(struct session *sess, const struct layer *tcp_layer, enum session_dir curr_dir);
static inline void session_update_udp_state(struct session *sess, const struct layer_record *udp_layer, enum session_dir curr_dir); static inline void session_update_udp_state(struct session *sess, const struct layer *udp_layer, enum session_dir curr_dir);
static inline void session_manager_update_session_state(struct session_manager *mgr, struct session *sess, enum session_state state); static inline void session_manager_update_session_state(struct session_manager *mgr, struct session *sess, enum session_state state);
static inline void session_manager_update_session_timer(struct session_manager *mgr, struct session *sess, session_expire_cb expire_cb, uint64_t timeout_sec); static inline void session_manager_update_session_timer(struct session_manager *mgr, struct session *sess, session_expire_cb expire_cb, uint64_t timeout_sec);
@@ -251,52 +339,52 @@ static inline int session_manager_check_options(struct session_manager_options *
return -1; return -1;
} }
// TCP duplicate packet filter opts // duplicate packet filter opts
if (opts->tcp_dupkt_filter_enable != 0 && opts->tcp_dupkt_filter_enable != 1) if (opts->duplicated_packet_filter_enable != 0 && opts->duplicated_packet_filter_enable != 1)
{ {
SESSION_LOG_ERROR("invalid tcp dupkt filter enable, support range: 0-1"); SESSION_LOG_ERROR("invalid duplicate packet filter enable, support range: 0-1");
return -1; return -1;
} }
if (opts->tcp_dupkt_filter_enable) if (opts->duplicated_packet_filter_enable)
{ {
if (opts->tcp_dupkt_filter_capacity == 0) if (opts->duplicated_packet_filter_capacity == 0)
{ {
SESSION_LOG_ERROR("invalid tcp dupkt filter capacity"); SESSION_LOG_ERROR("invalid duplicate packet filter capacity");
return -1; return -1;
} }
if (opts->tcp_dupkt_filter_timeout < 1 || opts->tcp_dupkt_filter_timeout > 60) if (opts->duplicated_packet_filter_timeout < 1 || opts->duplicated_packet_filter_timeout > 60)
{ {
SESSION_LOG_ERROR("invalid tcp dupkt filter timeout, support range: 1-60"); SESSION_LOG_ERROR("invalid duplicate packet filter timeout, support range: 1-60");
return -1; return -1;
} }
if (opts->tcp_dupkt_filter_error_rate < 0 || opts->tcp_dupkt_filter_error_rate > 1) if (opts->duplicated_packet_filter_error_rate < 0 || opts->duplicated_packet_filter_error_rate > 1)
{ {
SESSION_LOG_ERROR("invalid tcp dupkt filter error rate, support range: 0-1"); SESSION_LOG_ERROR("invalid duplicate packet filter error rate, support range: 0-1");
return -1; return -1;
} }
} }
// UDP eviction filter opts // eviction filter opts
if (opts->udp_eviction_filter_enable != 0 && opts->udp_eviction_filter_enable != 1) if (opts->evicted_session_filter_enable != 0 && opts->evicted_session_filter_enable != 1)
{ {
SESSION_LOG_ERROR("invalid udp eviction filter enable, support range: 0-1"); SESSION_LOG_ERROR("invalid eviction filter enable, support range: 0-1");
return -1; return -1;
} }
if (opts->udp_eviction_filter_enable) if (opts->evicted_session_filter_enable)
{ {
if (opts->udp_eviction_filter_capacity == 0) if (opts->evicted_session_filter_capacity == 0)
{ {
SESSION_LOG_ERROR("invalid udp eviction filter capacity"); SESSION_LOG_ERROR("invalid eviction filter capacity");
return -1; return -1;
} }
if (opts->udp_eviction_filter_timeout < 1 || opts->udp_eviction_filter_timeout > 60) if (opts->evicted_session_filter_timeout < 1 || opts->evicted_session_filter_timeout > 60)
{ {
SESSION_LOG_ERROR("invalid udp eviction filter timeout, support range: 1-60"); SESSION_LOG_ERROR("invalid eviction filter timeout, support range: 1-60");
return -1; return -1;
} }
if (opts->udp_eviction_filter_error_rate < 0 || opts->udp_eviction_filter_error_rate > 1) if (opts->evicted_session_filter_error_rate < 0 || opts->evicted_session_filter_error_rate > 1)
{ {
SESSION_LOG_ERROR("invalid udp eviction filter error rate, support range: 0-1"); SESSION_LOG_ERROR("invalid eviction filter error rate, support range: 0-1");
return -1; return -1;
} }
} }
@@ -304,11 +392,6 @@ static inline int session_manager_check_options(struct session_manager_options *
return 0; return 0;
} }
static inline uint64_t session_manager_alloc_session_id(void)
{
return id_generator_get();
}
// return 1: duplicate packet // return 1: duplicate packet
// return 0: not duplicate packet // return 0: not duplicate packet
static inline int session_manager_update_tcp_filter(struct session_manager *mgr, struct session *sess, const struct packet *pkt, enum session_dir curr_dir) static inline int session_manager_update_tcp_filter(struct session_manager *mgr, struct session *sess, const struct packet *pkt, enum session_dir curr_dir)
@@ -338,13 +421,13 @@ static inline int session_manager_update_tcp_filter(struct session_manager *mgr,
} }
dupkt_fitler: dupkt_fitler:
if (dupkt_filter_lookup(mgr->tcp_dupkt_filter, pkt)) if (duplicated_packet_filter_lookup(mgr->tcp_dup_pkt_filter, pkt, timestamp_get_sec()))
{ {
return 1; return 1;
} }
else else
{ {
dupkt_filter_add(mgr->tcp_dupkt_filter, pkt); duplicated_packet_filter_add(mgr->tcp_dup_pkt_filter, pkt, timestamp_get_sec());
return 0; return 0;
} }
} }
@@ -383,7 +466,7 @@ static inline enum session_dir judge_direction_by_session(const struct session *
} }
} }
static inline void session_update_tcp_state(struct session *sess, const struct layer_record *tcp_layer, enum session_dir curr_dir) static inline void session_update_tcp_state(struct session *sess, const struct layer *tcp_layer, enum session_dir curr_dir)
{ {
const struct tcphdr *hdr = (const struct tcphdr *)tcp_layer->hdr_ptr; const struct tcphdr *hdr = (const struct tcphdr *)tcp_layer->hdr_ptr;
uint64_t state = session_get_tcp_state(sess); uint64_t state = session_get_tcp_state(sess);
@@ -442,7 +525,7 @@ static inline void session_update_tcp_state(struct session *sess, const struct l
session_set_tcp_state(sess, (enum tcp_state)state); session_set_tcp_state(sess, (enum tcp_state)state);
} }
static inline void session_update_udp_state(struct session *sess, const struct layer_record *udp_layer, enum session_dir curr_dir) static inline void session_update_udp_state(struct session *sess, const struct layer *udp_layer, enum session_dir curr_dir)
{ {
uint64_t state = session_get_udp_state(sess); uint64_t state = session_get_udp_state(sess);
if (curr_dir == SESSION_DIR_C2S) if (curr_dir == SESSION_DIR_C2S)
@@ -589,7 +672,6 @@ static inline void session_manager_update_session_timer(struct session_manager *
static inline void session_manager_update_session_base(struct session_manager *mgr, struct session *sess, const struct tuple6 *key, enum session_dir curr_dir) static inline void session_manager_update_session_base(struct session_manager *mgr, struct session *sess, const struct tuple6 *key, enum session_dir curr_dir)
{ {
session_init(sess); session_init(sess);
session_set_id(sess, session_manager_alloc_session_id());
session_set_key(sess, key); session_set_key(sess, key);
session_set_key_dir(sess, curr_dir); session_set_key_dir(sess, curr_dir);
if (key->ip_proto == IPPROTO_UDP) if (key->ip_proto == IPPROTO_UDP)
@@ -643,7 +725,7 @@ static inline void session_manager_update_udp_to_closing(struct session_manager
{ {
session_manager_update_session_state(mgr, sess, SESSION_STATE_CLOSING); session_manager_update_session_state(mgr, sess, SESSION_STATE_CLOSING);
session_timer_del_session(mgr->sess_timer, sess); session_timer_del_session(mgr->sess_timer, sess);
eviction_filter_add(mgr->udp_eviction_filter, session_get0_1st_pkt(sess)); evicted_session_filter_add(mgr->udp_evc_sess_filter, session_get0_key(sess), timestamp_get_sec());
} }
static inline void session_manager_update_tcp_to_opening(struct session_manager *mgr, struct session *sess, int opening_by_syn) static inline void session_manager_update_tcp_to_opening(struct session_manager *mgr, struct session *sess, int opening_by_syn)
@@ -791,7 +873,7 @@ static inline void session_manager_handle_tcp_on_closing(struct session_manager
static inline struct session *session_manager_new_tcp_session(struct session_manager *mgr, const struct packet *pkt, const struct tuple6 *key) static inline struct session *session_manager_new_tcp_session(struct session_manager *mgr, const struct packet *pkt, const struct tuple6 *key)
{ {
const struct layer_record *tcp_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_TCP); const struct layer *tcp_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_TCP);
if (tcp_layer == NULL) if (tcp_layer == NULL)
{ {
mgr->npkts_miss_l4_proto++; mgr->npkts_miss_l4_proto++;
@@ -805,7 +887,7 @@ static inline struct session *session_manager_new_tcp_session(struct session_man
return NULL; return NULL;
} }
if (mgr->tcp_sess_num >= mgr->opts.max_tcp_session_num - 1) if (mgr->tcp_sess_num >= mgr->opts.max_tcp_session_num - RX_BURST_MAX - 1)
{ {
if (mgr->opts.tcp_overload_evict_old_sess) if (mgr->opts.tcp_overload_evict_old_sess)
{ {
@@ -828,7 +910,7 @@ static inline struct session *session_manager_new_tcp_session(struct session_man
} }
} }
struct session *sess = session_pool_alloc(mgr->sess_pool); struct session *sess = session_pool_pop(mgr->sess_pool);
assert(sess); assert(sess);
enum session_dir curr_dir = tcp_hdr_get_ack_flag(hdr) ? SESSION_DIR_S2C : SESSION_DIR_C2S; enum session_dir curr_dir = tcp_hdr_get_ack_flag(hdr) ? SESSION_DIR_S2C : SESSION_DIR_C2S;
@@ -843,20 +925,20 @@ static inline struct session *session_manager_new_tcp_session(struct session_man
session_manager_update_tcp_to_opening(mgr, sess, curr_dir == SESSION_DIR_C2S); session_manager_update_tcp_to_opening(mgr, sess, curr_dir == SESSION_DIR_C2S);
session_table_add_session(mgr->tcp_sess_table, key, sess); session_table_add_session(mgr->tcp_sess_table, key, sess);
dupkt_filter_add(mgr->tcp_dupkt_filter, pkt); duplicated_packet_filter_add(mgr->tcp_dup_pkt_filter, pkt, timestamp_get_sec());
return sess; return sess;
} }
static inline struct session *session_manager_new_udp_session(struct session_manager *mgr, const struct packet *pkt, const struct tuple6 *key) static inline struct session *session_manager_new_udp_session(struct session_manager *mgr, const struct packet *pkt, const struct tuple6 *key)
{ {
if (eviction_filter_lookup(mgr->udp_eviction_filter, pkt)) if (evicted_session_filter_lookup(mgr->udp_evc_sess_filter, key, timestamp_get_sec()))
{ {
mgr->npkts_hit_udp_evicted++; mgr->npkts_hit_udp_evicted++;
return NULL; return NULL;
} }
if (mgr->udp_sess_num >= mgr->opts.max_udp_session_num - 1) if (mgr->udp_sess_num >= mgr->opts.max_udp_session_num - RX_BURST_MAX - 1)
{ {
if (mgr->opts.udp_overload_evict_old_sess) if (mgr->opts.udp_overload_evict_old_sess)
{ {
@@ -879,7 +961,7 @@ static inline struct session *session_manager_new_udp_session(struct session_man
} }
} }
struct session *sess = session_pool_alloc(mgr->sess_pool); struct session *sess = session_pool_pop(mgr->sess_pool);
assert(sess); assert(sess);
enum session_dir curr_dir = judge_direction_by_tuple6(key); enum session_dir curr_dir = judge_direction_by_tuple6(key);
@@ -907,7 +989,7 @@ static inline int session_manager_update_tcp_session(struct session_manager *mgr
return -1; return -1;
} }
const struct layer_record *tcp_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_TCP); const struct layer *tcp_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_TCP);
if (tcp_layer == NULL) if (tcp_layer == NULL)
{ {
mgr->npkts_miss_l4_proto++; mgr->npkts_miss_l4_proto++;
@@ -930,6 +1012,9 @@ static inline int session_manager_update_tcp_session(struct session_manager *mgr
switch (sess_state) switch (sess_state)
{ {
case SESSION_STATE_INIT:
assert(0);
break;
case SESSION_STATE_OPENING: case SESSION_STATE_OPENING:
session_manager_handle_tcp_on_opening(mgr, sess, tcp_old_state, tcp_curr_state); session_manager_handle_tcp_on_opening(mgr, sess, tcp_old_state, tcp_curr_state);
break; break;
@@ -965,6 +1050,9 @@ static inline int session_manager_update_udp_session(struct session_manager *mgr
switch (sess_state) switch (sess_state)
{ {
case SESSION_STATE_INIT:
assert(0);
break;
case SESSION_STATE_OPENING: case SESSION_STATE_OPENING:
session_manager_update_udp_to_active(mgr, sess); session_manager_update_udp_to_active(mgr, sess);
break; break;
@@ -977,6 +1065,8 @@ static inline int session_manager_update_udp_session(struct session_manager *mgr
case SESSION_STATE_CLOSED: case SESSION_STATE_CLOSED:
assert(0); assert(0);
break; break;
default:
break;
} }
return 0; return 0;
@@ -991,7 +1081,7 @@ static inline void session_manager_evicte_session(struct session_manager *mgr, s
if (session_get_type(sess) == SESSION_TYPE_UDP) if (session_get_type(sess) == SESSION_TYPE_UDP)
{ {
eviction_filter_add(mgr->udp_eviction_filter, session_get0_1st_pkt(sess)); evicted_session_filter_add(mgr->udp_evc_sess_filter, session_get0_key(sess), timestamp_get_sec());
} }
} }
@@ -1013,6 +1103,19 @@ struct session_manager *session_manager_new(struct session_manager_options *opts
} }
memcpy(&mgr->opts, opts, sizeof(struct session_manager_options)); memcpy(&mgr->opts, opts, sizeof(struct session_manager_options));
struct duplicated_packet_filter_options dup_pkt_opts = {
.enable = mgr->opts.duplicated_packet_filter_enable,
.capacity = mgr->opts.duplicated_packet_filter_capacity,
.timeout_sec = mgr->opts.duplicated_packet_filter_timeout,
.error_rate = mgr->opts.duplicated_packet_filter_error_rate,
};
struct evicted_session_filter_options evc_sess_opts = {
.enable = mgr->opts.evicted_session_filter_enable,
.capacity = mgr->opts.evicted_session_filter_capacity,
.timeout_sec = mgr->opts.evicted_session_filter_timeout,
.error_rate = mgr->opts.evicted_session_filter_error_rate,
};
mgr->sess_pool = session_pool_new(mgr->opts.max_tcp_session_num + mgr->opts.max_udp_session_num); mgr->sess_pool = session_pool_new(mgr->opts.max_tcp_session_num + mgr->opts.max_udp_session_num);
if (mgr->sess_pool == NULL) if (mgr->sess_pool == NULL)
{ {
@@ -1043,14 +1146,14 @@ struct session_manager *session_manager_new(struct session_manager_options *opts
goto error; goto error;
} }
mgr->tcp_dupkt_filter = dupkt_filter_new(mgr->opts.tcp_dupkt_filter_enable, mgr->opts.tcp_dupkt_filter_capacity, mgr->opts.tcp_dupkt_filter_error_rate, mgr->opts.tcp_dupkt_filter_timeout); mgr->tcp_dup_pkt_filter = duplicated_packet_filter_new(&dup_pkt_opts, timestamp_get_sec());
if (mgr->tcp_dupkt_filter == NULL) if (mgr->tcp_dup_pkt_filter == NULL)
{ {
goto error; goto error;
} }
mgr->udp_eviction_filter = eviction_filter_new(mgr->opts.udp_eviction_filter_enable, mgr->opts.udp_eviction_filter_capacity, mgr->opts.udp_eviction_filter_error_rate, mgr->opts.udp_eviction_filter_timeout); mgr->udp_evc_sess_filter = evicted_session_filter_new(&evc_sess_opts, timestamp_get_sec());
if (mgr->udp_eviction_filter == NULL) if (mgr->udp_evc_sess_filter == NULL)
{ {
goto error; goto error;
} }
@@ -1085,8 +1188,8 @@ void session_manager_free(struct session_manager *mgr)
session_manager_free_session(mgr, sess); session_manager_free_session(mgr, sess);
} }
eviction_filter_free(mgr->udp_eviction_filter); evicted_session_filter_free(mgr->udp_evc_sess_filter);
dupkt_filter_free(mgr->tcp_dupkt_filter); duplicated_packet_filter_free(mgr->tcp_dup_pkt_filter);
session_queue_free(mgr->sess_evicted_queue); session_queue_free(mgr->sess_evicted_queue);
session_timer_free(mgr->sess_timer); session_timer_free(mgr->sess_timer);
session_table_free(mgr->udp_sess_table); session_table_free(mgr->udp_sess_table);
@@ -1173,7 +1276,7 @@ void session_manager_free_session(struct session_manager *mgr, struct session *s
session_set0_cur_pkt(sess, NULL); session_set0_cur_pkt(sess, NULL);
session_set_cur_dir(sess, SESSION_DIR_NONE); session_set_cur_dir(sess, SESSION_DIR_NONE);
session_free(sess); session_free(sess);
session_pool_free(mgr->sess_pool, sess); session_pool_push(mgr->sess_pool, sess);
sess = NULL; sess = NULL;
} }
} }

View File

@@ -33,17 +33,17 @@ struct session_manager_options
// UDP timeout // UDP timeout
uint64_t udp_timeout_data; // seconds, Range: 1-15,999,999 uint64_t udp_timeout_data; // seconds, Range: 1-15,999,999
// TCP duplicate packet filter // duplicate packet filter
uint8_t tcp_dupkt_filter_enable; uint8_t duplicated_packet_filter_enable;
uint64_t tcp_dupkt_filter_capacity; uint32_t duplicated_packet_filter_capacity;
uint64_t tcp_dupkt_filter_timeout; // seconds, Range: 1-60 uint32_t duplicated_packet_filter_timeout; // seconds, Range: 1-60
double tcp_dupkt_filter_error_rate; double duplicated_packet_filter_error_rate;
// UDP eviction filter // evicted session filter
uint8_t udp_eviction_filter_enable; uint8_t evicted_session_filter_enable;
uint64_t udp_eviction_filter_capacity; uint32_t evicted_session_filter_capacity;
uint64_t udp_eviction_filter_timeout; // seconds, Range: 1-60 uint32_t evicted_session_filter_timeout; // seconds, Range: 1-60
double udp_eviction_filter_error_rate; double evicted_session_filter_error_rate;
}; };
struct session_manager; struct session_manager;

View File

@@ -36,7 +36,7 @@ void session_pool_free(struct session_pool *pool)
} }
} }
struct session *session_pool_alloc(struct session_pool *pool) struct session *session_pool_pop(struct session_pool *pool)
{ {
if (pool == NULL) if (pool == NULL)
{ {
@@ -56,7 +56,7 @@ struct session *session_pool_alloc(struct session_pool *pool)
return sess; return sess;
} }
void session_pool_free(struct session_pool *pool, struct session *sess) void session_pool_push(struct session_pool *pool, struct session *sess)
{ {
if (pool == NULL || sess == NULL) if (pool == NULL || sess == NULL)
{ {

View File

@@ -12,8 +12,8 @@ struct session_pool;
struct session_pool *session_pool_new(uint64_t count); struct session_pool *session_pool_new(uint64_t count);
void session_pool_free(struct session_pool *pool); void session_pool_free(struct session_pool *pool);
struct session *session_pool_alloc(struct session_pool *pool); struct session *session_pool_pop(struct session_pool *pool);
void session_pool_free(struct session_pool *pool, struct session *sess); void session_pool_push(struct session_pool *pool, struct session *sess);
uint64_t session_pool_get_count(struct session_pool *pool); uint64_t session_pool_get_count(struct session_pool *pool);
#ifdef __cpluscplus #ifdef __cpluscplus

View File

@@ -34,7 +34,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SYN_DUP)
char tcp_pkt_c2s_syn_retransmission[1500] = {0}; char tcp_pkt_c2s_syn_retransmission[1500] = {0};
memcpy(tcp_pkt_c2s_syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); 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)); packet_parse(&pkt, (const char *)tcp_pkt_c2s_syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
const struct layer_record *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4); const struct layer *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer); EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234); ipv4_hdr_set_ipid(hdr, 0x1234);
@@ -86,7 +86,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, S2C_DUP)
char tcp_pkt_s2c_synack_retransmission[1500] = {0}; char tcp_pkt_s2c_synack_retransmission[1500] = {0};
memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack));
const struct layer_record *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4); const struct layer *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer); EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234); ipv4_hdr_set_ipid(hdr, 0x1234);
@@ -110,7 +110,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SKIP_FILTER)
struct packet pkt; struct packet pkt;
struct session *sess = NULL; struct session *sess = NULL;
struct session_manager *mgr = NULL; struct session_manager *mgr = NULL;
const struct layer_record *ipv4_layer; const struct layer *ipv4_layer;
struct ip *hdr; struct ip *hdr;
char tcp_pkt_c2s_syn_retransmission[1500] = {0}; char tcp_pkt_c2s_syn_retransmission[1500] = {0};
@@ -209,7 +209,7 @@ TEST(TCP_DUPKT_FILTER_DISABLE, C2S_DUPKT)
char tcp_pkt_c2s_syn_retransmission[1500] = {0}; char tcp_pkt_c2s_syn_retransmission[1500] = {0};
memcpy(tcp_pkt_c2s_syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); 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)); packet_parse(&pkt, (const char *)tcp_pkt_c2s_syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
const struct layer_record *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4); const struct layer *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer); EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234); ipv4_hdr_set_ipid(hdr, 0x1234);
@@ -264,7 +264,7 @@ TEST(TCP_DUPKT_FILTER_DISABLE, S2C_DUP)
char tcp_pkt_s2c_synack_retransmission[1500] = {0}; char tcp_pkt_s2c_synack_retransmission[1500] = {0};
memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack));
const struct layer_record *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4); const struct layer *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer); EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234); ipv4_hdr_set_ipid(hdr, 0x1234);

View File

@@ -2,7 +2,7 @@
static void overwrite_ipv4_saddr(struct packet *pkt, uint32_t saddr) static void overwrite_ipv4_saddr(struct packet *pkt, uint32_t saddr)
{ {
const struct layer_record *ipv4_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_IPV4); const struct layer *ipv4_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer); EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_src_addr(hdr, saddr); ipv4_hdr_set_src_addr(hdr, saddr);

View File

@@ -2,7 +2,7 @@
static void overwrite_ipv4_saddr(struct packet *pkt, uint32_t saddr) static void overwrite_ipv4_saddr(struct packet *pkt, uint32_t saddr)
{ {
const struct layer_record *ipv4_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_IPV4); const struct layer *ipv4_layer = packet_get_innermost_layer(pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer); EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_src_addr(hdr, saddr); ipv4_hdr_set_src_addr(hdr, saddr);

View File

@@ -14,42 +14,42 @@ TEST(SESSION_POOL, POP_PUSH)
EXPECT_TRUE(sess_pool != NULL); EXPECT_TRUE(sess_pool != NULL);
EXPECT_TRUE(session_pool_get_count(sess_pool) == 3); EXPECT_TRUE(session_pool_get_count(sess_pool) == 3);
sess1 = session_pool_alloc(sess_pool); sess1 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess1 != NULL); EXPECT_TRUE(sess1 != NULL);
EXPECT_TRUE(session_pool_get_count(sess_pool) == 2); EXPECT_TRUE(session_pool_get_count(sess_pool) == 2);
sess2 = session_pool_alloc(sess_pool); sess2 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess2 != NULL); EXPECT_TRUE(sess2 != NULL);
EXPECT_TRUE(session_pool_get_count(sess_pool) == 1); EXPECT_TRUE(session_pool_get_count(sess_pool) == 1);
sess3 = session_pool_alloc(sess_pool); sess3 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess3 != NULL); EXPECT_TRUE(sess3 != NULL);
EXPECT_TRUE(session_pool_get_count(sess_pool) == 0); EXPECT_TRUE(session_pool_get_count(sess_pool) == 0);
sess4 = session_pool_alloc(sess_pool); sess4 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess4 == NULL); EXPECT_TRUE(sess4 == NULL);
session_pool_free(sess_pool, sess1); session_pool_push(sess_pool, sess1);
EXPECT_TRUE(session_pool_get_count(sess_pool) == 1); EXPECT_TRUE(session_pool_get_count(sess_pool) == 1);
session_pool_free(sess_pool, sess2); session_pool_push(sess_pool, sess2);
EXPECT_TRUE(session_pool_get_count(sess_pool) == 2); EXPECT_TRUE(session_pool_get_count(sess_pool) == 2);
session_pool_free(sess_pool, sess3); session_pool_push(sess_pool, sess3);
EXPECT_TRUE(session_pool_get_count(sess_pool) == 3); EXPECT_TRUE(session_pool_get_count(sess_pool) == 3);
sess1 = session_pool_alloc(sess_pool); sess1 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess1 != NULL); EXPECT_TRUE(sess1 != NULL);
EXPECT_TRUE(session_pool_get_count(sess_pool) == 2); EXPECT_TRUE(session_pool_get_count(sess_pool) == 2);
sess2 = session_pool_alloc(sess_pool); sess2 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess2 != NULL); EXPECT_TRUE(sess2 != NULL);
EXPECT_TRUE(session_pool_get_count(sess_pool) == 1); EXPECT_TRUE(session_pool_get_count(sess_pool) == 1);
sess3 = session_pool_alloc(sess_pool); sess3 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess3 != NULL); EXPECT_TRUE(sess3 != NULL);
EXPECT_TRUE(session_pool_get_count(sess_pool) == 0); EXPECT_TRUE(session_pool_get_count(sess_pool) == 0);
sess4 = session_pool_alloc(sess_pool); sess4 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess4 == NULL); EXPECT_TRUE(sess4 == NULL);
session_pool_free(sess_pool, sess1); session_pool_push(sess_pool, sess1);
EXPECT_TRUE(session_pool_get_count(sess_pool) == 1); EXPECT_TRUE(session_pool_get_count(sess_pool) == 1);
session_pool_free(sess_pool, sess2); session_pool_push(sess_pool, sess2);
EXPECT_TRUE(session_pool_get_count(sess_pool) == 2); EXPECT_TRUE(session_pool_get_count(sess_pool) == 2);
session_pool_free(sess_pool, sess3); session_pool_push(sess_pool, sess3);
EXPECT_TRUE(session_pool_get_count(sess_pool) == 3); EXPECT_TRUE(session_pool_get_count(sess_pool) == 3);
session_pool_free(sess_pool); session_pool_free(sess_pool);

View File

@@ -41,7 +41,7 @@ static void session_free_callback(struct session *sess, void *arg)
if (sess) if (sess)
{ {
struct session_pool *sess_pool = (struct session_pool *)arg; struct session_pool *sess_pool = (struct session_pool *)arg;
session_pool_free(sess_pool, sess); session_pool_push(sess_pool, sess);
sess = NULL; sess = NULL;
} }
} }
@@ -74,17 +74,17 @@ TEST(SESSION_TABLE, OP_SESSION)
session_table_set_freecb(sess_table, session_free_callback, sess_pool); session_table_set_freecb(sess_table, session_free_callback, sess_pool);
// Add // Add
sess1 = session_pool_alloc(sess_pool); sess1 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess1 != NULL); EXPECT_TRUE(sess1 != NULL);
session_set_id(sess1, 1); session_set_id(sess1, 1);
session_set_key(sess1, &tuple_1); session_set_key(sess1, &tuple_1);
sess2 = session_pool_alloc(sess_pool); sess2 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess2 != NULL); EXPECT_TRUE(sess2 != NULL);
session_set_id(sess2, 2); session_set_id(sess2, 2);
session_set_key(sess2, &tuple_2); session_set_key(sess2, &tuple_2);
sess3 = session_pool_alloc(sess_pool); sess3 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess3 != NULL); EXPECT_TRUE(sess3 != NULL);
session_set_id(sess3, 3); session_set_id(sess3, 3);
session_set_key(sess3, &tuple_3); session_set_key(sess3, &tuple_3);
@@ -150,7 +150,7 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == NULL); 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_least_recently_used_session(sess_table) == NULL);
sess1 = session_pool_alloc(sess_pool); sess1 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess1 != NULL); EXPECT_TRUE(sess1 != NULL);
session_set_id(sess1, 1); session_set_id(sess1, 1);
session_set_key(sess1, &tuple_1); session_set_key(sess1, &tuple_1);
@@ -158,7 +158,7 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == sess1); 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_find_least_recently_used_session(sess_table) == sess1);
sess2 = session_pool_alloc(sess_pool); sess2 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess2 != NULL); EXPECT_TRUE(sess2 != NULL);
session_set_id(sess2, 2); session_set_id(sess2, 2);
session_set_key(sess2, &tuple_2); session_set_key(sess2, &tuple_2);
@@ -166,7 +166,7 @@ TEST(SESSION_TABLE, FIND_OLDEST_NEWEST)
EXPECT_TRUE(session_table_find_least_recently_unused_session(sess_table) == sess1); 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_find_least_recently_used_session(sess_table) == sess2);
sess3 = session_pool_alloc(sess_pool); sess3 = session_pool_pop(sess_pool);
EXPECT_TRUE(sess3 != NULL); EXPECT_TRUE(sess3 != NULL);
session_set_id(sess3, 3); session_set_id(sess3, 3);
session_set_key(sess3, &tuple_3); session_set_key(sess3, &tuple_3);

View File

@@ -193,7 +193,7 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_C2S_RST)
char tcp_pkt_c2s_rst[1500] = {0}; char tcp_pkt_c2s_rst[1500] = {0};
memcpy(tcp_pkt_c2s_rst, tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin)); memcpy(tcp_pkt_c2s_rst, tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin));
packet_parse(&pkt, (const char *)tcp_pkt_c2s_rst, sizeof(tcp_pkt9_c2s_fin)); packet_parse(&pkt, (const char *)tcp_pkt_c2s_rst, sizeof(tcp_pkt9_c2s_fin));
const struct layer_record *tcp_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_TCP); const struct layer *tcp_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_TCP);
EXPECT_TRUE(tcp_layer); EXPECT_TRUE(tcp_layer);
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr; struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
tcp_hdr_set_flags(hdr, 0); tcp_hdr_set_flags(hdr, 0);
@@ -257,7 +257,7 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_S2C_RST)
char tcp_pkt_s2c_rst[1500] = {0}; char tcp_pkt_s2c_rst[1500] = {0};
memcpy(tcp_pkt_s2c_rst, tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin)); memcpy(tcp_pkt_s2c_rst, tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin));
packet_parse(&pkt, (const char *)tcp_pkt_s2c_rst, sizeof(tcp_pkt10_s2c_fin)); packet_parse(&pkt, (const char *)tcp_pkt_s2c_rst, sizeof(tcp_pkt10_s2c_fin));
const struct layer_record *tcp_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_TCP); const struct layer *tcp_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_TCP);
EXPECT_TRUE(tcp_layer); EXPECT_TRUE(tcp_layer);
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr; struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
tcp_hdr_set_flags(hdr, 0); tcp_hdr_set_flags(hdr, 0);

View File

@@ -385,7 +385,7 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_RETRANSMISSION)
char tcp_pkt_c2s_syn_retransmission[1500] = {0}; char tcp_pkt_c2s_syn_retransmission[1500] = {0};
memcpy(tcp_pkt_c2s_syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn)); 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)); packet_parse(&pkt, (const char *)tcp_pkt_c2s_syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
const struct layer_record *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4); const struct layer *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer); EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234); ipv4_hdr_set_ipid(hdr, 0x1234);
@@ -483,7 +483,7 @@ TEST(TCP_INIT_TO_OPENING, BY_SYNACK_RETRANSMISSION)
char tcp_pkt_s2c_synack_retransmission[1500] = {0}; char tcp_pkt_s2c_synack_retransmission[1500] = {0};
memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack)); memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack)); packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack));
const struct layer_record *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4); const struct layer *ipv4_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_IPV4);
EXPECT_TRUE(ipv4_layer); EXPECT_TRUE(ipv4_layer);
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr; struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
ipv4_hdr_set_ipid(hdr, 0x1234); ipv4_hdr_set_ipid(hdr, 0x1234);

View File

@@ -159,7 +159,7 @@ TEST(TCP_OPENING_TO_CLOSING, BY_C2S_RST)
char tcp_pkt_c2s_rst[1500] = {0}; char tcp_pkt_c2s_rst[1500] = {0};
memcpy(tcp_pkt_c2s_rst, tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin)); memcpy(tcp_pkt_c2s_rst, tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin));
packet_parse(&pkt, (const char *)tcp_pkt_c2s_rst, sizeof(tcp_pkt9_c2s_fin)); packet_parse(&pkt, (const char *)tcp_pkt_c2s_rst, sizeof(tcp_pkt9_c2s_fin));
const struct layer_record *tcp_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_TCP); const struct layer *tcp_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_TCP);
EXPECT_TRUE(tcp_layer); EXPECT_TRUE(tcp_layer);
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr; struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
tcp_hdr_set_flags(hdr, 0); tcp_hdr_set_flags(hdr, 0);
@@ -223,7 +223,7 @@ TEST(TCP_OPENING_TO_CLOSING, BY_S2C_RST)
char tcp_pkt_s2c_rst[1500] = {0}; char tcp_pkt_s2c_rst[1500] = {0};
memcpy(tcp_pkt_s2c_rst, tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin)); memcpy(tcp_pkt_s2c_rst, tcp_pkt10_s2c_fin, sizeof(tcp_pkt10_s2c_fin));
packet_parse(&pkt, (const char *)tcp_pkt_s2c_rst, sizeof(tcp_pkt10_s2c_fin)); packet_parse(&pkt, (const char *)tcp_pkt_s2c_rst, sizeof(tcp_pkt10_s2c_fin));
const struct layer_record *tcp_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_TCP); const struct layer *tcp_layer = packet_get_innermost_layer(&pkt, LAYER_TYPE_TCP);
EXPECT_TRUE(tcp_layer); EXPECT_TRUE(tcp_layer);
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr; struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
tcp_hdr_set_flags(hdr, 0); tcp_hdr_set_flags(hdr, 0);

View File

@@ -35,17 +35,17 @@ struct session_manager_options opts = {
// udp timeout // udp timeout
.udp_timeout_data = 2, .udp_timeout_data = 2,
// tcp duplicate packet filter // duplicate packet filter
.tcp_dupkt_filter_enable = 1, .duplicated_packet_filter_enable = 1,
.tcp_dupkt_filter_capacity = 1000, .duplicated_packet_filter_capacity = 1000,
.tcp_dupkt_filter_timeout = 10, .duplicated_packet_filter_timeout = 10,
.tcp_dupkt_filter_error_rate = 0.0001, .duplicated_packet_filter_error_rate = 0.0001,
// udp eviction filter // evicted session filter
.udp_eviction_filter_enable = 1, .evicted_session_filter_enable = 1,
.udp_eviction_filter_capacity = 1000, .evicted_session_filter_capacity = 1000,
.udp_eviction_filter_timeout = 10, .evicted_session_filter_timeout = 10,
.udp_eviction_filter_error_rate = 0.0001, .evicted_session_filter_error_rate = 0.0001,
}; };
__attribute__((unused)) static void __session_dispatch(struct session *sess) __attribute__((unused)) static void __session_dispatch(struct session *sess)

View File

@@ -131,28 +131,29 @@ static void *main_loop(void *arg)
struct thread_context *threads_ctx = (struct thread_context *)arg; struct thread_context *threads_ctx = (struct thread_context *)arg;
struct packet_io *packet_io = stellar_ctx->packet_io; struct packet_io *packet_io = stellar_ctx->packet_io;
struct session_manager *sess_mgr = threads_ctx->sess_mgr; struct session_manager *sess_mgr = threads_ctx->sess_mgr;
struct ip_reassembly *ip_mgr = threads_ctx->ip_mgr; struct ip_reassembly *ip_reass = threads_ctx->ip_mgr;
void *plug_mgr = NULL; void *plug_mgr = NULL;
void *plug_mgr_ctx = NULL; void *plug_mgr_ctx = NULL;
int nr_recv; int nr_recv;
uint16_t thd_idx = threads_ctx->index; int need_drop_pkt = 1; // TODO
uint64_t now_msec = 0; uint64_t now_sec = 0;
uint16_t thr_idx = threads_ctx->index;
if (packet_io_init(packet_io, thd_idx) != 0) if (packet_io_init(packet_io, thr_idx) != 0)
{ {
STELLAR_LOG_ERROR("unable to init marsio thread"); STELLAR_LOG_ERROR("unable to init marsio thread");
return NULL; return NULL;
} }
ATOMIC_SET(&threads_ctx->is_runing, 1); ATOMIC_SET(&threads_ctx->is_runing, 1);
thread_set_name("stellar", thd_idx); thread_set_name("stellar", thr_idx);
STELLAR_LOG_STATE("worker thread %d runing", thd_idx); STELLAR_LOG_STATE("worker thread %d runing", thr_idx);
while (ATOMIC_READ(&threads_ctx->need_exit) == 0) while (ATOMIC_READ(&threads_ctx->need_exit) == 0)
{ {
now_msec = timestamp_get_msec(); now_sec = timestamp_get_sec(); // TODO
nr_recv = packet_io_ingress(packet_io, thd_idx, packets, RX_BURST_MAX); nr_recv = packet_io_ingress(packet_io, thr_idx, packets, RX_BURST_MAX);
if (nr_recv == 0) if (nr_recv == 0)
{ {
goto idle_tasks; goto idle_tasks;
@@ -162,53 +163,66 @@ static void *main_loop(void *arg)
{ {
pkt = &packets[i]; pkt = &packets[i];
// TODO // call plugin_manager_dispatch_raw_pkt();
// call packet plugin if (packet_is_fragment(pkt))
// ip fragment reassemble
if (pkt->frag_layer)
{ {
struct packet *temp = ip_reassembly_packet(ip_mgr, pkt); struct packet *defraged_pkt = ip_reassembly_packet(ip_reass, pkt, now_sec);
packet_io_egress(packet_io, thd_idx, pkt, 1); // forward the original fragment packet if (defraged_pkt == NULL)
if (temp == NULL)
{ {
continue; continue;
} }
else else
{ {
pkt = temp; // call plugin_manager_dispatch_defrag_pkt();
pkt = defraged_pkt;
} }
} }
// TODO filter protocol before session lookup
sess = session_manager_lookup_session(sess_mgr, pkt); sess = session_manager_lookup_session(sess_mgr, pkt);
if (sess == NULL) if (sess == NULL)
{ {
sess = session_manager_new_session(sess_mgr, pkt); sess = session_manager_new_session(sess_mgr, pkt);
if (sess == NULL) if (sess == NULL)
{ {
// 1.Not TCP or UDP
// 2.UDP evict packet continue;
// 3.UDP overloading and config to bypass new session
// 4.TCP no SYN flag
// 5.UDP overloading and config to bypass new session
goto fast_forward;
} }
plug_mgr_ctx = plugin_manager_new_ctx(); plug_mgr_ctx = plugin_manager_new_ctx();
session_set_id(sess, id_generator_alloc(now_sec, thr_idx));
session_set_user_data(sess, plug_mgr_ctx); session_set_user_data(sess, plug_mgr_ctx);
} }
else else
{ {
if (session_manager_update_session(sess_mgr, sess, pkt) == -1) session_manager_update_session(sess_mgr, sess, pkt);
{
// TCP duplicate packet
goto fast_forward;
}
} }
plugin_manager_dispatch(plug_mgr, sess, pkt); plugin_manager_dispatch(plug_mgr, sess, pkt);
}
fast_forward: if (unlikely(need_drop_pkt))
packet_io_egress(packet_io, thd_idx, pkt, 1); {
for (int i = 0; i < nr_recv; i++)
{
if (packet_get_action(&packets[i]) == PACKET_ACTION_DROP)
{
packet_io_drop(packet_io, thr_idx, &packets[i], 1);
}
else
{
packet_io_egress(packet_io, thr_idx, &packets[i], 1);
}
}
}
else
{
packet_io_egress(packet_io, thr_idx, packets, nr_recv);
}
idle_tasks:
// nr_recv packet atmost trigger nr_recv session evict
for (int i = 0; i < nr_recv; i++)
{
evicted_sess = session_manager_get_evicted_session(sess_mgr); evicted_sess = session_manager_get_evicted_session(sess_mgr);
if (evicted_sess) if (evicted_sess)
{ {
@@ -218,9 +232,7 @@ static void *main_loop(void *arg)
} }
} }
idle_tasks: while ((expired_sess = session_manager_get_expired_session(sess_mgr)))
expired_sess = session_manager_get_expired_session(sess_mgr);
if (expired_sess)
{ {
plug_mgr_ctx = session_get_user_data(expired_sess); plug_mgr_ctx = session_get_user_data(expired_sess);
plugin_manager_free_ctx(plug_mgr_ctx); plugin_manager_free_ctx(plug_mgr_ctx);
@@ -234,7 +246,7 @@ static void *main_loop(void *arg)
} }
ATOMIC_SET(&threads_ctx->is_runing, 0); ATOMIC_SET(&threads_ctx->is_runing, 0);
STELLAR_LOG_STATE("worker thread %d stop", thd_idx); STELLAR_LOG_STATE("worker thread %d stop", thr_idx);
return NULL; return NULL;
} }
@@ -331,13 +343,13 @@ int main(int argc, char **argv)
STELLAR_LOG_STATE("Start Stellar (version: %s)\n %s", __stellar_version, logo_str); STELLAR_LOG_STATE("Start Stellar (version: %s)\n %s", __stellar_version, logo_str);
if (config_load(&stellar_ctx->config, stellar_config_file) != 0) if (parse_config_file(stellar_config_file, &stellar_ctx->config) != 0)
{ {
STELLAR_LOG_ERROR("unable to load config file"); STELLAR_LOG_ERROR("unable to load config file");
return -1; return -1;
} }
config_dump(&stellar_ctx->config); print_config_options(&stellar_ctx->config);
if (id_generator_init(dev_opts->device_base, dev_opts->device_offset) != 0) if (id_generator_init(dev_opts->device_base, dev_opts->device_offset) != 0)
{ {
@@ -380,7 +392,6 @@ error_out:
// TODO free plugin // TODO free plugin
id_generator_free();
log_free(); log_free();
return 0; return 0;

View File

@@ -19,6 +19,9 @@ extern "C"
#define ATOMIC_SET(x, y) __atomic_store_n(x, y, __ATOMIC_RELAXED) #define ATOMIC_SET(x, y) __atomic_store_n(x, y, __ATOMIC_RELAXED)
#define MIN(x, y) ((x) < (y) ? (x) : (y)) #define MIN(x, y) ((x) < (y) ? (x) : (y))
#define likely(expr) __builtin_expect((expr), 1)
#define unlikely(expr) __builtin_expect((expr), 0)
#ifdef STELLAR_GIT_VERSION #ifdef STELLAR_GIT_VERSION
static __attribute__((__used__)) const char *__stellar_version = STELLAR_GIT_VERSION; static __attribute__((__used__)) const char *__stellar_version = STELLAR_GIT_VERSION;
#else #else

View File

@@ -1,7 +1,3 @@
###############################################################################
# gtest
###############################################################################
add_executable(gtest_timestamp gtest_timestamp.cpp) add_executable(gtest_timestamp gtest_timestamp.cpp)
target_link_libraries(gtest_timestamp timestamp gtest) target_link_libraries(gtest_timestamp timestamp gtest)

View File

@@ -1,7 +1,3 @@
###############################################################################
# tuple
###############################################################################
add_library(tuple tuple.cpp) add_library(tuple tuple.cpp)
target_include_directories(tuple PUBLIC ${CMAKE_CURRENT_LIST_DIR}) target_include_directories(tuple PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_include_directories(tuple PUBLIC ${CMAKE_SOURCE_DIR}/src/crc32) target_include_directories(tuple PUBLIC ${CMAKE_SOURCE_DIR}/src/crc32)

View File

@@ -1,7 +1,3 @@
###############################################################################
# gtest
###############################################################################
add_executable(gtest_tuple gtest_tuple.cpp) add_executable(gtest_tuple gtest_tuple.cpp)
target_link_libraries(gtest_tuple tuple gtest) target_link_libraries(gtest_tuple tuple gtest)

View File

@@ -296,75 +296,47 @@ int tuple6_cmp(const struct tuple6 *tuple_a, const struct tuple6 *tuple_b)
void tuple2_reverse(const struct tuple2 *in, struct tuple2 *out) void tuple2_reverse(const struct tuple2 *in, struct tuple2 *out)
{ {
memset(out, 0, sizeof(struct tuple2));
out->ip_type = in->ip_type; out->ip_type = in->ip_type;
if (in->ip_type == IP_TYPE_V4) memcpy(&out->src_addr, &in->dst_addr, sizeof(in->dst_addr));
{ memcpy(&out->dst_addr, &in->src_addr, sizeof(in->src_addr));
out->src_addr.v4.s_addr = in->dst_addr.v4.s_addr;
out->dst_addr.v4.s_addr = in->src_addr.v4.s_addr;
}
else
{
memcpy(&out->src_addr.v6, &in->dst_addr.v6, sizeof(in->dst_addr.v6));
memcpy(&out->dst_addr.v6, &in->src_addr.v6, sizeof(in->src_addr.v6));
}
} }
void tuple4_reverse(const struct tuple4 *in, struct tuple4 *out) void tuple4_reverse(const struct tuple4 *in, struct tuple4 *out)
{ {
memset(out, 0, sizeof(struct tuple4));
out->ip_type = in->ip_type; out->ip_type = in->ip_type;
out->src_port = in->dst_port; out->src_port = in->dst_port;
out->dst_port = in->src_port; out->dst_port = in->src_port;
if (in->ip_type == IP_TYPE_V4) memcpy(&out->src_addr, &in->dst_addr, sizeof(in->dst_addr));
{ memcpy(&out->dst_addr, &in->src_addr, sizeof(in->src_addr));
out->src_addr.v4.s_addr = in->dst_addr.v4.s_addr;
out->dst_addr.v4.s_addr = in->src_addr.v4.s_addr;
}
else
{
memcpy(&out->src_addr.v6, &in->dst_addr.v6, sizeof(in->dst_addr.v6));
memcpy(&out->dst_addr.v6, &in->src_addr.v6, sizeof(in->src_addr.v6));
}
} }
void tuple5_reverse(const struct tuple5 *in, struct tuple5 *out) void tuple5_reverse(const struct tuple5 *in, struct tuple5 *out)
{ {
memset(out, 0, sizeof(struct tuple5));
out->ip_type = in->ip_type; out->ip_type = in->ip_type;
out->ip_proto = in->ip_proto; out->ip_proto = in->ip_proto;
out->src_port = in->dst_port; out->src_port = in->dst_port;
out->dst_port = in->src_port; out->dst_port = in->src_port;
if (in->ip_type == IP_TYPE_V4) memcpy(&out->src_addr, &in->dst_addr, sizeof(in->dst_addr));
{ memcpy(&out->dst_addr, &in->src_addr, sizeof(in->src_addr));
out->src_addr.v4.s_addr = in->dst_addr.v4.s_addr;
out->dst_addr.v4.s_addr = in->src_addr.v4.s_addr;
}
else
{
memcpy(&out->src_addr.v6, &in->dst_addr.v6, sizeof(in->dst_addr.v6));
memcpy(&out->dst_addr.v6, &in->src_addr.v6, sizeof(in->src_addr.v6));
}
} }
void tuple6_reverse(const struct tuple6 *in, struct tuple6 *out) void tuple6_reverse(const struct tuple6 *in, struct tuple6 *out)
{ {
memset(out, 0, sizeof(struct tuple6));
out->ip_type = in->ip_type; out->ip_type = in->ip_type;
out->ip_proto = in->ip_proto; out->ip_proto = in->ip_proto;
out->domain = in->domain; out->domain = in->domain;
out->src_port = in->dst_port; out->src_port = in->dst_port;
out->dst_port = in->src_port; out->dst_port = in->src_port;
if (in->ip_type == IP_TYPE_V4) memcpy(&out->src_addr, &in->dst_addr, sizeof(in->dst_addr));
{ memcpy(&out->dst_addr, &in->src_addr, sizeof(in->src_addr));
out->src_addr.v4.s_addr = in->dst_addr.v4.s_addr;
out->dst_addr.v4.s_addr = in->src_addr.v4.s_addr;
}
else
{
memcpy(&out->src_addr.v6, &in->dst_addr.v6, sizeof(in->dst_addr.v6));
memcpy(&out->dst_addr.v6, &in->src_addr.v6, sizeof(in->src_addr.v6));
}
} }
void tuple2_to_str(const struct tuple2 *tuple, char *buf, uint32_t size) void tuple2_to_str(const struct tuple2 *tuple, char *buf, uint32_t size)