#include #include #include #include "config.h" #include "toml.h" // return 0: success // retuun -1: failed static int parse_device_options(struct device_options *dev_opts, toml_table_t *conf_file_handle) { const char *ptr; toml_table_t *device_table; device_table = toml_table_in(conf_file_handle, "device"); if (device_table == NULL) { CONFIG_LOG_ERROR("config file missing device section"); return -1; } ptr = toml_raw_in(device_table, "device_base"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing device.device_base"); return -1; } dev_opts->device_base = atoi(ptr); ptr = toml_raw_in(device_table, "device_offset"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing device.device_offset"); return -1; } dev_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) { const char *ptr; toml_table_t *packet_io_table; toml_array_t *mask_array; packet_io_table = toml_table_in(conf_file_handle, "packet_io"); if (packet_io_table == NULL) { CONFIG_LOG_ERROR("config file missing packet_io section"); return -1; } ptr = toml_raw_in(packet_io_table, "mode"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing packet_io.mode"); return -1; } if (strcmp(ptr, "dumpfile") == 0) { pkt_io_opts->mode = PACKET_IO_DUMPFILE; } else if (strcmp(ptr, "marsio") == 0) { pkt_io_opts->mode = PACKET_IO_MARSIO; } else { CONFIG_LOG_ERROR("config file invalid packet_io.mode %s, only support dumpfile and marsio", ptr); return -1; } if (pkt_io_opts->mode == PACKET_IO_DUMPFILE) { ptr = toml_raw_in(packet_io_table, "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); } else { ptr = toml_raw_in(packet_io_table, "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); ptr = toml_raw_in(packet_io_table, "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); } ptr = toml_raw_in(packet_io_table, "nr_threads"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing packet_io.nr_threads"); return -1; } if (atoi(ptr) <= 0 || atoi(ptr) > MAX_THREAD_NUM) { CONFIG_LOG_ERROR("config file invalid packet_io.nr_threads %d, range [1, %d]", atoi(ptr), MAX_THREAD_NUM); return -1; } pkt_io_opts->nr_threads = atoi(ptr); mask_array = toml_array_in(packet_io_table, "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++) { ptr = toml_raw_at(mask_array, i); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing packet_io.cpu_mask[%d]", i); return -1; } pkt_io_opts->cpu_mask[i] = atoi(ptr); } return 0; } // 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) { const char *ptr; toml_table_t *ip_reass_table; ip_reass_table = toml_table_in(conf_file_handle, "ip_reassembly"); if (ip_reass_table == NULL) { CONFIG_LOG_ERROR("config file missing ip_reassembly section"); return -1; } ptr = toml_raw_in(ip_reass_table, "enable"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing ip_reassembly.enable"); return -1; } ip_reass_opts->enable = atoi(ptr); ptr = toml_raw_in(ip_reass_table, "timeout"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing ip_reassembly.timeout"); return -1; } ip_reass_opts->timeout = atoi(ptr); ptr = toml_raw_in(ip_reass_table, "bucket_entries"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing ip_reassembly.bucket_entries"); return -1; } ip_reass_opts->bucket_entries = atoi(ptr); ptr = toml_raw_in(ip_reass_table, "bucket_num"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing ip_reassembly.bucket_num"); return -1; } ip_reass_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) { const char *ptr; toml_table_t *sess_mgr_table; sess_mgr_table = toml_table_in(conf_file_handle, "session_manager"); if (sess_mgr_table == 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"); 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); ptr = toml_raw_in(sess_mgr_table, "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); // session overload (1: evict old session, 0: bypass new session) ptr = toml_raw_in(sess_mgr_table, "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); ptr = toml_raw_in(sess_mgr_table, "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); // TCP timeout ptr = toml_raw_in(sess_mgr_table, "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); ptr = toml_raw_in(sess_mgr_table, "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); ptr = toml_raw_in(sess_mgr_table, "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); ptr = toml_raw_in(sess_mgr_table, "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); ptr = toml_raw_in(sess_mgr_table, "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); ptr = toml_raw_in(sess_mgr_table, "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); // UDP timeout ptr = toml_raw_in(sess_mgr_table, "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); // TCP duplicate packet filter ptr = toml_raw_in(sess_mgr_table, "tcp_dupkt_filter_enable"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing session_manager.tcp_dupkt_filter_enable"); return -1; } sess_mgr_opts->tcp_dupkt_filter_enable = atoi(ptr); ptr = toml_raw_in(sess_mgr_table, "tcp_dupkt_filter_capacity"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing session_manager.tcp_dupkt_filter_capacity"); return -1; } sess_mgr_opts->tcp_dupkt_filter_capacity = atoll(ptr); ptr = toml_raw_in(sess_mgr_table, "tcp_dupkt_filter_timeout"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing session_manager.tcp_dupkt_filter_timeout"); return -1; } sess_mgr_opts->tcp_dupkt_filter_timeout = atoll(ptr); ptr = toml_raw_in(sess_mgr_table, "tcp_dupkt_filter_error_rate"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing session_manager.tcp_dupkt_filter_error_rate"); return -1; } sess_mgr_opts->tcp_dupkt_filter_error_rate = atof(ptr); // UDP eviction filter ptr = toml_raw_in(sess_mgr_table, "udp_eviction_filter_enable"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing session_manager.udp_eviction_filter_enable"); return -1; } sess_mgr_opts->udp_eviction_filter_enable = atoi(ptr); ptr = toml_raw_in(sess_mgr_table, "udp_eviction_filter_capacity"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing session_manager.udp_eviction_filter_capacity"); return -1; } sess_mgr_opts->udp_eviction_filter_capacity = atoll(ptr); ptr = toml_raw_in(sess_mgr_table, "udp_eviction_filter_timeout"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing session_manager.udp_eviction_filter_timeout"); return -1; } sess_mgr_opts->udp_eviction_filter_timeout = atoll(ptr); ptr = toml_raw_in(sess_mgr_table, "udp_eviction_filter_error_rate"); if (ptr == NULL) { CONFIG_LOG_ERROR("config file missing session_manager.udp_eviction_filter_error_rate"); return -1; } sess_mgr_opts->udp_eviction_filter_error_rate = atof(ptr); return 0; } // return 0: success // retuun -1: failed int config_load(struct config *cfg, const char *cfg_file) { int ret = -1; char errbuf[200]; FILE *fp = NULL; toml_table_t *conf_file_handle = NULL; memset(cfg, 0, sizeof(*cfg)); fp = fopen(cfg_file, "r"); if (fp == NULL) { CONFIG_LOG_ERROR("open config file %s failed, %s", cfg_file, strerror(errno)); goto error_out; } conf_file_handle = toml_parse_file(fp, errbuf, sizeof(errbuf)); if (conf_file_handle == NULL) { CONFIG_LOG_ERROR("parse config file %s failed, %s", cfg_file, errbuf); goto error_out; } if (parse_device_options(&cfg->dev_opts, conf_file_handle) != 0) { goto error_out; } if (parse_packet_io_options(&cfg->pkt_io_opts, conf_file_handle) != 0) { goto error_out; } if (parse_ip_reassembly_options(&cfg->ip_reass_opts, conf_file_handle) != 0) { goto error_out; } if (parse_session_manager_options(&cfg->sess_mgr_opts, conf_file_handle) != 0) { goto error_out; } ret = 0; error_out: if (conf_file_handle) { toml_free(conf_file_handle); } if (fp) { fclose(fp); } return ret; } void config_dump(struct config *cfg) { if (cfg == 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; // device config CONFIG_LOG_DEBUG("device->device_base : %d", dev_opts->device_base); CONFIG_LOG_DEBUG("device->device_offset : %d", dev_opts->device_offset); // packet io config CONFIG_LOG_DEBUG("packet_io->mode : %s", pkt_io_opts->mode == PACKET_IO_DUMPFILE ? "dumpfile" : "marsio"); if (pkt_io_opts->mode == PACKET_IO_DUMPFILE) { CONFIG_LOG_DEBUG("packet_io->dumpfile_dir : %s", pkt_io_opts->dumpfile_dir); } else { CONFIG_LOG_DEBUG("packet_io->app_symbol : %s", pkt_io_opts->app_symbol); CONFIG_LOG_DEBUG("packet_io->dev_symbol : %s", pkt_io_opts->dev_symbol); } CONFIG_LOG_DEBUG("packet_io->nr_threads : %d", pkt_io_opts->nr_threads); for (uint8_t i = 0; i < pkt_io_opts->nr_threads; i++) { CONFIG_LOG_DEBUG("packet_io->cpu_mask[%03d] : %d", i, pkt_io_opts->cpu_mask[i]); } // ip reassemble config CONFIG_LOG_DEBUG("ip_reassembly->enable : %d", ip_reass_opts->enable); CONFIG_LOG_DEBUG("ip_reassembly->timeout : %d", ip_reass_opts->timeout); CONFIG_LOG_DEBUG("ip_reassembly->bucket_entries : %d", ip_reass_opts->bucket_entries); CONFIG_LOG_DEBUG("ip_reassembly->bucket_num : %d", ip_reass_opts->bucket_num); // session manager config CONFIG_LOG_DEBUG("session_manager->max_tcp_session_num : %ld", sess_mgr_opts->max_tcp_session_num); CONFIG_LOG_DEBUG("session_manager->max_udp_session_num : %ld", sess_mgr_opts->max_udp_session_num); CONFIG_LOG_DEBUG("session_manager->tcp_overload_evict_old_sess : %d", sess_mgr_opts->tcp_overload_evict_old_sess); CONFIG_LOG_DEBUG("session_manager->udp_overload_evict_old_sess : %d", sess_mgr_opts->udp_overload_evict_old_sess); CONFIG_LOG_DEBUG("session_manager->tcp_timeout_init : %ld", sess_mgr_opts->tcp_timeout_init); CONFIG_LOG_DEBUG("session_manager->tcp_timeout_handshake : %ld", sess_mgr_opts->tcp_timeout_handshake); CONFIG_LOG_DEBUG("session_manager->tcp_timeout_data : %ld", sess_mgr_opts->tcp_timeout_data); CONFIG_LOG_DEBUG("session_manager->tcp_timeout_half_closed : %ld", sess_mgr_opts->tcp_timeout_half_closed); CONFIG_LOG_DEBUG("session_manager->tcp_timeout_time_wait : %ld", sess_mgr_opts->tcp_timeout_time_wait); CONFIG_LOG_DEBUG("session_manager->tcp_timeout_discard : %ld", sess_mgr_opts->tcp_timeout_discard); 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->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); }