reactor packet I/O & duplicated packet filter & evicted session filter
This commit is contained in:
@@ -37,14 +37,14 @@ tcp_timeout_discard = 90 # seconds, Range: 1-15,999,999
|
||||
# UDP timeout
|
||||
udp_timeout_data = 10 # seconds, Range: 1-15,999,999
|
||||
|
||||
# TCP duplicate packet filter
|
||||
tcp_dupkt_filter_enable = 1
|
||||
tcp_dupkt_filter_capacity = 1000000
|
||||
tcp_dupkt_filter_timeout = 10 # seconds, Range: 1-60
|
||||
tcp_dupkt_filter_error_rate = 0.00001
|
||||
# duplicate packet filter
|
||||
duplicated_packet_filter_enable = 1
|
||||
duplicated_packet_filter_capacity = 1000000
|
||||
duplicated_packet_filter_timeout = 10 # seconds, Range: 1-60
|
||||
duplicated_packet_filter_error_rate = 0.00001
|
||||
|
||||
# UDP eviction filter
|
||||
udp_eviction_filter_enable = 1
|
||||
udp_eviction_filter_capacity = 1000000
|
||||
udp_eviction_filter_timeout = 10 # seconds, Range: 1-60
|
||||
udp_eviction_filter_error_rate = 0.00001
|
||||
# evicted session filter
|
||||
evicted_session_filter_enable = 1
|
||||
evicted_session_filter_capacity = 1000000
|
||||
evicted_session_filter_timeout = 10 # seconds, Range: 1-60
|
||||
evicted_session_filter_error_rate = 0.00001
|
||||
|
||||
@@ -6,8 +6,8 @@ add_subdirectory(packet)
|
||||
add_subdirectory(packet_io)
|
||||
add_subdirectory(id_generator)
|
||||
add_subdirectory(ip_reassembly)
|
||||
add_subdirectory(dupkt_filter)
|
||||
add_subdirectory(eviction_filter)
|
||||
add_subdirectory(duplicated_packet_filter)
|
||||
add_subdirectory(evicted_session_filter)
|
||||
add_subdirectory(session)
|
||||
add_subdirectory(config)
|
||||
add_subdirectory(stellar)
|
||||
@@ -1,7 +1,3 @@
|
||||
###############################################################################
|
||||
# config
|
||||
###############################################################################
|
||||
|
||||
add_library(config config.cpp)
|
||||
target_include_directories(config PUBLIC ${CMAKE_CURRENT_LIST_DIR})
|
||||
target_link_libraries(config toml packet_io ip_reassembly session_manager)
|
||||
@@ -7,53 +7,53 @@
|
||||
|
||||
// return 0: success
|
||||
// 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;
|
||||
toml_table_t *device_table;
|
||||
toml_table_t *device;
|
||||
|
||||
device_table = toml_table_in(conf_file_handle, "device");
|
||||
if (device_table == NULL)
|
||||
device = toml_table_in(table, "device");
|
||||
if (device == NULL)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing device section");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr = toml_raw_in(device_table, "device_base");
|
||||
ptr = toml_raw_in(device, "device_base");
|
||||
if (ptr == NULL)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing device.device_base");
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing device.device_offset");
|
||||
return -1;
|
||||
}
|
||||
dev_opts->device_offset = atoi(ptr);
|
||||
opts->device_offset = atoi(ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// return 0: success
|
||||
// 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;
|
||||
toml_table_t *packet_io_table;
|
||||
toml_table_t *packet_io;
|
||||
toml_array_t *mask_array;
|
||||
|
||||
packet_io_table = toml_table_in(conf_file_handle, "packet_io");
|
||||
if (packet_io_table == NULL)
|
||||
packet_io = toml_table_in(table, "packet_io");
|
||||
if (packet_io == NULL)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing packet_io section");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr = toml_raw_in(packet_io_table, "mode");
|
||||
ptr = toml_raw_in(packet_io, "mode");
|
||||
if (ptr == NULL)
|
||||
{
|
||||
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)
|
||||
{
|
||||
pkt_io_opts->mode = PACKET_IO_DUMPFILE;
|
||||
opts->mode = PACKET_IO_DUMPFILE;
|
||||
}
|
||||
else if (strcmp(ptr, "marsio") == 0)
|
||||
{
|
||||
pkt_io_opts->mode = PACKET_IO_MARSIO;
|
||||
opts->mode = PACKET_IO_MARSIO;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -73,37 +73,37 @@ static int parse_packet_io_options(struct packet_io_options *pkt_io_opts, toml_t
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing packet_io.dumpfile_dir");
|
||||
return -1;
|
||||
}
|
||||
// skip ""
|
||||
strncpy(pkt_io_opts->dumpfile_dir, ptr + 1, strlen(ptr) - 2);
|
||||
strncpy(opts->dumpfile_dir, ptr + 1, strlen(ptr) - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = toml_raw_in(packet_io_table, "app_symbol");
|
||||
ptr = toml_raw_in(packet_io, "app_symbol");
|
||||
if (ptr == NULL)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing packet_io.app_symbol");
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing packet_io.dev_symbol");
|
||||
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)
|
||||
{
|
||||
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);
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing packet_io.cpu_mask");
|
||||
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);
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
pkt_io_opts->cpu_mask[i] = atoi(ptr);
|
||||
opts->cpu_mask[i] = atoi(ptr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -138,269 +138,269 @@ static int parse_packet_io_options(struct packet_io_options *pkt_io_opts, toml_t
|
||||
|
||||
// return 0: success
|
||||
// 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;
|
||||
toml_table_t *ip_reass_table;
|
||||
toml_table_t *ip_reassembly;
|
||||
|
||||
ip_reass_table = toml_table_in(conf_file_handle, "ip_reassembly");
|
||||
if (ip_reass_table == NULL)
|
||||
ip_reassembly = toml_table_in(table, "ip_reassembly");
|
||||
if (ip_reassembly == NULL)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing ip_reassembly section");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr = toml_raw_in(ip_reass_table, "enable");
|
||||
ptr = toml_raw_in(ip_reassembly, "enable");
|
||||
if (ptr == NULL)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing ip_reassembly.enable");
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing ip_reassembly.timeout");
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing ip_reassembly.bucket_entries");
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing ip_reassembly.bucket_num");
|
||||
return -1;
|
||||
}
|
||||
ip_reass_opts->bucket_num = atoi(ptr);
|
||||
opts->bucket_num = atoi(ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// return 0: success
|
||||
// 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;
|
||||
toml_table_t *sess_mgr_table;
|
||||
toml_table_t *session_manager;
|
||||
|
||||
sess_mgr_table = toml_table_in(conf_file_handle, "session_manager");
|
||||
if (sess_mgr_table == NULL)
|
||||
session_manager = toml_table_in(table, "session_manager");
|
||||
if (session_manager == NULL)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing session_manager section");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing session_manager.max_tcp_session_num");
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing session_manager.max_udp_session_num");
|
||||
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)
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing session_manager.tcp_overload_evict_old_sess");
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing session_manager.udp_overload_evict_old_sess");
|
||||
return -1;
|
||||
}
|
||||
sess_mgr_opts->udp_overload_evict_old_sess = atoi(ptr);
|
||||
opts->udp_overload_evict_old_sess = atoi(ptr);
|
||||
|
||||
// TCP timeout
|
||||
ptr = toml_raw_in(sess_mgr_table, "tcp_timeout_init");
|
||||
ptr = toml_raw_in(session_manager, "tcp_timeout_init");
|
||||
if (ptr == NULL)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_init");
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_handshake");
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_data");
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_half_closed");
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_time_wait");
|
||||
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)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing session_manager.tcp_timeout_discard");
|
||||
return -1;
|
||||
}
|
||||
sess_mgr_opts->tcp_timeout_discard = atoll(ptr);
|
||||
opts->tcp_timeout_discard = atoll(ptr);
|
||||
|
||||
// UDP timeout
|
||||
ptr = toml_raw_in(sess_mgr_table, "udp_timeout_data");
|
||||
ptr = toml_raw_in(session_manager, "udp_timeout_data");
|
||||
if (ptr == NULL)
|
||||
{
|
||||
CONFIG_LOG_ERROR("config file missing session_manager.udp_timeout_data");
|
||||
return -1;
|
||||
}
|
||||
sess_mgr_opts->udp_timeout_data = atoll(ptr);
|
||||
opts->udp_timeout_data = atoll(ptr);
|
||||
|
||||
// TCP duplicate packet filter
|
||||
ptr = toml_raw_in(sess_mgr_table, "tcp_dupkt_filter_enable");
|
||||
// duplicate packet filter
|
||||
ptr = toml_raw_in(session_manager, "duplicated_packet_filter_enable");
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
sess_mgr_opts->tcp_dupkt_filter_error_rate = atof(ptr);
|
||||
opts->duplicated_packet_filter_error_rate = atof(ptr);
|
||||
|
||||
// UDP eviction filter
|
||||
ptr = toml_raw_in(sess_mgr_table, "udp_eviction_filter_enable");
|
||||
// eviction filter
|
||||
ptr = toml_raw_in(session_manager, "evicted_session_filter_enable");
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
sess_mgr_opts->udp_eviction_filter_error_rate = atof(ptr);
|
||||
opts->evicted_session_filter_error_rate = atof(ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// return 0: success
|
||||
// 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;
|
||||
char errbuf[200];
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
conf_file_handle = toml_parse_file(fp, errbuf, sizeof(errbuf));
|
||||
if (conf_file_handle == NULL)
|
||||
table = toml_parse_file(fp, errbuf, sizeof(errbuf));
|
||||
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;
|
||||
}
|
||||
|
||||
if (parse_device_options(&cfg->dev_opts, conf_file_handle) != 0)
|
||||
if (parse_device_options(table, &config->dev_opts) != 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -408,9 +408,9 @@ int config_load(struct config *cfg, const char *cfg_file)
|
||||
ret = 0;
|
||||
|
||||
error_out:
|
||||
if (conf_file_handle)
|
||||
if (table)
|
||||
{
|
||||
toml_free(conf_file_handle);
|
||||
toml_free(table);
|
||||
}
|
||||
|
||||
if (fp)
|
||||
@@ -421,17 +421,17 @@ error_out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void config_dump(struct config *cfg)
|
||||
void print_config_options(struct config *config)
|
||||
{
|
||||
if (cfg == NULL)
|
||||
if (config == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
struct device_options *dev_opts = &cfg->dev_opts;
|
||||
struct packet_io_options *pkt_io_opts = &cfg->pkt_io_opts;
|
||||
struct ip_reassembly_options *ip_reass_opts = &cfg->ip_reass_opts;
|
||||
struct session_manager_options *sess_mgr_opts = &cfg->sess_mgr_opts;
|
||||
struct device_options *dev_opts = &config->dev_opts;
|
||||
struct packet_io_options *pkt_io_opts = &config->pkt_io_opts;
|
||||
struct ip_reassembly_options *ip_reass_opts = &config->ip_reass_opts;
|
||||
struct session_manager_options *sess_mgr_opts = &config->sess_mgr_opts;
|
||||
|
||||
// device config
|
||||
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->tcp_dupkt_filter_enable : %d", sess_mgr_opts->tcp_dupkt_filter_enable);
|
||||
CONFIG_LOG_DEBUG("session_manager->tcp_dupkt_filter_capacity : %ld", sess_mgr_opts->tcp_dupkt_filter_capacity);
|
||||
CONFIG_LOG_DEBUG("session_manager->tcp_dupkt_filter_timeout : %ld", sess_mgr_opts->tcp_dupkt_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_enable : %d", sess_mgr_opts->duplicated_packet_filter_enable);
|
||||
CONFIG_LOG_DEBUG("session_manager->duplicated_packet_filter_capacity : %d", sess_mgr_opts->duplicated_packet_filter_capacity);
|
||||
CONFIG_LOG_DEBUG("session_manager->duplicated_packet_filter_timeout : %d", sess_mgr_opts->duplicated_packet_filter_timeout);
|
||||
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->udp_eviction_filter_capacity : %ld", sess_mgr_opts->udp_eviction_filter_capacity);
|
||||
CONFIG_LOG_DEBUG("session_manager->udp_eviction_filter_timeout : %ld", sess_mgr_opts->udp_eviction_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_enable : %d", sess_mgr_opts->evicted_session_filter_enable);
|
||||
CONFIG_LOG_DEBUG("session_manager->evicted_session_filter_capacity : %d", sess_mgr_opts->evicted_session_filter_capacity);
|
||||
CONFIG_LOG_DEBUG("session_manager->evicted_session_filter_timeout : %d", sess_mgr_opts->evicted_session_filter_timeout);
|
||||
CONFIG_LOG_DEBUG("session_manager->evicted_session_filter_error_rate : %f", sess_mgr_opts->evicted_session_filter_error_rate);
|
||||
}
|
||||
|
||||
@@ -6,21 +6,12 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "stellar.h"
|
||||
#include "packet_io.h"
|
||||
#include "ip_reassembly.h"
|
||||
#include "session_manager.h"
|
||||
|
||||
#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__)
|
||||
#ifndef CONFIG_LOG_DEBUG
|
||||
#define CONFIG_LOG_DEBUG(format, ...) \
|
||||
fprintf(stderr, "DEBUG (config), " format "\n", ##__VA_ARGS__);
|
||||
#endif
|
||||
|
||||
struct device_options
|
||||
{
|
||||
@@ -36,8 +27,10 @@ struct config
|
||||
struct session_manager_options sess_mgr_opts;
|
||||
};
|
||||
|
||||
int config_load(struct config *cfg, const char *cfg_file);
|
||||
void config_dump(struct config *cfg);
|
||||
// return 0: success
|
||||
// retuun -1: failed
|
||||
int parse_config_file(const char *file, struct config *config);
|
||||
void print_config_options(struct config *config);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
|
||||
@@ -8,9 +8,8 @@ extern "C"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define CRC32_UPD(crc, n) \
|
||||
(crc32c_tables[(n)][(crc) & 0xFF] ^ \
|
||||
crc32c_tables[(n)-1][((crc) >> 8) & 0xFF])
|
||||
#define CRC32_UPD(crc, n) \
|
||||
(crc32c_tables[(n)][(crc) & 0xFF] ^ crc32c_tables[(n)-1][((crc) >> 8) & 0xFF])
|
||||
|
||||
static const uint32_t crc32c_tables[8][256] = {
|
||||
{0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
|
||||
|
||||
@@ -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)
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
5
src/duplicated_packet_filter/CMakeLists.txt
Normal file
5
src/duplicated_packet_filter/CMakeLists.txt
Normal 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)
|
||||
144
src/duplicated_packet_filter/duplicated_packet_filter.cpp
Normal file
144
src/duplicated_packet_filter/duplicated_packet_filter.cpp
Normal 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);
|
||||
}
|
||||
35
src/duplicated_packet_filter/duplicated_packet_filter.h
Normal file
35
src/duplicated_packet_filter/duplicated_packet_filter.h
Normal 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
|
||||
5
src/duplicated_packet_filter/test/CMakeLists.txt
Normal file
5
src/duplicated_packet_filter/test/CMakeLists.txt
Normal 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)
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "dupkt_filter.h"
|
||||
#include "timestamp.h"
|
||||
#include "duplicated_packet_filter.h"
|
||||
|
||||
/******************************************************************************
|
||||
* [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,
|
||||
0x04, 0x02};
|
||||
|
||||
struct config
|
||||
{
|
||||
uint8_t enable;
|
||||
unsigned int capacity;
|
||||
double error_rate;
|
||||
int timeout_s;
|
||||
} config = {
|
||||
struct duplicated_packet_filter_options opts = {
|
||||
.enable = 1,
|
||||
.capacity = 1000000,
|
||||
.timeout_sec = 2,
|
||||
.error_rate = 0.00001,
|
||||
.timeout_s = 3,
|
||||
};
|
||||
|
||||
TEST(DUPKT_FILTER, TEST)
|
||||
TEST(DUPLICATED_PACKET_FILTER, TEST)
|
||||
{
|
||||
timestamp_update();
|
||||
|
||||
struct packet pkt;
|
||||
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(dupkt_filter_lookup(filter, &pkt) == 0); // no found
|
||||
dupkt_filter_add(filter, &pkt); // add
|
||||
EXPECT_TRUE(duplicated_packet_filter_lookup(filter, &pkt, 1) == 0); // no found
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
duplicated_packet_filter_free(filter);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
5
src/evicted_session_filter/CMakeLists.txt
Normal file
5
src/evicted_session_filter/CMakeLists.txt
Normal 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)
|
||||
86
src/evicted_session_filter/evicted_session_filter.cpp
Normal file
86
src/evicted_session_filter/evicted_session_filter.cpp
Normal 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);
|
||||
}
|
||||
31
src/evicted_session_filter/evicted_session_filter.h
Normal file
31
src/evicted_session_filter/evicted_session_filter.h
Normal 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
|
||||
5
src/evicted_session_filter/test/CMakeLists.txt
Normal file
5
src/evicted_session_filter/test/CMakeLists.txt
Normal 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)
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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();
|
||||
}
|
||||
@@ -1,7 +1,3 @@
|
||||
###############################################################################
|
||||
# file
|
||||
###############################################################################
|
||||
|
||||
add_library(file file_scan.cpp)
|
||||
target_include_directories(file PUBLIC ${CMAKE_CURRENT_LIST_DIR})
|
||||
target_link_libraries(file log)
|
||||
@@ -8,8 +8,8 @@ extern "C"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#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_ERROR(format, ...) LOG_ERROR("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);
|
||||
int file_scan(const char *dir, file_handle *cb, void *arg);
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
###############################################################################
|
||||
# id_generator
|
||||
###############################################################################
|
||||
|
||||
add_library(id_generator id_generator.cpp)
|
||||
target_include_directories(id_generator PUBLIC ${CMAKE_CURRENT_LIST_DIR})
|
||||
target_include_directories(id_generator PUBLIC ${CMAKE_SOURCE_DIR}/src/stellar)
|
||||
target_link_libraries(id_generator log timestamp)
|
||||
target_link_libraries(id_generator log)
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "id_generator.h"
|
||||
#include "stellar.h"
|
||||
#include "timestamp.h"
|
||||
|
||||
struct id_generator
|
||||
{
|
||||
@@ -49,11 +48,6 @@ int id_generator_init(uint8_t device_base, uint8_t device_offset)
|
||||
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 |
|
||||
* +------+------------------+----------------+------------------------+---------------------------+
|
||||
*/
|
||||
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_BASE_TIME (268435456L)
|
||||
|
||||
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_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) |
|
||||
(thread_index << 43) |
|
||||
(id_base_time << 15) |
|
||||
|
||||
@@ -22,8 +22,7 @@ extern "C"
|
||||
* return -1: failed
|
||||
*/
|
||||
int id_generator_init(uint8_t device_base, uint8_t device_offset);
|
||||
void id_generator_free();
|
||||
uint64_t id_generator_get();
|
||||
uint64_t id_generator_alloc(uint64_t now_sec, uint64_t thread_index);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
###############################################################################
|
||||
# ip_reassembly
|
||||
###############################################################################
|
||||
|
||||
add_library(ip_reassembly ip_reassembly.cpp)
|
||||
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)
|
||||
@@ -4,12 +4,10 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "packet.h"
|
||||
#include "timestamp.h"
|
||||
#include "crc32_hash.h"
|
||||
#include "checksum.h"
|
||||
#include "ipv4_utils.h"
|
||||
#include "ipv6_utils.h"
|
||||
#include "packet_utils.h"
|
||||
#include "ip_reassembly.h"
|
||||
|
||||
#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)
|
||||
{
|
||||
struct layer_record *layer = pkt->frag_layer;
|
||||
struct layer *layer = pkt->frag_layer;
|
||||
|
||||
if (layer->type == LAYER_TYPE_IPV6)
|
||||
{
|
||||
@@ -367,7 +365,7 @@ static inline void ip_frag_pkt_free(struct ip_frag_pkt *frag)
|
||||
* ip flow
|
||||
******************************************************************************/
|
||||
|
||||
static inline void ip_flow_init(struct ip_flow *flow, const struct ip_flow_key *key)
|
||||
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 = {
|
||||
.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_prev = NULL;
|
||||
flow->key = *key;
|
||||
flow->create_time = timestamp_get_sec();
|
||||
flow->create_time = now_sec;
|
||||
flow->expected_total_size = UINT32_MAX;
|
||||
flow->received_frag_size = 0;
|
||||
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--;
|
||||
}
|
||||
|
||||
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_flow_free(flow);
|
||||
ip_flow_init(flow, key);
|
||||
ip_flow_init(flow, key, now_sec);
|
||||
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
|
||||
* 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);
|
||||
|
||||
@@ -522,7 +520,6 @@ static struct ip_flow *ip_reassembly_find_flow(struct ip_reassembly *mgr, const
|
||||
struct ip_flow *empty = NULL;
|
||||
uint64_t timeout = mgr->timeout;
|
||||
uint32_t assoc = mgr->bucket_entries;
|
||||
uint64_t tms = timestamp_get_sec();
|
||||
for (uint32_t i = 0; i != assoc; i++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else if (timeout + p1[i].create_time <= tms)
|
||||
else if (timeout + p1[i].create_time <= now_sec)
|
||||
{
|
||||
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;
|
||||
}
|
||||
else if (timeout + p2[i].create_time <= tms)
|
||||
else if (timeout + p2[i].create_time <= now_sec)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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 *free = 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 (expired)
|
||||
{
|
||||
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);
|
||||
|
||||
mgr->last = expired;
|
||||
@@ -583,7 +580,7 @@ static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, cons
|
||||
if (free)
|
||||
{
|
||||
IP_REASSEMBLE_DEBUG1("add ip flow success: use free entry", key);
|
||||
ip_flow_init(free, key);
|
||||
ip_flow_init(free, key, now_sec);
|
||||
ip_reassembly_add_flow(mgr, free);
|
||||
|
||||
mgr->last = free;
|
||||
@@ -598,10 +595,10 @@ static struct ip_flow *ip_reassembly_update_flow(struct ip_reassembly *mgr, cons
|
||||
else
|
||||
{
|
||||
// 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_reassembly_reuse_flow(mgr, flow, key);
|
||||
ip_reassembly_reuse_flow(mgr, flow, key, now_sec);
|
||||
ip_reassembly_stat_inc(mgr, timeout, key);
|
||||
|
||||
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;
|
||||
uint64_t curr_ts = timestamp_get_sec();
|
||||
uint64_t timeout = mgr->timeout;
|
||||
|
||||
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_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)
|
||||
{
|
||||
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
|
||||
*/
|
||||
|
||||
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 *pkt2;
|
||||
@@ -888,7 +856,7 @@ struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct pack
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct layer_record *layer = pkt->frag_layer;
|
||||
const struct layer *layer = pkt->frag_layer;
|
||||
if (layer == 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)
|
||||
{
|
||||
pkt1 = ipv4_reassembly_packet(mgr, pkt);
|
||||
pkt1 = ipv4_reassembly_packet(mgr, pkt, now_sec);
|
||||
if (pkt1 && pkt1->frag_layer)
|
||||
{
|
||||
pkt2 = ip_reassembly_packet(mgr, pkt1);
|
||||
pkt2 = ip_reassembly_packet(mgr, pkt1, now_sec);
|
||||
packet_free(pkt1);
|
||||
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)
|
||||
{
|
||||
pkt1 = ipv6_reassembly_packet(mgr, pkt);
|
||||
pkt1 = ipv6_reassembly_packet(mgr, pkt, now_sec);
|
||||
if (pkt1 && pkt1->frag_layer)
|
||||
{
|
||||
pkt2 = ip_reassembly_packet(mgr, pkt1);
|
||||
pkt2 = ip_reassembly_packet(mgr, pkt1, now_sec);
|
||||
packet_free(pkt1);
|
||||
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;
|
||||
uint16_t frag_len = ipv4_hdr_get_total_len(hdr) - ipv4_hdr_get_hdr_len(hdr);
|
||||
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.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)
|
||||
{
|
||||
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_frag *frag_hdr = ipv6_hdr_get_frag_ext(hdr);
|
||||
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.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)
|
||||
{
|
||||
return NULL;
|
||||
|
||||
@@ -52,17 +52,16 @@ struct ip_reassembly_stat
|
||||
|
||||
struct ip_reassembly *ip_reassembly_new(const struct ip_reassembly_options *opts);
|
||||
void ip_reassembly_free(struct ip_reassembly *mgr);
|
||||
void ip_reassembly_expire(struct ip_reassembly *mgr);
|
||||
void ip_reassembly_print_stat(struct ip_reassembly *mgr);
|
||||
void ip_reassembly_expire(struct ip_reassembly *mgr, uint64_t now_sec);
|
||||
struct ip_reassembly_stat *ip_reassembly_get_stat(struct ip_reassembly *mgr);
|
||||
|
||||
/*
|
||||
* Returns the reassembled packet, or NULL if the packet is not reassembled
|
||||
* The returned packet should be freed by calling the packet_free() function
|
||||
*/
|
||||
struct packet *ip_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt);
|
||||
struct packet *ipv4_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt);
|
||||
struct packet *ipv6_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, uint64_t now_sec);
|
||||
struct packet *ipv6_reassembly_packet(struct ip_reassembly *mgr, const struct packet *pkt, uint64_t now_sec);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
###############################################################################
|
||||
# gtest
|
||||
###############################################################################
|
||||
|
||||
add_executable(gtest_ipv4_reassembly gtest_ipv4_reassembly.cpp)
|
||||
target_link_libraries(gtest_ipv4_reassembly ip_reassembly gtest)
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet *new_pkt;
|
||||
const struct layer_record *layer;
|
||||
const struct layer *layer;
|
||||
struct ip_reassembly *mgr;
|
||||
struct ip_reassembly_options opts = {
|
||||
.enable = true,
|
||||
@@ -205,11 +205,9 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
|
||||
.bucket_num = 8,
|
||||
};
|
||||
|
||||
timestamp_update();
|
||||
|
||||
mgr = ip_reassembly_new(&opts);
|
||||
EXPECT_TRUE(mgr != NULL);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -218,9 +216,9 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -229,9 +227,9 @@ TEST(IPV4_REASSEMBLE, PADDING_ORDER)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -291,7 +289,7 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet *new_pkt;
|
||||
const struct layer_record *layer;
|
||||
const struct layer *layer;
|
||||
struct ip_reassembly *mgr;
|
||||
struct ip_reassembly_options opts = {
|
||||
.enable = true,
|
||||
@@ -300,11 +298,9 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
|
||||
.bucket_num = 8,
|
||||
};
|
||||
|
||||
timestamp_update();
|
||||
|
||||
mgr = ip_reassembly_new(&opts);
|
||||
EXPECT_TRUE(mgr != NULL);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -313,9 +309,9 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -324,9 +320,9 @@ TEST(IPV4_REASSEMBLE, PADDING_UNORDER)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -394,11 +390,9 @@ TEST(IPV4_REASSEMBLE, EXPIRE)
|
||||
.bucket_num = 8,
|
||||
};
|
||||
|
||||
timestamp_update();
|
||||
|
||||
mgr = ip_reassembly_new(&opts);
|
||||
EXPECT_TRUE(mgr != NULL);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -407,24 +401,20 @@ TEST(IPV4_REASSEMBLE, EXPIRE)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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, // ip6: find, add, del, timeout
|
||||
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
|
||||
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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -443,7 +433,7 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet *new_pkt;
|
||||
const struct layer_record *layer;
|
||||
const struct layer *layer;
|
||||
struct ip_reassembly *mgr;
|
||||
struct ip_reassembly_options opts = {
|
||||
.enable = true,
|
||||
@@ -452,11 +442,9 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
|
||||
.bucket_num = 8,
|
||||
};
|
||||
|
||||
timestamp_update();
|
||||
|
||||
mgr = ip_reassembly_new(&opts);
|
||||
EXPECT_TRUE(mgr != NULL);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -465,9 +453,9 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -476,9 +464,9 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -487,9 +475,9 @@ TEST(IPV4_REASSEMBLE, DUP_FIRST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -549,7 +537,7 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet *new_pkt;
|
||||
const struct layer_record *layer;
|
||||
const struct layer *layer;
|
||||
struct ip_reassembly *mgr;
|
||||
struct ip_reassembly_options opts = {
|
||||
.enable = true,
|
||||
@@ -558,11 +546,9 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
|
||||
.bucket_num = 8,
|
||||
};
|
||||
|
||||
timestamp_update();
|
||||
|
||||
mgr = ip_reassembly_new(&opts);
|
||||
EXPECT_TRUE(mgr != NULL);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -571,9 +557,9 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -582,9 +568,9 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -593,9 +579,9 @@ TEST(IPV4_REASSEMBLE, DUP_LAST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -663,11 +649,9 @@ TEST(IPV4_REASSEMBLE, FULL)
|
||||
.bucket_num = 1,
|
||||
};
|
||||
|
||||
timestamp_update();
|
||||
|
||||
mgr = ip_reassembly_new(&opts);
|
||||
EXPECT_TRUE(mgr != NULL);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -680,9 +664,9 @@ TEST(IPV4_REASSEMBLE, FULL)
|
||||
|
||||
// flow1
|
||||
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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -691,9 +675,9 @@ TEST(IPV4_REASSEMBLE, FULL)
|
||||
|
||||
// flow2
|
||||
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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -702,9 +686,9 @@ TEST(IPV4_REASSEMBLE, FULL)
|
||||
|
||||
// flow3
|
||||
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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
|
||||
@@ -607,7 +607,7 @@ TEST(IPV6_REASSEMBLE, NORMAL)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet *new_pkt;
|
||||
const struct layer_record *layer;
|
||||
const struct layer *layer;
|
||||
struct ip_reassembly *mgr;
|
||||
struct ip_reassembly_options opts = {
|
||||
.enable = true,
|
||||
@@ -616,11 +616,9 @@ TEST(IPV6_REASSEMBLE, NORMAL)
|
||||
.bucket_num = 8,
|
||||
};
|
||||
|
||||
timestamp_update();
|
||||
|
||||
mgr = ip_reassembly_new(&opts);
|
||||
EXPECT_TRUE(mgr != NULL);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -629,9 +627,9 @@ TEST(IPV6_REASSEMBLE, NORMAL)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -640,9 +638,9 @@ TEST(IPV6_REASSEMBLE, NORMAL)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -651,9 +649,9 @@ TEST(IPV6_REASSEMBLE, NORMAL)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -662,9 +660,9 @@ TEST(IPV6_REASSEMBLE, NORMAL)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -726,11 +724,9 @@ TEST(IPV6_REASSEMBLE, EXPIRE)
|
||||
.bucket_num = 8,
|
||||
};
|
||||
|
||||
timestamp_update();
|
||||
|
||||
mgr = ip_reassembly_new(&opts);
|
||||
EXPECT_TRUE(mgr != NULL);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -739,24 +735,20 @@ TEST(IPV6_REASSEMBLE, EXPIRE)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
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
|
||||
|
||||
// sleep 1
|
||||
sleep(1);
|
||||
timestamp_update();
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -775,7 +767,7 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet *new_pkt;
|
||||
const struct layer_record *layer;
|
||||
const struct layer *layer;
|
||||
struct ip_reassembly *mgr;
|
||||
struct ip_reassembly_options opts = {
|
||||
.enable = true,
|
||||
@@ -784,11 +776,9 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
|
||||
.bucket_num = 8,
|
||||
};
|
||||
|
||||
timestamp_update();
|
||||
|
||||
mgr = ip_reassembly_new(&opts);
|
||||
EXPECT_TRUE(mgr != NULL);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -797,9 +787,9 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -808,9 +798,9 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -819,9 +809,9 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -830,9 +820,9 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -841,9 +831,9 @@ TEST(IPV6_REASSEMBLE, DUP_FIRST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -897,7 +887,7 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
|
||||
{
|
||||
struct packet pkt;
|
||||
struct packet *new_pkt;
|
||||
const struct layer_record *layer;
|
||||
const struct layer *layer;
|
||||
struct ip_reassembly *mgr;
|
||||
struct ip_reassembly_options opts = {
|
||||
.enable = true,
|
||||
@@ -906,11 +896,9 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
|
||||
.bucket_num = 8,
|
||||
};
|
||||
|
||||
timestamp_update();
|
||||
|
||||
mgr = ip_reassembly_new(&opts);
|
||||
EXPECT_TRUE(mgr != NULL);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -919,9 +907,9 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -930,9 +918,9 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -941,9 +929,9 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -952,9 +940,9 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -963,9 +951,9 @@ TEST(IPV6_REASSEMBLE, DUP_LAST_FRAG)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -1028,11 +1016,9 @@ TEST(IPV6_REASSEMBLE, FULL)
|
||||
.bucket_num = 1,
|
||||
};
|
||||
|
||||
timestamp_update();
|
||||
|
||||
mgr = ip_reassembly_new(&opts);
|
||||
EXPECT_TRUE(mgr != NULL);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -1046,9 +1032,9 @@ TEST(IPV6_REASSEMBLE, FULL)
|
||||
// flow1
|
||||
memset(&src_addr, 1, sizeof(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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -1058,9 +1044,9 @@ TEST(IPV6_REASSEMBLE, FULL)
|
||||
// flow2
|
||||
memset(&src_addr, 2, sizeof(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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -1070,9 +1056,9 @@ TEST(IPV6_REASSEMBLE, FULL)
|
||||
// flow3
|
||||
memset(&src_addr, 3, sizeof(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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -1099,11 +1085,9 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
|
||||
.bucket_num = 8,
|
||||
};
|
||||
|
||||
timestamp_update();
|
||||
|
||||
mgr = ip_reassembly_new(&opts);
|
||||
EXPECT_TRUE(mgr != NULL);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -1112,9 +1096,9 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -1123,9 +1107,9 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -1137,9 +1121,9 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
|
||||
memcpy(dup_frag, frag3, sizeof(frag3));
|
||||
packet_parse(&pkt, (const char *)dup_frag, sizeof(dup_frag));
|
||||
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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
@@ -1148,9 +1132,9 @@ TEST(IPV6_REASSEMBLE, OVERLAP)
|
||||
|
||||
// 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);
|
||||
// ip_reassembly_print_stat(mgr);
|
||||
|
||||
check_stat(ip_reassembly_get_stat(mgr),
|
||||
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
|
||||
|
||||
@@ -8,17 +8,15 @@ extern "C"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "timestamp.h"
|
||||
#include "udp_utils.h"
|
||||
#include "tcp_utils.h"
|
||||
#include "ipv4_utils.h"
|
||||
#include "ipv6_utils.h"
|
||||
#include "packet_utils.h"
|
||||
#include "ip_reassembly.h"
|
||||
|
||||
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);
|
||||
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
|
||||
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)
|
||||
{
|
||||
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);
|
||||
struct ip6_hdr *hdr = (struct ip6_hdr *)ipv6_layer->hdr_ptr;
|
||||
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)
|
||||
{
|
||||
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);
|
||||
struct ip6_hdr *hdr = (struct ip6_hdr *)ipv6_layer->hdr_ptr;
|
||||
struct ip6_frag *frag_hdr = ipv6_hdr_get_frag_ext(hdr);
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
###############################################################################
|
||||
# log
|
||||
###############################################################################
|
||||
|
||||
add_library(log log.cpp)
|
||||
target_include_directories(log PUBLIC ${CMAKE_CURRENT_LIST_DIR})
|
||||
target_link_libraries(log toml)
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
###############################################################################
|
||||
# gtest
|
||||
###############################################################################
|
||||
|
||||
add_executable(gtest_log gtest_log.cpp)
|
||||
target_link_libraries(gtest_log log gtest)
|
||||
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
###############################################################################
|
||||
# packet
|
||||
###############################################################################
|
||||
|
||||
add_library(packet packet.cpp packet_utils.cpp)
|
||||
add_library(packet packet.cpp)
|
||||
target_include_directories(packet PUBLIC ${CMAKE_CURRENT_LIST_DIR})
|
||||
target_include_directories(packet PUBLIC ${CMAKE_SOURCE_DIR}/deps/uthash)
|
||||
target_link_libraries(packet tuple log)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,10 +11,9 @@ extern "C"
|
||||
#include "tuple.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_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
|
||||
{
|
||||
@@ -61,7 +60,49 @@ enum ldbc_method
|
||||
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;
|
||||
const char *hdr_ptr; // header pointer
|
||||
@@ -71,61 +112,90 @@ struct layer_record
|
||||
uint16_t pld_len; // payload length
|
||||
};
|
||||
|
||||
#define MAX_SID_NUM 8
|
||||
#define MAX_ROUTE_LEN 64
|
||||
|
||||
struct packet
|
||||
{
|
||||
struct layer_record layers[PACKET_MAX_LAYERS];
|
||||
struct layer_record *frag_layer; // fragment layer
|
||||
struct layer layers[PACKET_MAX_LAYERS];
|
||||
struct layer *frag_layer; // fragment layer
|
||||
int8_t layers_used;
|
||||
int8_t layers_size;
|
||||
|
||||
const char *data_ptr;
|
||||
uint16_t data_len;
|
||||
uint64_t domain;
|
||||
bool need_free;
|
||||
|
||||
// metadata
|
||||
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;
|
||||
struct metadata meta;
|
||||
};
|
||||
|
||||
// return innermost payload
|
||||
const char *packet_parse(struct packet *handler, const char *data, uint16_t len);
|
||||
void packet_print(const struct packet *handler);
|
||||
const char *packet_parse(struct packet *pkt, const char *data, uint16_t len);
|
||||
void packet_print(const struct packet *pkt);
|
||||
|
||||
// return 0 : found
|
||||
// return -1 : not found
|
||||
int packet_get_innermost_tuple2(const struct packet *handler, struct tuple2 *tuple);
|
||||
int packet_get_outermost_tuple2(const struct packet *handler, struct tuple2 *tuple);
|
||||
// return 0: found
|
||||
// return -1: not found
|
||||
int packet_get_innermost_tuple2(const struct packet *pkt, struct tuple2 *tuple);
|
||||
int packet_get_outermost_tuple2(const struct packet *pkt, struct tuple2 *tuple);
|
||||
|
||||
// return 0 : found
|
||||
// return -1 : not found
|
||||
int packet_get_innermost_tuple4(const struct packet *handler, struct tuple4 *tuple);
|
||||
int packet_get_outermost_tuple4(const struct packet *handler, struct tuple4 *tuple);
|
||||
// return 0: found
|
||||
// return -1: not found
|
||||
int packet_get_innermost_tuple4(const struct packet *pkt, struct tuple4 *tuple);
|
||||
int packet_get_outermost_tuple4(const struct packet *pkt, struct tuple4 *tuple);
|
||||
|
||||
// return 0 : found
|
||||
// return -1 : not found
|
||||
int packet_get_innermost_tuple6(const struct packet *handler, struct tuple6 *tuple);
|
||||
int packet_get_outermost_tuple6(const struct packet *handler, struct tuple6 *tuple);
|
||||
// return 0: found
|
||||
// return -1: not found
|
||||
int packet_get_innermost_tuple6(const struct packet *pkt, 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_record *packet_get_outermost_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 *packet_get_outermost_layer(const struct packet *pkt, enum layer_type type);
|
||||
|
||||
// direction 1: E2I
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,7 +1,3 @@
|
||||
###############################################################################
|
||||
# gtest
|
||||
###############################################################################
|
||||
|
||||
add_executable(gtest_packet gtest_packet.cpp)
|
||||
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)
|
||||
target_link_libraries(gtest_ipv6_utils packet gtest)
|
||||
|
||||
add_executable(gtest_packet_utils gtest_packet_utils.cpp)
|
||||
target_link_libraries(gtest_packet_utils packet gtest)
|
||||
add_executable(gtest_packet_frag gtest_packet_frag.cpp)
|
||||
target_link_libraries(gtest_packet_frag packet gtest)
|
||||
|
||||
include(GoogleTest)
|
||||
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_ipv4_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
@@ -1,6 +1,6 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "packet_utils.h"
|
||||
#include "packet.h"
|
||||
|
||||
/******************************************************************************
|
||||
* [Protocols in frame: eth:ethertype:ip:data]
|
||||
@@ -44,15 +44,15 @@ unsigned char data1[] = {
|
||||
0x00, 0x00, 0x31, 0x32, 0x33, 0x0a, 0x00, 0x00};
|
||||
|
||||
#if 1
|
||||
TEST(PACKET_UTILS, IPV4_FRAGMENT)
|
||||
TEST(PACKET_FRAG, IPV4_FRAGMENT)
|
||||
{
|
||||
struct packet handler;
|
||||
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);
|
||||
EXPECT_TRUE(dup != NULL);
|
||||
EXPECT_TRUE(paket_is_fragment(dup) == true);
|
||||
EXPECT_TRUE(packet_is_fragment(dup) == true);
|
||||
packet_free(dup);
|
||||
}
|
||||
#endif
|
||||
@@ -152,15 +152,15 @@ unsigned char data2[] = {
|
||||
0x68, 0x68};
|
||||
|
||||
#if 1
|
||||
TEST(PACKET_UTILS, IPV6_FRAGMENT)
|
||||
TEST(PACKET_FRAG, IPV6_FRAGMENT)
|
||||
{
|
||||
struct packet handler;
|
||||
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);
|
||||
EXPECT_TRUE(dup != NULL);
|
||||
EXPECT_TRUE(paket_is_fragment(dup) == true);
|
||||
EXPECT_TRUE(packet_is_fragment(dup) == true);
|
||||
packet_free(dup);
|
||||
}
|
||||
#endif
|
||||
@@ -228,15 +228,15 @@ unsigned char data3[] = {
|
||||
0x04, 0x02};
|
||||
|
||||
#if 1
|
||||
TEST(PACKET_UTILS, IPV4_IPV6_NOT_FRAGMENT)
|
||||
TEST(PACKET_FRAG, IPV4_IPV6_NOT_FRAGMENT)
|
||||
{
|
||||
struct packet handler;
|
||||
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);
|
||||
EXPECT_TRUE(dup != NULL);
|
||||
EXPECT_TRUE(paket_is_fragment(dup) == false);
|
||||
EXPECT_TRUE(packet_is_fragment(dup) == false);
|
||||
packet_free(dup);
|
||||
}
|
||||
#endif
|
||||
@@ -290,15 +290,15 @@ unsigned char data4[] = {
|
||||
0x58, 0x58};
|
||||
|
||||
#if 1
|
||||
TEST(PACKET_UTILS, IPV6_IPV6_NOT_FRAGMENT)
|
||||
TEST(PACKET_FRAG, IPV6_IPV6_NOT_FRAGMENT)
|
||||
{
|
||||
struct packet handler;
|
||||
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);
|
||||
EXPECT_TRUE(dup != NULL);
|
||||
EXPECT_TRUE(paket_is_fragment(dup) == false);
|
||||
EXPECT_TRUE(packet_is_fragment(dup) == false);
|
||||
packet_free(dup);
|
||||
}
|
||||
#endif
|
||||
@@ -1,8 +1,4 @@
|
||||
###############################################################################
|
||||
# packet_io
|
||||
###############################################################################
|
||||
|
||||
add_library(packet_io packet_queue.cpp packet_io.cpp packet_io_dumpfile.cpp packet_io_marsio.cpp)
|
||||
add_library(packet_io packet_io_dumpfile.cpp packet_io_marsio.cpp lock_free_queue.cpp packet_io.cpp)
|
||||
target_include_directories(packet_io PUBLIC ${CMAKE_CURRENT_LIST_DIR})
|
||||
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)
|
||||
@@ -2,11 +2,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "packet_io.h"
|
||||
#include "packet_utils.h"
|
||||
#include "packet_queue.h"
|
||||
#include "stellar.h"
|
||||
#include "lock_free_queue.h"
|
||||
|
||||
struct packet_queue
|
||||
struct lock_free_queue
|
||||
{
|
||||
uint64_t *queue;
|
||||
uint32_t size;
|
||||
@@ -14,19 +13,19 @@ struct packet_queue
|
||||
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)
|
||||
{
|
||||
PACKET_IO_LOG_ERROR("unable to alloc packet queue");
|
||||
LOCK_FREE_QUEUE_LOG_ERROR("unable to new lock free queue");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
queue->queue = (uint64_t *)calloc(size, sizeof(uint64_t));
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
@@ -38,22 +37,17 @@ struct packet_queue *packet_queue_new(uint32_t size)
|
||||
return queue;
|
||||
}
|
||||
|
||||
void packet_queue_free(struct packet_queue *queue)
|
||||
void lock_free_queue_free(struct lock_free_queue *queue)
|
||||
{
|
||||
if (queue == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
struct packet *pkt = NULL;
|
||||
while (1)
|
||||
// wait queue is empty
|
||||
while (queue->head != queue->tail)
|
||||
{
|
||||
packet_queue_pop(queue, &pkt);
|
||||
if (pkt == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
packet_free(pkt);
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
if (queue->queue)
|
||||
@@ -65,13 +59,13 @@ void packet_queue_free(struct packet_queue *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;
|
||||
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);
|
||||
wait *= 2;
|
||||
goto retry;
|
||||
@@ -80,15 +74,15 @@ retry:
|
||||
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]);
|
||||
if (read == 0)
|
||||
{
|
||||
*pkt = NULL;
|
||||
*data = NULL;
|
||||
return;
|
||||
}
|
||||
__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;
|
||||
}
|
||||
26
src/packet_io/lock_free_queue.h
Normal file
26
src/packet_io/lock_free_queue.h
Normal 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
|
||||
@@ -5,22 +5,26 @@
|
||||
#include "packet_io_marsio.h"
|
||||
#include "packet_io_dumpfile.h"
|
||||
|
||||
typedef void *new_cb(void *options);
|
||||
typedef void free_cb(void *handle);
|
||||
typedef void *stat_cb(void *handle);
|
||||
typedef int init_cb(void *handle, uint16_t thread_id);
|
||||
typedef int recv_cb(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_new(void *options);
|
||||
typedef void on_free(void *handle);
|
||||
typedef void *on_stat(void *handle);
|
||||
typedef int on_init(void *handle, uint16_t thread_id);
|
||||
typedef int on_recv(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
|
||||
{
|
||||
void *handle;
|
||||
new_cb *on_new;
|
||||
free_cb *on_free;
|
||||
stat_cb *on_stat;
|
||||
init_cb *on_init;
|
||||
recv_cb *on_recv;
|
||||
send_cb *on_send;
|
||||
on_new *new_func;
|
||||
on_free *free_func;
|
||||
on_stat *stat_func;
|
||||
on_init *init_func;
|
||||
on_recv *recv_func;
|
||||
on_send *send_func;
|
||||
on_drop *drop_func;
|
||||
on_inject *inject_func;
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
struct packet_io_marsio_opts marsio_opts;
|
||||
strncpy(marsio_opts.app_symbol, opts->app_symbol, sizeof(marsio_opts.app_symbol));
|
||||
strncpy(marsio_opts.dev_symbol, opts->dev_symbol, sizeof(marsio_opts.dev_symbol));
|
||||
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;
|
||||
struct packet_io_marsio_options opts_marsio;
|
||||
struct packet_io_dumpfile_options opts_dumpfile;
|
||||
void *opts_ptr = NULL;
|
||||
|
||||
if (opts->mode == PACKET_IO_MARSIO)
|
||||
{
|
||||
_opts = &marsio_opts;
|
||||
handle->on_new = (new_cb *)packet_io_marsio_new;
|
||||
handle->on_free = (free_cb *)packet_io_marsio_free;
|
||||
handle->on_stat = (stat_cb *)packet_io_marsio_stat;
|
||||
handle->on_init = (init_cb *)packet_io_marsio_init;
|
||||
handle->on_recv = (recv_cb *)packet_io_marsio_recv;
|
||||
handle->on_send = (send_cb *)packet_io_marsio_send;
|
||||
strncpy(opts_marsio.app_symbol, opts->app_symbol, sizeof(opts_marsio.app_symbol));
|
||||
strncpy(opts_marsio.dev_symbol, opts->dev_symbol, sizeof(opts_marsio.dev_symbol));
|
||||
memcpy(opts_marsio.cpu_mask, opts->cpu_mask, sizeof(opts_marsio.cpu_mask));
|
||||
opts_marsio.nr_threads = opts->nr_threads;
|
||||
|
||||
opts_ptr = &opts_marsio;
|
||||
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
|
||||
{
|
||||
_opts = &dumpfile_opts;
|
||||
handle->on_new = (new_cb *)packet_io_dumpfile_new;
|
||||
handle->on_free = (free_cb *)packet_io_dumpfile_free;
|
||||
handle->on_stat = (stat_cb *)packet_io_dumpfile_stat;
|
||||
handle->on_init = (init_cb *)packet_io_dumpfile_init;
|
||||
handle->on_recv = (recv_cb *)packet_io_dumpfile_recv;
|
||||
handle->on_send = (send_cb *)packet_io_dumpfile_send;
|
||||
strncpy(opts_dumpfile.dumpfile_dir, opts->dumpfile_dir, sizeof(opts_dumpfile.dumpfile_dir));
|
||||
opts_dumpfile.nr_threads = opts->nr_threads;
|
||||
|
||||
opts_ptr = &opts_dumpfile;
|
||||
handle->new_func = (on_new *)packet_io_dumpfile_new;
|
||||
handle->free_func = (on_free *)packet_io_dumpfile_free;
|
||||
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)
|
||||
{
|
||||
goto error_out;
|
||||
@@ -82,39 +90,40 @@ void packet_io_free(struct packet_io *handle)
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
handle->on_free(handle->handle);
|
||||
handle->free_func(handle->handle);
|
||||
free(handle);
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -55,13 +55,18 @@ struct packet_io_options
|
||||
struct packet_io;
|
||||
struct packet_io *packet_io_new(struct packet_io_options *opts);
|
||||
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);
|
||||
|
||||
// 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);
|
||||
// return number of packets received
|
||||
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_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
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
#include <pcap/pcap.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "stellar.h"
|
||||
#include "file_scan.h"
|
||||
#include "packet_io.h"
|
||||
#include "packet_utils.h"
|
||||
#include "packet_queue.h"
|
||||
#include "lock_free_queue.h"
|
||||
#include "packet_io_dumpfile.h"
|
||||
|
||||
#define MAX_PACKET_QUEUE_SIZE (4096 * 1000)
|
||||
@@ -17,12 +19,18 @@ struct packet_io_dumpfile
|
||||
char dumpfile_dir[256];
|
||||
|
||||
pcap_t *pcap;
|
||||
struct packet_queue *queue[MAX_THREAD_NUM];
|
||||
struct lock_free_queue *queue[MAX_THREAD_NUM];
|
||||
struct packet_io_stat stat;
|
||||
uint64_t io_thread_need_exit;
|
||||
uint64_t io_thread_is_runing;
|
||||
};
|
||||
|
||||
struct pcap_pkt
|
||||
{
|
||||
char *data;
|
||||
int len;
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
* 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 *pkt = packet_new(h->caplen);
|
||||
if (pkt == NULL)
|
||||
// copy packet data to new memory
|
||||
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");
|
||||
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);
|
||||
packet_parse(pkt, pkt->data_ptr, h->caplen);
|
||||
// calculate packet hash
|
||||
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);
|
||||
struct packet_queue *queue = handle->queue[hash % handle->nr_threads];
|
||||
packet_queue_push(queue, pkt);
|
||||
// push packet to queue
|
||||
struct lock_free_queue *queue = handle->queue[hash % handle->nr_threads];
|
||||
lock_free_queue_push(queue, pcap_pkt);
|
||||
|
||||
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;
|
||||
|
||||
PACKET_IO_LOG_STATE("dumpfile %s inprocessing", file)
|
||||
PACKET_IO_LOG_STATE("dumpfile %s in-processing", file)
|
||||
|
||||
handle->pcap = pcap_open_offline(file, NULL);
|
||||
if (handle->pcap == NULL)
|
||||
@@ -91,7 +105,7 @@ static void *dumpfile_thread_cycle(void *arg)
|
||||
* 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;
|
||||
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++)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
packet_queue_free(handle->queue[i]);
|
||||
lock_free_queue_free(handle->queue[i]);
|
||||
}
|
||||
free(handle);
|
||||
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;
|
||||
}
|
||||
@@ -157,55 +171,84 @@ int packet_io_dumpfile_init(struct packet_io_dumpfile *handle, uint16_t thread_i
|
||||
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 packet *pkt = NULL;
|
||||
struct lock_free_queue *queue = handle->queue[thread_id];
|
||||
struct pcap_pkt *pcap_pkt = NULL;
|
||||
int nr_parsed = 0;
|
||||
|
||||
for (int i = 0; i < nr_pkts; i++)
|
||||
{
|
||||
packet_queue_pop(queue, &pkt);
|
||||
if (pkt == NULL)
|
||||
lock_free_queue_pop(queue, (void **)&pcap_pkt);
|
||||
if (pcap_pkt == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
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++];
|
||||
memset(temp, 0, sizeof(struct packet));
|
||||
packet_parse(temp, pkt->data_ptr, pkt->data_len);
|
||||
packet_set_io_ctx(temp, pkt);
|
||||
packet_set_type(temp, PACKET_TYPE_DATA);
|
||||
packet_set_action(temp, PACKET_ACTION_FORWARD);
|
||||
struct packet *pkt = &pkts[nr_parsed++];
|
||||
memset(pkt, 0, sizeof(struct packet));
|
||||
packet_parse(pkt, pcap_pkt->data, pcap_pkt->len);
|
||||
packet_set_user_data(pkt, pcap_pkt);
|
||||
packet_set_type(pkt, PACKET_TYPE_DATA);
|
||||
packet_set_action(pkt, PACKET_ACTION_FORWARD);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
for (int i = 0; i < nr_pkts; i++)
|
||||
{
|
||||
pkt = &pkts[i];
|
||||
|
||||
if (packet_get_action(pkt) == PACKET_ACTION_DROP)
|
||||
{
|
||||
ATOMIC_ADD(&handle->stat.drop_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.drop_bytes, packet_get_len(pkt));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMIC_ADD(&handle->stat.tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.tx_bytes, packet_get_len(pkt));
|
||||
}
|
||||
ATOMIC_ADD(&handle->stat.tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.tx_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 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ extern "C"
|
||||
|
||||
#include "packet.h"
|
||||
|
||||
struct packet_io_dumpfile_opts
|
||||
struct packet_io_dumpfile_options
|
||||
{
|
||||
char dumpfile_dir[256];
|
||||
uint8_t nr_threads;
|
||||
@@ -16,13 +16,18 @@ struct packet_io_dumpfile_opts
|
||||
|
||||
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);
|
||||
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_recv(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
|
||||
void packet_io_dumpfile_send(struct packet_io_dumpfile *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
|
||||
// return number of packets received
|
||||
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
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#include <sched.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <netinet/ether.h>
|
||||
|
||||
#include "stellar.h"
|
||||
#include "marsio.h"
|
||||
#include "packet.h"
|
||||
#include "packet_io.h"
|
||||
#include "packet_utils.h"
|
||||
#include "packet_io_marsio.h"
|
||||
|
||||
struct packet_io_marsio
|
||||
@@ -22,21 +25,25 @@ struct packet_io_marsio
|
||||
|
||||
static void metadata_to_packet(marsio_buff_t *mbuff, struct packet *pkt)
|
||||
{
|
||||
packet_set_io_ctx(pkt, mbuff);
|
||||
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);
|
||||
marsio_buff_get_metadata(mbuff, MR_BUFF_SESSION_ID, &(pkt->session_id), sizeof(pkt->session_id));
|
||||
marsio_buff_get_metadata(mbuff, MR_BUFF_DIR, &(pkt->direction), sizeof(pkt->direction));
|
||||
struct metadata *meta = &pkt->meta;
|
||||
|
||||
packet_set_user_data(pkt, mbuff);
|
||||
meta->sid.used = marsio_buff_get_sid_list(mbuff, meta->sid.list, MAX_SID_NUM);
|
||||
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_action(pkt, PACKET_ACTION_FORWARD);
|
||||
}
|
||||
|
||||
static void metadata_to_mbuff(marsio_buff_t *mbuff, struct packet *pkt)
|
||||
{
|
||||
marsio_buff_set_sid_list(mbuff, pkt->sid_list, pkt->sid_used);
|
||||
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_metadata(mbuff, MR_BUFF_DIR, &(pkt->direction), sizeof(pkt->direction));
|
||||
struct metadata *meta = &pkt->meta;
|
||||
|
||||
marsio_buff_set_sid_list(mbuff, meta->sid.list, meta->sid.used);
|
||||
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)
|
||||
{
|
||||
marsio_buff_set_ctrlbuf(mbuff);
|
||||
@@ -65,7 +72,7 @@ static int is_keepalive_packet(const char *data, int len)
|
||||
* 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;
|
||||
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;
|
||||
}
|
||||
@@ -162,7 +169,7 @@ int packet_io_marsio_init(struct packet_io_marsio *handle, uint16_t thread_id)
|
||||
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_buffs[RX_BURST_MAX];
|
||||
@@ -197,13 +204,38 @@ int packet_io_marsio_recv(struct packet_io_marsio *handle, uint16_t thread_id, s
|
||||
continue;
|
||||
}
|
||||
|
||||
packet_parse(&pkts[nr_parsed], raw_data, raw_len);
|
||||
metadata_to_packet(rx_buff, &pkts[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;
|
||||
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++)
|
||||
{
|
||||
pkt = &pkts[i];
|
||||
tx_buff = (marsio_buff_t *)packet_get_io_ctx(pkt);
|
||||
if (packet_get_action(pkt) == PACKET_ACTION_DROP)
|
||||
tx_buff = (marsio_buff_t *)packet_get_user_data(pkt);
|
||||
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)
|
||||
{
|
||||
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
|
||||
}
|
||||
PACKET_IO_LOG_ERROR("unable to alloc tx buffer");
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
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));
|
||||
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));
|
||||
memcpy(dst, packet_get_data(pkt), 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));
|
||||
|
||||
ATOMIC_ADD(&handle->stat.tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.tx_bytes, packet_get_len(pkt));
|
||||
metadata_to_mbuff(tx_buff, pkt);
|
||||
marsio_send_burst(handle->mr_path, thread_id, &tx_buff, 1);
|
||||
}
|
||||
ATOMIC_ADD(&handle->stat.tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.tx_bytes, packet_get_len(pkt));
|
||||
metadata_to_mbuff(tx_buff, pkt);
|
||||
marsio_send_burst(handle->mr_path, thread_id, &tx_buff, 1);
|
||||
|
||||
fast_end:
|
||||
packet_free(pkt);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ extern "C"
|
||||
|
||||
#include "packet.h"
|
||||
|
||||
struct packet_io_marsio_opts
|
||||
struct packet_io_marsio_options
|
||||
{
|
||||
char app_symbol[64];
|
||||
char dev_symbol[64];
|
||||
@@ -18,13 +18,18 @@ struct packet_io_marsio_opts
|
||||
|
||||
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);
|
||||
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_recv(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
|
||||
void packet_io_marsio_send(struct packet_io_marsio *handle, uint16_t thread_id, struct packet *pkts, int nr_pkts);
|
||||
// return number of packets received
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -1,7 +1,3 @@
|
||||
###############################################################################
|
||||
# session manager
|
||||
###############################################################################
|
||||
|
||||
add_library(session_manager
|
||||
session.cpp
|
||||
session_pool.cpp
|
||||
@@ -11,6 +7,6 @@ add_library(session_manager
|
||||
session_manager.cpp
|
||||
)
|
||||
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)
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <assert.h>
|
||||
|
||||
#include "session_private.h"
|
||||
#include "packet_utils.h"
|
||||
|
||||
#define EX_KEY_MAX_LEN 64
|
||||
|
||||
@@ -506,6 +505,8 @@ const char *session_state_to_str(enum session_state state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case SESSION_STATE_INIT:
|
||||
return "init";
|
||||
case SESSION_STATE_OPENING:
|
||||
return "opening";
|
||||
case SESSION_STATE_ACTIVE:
|
||||
|
||||
@@ -37,10 +37,12 @@ enum udp_state
|
||||
|
||||
enum session_state
|
||||
{
|
||||
SESSION_STATE_OPENING = 0x1,
|
||||
SESSION_STATE_ACTIVE = 0x2,
|
||||
SESSION_STATE_CLOSING = 0x3,
|
||||
SESSION_STATE_CLOSED = 0x4,
|
||||
SESSION_STATE_INIT = 0,
|
||||
SESSION_STATE_OPENING = 1,
|
||||
SESSION_STATE_ACTIVE = 2,
|
||||
SESSION_STATE_CLOSING = 3,
|
||||
SESSION_STATE_CLOSED = 4,
|
||||
SESSION_STATE_MAX = 5,
|
||||
};
|
||||
|
||||
enum session_type
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "stellar.h"
|
||||
#include "timestamp.h"
|
||||
#include "session_private.h"
|
||||
#include "session_pool.h"
|
||||
@@ -10,9 +11,8 @@
|
||||
#include "session_manager.h"
|
||||
#include "tcp_utils.h"
|
||||
#include "udp_utils.h"
|
||||
#include "packet_utils.h"
|
||||
#include "dupkt_filter.h"
|
||||
#include "eviction_filter.h"
|
||||
#include "duplicated_packet_filter.h"
|
||||
#include "evicted_session_filter.h"
|
||||
#include "id_generator.h"
|
||||
|
||||
struct session_manager
|
||||
@@ -23,8 +23,8 @@ struct session_manager
|
||||
struct session_timer *sess_timer;
|
||||
struct session_queue *sess_evicted_queue;
|
||||
|
||||
struct dupkt_filter *tcp_dupkt_filter;
|
||||
struct eviction_filter *udp_eviction_filter;
|
||||
struct duplicated_packet_filter *tcp_dup_pkt_filter;
|
||||
struct evicted_session_filter *udp_evc_sess_filter;
|
||||
|
||||
struct session_manager_options opts;
|
||||
|
||||
@@ -58,6 +58,95 @@ struct session_manager
|
||||
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_handshake_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 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 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 void session_update_tcp_state(struct session *sess, const struct layer_record *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_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 *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_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;
|
||||
}
|
||||
|
||||
// TCP duplicate packet filter opts
|
||||
if (opts->tcp_dupkt_filter_enable != 0 && opts->tcp_dupkt_filter_enable != 1)
|
||||
// duplicate packet filter opts
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// UDP eviction filter opts
|
||||
if (opts->udp_eviction_filter_enable != 0 && opts->udp_eviction_filter_enable != 1)
|
||||
// eviction filter opts
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -304,11 +392,6 @@ static inline int session_manager_check_options(struct session_manager_options *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint64_t session_manager_alloc_session_id(void)
|
||||
{
|
||||
return id_generator_get();
|
||||
}
|
||||
|
||||
// return 1: 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)
|
||||
@@ -338,13 +421,13 @@ static inline int session_manager_update_tcp_filter(struct session_manager *mgr,
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
dupkt_filter_add(mgr->tcp_dupkt_filter, pkt);
|
||||
duplicated_packet_filter_add(mgr->tcp_dup_pkt_filter, pkt, timestamp_get_sec());
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
session_init(sess);
|
||||
session_set_id(sess, session_manager_alloc_session_id());
|
||||
session_set_key(sess, key);
|
||||
session_set_key_dir(sess, curr_dir);
|
||||
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_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)
|
||||
@@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
mgr->npkts_miss_l4_proto++;
|
||||
@@ -805,7 +887,7 @@ static inline struct session *session_manager_new_tcp_session(struct session_man
|
||||
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)
|
||||
{
|
||||
@@ -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);
|
||||
|
||||
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_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;
|
||||
}
|
||||
|
||||
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++;
|
||||
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)
|
||||
{
|
||||
@@ -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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
mgr->npkts_miss_l4_proto++;
|
||||
@@ -930,6 +1012,9 @@ static inline int session_manager_update_tcp_session(struct session_manager *mgr
|
||||
|
||||
switch (sess_state)
|
||||
{
|
||||
case SESSION_STATE_INIT:
|
||||
assert(0);
|
||||
break;
|
||||
case SESSION_STATE_OPENING:
|
||||
session_manager_handle_tcp_on_opening(mgr, sess, tcp_old_state, tcp_curr_state);
|
||||
break;
|
||||
@@ -965,6 +1050,9 @@ static inline int session_manager_update_udp_session(struct session_manager *mgr
|
||||
|
||||
switch (sess_state)
|
||||
{
|
||||
case SESSION_STATE_INIT:
|
||||
assert(0);
|
||||
break;
|
||||
case SESSION_STATE_OPENING:
|
||||
session_manager_update_udp_to_active(mgr, sess);
|
||||
break;
|
||||
@@ -977,6 +1065,8 @@ static inline int session_manager_update_udp_session(struct session_manager *mgr
|
||||
case SESSION_STATE_CLOSED:
|
||||
assert(0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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));
|
||||
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);
|
||||
if (mgr->sess_pool == NULL)
|
||||
{
|
||||
@@ -1043,14 +1146,14 @@ struct session_manager *session_manager_new(struct session_manager_options *opts
|
||||
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);
|
||||
if (mgr->tcp_dupkt_filter == NULL)
|
||||
mgr->tcp_dup_pkt_filter = duplicated_packet_filter_new(&dup_pkt_opts, timestamp_get_sec());
|
||||
if (mgr->tcp_dup_pkt_filter == NULL)
|
||||
{
|
||||
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);
|
||||
if (mgr->udp_eviction_filter == NULL)
|
||||
mgr->udp_evc_sess_filter = evicted_session_filter_new(&evc_sess_opts, timestamp_get_sec());
|
||||
if (mgr->udp_evc_sess_filter == NULL)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
@@ -1085,8 +1188,8 @@ void session_manager_free(struct session_manager *mgr)
|
||||
session_manager_free_session(mgr, sess);
|
||||
}
|
||||
|
||||
eviction_filter_free(mgr->udp_eviction_filter);
|
||||
dupkt_filter_free(mgr->tcp_dupkt_filter);
|
||||
evicted_session_filter_free(mgr->udp_evc_sess_filter);
|
||||
duplicated_packet_filter_free(mgr->tcp_dup_pkt_filter);
|
||||
session_queue_free(mgr->sess_evicted_queue);
|
||||
session_timer_free(mgr->sess_timer);
|
||||
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_set_cur_dir(sess, SESSION_DIR_NONE);
|
||||
session_free(sess);
|
||||
session_pool_free(mgr->sess_pool, sess);
|
||||
session_pool_push(mgr->sess_pool, sess);
|
||||
sess = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,17 +33,17 @@ struct session_manager_options
|
||||
// UDP timeout
|
||||
uint64_t udp_timeout_data; // seconds, Range: 1-15,999,999
|
||||
|
||||
// TCP duplicate packet filter
|
||||
uint8_t tcp_dupkt_filter_enable;
|
||||
uint64_t tcp_dupkt_filter_capacity;
|
||||
uint64_t tcp_dupkt_filter_timeout; // seconds, Range: 1-60
|
||||
double tcp_dupkt_filter_error_rate;
|
||||
// duplicate packet filter
|
||||
uint8_t duplicated_packet_filter_enable;
|
||||
uint32_t duplicated_packet_filter_capacity;
|
||||
uint32_t duplicated_packet_filter_timeout; // seconds, Range: 1-60
|
||||
double duplicated_packet_filter_error_rate;
|
||||
|
||||
// UDP eviction filter
|
||||
uint8_t udp_eviction_filter_enable;
|
||||
uint64_t udp_eviction_filter_capacity;
|
||||
uint64_t udp_eviction_filter_timeout; // seconds, Range: 1-60
|
||||
double udp_eviction_filter_error_rate;
|
||||
// evicted session filter
|
||||
uint8_t evicted_session_filter_enable;
|
||||
uint32_t evicted_session_filter_capacity;
|
||||
uint32_t evicted_session_filter_timeout; // seconds, Range: 1-60
|
||||
double evicted_session_filter_error_rate;
|
||||
};
|
||||
|
||||
struct session_manager;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -56,7 +56,7 @@ struct session *session_pool_alloc(struct session_pool *pool)
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -12,8 +12,8 @@ struct session_pool;
|
||||
struct session_pool *session_pool_new(uint64_t count);
|
||||
void session_pool_free(struct session_pool *pool);
|
||||
|
||||
struct session *session_pool_alloc(struct session_pool *pool);
|
||||
void session_pool_free(struct session_pool *pool, struct session *sess);
|
||||
struct session *session_pool_pop(struct session_pool *pool);
|
||||
void session_pool_push(struct session_pool *pool, struct session *sess);
|
||||
uint64_t session_pool_get_count(struct session_pool *pool);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
|
||||
@@ -34,7 +34,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SYN_DUP)
|
||||
char tcp_pkt_c2s_syn_retransmission[1500] = {0};
|
||||
memcpy(tcp_pkt_c2s_syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
|
||||
packet_parse(&pkt, (const char *)tcp_pkt_c2s_syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
|
||||
const struct layer_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);
|
||||
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
|
||||
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};
|
||||
memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
|
||||
packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack));
|
||||
const struct layer_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);
|
||||
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
|
||||
ipv4_hdr_set_ipid(hdr, 0x1234);
|
||||
@@ -110,7 +110,7 @@ TEST(TCP_DUPKT_FILTER_ENABLE, SKIP_FILTER)
|
||||
struct packet pkt;
|
||||
struct session *sess = NULL;
|
||||
struct session_manager *mgr = NULL;
|
||||
const struct layer_record *ipv4_layer;
|
||||
const struct layer *ipv4_layer;
|
||||
struct ip *hdr;
|
||||
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};
|
||||
memcpy(tcp_pkt_c2s_syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
|
||||
packet_parse(&pkt, (const char *)tcp_pkt_c2s_syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
|
||||
const struct layer_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);
|
||||
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
|
||||
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};
|
||||
memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
|
||||
packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack));
|
||||
const struct layer_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);
|
||||
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
|
||||
ipv4_hdr_set_ipid(hdr, 0x1234);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
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);
|
||||
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
|
||||
ipv4_hdr_set_src_addr(hdr, saddr);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
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);
|
||||
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
|
||||
ipv4_hdr_set_src_addr(hdr, saddr);
|
||||
|
||||
@@ -14,42 +14,42 @@ TEST(SESSION_POOL, POP_PUSH)
|
||||
EXPECT_TRUE(sess_pool != NULL);
|
||||
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(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(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(session_pool_get_count(sess_pool) == 0);
|
||||
sess4 = session_pool_alloc(sess_pool);
|
||||
sess4 = session_pool_pop(sess_pool);
|
||||
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);
|
||||
session_pool_free(sess_pool, sess2);
|
||||
session_pool_push(sess_pool, sess2);
|
||||
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);
|
||||
|
||||
sess1 = session_pool_alloc(sess_pool);
|
||||
sess1 = session_pool_pop(sess_pool);
|
||||
EXPECT_TRUE(sess1 != NULL);
|
||||
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(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(session_pool_get_count(sess_pool) == 0);
|
||||
sess4 = session_pool_alloc(sess_pool);
|
||||
sess4 = session_pool_pop(sess_pool);
|
||||
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);
|
||||
session_pool_free(sess_pool, sess2);
|
||||
session_pool_push(sess_pool, sess2);
|
||||
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);
|
||||
|
||||
session_pool_free(sess_pool);
|
||||
|
||||
@@ -41,7 +41,7 @@ static void session_free_callback(struct session *sess, void *arg)
|
||||
if (sess)
|
||||
{
|
||||
struct session_pool *sess_pool = (struct session_pool *)arg;
|
||||
session_pool_free(sess_pool, sess);
|
||||
session_pool_push(sess_pool, sess);
|
||||
sess = NULL;
|
||||
}
|
||||
}
|
||||
@@ -74,17 +74,17 @@ TEST(SESSION_TABLE, OP_SESSION)
|
||||
session_table_set_freecb(sess_table, session_free_callback, sess_pool);
|
||||
|
||||
// Add
|
||||
sess1 = session_pool_alloc(sess_pool);
|
||||
sess1 = session_pool_pop(sess_pool);
|
||||
EXPECT_TRUE(sess1 != NULL);
|
||||
session_set_id(sess1, 1);
|
||||
session_set_key(sess1, &tuple_1);
|
||||
|
||||
sess2 = session_pool_alloc(sess_pool);
|
||||
sess2 = session_pool_pop(sess_pool);
|
||||
EXPECT_TRUE(sess2 != NULL);
|
||||
session_set_id(sess2, 2);
|
||||
session_set_key(sess2, &tuple_2);
|
||||
|
||||
sess3 = session_pool_alloc(sess_pool);
|
||||
sess3 = session_pool_pop(sess_pool);
|
||||
EXPECT_TRUE(sess3 != NULL);
|
||||
session_set_id(sess3, 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_used_session(sess_table) == NULL);
|
||||
|
||||
sess1 = session_pool_alloc(sess_pool);
|
||||
sess1 = session_pool_pop(sess_pool);
|
||||
EXPECT_TRUE(sess1 != NULL);
|
||||
session_set_id(sess1, 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_used_session(sess_table) == sess1);
|
||||
|
||||
sess2 = session_pool_alloc(sess_pool);
|
||||
sess2 = session_pool_pop(sess_pool);
|
||||
EXPECT_TRUE(sess2 != NULL);
|
||||
session_set_id(sess2, 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_used_session(sess_table) == sess2);
|
||||
|
||||
sess3 = session_pool_alloc(sess_pool);
|
||||
sess3 = session_pool_pop(sess_pool);
|
||||
EXPECT_TRUE(sess3 != NULL);
|
||||
session_set_id(sess3, 3);
|
||||
session_set_key(sess3, &tuple_3);
|
||||
|
||||
@@ -193,7 +193,7 @@ TEST(TCP_ACTIVE_TO_CLOSING, BY_C2S_RST)
|
||||
char tcp_pkt_c2s_rst[1500] = {0};
|
||||
memcpy(tcp_pkt_c2s_rst, tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin));
|
||||
packet_parse(&pkt, (const char *)tcp_pkt_c2s_rst, sizeof(tcp_pkt9_c2s_fin));
|
||||
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);
|
||||
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
|
||||
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};
|
||||
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));
|
||||
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);
|
||||
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
|
||||
tcp_hdr_set_flags(hdr, 0);
|
||||
|
||||
@@ -385,7 +385,7 @@ TEST(TCP_INIT_TO_OPENING, BY_SYN_RETRANSMISSION)
|
||||
char tcp_pkt_c2s_syn_retransmission[1500] = {0};
|
||||
memcpy(tcp_pkt_c2s_syn_retransmission, tcp_pkt1_c2s_syn, sizeof(tcp_pkt1_c2s_syn));
|
||||
packet_parse(&pkt, (const char *)tcp_pkt_c2s_syn_retransmission, sizeof(tcp_pkt1_c2s_syn));
|
||||
const struct layer_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);
|
||||
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
|
||||
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};
|
||||
memcpy(tcp_pkt_s2c_synack_retransmission, tcp_pkt2_s2c_syn_ack, sizeof(tcp_pkt2_s2c_syn_ack));
|
||||
packet_parse(&pkt, (const char *)tcp_pkt_s2c_synack_retransmission, sizeof(tcp_pkt2_s2c_syn_ack));
|
||||
const struct layer_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);
|
||||
struct ip *hdr = (struct ip *)ipv4_layer->hdr_ptr;
|
||||
ipv4_hdr_set_ipid(hdr, 0x1234);
|
||||
|
||||
@@ -159,7 +159,7 @@ TEST(TCP_OPENING_TO_CLOSING, BY_C2S_RST)
|
||||
char tcp_pkt_c2s_rst[1500] = {0};
|
||||
memcpy(tcp_pkt_c2s_rst, tcp_pkt9_c2s_fin, sizeof(tcp_pkt9_c2s_fin));
|
||||
packet_parse(&pkt, (const char *)tcp_pkt_c2s_rst, sizeof(tcp_pkt9_c2s_fin));
|
||||
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);
|
||||
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
|
||||
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};
|
||||
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));
|
||||
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);
|
||||
struct tcphdr *hdr = (struct tcphdr *)tcp_layer->hdr_ptr;
|
||||
tcp_hdr_set_flags(hdr, 0);
|
||||
|
||||
@@ -35,17 +35,17 @@ struct session_manager_options opts = {
|
||||
// udp timeout
|
||||
.udp_timeout_data = 2,
|
||||
|
||||
// tcp duplicate packet filter
|
||||
.tcp_dupkt_filter_enable = 1,
|
||||
.tcp_dupkt_filter_capacity = 1000,
|
||||
.tcp_dupkt_filter_timeout = 10,
|
||||
.tcp_dupkt_filter_error_rate = 0.0001,
|
||||
// duplicate packet filter
|
||||
.duplicated_packet_filter_enable = 1,
|
||||
.duplicated_packet_filter_capacity = 1000,
|
||||
.duplicated_packet_filter_timeout = 10,
|
||||
.duplicated_packet_filter_error_rate = 0.0001,
|
||||
|
||||
// udp eviction filter
|
||||
.udp_eviction_filter_enable = 1,
|
||||
.udp_eviction_filter_capacity = 1000,
|
||||
.udp_eviction_filter_timeout = 10,
|
||||
.udp_eviction_filter_error_rate = 0.0001,
|
||||
// evicted session filter
|
||||
.evicted_session_filter_enable = 1,
|
||||
.evicted_session_filter_capacity = 1000,
|
||||
.evicted_session_filter_timeout = 10,
|
||||
.evicted_session_filter_error_rate = 0.0001,
|
||||
};
|
||||
|
||||
__attribute__((unused)) static void __session_dispatch(struct session *sess)
|
||||
|
||||
@@ -131,28 +131,29 @@ static void *main_loop(void *arg)
|
||||
struct thread_context *threads_ctx = (struct thread_context *)arg;
|
||||
struct packet_io *packet_io = stellar_ctx->packet_io;
|
||||
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_ctx = NULL;
|
||||
|
||||
int nr_recv;
|
||||
uint16_t thd_idx = threads_ctx->index;
|
||||
uint64_t now_msec = 0;
|
||||
int need_drop_pkt = 1; // TODO
|
||||
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");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ATOMIC_SET(&threads_ctx->is_runing, 1);
|
||||
thread_set_name("stellar", thd_idx);
|
||||
STELLAR_LOG_STATE("worker thread %d runing", thd_idx);
|
||||
thread_set_name("stellar", thr_idx);
|
||||
STELLAR_LOG_STATE("worker thread %d runing", thr_idx);
|
||||
|
||||
while (ATOMIC_READ(&threads_ctx->need_exit) == 0)
|
||||
{
|
||||
now_msec = timestamp_get_msec();
|
||||
nr_recv = packet_io_ingress(packet_io, thd_idx, packets, RX_BURST_MAX);
|
||||
now_sec = timestamp_get_sec(); // TODO
|
||||
nr_recv = packet_io_ingress(packet_io, thr_idx, packets, RX_BURST_MAX);
|
||||
if (nr_recv == 0)
|
||||
{
|
||||
goto idle_tasks;
|
||||
@@ -162,53 +163,66 @@ static void *main_loop(void *arg)
|
||||
{
|
||||
pkt = &packets[i];
|
||||
|
||||
// TODO
|
||||
// call packet plugin
|
||||
|
||||
// ip fragment reassemble
|
||||
if (pkt->frag_layer)
|
||||
// call plugin_manager_dispatch_raw_pkt();
|
||||
if (packet_is_fragment(pkt))
|
||||
{
|
||||
struct packet *temp = ip_reassembly_packet(ip_mgr, pkt);
|
||||
packet_io_egress(packet_io, thd_idx, pkt, 1); // forward the original fragment packet
|
||||
if (temp == NULL)
|
||||
struct packet *defraged_pkt = ip_reassembly_packet(ip_reass, pkt, now_sec);
|
||||
if (defraged_pkt == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
if (sess == NULL)
|
||||
{
|
||||
sess = session_manager_new_session(sess_mgr, pkt);
|
||||
if (sess == NULL)
|
||||
{
|
||||
// 1.Not TCP or UDP
|
||||
// 2.UDP evict packet
|
||||
// 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;
|
||||
|
||||
continue;
|
||||
}
|
||||
plug_mgr_ctx = plugin_manager_new_ctx();
|
||||
session_set_id(sess, id_generator_alloc(now_sec, thr_idx));
|
||||
session_set_user_data(sess, plug_mgr_ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (session_manager_update_session(sess_mgr, sess, pkt) == -1)
|
||||
{
|
||||
// TCP duplicate packet
|
||||
goto fast_forward;
|
||||
}
|
||||
session_manager_update_session(sess_mgr, sess, pkt);
|
||||
}
|
||||
plugin_manager_dispatch(plug_mgr, sess, pkt);
|
||||
}
|
||||
|
||||
fast_forward:
|
||||
packet_io_egress(packet_io, thd_idx, pkt, 1);
|
||||
if (unlikely(need_drop_pkt))
|
||||
{
|
||||
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);
|
||||
if (evicted_sess)
|
||||
{
|
||||
@@ -218,9 +232,7 @@ static void *main_loop(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
idle_tasks:
|
||||
expired_sess = session_manager_get_expired_session(sess_mgr);
|
||||
if (expired_sess)
|
||||
while ((expired_sess = session_manager_get_expired_session(sess_mgr)))
|
||||
{
|
||||
plug_mgr_ctx = session_get_user_data(expired_sess);
|
||||
plugin_manager_free_ctx(plug_mgr_ctx);
|
||||
@@ -234,7 +246,7 @@ static void *main_loop(void *arg)
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -331,13 +343,13 @@ int main(int argc, char **argv)
|
||||
|
||||
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");
|
||||
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)
|
||||
{
|
||||
@@ -380,7 +392,6 @@ error_out:
|
||||
|
||||
// TODO free plugin
|
||||
|
||||
id_generator_free();
|
||||
log_free();
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -19,6 +19,9 @@ extern "C"
|
||||
#define ATOMIC_SET(x, y) __atomic_store_n(x, y, __ATOMIC_RELAXED)
|
||||
#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
|
||||
static __attribute__((__used__)) const char *__stellar_version = STELLAR_GIT_VERSION;
|
||||
#else
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
###############################################################################
|
||||
# gtest
|
||||
###############################################################################
|
||||
|
||||
add_executable(gtest_timestamp gtest_timestamp.cpp)
|
||||
target_link_libraries(gtest_timestamp timestamp gtest)
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
###############################################################################
|
||||
# tuple
|
||||
###############################################################################
|
||||
|
||||
add_library(tuple tuple.cpp)
|
||||
target_include_directories(tuple PUBLIC ${CMAKE_CURRENT_LIST_DIR})
|
||||
target_include_directories(tuple PUBLIC ${CMAKE_SOURCE_DIR}/src/crc32)
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
###############################################################################
|
||||
# gtest
|
||||
###############################################################################
|
||||
|
||||
add_executable(gtest_tuple gtest_tuple.cpp)
|
||||
target_link_libraries(gtest_tuple tuple gtest)
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
memset(out, 0, sizeof(struct tuple2));
|
||||
out->ip_type = in->ip_type;
|
||||
|
||||
if (in->ip_type == IP_TYPE_V4)
|
||||
{
|
||||
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));
|
||||
}
|
||||
memcpy(&out->src_addr, &in->dst_addr, sizeof(in->dst_addr));
|
||||
memcpy(&out->dst_addr, &in->src_addr, sizeof(in->src_addr));
|
||||
}
|
||||
|
||||
void tuple4_reverse(const struct tuple4 *in, struct tuple4 *out)
|
||||
{
|
||||
memset(out, 0, sizeof(struct tuple4));
|
||||
out->ip_type = in->ip_type;
|
||||
out->src_port = in->dst_port;
|
||||
out->dst_port = in->src_port;
|
||||
|
||||
if (in->ip_type == IP_TYPE_V4)
|
||||
{
|
||||
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));
|
||||
}
|
||||
memcpy(&out->src_addr, &in->dst_addr, sizeof(in->dst_addr));
|
||||
memcpy(&out->dst_addr, &in->src_addr, sizeof(in->src_addr));
|
||||
}
|
||||
|
||||
void tuple5_reverse(const struct tuple5 *in, struct tuple5 *out)
|
||||
{
|
||||
memset(out, 0, sizeof(struct tuple5));
|
||||
out->ip_type = in->ip_type;
|
||||
out->ip_proto = in->ip_proto;
|
||||
out->src_port = in->dst_port;
|
||||
out->dst_port = in->src_port;
|
||||
|
||||
if (in->ip_type == IP_TYPE_V4)
|
||||
{
|
||||
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));
|
||||
}
|
||||
memcpy(&out->src_addr, &in->dst_addr, sizeof(in->dst_addr));
|
||||
memcpy(&out->dst_addr, &in->src_addr, sizeof(in->src_addr));
|
||||
}
|
||||
|
||||
void tuple6_reverse(const struct tuple6 *in, struct tuple6 *out)
|
||||
{
|
||||
memset(out, 0, sizeof(struct tuple6));
|
||||
out->ip_type = in->ip_type;
|
||||
out->ip_proto = in->ip_proto;
|
||||
out->domain = in->domain;
|
||||
out->src_port = in->dst_port;
|
||||
out->dst_port = in->src_port;
|
||||
|
||||
if (in->ip_type == IP_TYPE_V4)
|
||||
{
|
||||
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));
|
||||
}
|
||||
memcpy(&out->src_addr, &in->dst_addr, sizeof(in->dst_addr));
|
||||
memcpy(&out->dst_addr, &in->src_addr, sizeof(in->src_addr));
|
||||
}
|
||||
|
||||
void tuple2_to_str(const struct tuple2 *tuple, char *buf, uint32_t size)
|
||||
|
||||
Reference in New Issue
Block a user