#pragma once #include #include #include #include "uthash.h" #include "session_table.h" #include "utils.h" #include "shaper_stat.h" #include "shaper_global_stat.h" #include "shaper_aqm.h" extern "C" { #include "timeout.h" } #define SHAPING_RULE_NUM_MAX 8 #define SHAPING_REF_PROFILE_NUM_MAX 8 #define SHAPING_PRIORITY_NUM_MAX 10 #define SHAPER_FLOW_POP_NUM_MAX 10 #define SESSION_CLOSE 0x1 #define CONFIRM_PRIORITY_PKTS 20 #define SHAPING_WROK_THREAD_NUM_MAX 256 #define SHAPING_STAT_REFRESH_INTERVAL_SEC 2 #define SHAPING_STAT_REFRESH_MAX_PER_POLLING 5 #define NANO_SECONDS_PER_MICRO_SEC 1000 #define MICRO_SECONDS_PER_SEC 1000000 #define NANO_SECONDS_PER_SEC 1000000000 #define NANO_SECONDS_PER_MILLI_SEC 1000000 #define MILLI_SECONDS_PER_SEC 1000 #define SHAPING_GLOBAL_CONF_FILE "./conf/shaping.conf" struct shaping_system_conf { unsigned int session_queue_len_max; unsigned int priority_queue_len_max; unsigned int pkt_max_delay_time_us; int token_multiple_min; int token_multiple_max; int polling_node_num_max[SHAPING_PRIORITY_NUM_MAX]; int work_thread_num; int cpu_affinity_enable; int firewall_sid; cpu_set_t cpu_affinity_mask; int check_rule_enable_interval_sec; }; struct shaping_thread_ctx { pthread_t tid; int thread_index; struct shaping_global_stat_data thread_global_stat; struct shaping_ctx *ref_ctx; struct shaper *sp; struct shaping_stat *stat; struct shaping_marsio_info *marsio_info; struct swarmkv *swarmkv_db;//handle of swarmkv struct shaping_maat_info *maat_info; struct session_table *session_table; struct timeouts *expires; time_t last_update_timeout_sec; int session_need_reset; struct shaping_system_conf conf; }; struct shaping_ctx { int thread_num; struct swarmkv *swarmkv_db;//handle of swarmkv struct shaping_maat_info *maat_info; struct shaping_marsio_info *marsio_info; struct shaping_stat *stat; struct shaping_global_stat *global_stat; struct shaping_thread_ctx *thread_ctx; }; enum shaping_packet_dir { SHAPING_DIR_IN = 0, SHAPING_DIR_OUT, SHAPING_DIR_MAX }; enum shaping_packet_action { SHAPING_FORWARD = 0, SHAPING_QUEUED, SHAPING_DROP }; enum shaping_profile_type_in_rule { PROFILE_IN_RULE_TYPE_PRIMARY = 0, PROFILE_IN_RULE_TYPE_BORROW }; enum shaping_profile_type { PROFILE_TYPE_GENERIC, PROFILE_TYPE_HOST_FARINESS, PROFILE_TYPE_MAX_MIN_HOST_FAIRNESS, PROFILE_TYPE_SPLIT_BY_LOCAL_HOST }; enum shaping_profile_limit_direction { PROFILE_LIMIT_DIRECTION_BIDIRECTION, PROFILE_LIMIT_DIRECTION_INCOMING_OUTGOING, }; struct shaper_token_multiple { int token_get_multiple; unsigned char token_not_enough; unsigned char has_failed_get_token; time_t token_multiple_update_time_s; }; struct shaping_profile_hash_node { int id; enum shaper_aqm_type aqm_type; enum shaping_profile_limit_direction limit_direction; long long in_deposit_token_bits[SHAPING_PRIORITY_NUM_MAX]; long long out_deposit_token_bits[SHAPING_PRIORITY_NUM_MAX]; long long bidirection_deposit_token_bits[SHAPING_PRIORITY_NUM_MAX]; long long last_failed_get_token_ms[SHAPING_DIR_MAX]; long long last_hmget_ms; long long queue_len[SHAPING_PRIORITY_NUM_MAX]; long long local_queue_len[SHAPING_PRIORITY_NUM_MAX]; long long local_queue_len_update_time_us[SHAPING_PRIORITY_NUM_MAX]; long long priority_blocked_time_ms[SHAPING_PRIORITY_NUM_MAX]; int hmget_ref_cnt; int tconsume_ref_cnt; unsigned long long last_refresh_time_ms; struct shaper_token_multiple token_multiple; struct shaper_aqm_blue_para aqm_blue_para; struct shaper_aqm_codel_para aqm_codel_para; unsigned char is_invalid; unsigned char async_pass[SHAPING_PRIORITY_NUM_MAX][SHAPING_DIR_MAX]; struct timeout timeout_handle; UT_hash_handle hh; }; struct shaping_profile_info { int id;//profile_id enum shaping_profile_type type; int priority; unsigned char async_pass[SHAPING_DIR_MAX]; long long in_deposit_token_bits; long long out_deposit_token_bits; long long bidirection_deposit_token_bits; long long last_failed_get_token_ms[SHAPING_DIR_MAX]; unsigned long long enqueue_time_us;//to calculate max latency struct shaping_stat_for_profile stat; struct shaping_profile_hash_node *hash_node; }; struct shaping_rule_info { int vsys_id; int id;//rule_id int fair_factor; struct shaping_profile_info primary; struct shaping_profile_info borrowing[SHAPING_REF_PROFILE_NUM_MAX - 1]; int borrowing_num; int is_enabled; }; struct shaping_packet_wrapper { void *pkt_buff; unsigned long long income_time_ns; unsigned long long enqueue_time_us;//first enqueue time unsigned int length; int rule_anchor; int aqm_processed_pf_ids[SHAPING_REF_PROFILE_NUM_MAX]; unsigned char direction; TAILQ_ENTRY(shaping_packet_wrapper) node; }; TAILQ_HEAD(delay_queue, shaping_packet_wrapper); struct metadata { uint64_t session_id; char *raw_data; int raw_len; int dir; int is_tcp_pure_ctrl; int is_ctrl_pkt; uint16_t l7_offset; // only control packet set l7_offset struct sids sids; struct route_ctx route_ctx; }; struct shaping_flow { char *src_ip_str; size_t src_ip_str_len; struct delay_queue packet_queue; int rule_num; struct shaping_rule_info matched_rule_infos[SHAPING_RULE_NUM_MAX]; int priority; unsigned char dscp_enable; unsigned char dscp_value; struct addr_tuple4 tuple4; int anchor;//rule_idx int ref_cnt; unsigned int queue_len; unsigned int flag; struct metadata ctrl_meta; unsigned long long processed_pkts; unsigned long long stat_update_time_us; time_t check_rule_time; }; struct shaper_flow_instance { struct shaping_flow *sf; int priority; }; struct shaping_tconsume_cb_arg { struct shaping_thread_ctx *ctx; struct shaping_profile_info *profile; struct shaping_flow *sf; unsigned char direction; long long start_time_us; }; struct shaping_hmget_cb_arg { struct shaping_thread_ctx *ctx; struct shaping_profile_hash_node *pf_hash_node; long long start_time_us; }; struct shaping_hincrby_cb_arg { struct shaping_thread_ctx *ctx; long long start_time_us; long long queue_len; int profile_id; int priority; int retry_cnt; }; struct shaper;//instance of shaping, thread unsafe struct shaping_flow* shaping_flow_new(struct shaping_thread_ctx *ctx); void shaping_flow_free(struct shaping_thread_ctx *ctx, struct shaping_flow *sf); struct shaper* shaper_new(unsigned int priority_queue_len_max); void shaper_free(struct shaper *sp); bool shaper_queue_empty(struct shaping_flow *sf); void shaper_packet_dequeue(struct shaping_flow *sf); struct shaping_packet_wrapper* shaper_first_pkt_get(struct shaping_flow *sf); void shaper_queue_clear(struct shaping_flow *sf, struct shaping_thread_ctx *ctx); int shaper_flow_in_order_get(struct shaper *sp, struct shaper_flow_instance sf_ins[], int priority, int max_sf_num); void shaper_profile_hash_node_set(struct shaping_thread_ctx *ctx, struct shaping_profile_info *profile); int shaper_global_conf_init(struct shaping_system_conf *conf); void shaper_packet_recv_and_process(struct shaping_thread_ctx *ctx); void shaping_packet_process(struct shaping_thread_ctx *ctx, marsio_buff_t *rx_buff, struct metadata *meta, struct shaping_flow *sf); struct shaping_ctx *shaping_engine_init(); void shaping_engine_destroy(struct shaping_ctx *ctx); void shaper_thread_resource_clear();