From 31f55f0b88d4af34a8a36497f5e49c69b88b2fbf Mon Sep 17 00:00:00 2001 From: "linuxrc@163.com" Date: Tue, 2 Nov 2021 12:34:05 +0800 Subject: 鍒涘缓 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/MESA/MESA_handle_logger.h | 68 ++++ include/MESA/MESA_htable.h | 425 +++++++++++++++++++++ include/MESA/MESA_list.h | 34 ++ include/MESA/MESA_list_count.h | 31 ++ include/MESA/MESA_list_queue.h | 115 ++++++ include/MESA/MESA_prof_load.h | 189 +++++++++ include/MESA/MESA_tcp_interface.h | 174 +++++++++ include/MESA/Maat_command.h | 192 ++++++++++ include/MESA/Maat_rule.h | 334 ++++++++++++++++ include/MESA/field_stat2.h | 89 +++++ include/MESA/http.h | 236 ++++++++++++ include/MESA/rulescan.h | 324 ++++++++++++++++ include/MESA/sapp_api.h | 63 +++ include/MESA/sapp_cla.h | 42 ++ include/MESA/sapp_limits.h | 24 ++ include/MESA/sapp_state.h | 27 ++ include/MESA/sapp_std.h | 24 ++ include/MESA/sapp_timer.h | 90 +++++ include/MESA/stream.h | 104 +++++ include/MESA/stream_inc/gdev_keepalive.h | 37 ++ include/MESA/stream_inc/sapp_inject.h | 37 ++ include/MESA/stream_inc/stream_base.h | 634 +++++++++++++++++++++++++++++++ include/MESA/stream_inc/stream_bridge.h | 100 +++++ include/MESA/stream_inc/stream_control.h | 342 +++++++++++++++++ include/MESA/stream_inc/stream_entry.h | 98 +++++ include/MESA/stream_inc/stream_inject.h | 282 ++++++++++++++ include/MESA/stream_inc/stream_project.h | 160 ++++++++ include/MESA/stream_inc/stream_proxy.h | 53 +++ include/MESA/stream_inc/stream_rawpkt.h | 112 ++++++ include/MESA/stream_inc/stream_tunnel.h | 104 +++++ include/MESA/wiredLB.h | 70 ++++ include/MESA/wired_cfg.h | 38 ++ 32 files changed, 4652 insertions(+) create mode 100644 include/MESA/MESA_handle_logger.h create mode 100644 include/MESA/MESA_htable.h create mode 100644 include/MESA/MESA_list.h create mode 100644 include/MESA/MESA_list_count.h create mode 100644 include/MESA/MESA_list_queue.h create mode 100644 include/MESA/MESA_prof_load.h create mode 100644 include/MESA/MESA_tcp_interface.h create mode 100644 include/MESA/Maat_command.h create mode 100644 include/MESA/Maat_rule.h create mode 100644 include/MESA/field_stat2.h create mode 100644 include/MESA/http.h create mode 100644 include/MESA/rulescan.h create mode 100644 include/MESA/sapp_api.h create mode 100644 include/MESA/sapp_cla.h create mode 100644 include/MESA/sapp_limits.h create mode 100644 include/MESA/sapp_state.h create mode 100644 include/MESA/sapp_std.h create mode 100644 include/MESA/sapp_timer.h create mode 100644 include/MESA/stream.h create mode 100644 include/MESA/stream_inc/gdev_keepalive.h create mode 100644 include/MESA/stream_inc/sapp_inject.h create mode 100644 include/MESA/stream_inc/stream_base.h create mode 100644 include/MESA/stream_inc/stream_bridge.h create mode 100644 include/MESA/stream_inc/stream_control.h create mode 100644 include/MESA/stream_inc/stream_entry.h create mode 100644 include/MESA/stream_inc/stream_inject.h create mode 100644 include/MESA/stream_inc/stream_project.h create mode 100644 include/MESA/stream_inc/stream_proxy.h create mode 100644 include/MESA/stream_inc/stream_rawpkt.h create mode 100644 include/MESA/stream_inc/stream_tunnel.h create mode 100644 include/MESA/wiredLB.h create mode 100644 include/MESA/wired_cfg.h (limited to 'include') diff --git a/include/MESA/MESA_handle_logger.h b/include/MESA/MESA_handle_logger.h new file mode 100644 index 0000000..c615b53 --- /dev/null +++ b/include/MESA/MESA_handle_logger.h @@ -0,0 +1,68 @@ +#ifndef MESA_HANDLE__LOGGER_H +#define MESA_HANDLE__LOGGER_H + +/* + * runtime_log with handle, + * based on runtime_log. + * yang wei + * create time:2014-03-24 + * version:20140324 + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define RLOG_LV_DEBUG 10 +#define RLOG_LV_INFO 20 +#define RLOG_LV_FATAL 30 + + +#define MESA_HANDLE_RUNTIME_LOG(handle, lv, mod, fmt, args...) \ + MESA_handle_runtime_log((handle), (lv), (mod), "file %s, line %d, " fmt, \ + __FILE__, __LINE__, ##args) + +/* + * name: MESA_create_runtime_log_handle + * functionality: get runtime_log handle; + * params: + * file_path: path of log file, like "./log/runtime_log"; + * level: level of log; + * returns: + * not NULL, if succeeded; + * NULL, if file is not absolute path, or failed to create log file; + */ +void *MESA_create_runtime_log_handle(const char *file_path, int level); + +/* + * name: MESA_handle_runtime_log + * functionality: appends log message to runtime log file; + * params: + * handle:handle of runtime log, which is created by MESA_create_runtime_log_handle; + * level: log level, messages with level value smaller the global var + * "runtime_log_level" are ignored; + * module: name of loggin module; + * fmt: format string; + * returns: + * none; + */ +void MESA_handle_runtime_log(void *handle, int level, const char *module, const char *fmt, ...); + +/* + * name: MESA_destroy_runtime_log_handle + * functionality: release runtime log handle memory. + * params: + * handle: runtime log handle which is going to be released; + * returns: + * none; + */ +void MESA_destroy_runtime_log_handle(void *handle); + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/include/MESA/MESA_htable.h b/include/MESA/MESA_htable.h new file mode 100644 index 0000000..26d976e --- /dev/null +++ b/include/MESA/MESA_htable.h @@ -0,0 +1,425 @@ +#ifndef __MESA_HTABLE_H_ +#define __MESA_HTABLE_H_ +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include + +/* + * general purpose hash table implementation. + * + * xiang hong + * 2002-07-28 + *History: + * 2012-03-23 zhengchao add thread safe option and link expire feature; + * 2014-01-27 lijia add reentrant feature. + */ +#define MESA_HTABLE_VERSION_MACRO (20170104) +extern const unsigned int MESA_HTABLE_VERSION_INT; + +#define MESA_HASH_DEBUG (0) + +#define COMPLEX_KEY_SWITCH (1) + +#define ELIMINATE_TYPE_NUM (1) +#define ELIMINATE_TYPE_TIME (2) +#define ELIMINATE_TYPE_MANUAL (3) /* delete oldest item by manual */ + +typedef void * MESA_htable_handle; + + +#define HASH_MALLOC(_n_) malloc(_n_) +#define HASH_FREE(_p_) free(_p_) + + +#ifndef uchar +#define uchar unsigned char +#endif +#ifndef uint +#define uint unsigned int +#endif + +/* eliminate algorithm */ +#define HASH_ELIMINATE_ALGO_FIFO (0) /* by default */ +#define HASH_ELIMINATE_ALGO_LRU (1) + +/* + * hash key compare function prototype, see hash_key_comp(). + * return value: + * 0:key1 and key2 are equal; + * other:key1 and key2 not equal. + */ +typedef int key_comp_fun_t(const uchar * key1, uint size1, const uchar * key2, uint size2); + +/* + * hash key->index computing function prototype, see hash_key2index(). + */ +typedef uint key2index_fun_t(const MESA_htable_handle table, const uchar * key, uint size); + +/* common HASH algorithm, MESA_htable use BKDR_hash_algo as default, user can choose any one */ +extern uint BKDR_hash_algo(MESA_htable_handle api_table, const uchar *str, uint size); +extern uint APHash_algo(MESA_htable_handle api_table, const uchar *str, uint size); +extern uint murmur3_32_algo(MESA_htable_handle api_table, const uchar* str, uint size) ; + +typedef void MESA_htable_data_free_cbfun_t(void *data); + +typedef int MESA_htable_expire_notify_cbfun_t(void *data, int eliminate_type); + +typedef uchar* MESA_htable_complex_key_dup_cbfun_t(const uchar *key, uint key_size); + +typedef void MESA_htable_complex_key_free_cbfun_t(uchar *key, uint key_size); + +typedef long hash_cb_fun_t(void *data, const uchar *key, uint size, void *user_arg); + +/* + * thread_safe: 0:create hash table without thread safe features; + * positive:the bigger number has more performance, less collide, but less timeout accuracy. + * max number is 1024. + * recursive: 0:can't recursive call MESA_htable_xxx series function + * 1:can recursive call MESA_htable_xxx series function. + * hash_slot_size: how big do you want the table to be, must be 2^N; + * max_elem_num: the maximum elements of the HASH-table,0 means infinite; + * key_comp: hash key compare function, use default function if NULL; + * suggest implement by yourself. + * key2index: hash key->index computing function, use default function if NULL; + * suggest use MESA_htable built-in function. + * data_free: release resources function; + * data_expire_with_condition: + * if expire_time > 0 and data_expire_with_condition != NULL, + * then call this function when an element expired, and give the reason by the 'type' + * if expire_time > 0 and data_expire_with_condition is NULL, + * eliminate the item immediately; + * args: + * data: pointer to attached data; + * type: item eliminate reason, ELIMINATE_TYPE_NUM or ELIMINATE_TYPE_TIME; + * return value of 'data_expire_with_condition': + * 1: the item can be eliminated; + * 0: the item can't be eliminated, renew the item. + * eliminate_type: the algorithm of elimanate a expired element, 0:FIFO; 1:LRU. + * expire_time: the element expire time in second, 0 means infinite. + */ +typedef struct{ + unsigned int thread_safe; + int recursive; + unsigned int hash_slot_size; + unsigned int max_elem_num; + int eliminate_type; + int expire_time; + key_comp_fun_t * key_comp; + key2index_fun_t * key2index; + void (* data_free)(void *data); + int (*data_expire_with_condition)(void *data, int eliminate_type); +#if COMPLEX_KEY_SWITCH + uchar* (*complex_key_dup)(const uchar *key, uint key_size); + void (* complex_key_free)(uchar *key, uint key_size); +#endif +}MESA_htable_create_args_t; + + +/* All of the following functions return value */ +typedef enum{ + MESA_HTABLE_RET_OK = 0, /* success */ + MESA_HTABLE_RET_COMMON_ERR = -1, /* general、undefined errors */ + MESA_HTABLE_RET_ARG_ERR = -2, /* invalid args */ + MESA_HTABLE_RET_NUM_FULL = -3, /* htable number full */ + MESA_HTABLE_RET_QEMPTY = -4, /* htable empty */ + MESA_HTABLE_RET_DUP_ITEM = -5, /* duplicate item */ + MESA_HTABLE_RET_NOT_FOUND = -6, /* not found item */ + MESA_HTABLE_RET_LEN_ERR = -7, /* length error */ + MESA_HTABLE_RET_CANT_GET_LOCK = -8, /* can't get lock in non-block mode */ + MESA_HTABLE_RET_GET_LOCK_TMOUT = -9, /* get lock timeout */ +}MESA_htable_errno_t; + +/* + * You should never use this API to create a hash table, use MESA_htable_born() instead. + * name: MESA_htable_create + * functionality: allocats memory for hash slots, and initialize hash structure; + * param: + * args: argments set; + * args_len: length of argment set; + * returns: + * NULL : error; + * Non-NULL : success; + */ +MESA_htable_handle MESA_htable_create(const MESA_htable_create_args_t *args, int args_struct_len); + +/* + * get total number of HASH element. +*/ +unsigned int MESA_htable_get_elem_num(const MESA_htable_handle table); + +/* + * name: MESA_htable_destroy + * functionality: cleans up hash structure, frees memory occupied; + * param: + * table: who is the victim; + * func: callback function to clean up data attached to hash items, has higher priority level than MESA_htable_data_free_cbfun_t in initialization. + + * returns: + * always returns 0; + */ +int MESA_htable_destroy(MESA_htable_handle table, void (* func)(void *)); + +/* + * name: MESA_htable_add + * functionality: adds item to table, call hash_expire() if elem_count gets + * bigger than threshold_hi, and adjust threshold; + * param: + * table: to which table do you want to add; + * key: what is the label; + * size: how long is the label; + * data: what data do you want to attach; + * returns: + * >0: success,return hash elems' linklist size; + * 0: success. + * <0: error, refer to MESA_htable_errno_t. + */ +int MESA_htable_add(MESA_htable_handle table, const uchar * key, uint size, const void *data); + +/* + TODO, + sturct hash_status{ + uint hlist_max; + uint hlist_max_slot_index; + uint cur_index_hlist_num; + uint hash_value; + }; + + 新增MESA_htable_add_feedback(MESA_htable_handle table, const uchar * key, uint size, const void *data, sturct hash_status *hstat); + 用于返回HASH表的一些关键信息, + +*/ + +#if 0 +/* + * name: hash_add_with_expire + * functionality: adds item to table, than call hash_expire() on its list + * param: + * table: to which table do you want to add; + * key: what is the label; + * size: how long is the label; + * data: what data do you want to attach; + * returns: + * >0 success,return hash elems' linklist size + * -1, duplicates found and can't add this one; + * -2, memory failure; + */ +int MESA_hash_add_with_expire_v3(MESA_htable_inner_t * table, uchar * key, uint size, void * data); + +#endif + + +/* + * name: MESA_htable_del + * functionality: deletes item from table. + * param: + * table: from which table do you want to delete; + * key : what is the label; + * size : how long is the label; + * func : callback function to clean up data attached to hash items, + if this pointer is NULL will call "data_free" in MESA_hash_create(), + * returns: + * 0 : success; + * <0: error, refer to MESA_htable_errno_t. + */ +int MESA_htable_del(MESA_htable_handle table, const uchar * key, uint size, + void (* func)(void *)); +/* + TODO: + 新增MESA_htable_del_with_hash(MESA_htable_handle table, const uchar * key, uint size, uint hash_value, + void (* func)(void *)); + 删除时带入之前的hash_value, 减少一次hash计算开销, +*/ + + +/* + * name: MESA_htable_del_oldest_manual + * functionality: deletes oldest item from table. + * param: + * table: from which table do you want to delete; + * func : callback function to clean up data attached to hash items, + if this pointer is NULL will call "data_free" in MESA_hash_create(), + * batch_num: delete oldest items. + * returns: + * 0, do nothing ; + * >0, delete items; + */ +int MESA_htable_del_oldest_manual(MESA_htable_handle table, void (* func)(void *), int batch_num); + +/* + * name: MESA_htable_search + * functionality: selects item from table; + * param: + * table: from which table do you want to select; + * key : what is the label; + * size : how long is the label; + * + * return: + * not NULL :pointer to attached data; + * NULL :not found(thus be careful if you are attaching NULL data on purpose). + */ +void *MESA_htable_search(const MESA_htable_handle table, const uchar * key, uint size); + +/* + * name: MESA_htable_search_cb + * functionality: selects item from table, and then call 'cb', reentrant; + * in param: + * table: from which table do you want to select; + * key : what is the label; + * size : how long is the label; + * cb : call this function when found the attached data; + * arg : the argument of "cb" function. + * out param: + * cb_ret: the return value of the function "cb". + * return: + * not NULL :pointer to attached data; + * NULL :not found(thus be careful if you are attaching NULL data on purpose). + */ +void *MESA_htable_search_cb(const MESA_htable_handle table, const uchar * key, uint size, + hash_cb_fun_t *cb, void *arg, long *cb_ret); + +/* + * name: MESA_htable_iterate + * functionality: iterates each hash item; + * params: + * table: what table is to be iterated; + * func: what do you want to do to each attached data item; + * returns: + * 0: iterates all items; + * -1: error; + */ +int MESA_htable_iterate(MESA_htable_handle table, + void (* func)(const uchar * key, uint size, void * data, void *user), void * user); + + +/* + * name: MESA_htable_iterate_bytime + * functionality: iterates each hash item by your demand; + * note: + * if 'thread_safe' more than one, this function is not correct. + * params: + * table: what table is to be iterated; + * iterate_type: 1: newest item first; 2: oldest item first; + * iterate_cb: what do you want to do to each attached data item; + * return value of iterate_cb: + * refer to ITERATE_CB_RET_xxx; + * returns: + * 0: iterates all items; + * -1: uncomplete break. + * -2: error; + */ +#define ITERATE_CB_RET_CONTINUE_FLAG (0) /* default, like MESA_htable_iterate() */ +#define ITERATE_CB_RET_BREAK_FLAG (1<<1) /* break iterate, return from MESA_htable_iterate_bytime() immediately */ +#define ITERATE_CB_RET_DEL_FLAG (1<<2) /* del this item, like but faster than call MESA_htable_del() */ +#define ITERATE_CB_RET_REVERSE_FLAG (1<<3) /* if the item is newest item, it will become the oldest item, and vice versa */ +#define ITERATE_CB_RET_REMOVE_BUT_NOT_FREE (1<<4) /* only remove the item from Hash table, but don't free the attached data, be careful */ + +#define ITERATE_TYPE_NEWEST_FIRST (1) +#define ITERATE_TYPE_OLDEST_FIRST (2) +int MESA_htable_iterate_bytime(MESA_htable_handle table, int iterate_type, + int (*iterate_cb)(const uchar * key, uint size, void * data, void *user), void * user); + +/* + args: + print_switch: + 0: disable print message; + 1: enable print message; +*/ +void MESA_htable_print_crtl(MESA_htable_handle table, int print_switch); + + +/* + Create a htable handle and Alloc memory, and set default option, + but can't running before call MESA_htable_mature(). + + return value: + not NULL: success. + NULL : error. +*/ +MESA_htable_handle MESA_htable_born(void); + +/* + MESA_htable option definition. +*/ +enum MESA_htable_opt{ + MHO_THREAD_SAFE = 0, /* must be int, 1:create hash table with thread safe features, default is 0 */ + MHO_MUTEX_NUM, /* must be int, valid only if MHO_THREAD_SAFE is not zero, max value is 1024, defalut is 1. the bigger number has more performance and less mutex collide, but less timeout accuracy */ + MHO_HASH_SLOT_SIZE, /* must be unsigned int, default is 1048576. */ + MHO_HASH_MAX_ELEMENT_NUM, /* must be unsigned int, defalut is 0, means infinite */ + MHO_EXPIRE_TIME, /* must be int, defalut is 0, means infinite */ + MHO_ELIMIMINATE_TYPE, /* must be int, valid only if MHO_EXPIRE_TIME is not zero. HASH_ELIMINATE_ALGO_FIFO or HASH_ELIMINATE_ALGO_LRU, defalut HASH_ELIMINATE_ALGO_FIFO */ + MHO_CBFUN_KEY_COMPARE, /* must be key_comp_fun_t, hash key compare function, use default function if NULL */ + MHO_CBFUN_KEY_TO_INDEX, /* must be key2index_fun_t, hash key->index computing function, use default function if NULL */ + MHO_CBFUN_DATA_FREE, /* must be MESA_htable_data_free_cbfun_t, release resources function */ + /* data_expire_notify, must be MESA_htable_expire_notify_cbfun_t, + * if expire_time > 0 and data_expire_notify != NULL, + * then call this function when an element expired, and give the reason by the 'type' + * if expire_time > 0 and data_expire_notify is NULL, + * eliminate the item immediately; + * args: + * data: pointer to attached data; + * type: item eliminate reason, ELIMINATE_TYPE_NUM or ELIMINATE_TYPE_TIME; + * return value of 'data_expire_with_condition': + * 1: the item can be eliminated; + * 0: the item can't be eliminated, renew the item. + */ + MHO_CBFUN_DATA_EXPIRE_NOTIFY, + MHO_CBFUN_COMPLEX_KEY_DUP, /* must be MESA_htable_complex_key_dup_cbfun_t, if key store in a complex struct, caller must be implement this duplicate function. */ + MHO_CBFUN_COMPLEX_KEY_FREE, /* must be MESA_htable_complex_key_free_cbfun_t, if key store in a complex struct, caller must be implement this duplicate function. */ + MHO_AUTO_UPDATE_TIME, /* must be int, create a background thread used to update current_time instead of time(NULL). 1:enable; 0:disable; default value is 0; */ + MHO_SCREEN_PRINT_CTRL, /* must be int, 1:enable screen print; 0:disable screen print; default is 1. */ + MHO_HASH_LIST_COLLIDE_THRESHOLD, /* must be int, write log when hash collide number more than this, default is 100, 0 means infinite. */ + MHO_HASH_LOG_FILE, /* must be char * with EOF, default is "./log/htable_runtime_%p_%t.log", opt_len is strlen(optval) */ + MHO_HASH_SEARCH_MAX_TIMES, /* must be int, max compare items in once MESA_htable_search() */ + MHO_HASH_SEARCH_AVG_TIMES, /* must be double, average compare items in all previous MESA_htable_search() */ + MHO_AUTO_EXPAND_MULTIPLE, /* must be int, used for save memory, default is 0, if this option value bigger than zero, user should set small SLOT_SIZE in initialization, htable will auto expand SLOT_SIZE if many colliding happen. */ + __MHO_MAX_VAL, /* caller can't use this definition, it's value maybe changed in next version!! */ +}; + + +/* + to set features of specified MESA_htable handle. + opt_type: option type, refer to enum MESA_htable_opt; + opt_val : option value, depend on opt type; + opt_len : opt_val size, depend on opt type; + + return value: + 0 :success; + <0:error; +*/ +int MESA_htable_set_opt(MESA_htable_handle table, enum MESA_htable_opt opt_type, void *opt_val, int opt_len); + +/* + to get features of specified MESA_htable handle. + opt_type: option type, refer to enum MESA_htable_opt; + opt_val : option value, depend on opt type; + opt_len : value-result argument, opt_val size, depend on opt type; + + return value: + 0 :success; + <0:error; +*/ +int MESA_htable_get_opt(MESA_htable_handle api_table, enum MESA_htable_opt opt_type, void *opt_val, int *opt_len); + +/* + Construct htable and ready to running. + + return value: + 0 : success; + <0: error. +*/ +int MESA_htable_mature(MESA_htable_handle table); + + +#ifdef __cplusplus +} +#endif + +#endif /* _LIB_HASH_H_INCLUDED_ */ + + diff --git a/include/MESA/MESA_list.h b/include/MESA/MESA_list.h new file mode 100644 index 0000000..6ad7c45 --- /dev/null +++ b/include/MESA/MESA_list.h @@ -0,0 +1,34 @@ +#ifndef _MESA_LIST_H_ +#define _MESA_LIST_H_ + +typedef struct MESA_list{ + struct MESA_list *nextele; + struct MESA_list *preele; + void *quiddity; +}MESA_list_t; + + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define MESA_LIST_VERSION_MACRO (20150529) +extern const unsigned int MESA_LIST_VERSION_INT; + +void MESA_list_init_head(struct MESA_list *head); +int MESA_list_is_empty(const struct MESA_list *head); +void MESA_list_add(struct MESA_list *head, struct MESA_list *new_list); +void MESA_list_add_tail(struct MESA_list *head, struct MESA_list *new_list); +void MESA_list_del(struct MESA_list *head, struct MESA_list *del_list); +void MESA_list_move(struct MESA_list *head, struct MESA_list *list); +void MESA_list_move_tail(struct MESA_list *head, struct MESA_list *list); +struct MESA_list *MESA_list_join_n(struct MESA_list *head, struct MESA_list *op_place, struct MESA_list *new_obj); +struct MESA_list *MESA_list_join_p(struct MESA_list *head, struct MESA_list *new_obj, struct MESA_list *op_place); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/MESA/MESA_list_count.h b/include/MESA/MESA_list_count.h new file mode 100644 index 0000000..884ee74 --- /dev/null +++ b/include/MESA/MESA_list_count.h @@ -0,0 +1,31 @@ +#ifndef _MESA_LIST_COUNT_H_ +#define _MESA_LIST_COUNT_H_ + +typedef struct MESA_list_count{ + struct MESA_list_count *nextele; + struct MESA_list_count *preele; + void *quiddity; +}MESA_list_count_t; + +#ifdef __cplusplus +extern "C" +{ +#endif + +void MESA_list_count_init_head(struct MESA_list_count *head); +long MESA_list_count_get_count(const struct MESA_list_count *head); +int MESA_list_count_is_empty(const struct MESA_list_count *head); +void MESA_list_count_add(struct MESA_list_count *head, struct MESA_list_count *new_list); +void MESA_list_count_add_tail(struct MESA_list_count *head, struct MESA_list_count *new_list); +void MESA_list_count_del(struct MESA_list_count *head, struct MESA_list_count *del_list); +void MESA_list_count_move(struct MESA_list_count *head, struct MESA_list_count *list); +void MESA_list_count_move_tail(struct MESA_list_count *head, struct MESA_list_count *list); +struct MESA_list_count *MESA_list_count_join_n(struct MESA_list_count *head, struct MESA_list_count *op_place, struct MESA_list_count *new_obj); +struct MESA_list_count *MESA_list_count_join_p(struct MESA_list_count *head, struct MESA_list_count *new_obj, struct MESA_list_count *op_place); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/MESA/MESA_list_queue.h b/include/MESA/MESA_list_queue.h new file mode 100644 index 0000000..08ce32b --- /dev/null +++ b/include/MESA/MESA_list_queue.h @@ -0,0 +1,115 @@ +#ifndef _MESA_LIST_QUEUE_H_ +#define _MESA_LIST_QUEUE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + MESA_list 第三版, + 1-增加线程安全特性; + 2-隐藏内部结构, 更安全、接口更简洁; + 3-调用者无需自行管理节点结构,使用更方便; +*/ + +#define MESA_LIST_QUEUE_VERSION_MACRO (20160308) +extern const unsigned int MESA_LIST_QUEUE_VERSION_INT; + +#define MESA_LIST_OP_PLACE_HEAD (0x1) +#define MESA_LIST_OP_PLACE_TAIL (0x2) + +#define MESA_list_GET (0x1) +#define MESA_list_JOIN (0x2) + +#define MESA_list_BOLCK (0x4) +#define MESA_list_NONBOLCK (0x8) + +#define MESA_list_JOIN_BLOCK (MESA_list_JOIN|MESA_list_BOLCK) +#define MESA_list_JOIN_NONBLOCK (MESA_list_JOIN|MESA_list_NONBOLCK) +#define MESA_list_GET_BLOCK (MESA_list_GET|MESA_list_BOLCK) +#define MESA_list_GET_NONBLOCK (MESA_list_GET|MESA_list_NONBOLCK) + +typedef void * MESA_lqueue_head; +typedef int (* MESA_lqueue_cb_t)(void *data, long data_len, void *arg); + +/* All of the following functions return value */ +typedef enum{ + MESA_QUEUE_RET_OK = 0, /* success */ + MESA_QUEUE_RET_COMMON_ERR = -1, /* general、undefined errors */ + MESA_QUEUE_RET_ARG_ERR = -2, /* invalid args */ + MESA_QUEUE_RET_NUM_FULL = -3, /* queue number full */ + MESA_QUEUE_RET_MEM_FULL = -4, /* queue memory full */ + MESA_QUEUE_RET_QEMPTY = -5, /* queue empty */ + MESA_QUEUE_RET_LEN_ERR = -6, /* length error */ + MESA_QUEUE_RET_CANT_GET_LOCK = -7, /* can't get lock in non-block mode */ + MESA_QUEUE_RET_GET_LOCK_TMOUT = -8, /* get lock timeout */ +}MESA_queue_errno_t; + +/* + args description: + [IN] + thread_safe : 1:create thread safe queue; 0:without thread safe insurance. + max_item_num: maximum queue items of the queue, 0 means infinity. +*/ +MESA_lqueue_head MESA_lqueue_create(int thread_safe, long max_item_num); + +/* + attention: + The follow two functions is get some value of queue in a moment, + however, the value you got is not exactly, + because it's maybe changed immediately by other thread when this functions is return. +*/ +long MESA_lqueue_get_mem_used(MESA_lqueue_head head); +long MESA_lqueue_get_count(MESA_lqueue_head head); + + +/* + args description: + [IN]: + lq_head : the handler of MESA_lqueue. + + [OUT]: + data : receive buffer. + + [IN && OUT]: + data_len: + is value-result argument, like "addrlen of recvfrom(2)", + the caller should initialize the size of the 'data', + will modified on return to indicate the actual size of the queue item. + +*/ +int MESA_lqueue_read_head(MESA_lqueue_head lq_head, void *data, long *data_len); +int MESA_lqueue_get_head(MESA_lqueue_head lqhead, void *data, long *data_len); + +/* + if return value of "cb" is 0, the behaviour is like MESA_lqueue_read_head(), + else if return value of "cb" is not 0, the behaviour is like MESA_lqueue_get_head(). +*/ +int MESA_lqueue_detect_get_head(MESA_lqueue_head lq_head, MESA_lqueue_cb_t cb, void *data, long *data_len, void *cb_arg); +int MESA_lqueue_get_tail(MESA_lqueue_head lq_head, void *data, long *data_len); + +int MESA_lqueue_join_head(MESA_lqueue_head lq_head, const void *data, long data_len); +int MESA_lqueue_join_tail(MESA_lqueue_head lq_head, const void *data, long data_len); + + +/* these functions features same with above no "try", + except shall return immediately, in other word is "Non-block mode"! + */ +int MESA_lqueue_try_read_head(MESA_lqueue_head lq_head, void *data, long *data_len); +int MESA_lqueue_try_get_head(MESA_lqueue_head lq_head, void *data, long *data_len); +int MESA_lqueue_try_get_tail(MESA_lqueue_head lq_head, void *data, long *data_len); +int MESA_lqueue_try_join_head(MESA_lqueue_head lq_head, const void *data, long data_len); +int MESA_lqueue_try_join_tail(MESA_lqueue_head lq_head, const void *data, long data_len); + + +void MESA_lqueue_destroy(MESA_lqueue_head head, MESA_lqueue_cb_t cb, void *cb_arg); + +const char *MESA_lqueue_strerror(MESA_queue_errno_t error_num); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/MESA/MESA_prof_load.h b/include/MESA/MESA_prof_load.h new file mode 100644 index 0000000..ecfc50f --- /dev/null +++ b/include/MESA/MESA_prof_load.h @@ -0,0 +1,189 @@ +#ifndef SLIB_LOADPROF_H +#define SLIB_LOADPROF_H +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +// Read in specified integer value +// +// Return: +// 0 : success +// < 0 : error, val is set to default +int MESA_load_profile_int_def( + const char *file, // [IN] initialization file path + const char *section, // [IN] section name in initialization file + const char *key, // [IN] keyword name in initialization file + int *val, // [OUT] returned value + const int dval); // [IN] default value + + + +// Read in specified integer value +// +// Return: +// 0 : success +// -1 : failed to get the key,may be have no thie section, key or the val which the key pointed error +// -2 : error ,the val if out of range +int MESA_load_profile_int_nodef( + const char *file, // [IN] initialization file path + const char *section, // [IN] section name in initialization file + const char *key, // [IN] keyword name in initialization file + int *val); // [OUT] returned value + + + + +// Read in specified unsigned integer value +// +// Return: +// 0 : success +// < 0 : error, val is set to default +int MESA_load_profile_uint_def( + const char *file, // [IN] initialization file path + const char *section, // [IN] section name in initialization file + const char *key, // [IN] keyword name in initialization file + unsigned int *val, // [OUT] returned value + const unsigned int dval); // [IN] default value + + + +// Read in specified unsigned integer value +// +// Return: +// 0 : success +// -1 : failed to get the key,may be have no thie section, key or the val which the key pointed error +// -2 : error ,the val if out of range +int MESA_load_profile_uint_nodef( + const char *file, // [IN] initialization file path + const char *section, // [IN] section name in initialization file + const char *key, // [IN] keyword name in initialization file + unsigned int *val); // [OUT] returned value + + + +// Read in specified short integer value +// +// Return: +// 0 : success +// < 0 : error, val is set to default +int MESA_load_profile_short_def( + const char *file, // [IN] initialization file path + const char *section, // [IN] section name in initialization file + const char *key, // [IN] keyword name in initialization file + short *val, // [OUT] returned value + const short dval); // [IN] default value + + + +// Read in specified short integer value +// +// Return: +// 0 : success +// -1 : failed to get the key,may be have no thie section, key or the val which the key pointed error +// -2 : error ,the val if out of range +int MESA_load_profile_short_nodef( + const char *file, // [IN] initialization file path + const char *section, // [IN] section name in initialization file + const char *key, // [IN] keyword name in initialization file + short *val); // [OUT] returned value + + + +// Read in specified string value, +// if value string is too long to return, extra chars truncated. +// prefix/postfix space chars cutted, +// space chars: ' ', '\t' '\n' '\r' +// +// Return: +// >= 0 : length of val +// -1 : failed to get the key,may be have no thie section, key or the val which the key pointed error + +int MESA_load_profile_string_nodef( + const char *file, // [IN] initialization file path + const char *section, // [IN] section name in initialization file + const char *key, // [IN] keyword name in initialization file + char *str, // [OUT] returned string + const size_t size); // [IN] buffer size(bytes) + + + +// Read in specified string value, +// if value string is too long to return, extra chars truncated. +// prefix/postfix space chars cutted, +// space chars: ' ', '\t' '\n' '\r' +// +// Return: +// >= 0 : length of val +// < 0 : error, str is set to default +int MESA_load_profile_string_def( + const char *file, // [IN] initialization file path + const char *section, // [IN] section name in initialization file + const char *key, // [IN] keyword name in initialization file + char *str, // [OUT] returned string + const size_t size, // [IN] buffer size(bytes) + const char *dstr); // [IN] default string + +//read muti unint number from config file, e.g "1-3,5-9" +//return : +// >=0 : success,return the number of uint read from file successfully +// -1 : failed to get the key,may be have no thie section, key or the val which the key pointed error +// -2 : error,invalid uint +int MESA_load_profile_uint_range( + const char *file, // [IN] initialization file path + const char *section, // [IN] section name in initialization file + const char *key, // [IN] keyword name in initialization file + const size_t size, // [IN] the number of unit memory out pointed + unsigned int *out); // [OUT] return ipset network bytes order + +//read ips from config file +//return : +// >=0 : success,return the number of ip read from file successfully +// -1 : failed to get the key,may be have no thie section, key or the val which the key pointed error +// -2 : error,invalid ip + +#if 0 +int MESA_load_profile_ipset( + const char *file, // [IN] initialization file path + const char *section, // [IN] section name in initialization file + const char *key, // [IN] keyword name in initialization file + const size_t size, // [IN] the size of memory ips point,it must equel or greater than ip_num*sizeof(unsigned int) + unsigned int *ipset); // [OUT] return ipset network bytes order + +// Write the a int into specified position of the config file,the position is decided by section and key +// Return: +// >= 0 : success +// -1 : failed to write profile,maybe fopen failed, or malloc failed +int MESA_write_profile_int( + const char *file, // [IN] initialization file path + const char *section, // [IN] section name in initialization file + const char *key, // [IN] keyword name in initialization file + const int value); // [IN] the integer need write + +// Write the a float into specified position of the config file,the position is decided by section and key +// Return: +// >= 0 : success +// -1 : failed to write profile,maybe fopen failed, or malloc failed +int MESA_write_profile_float( + const char *file, // [IN] initialization file path + const char *section, // [IN] section name in initialization file + const char *key, // [IN] keyword name in initialization file + const float value); // [IN] the float need write + +// Write the a string into specified position of the config file,the position is decided by section and key +// Return: +// >= 0 : success +// -1 : failed to write profile,maybe fopen failed, or malloc failed +int MESA_write_profile_string( + const char *file, // [IN] initialization file path + const char *section, // [IN] section name in initialization file + const char *key, // [IN] keyword name in initialization file + const char *value); // [IN] the string need write +#endif +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef SLIB_LOADPROF_H */ diff --git a/include/MESA/MESA_tcp_interface.h b/include/MESA/MESA_tcp_interface.h new file mode 100644 index 0000000..5d95258 --- /dev/null +++ b/include/MESA/MESA_tcp_interface.h @@ -0,0 +1,174 @@ +#ifndef MESA_TCP_INTERFACE_H__ +#define MESA_TCP_INTERFACE_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +/*the optype for MESA_tcp_set*/ +#define MESA_TCP_IO_MODE (0) /*uint32_t, 1: block; 0:nonblock,默认:1*/ +#define MESA_TCP_L_PORT (1) /*uint16_t, 监听端口*/ +#define MESA_TCP_RUNTIME_LOG (2) /*void *, 日志句柄,支持日志输出,默认:NULL*/ +#define MESA_TCP_SOCKHD_LIMIT (3) /*uint32_t, 建立sock句柄上限,默认:1024*/ +#define MESA_TCP_LIMITE_SEND_CACHE (4) /*uint32_t, 链接发送缓存区大小,单位:B ,默认:10M*/ +#define MESA_TCP_LIMITE_RECV_CACHE (5) /*uint32_t,链接接收缓存区大小,单位:B ,默认:10M*/ +#define MESA_TCP_SEND_PTHREAD_AMOUNT (6) /*uint32_t, 发送线程数默认:1*/ +#define MESA_TCP_RECV_PTHREAD_AMOUNT (7) /*uint32_t, 接收线程数默认:1*/ +#define MESA_TCP_CONNECT_TIME (8) /* uint32_t, 连接超时, 单位:s , 默认:5s*/ +#define MESA_TCP_HIGH_SPEED_SEND (9) /*1:on, 0:off,默认:0*/ +#define MESA_TCP_C_PORT (10) /*uint16_t, 客服端绑定端口*/ +#define MESA_TCP_SEND_TIME_OUT (11) /*uint32_t, 连接发送超时,默认为0*/ +#define MESA_TCP_RECV_TIME_OUT (12) /*uint32_t,连接接收超时,默认为0*/ + + +/*使用mesa_tcp_recv_v1 时希望缓存区的大小*/ +#define MESA_TCP_RECV_LEN (1024*2) + + +/*the value for the MESA_tcp_set*/ +#define MESA_TCP_MOD_BLOCK 1 +#define MESA_TCP_MOD_NONBLOCK 0 + +typedef void * MESA_tcp_handle; + + + enum mesa_tcp_state { + MESA_TCP_STATE_CREATE = 0, + MESA_TCP_STATE_ACCEPT, //第一次调用recv + MESA_TCP_STATE_CONTENT, //连接正常 + MESA_TCP_STATE_CLOSE, //连接主动关闭 + MESA_TCP_STATE_DISTORY, //连接被动关闭 + MESA_TCP_STATE_TIME_OUT //连接接收超时 +// MESA_TCP_STATE_WAIT +// MESA_TCP_STATE_RECONTENT +}; + + enum mesa_tcp_peer { + MESA_TCP_PEER_CHUNK_SIZE = 0, /*int */ + MESA_TCP_PEER_CONTEXT , /*void */ + MESA_TCP_PEER_CONTEXT_FREE /*peer_context_free_t */ +}; + +typedef struct _mesa_tcp_snipping_ +{ + int32_t len; + void *data; +}meta_tcp_snipping_t; + +typedef struct _mesa_chunk_ +{ + uint32_t ip; + uint16_t port; + void *data; + uint32_t data_len; + void *peer_context; + enum mesa_tcp_state tcp_state; +}mesa_chunk_t; + +typedef void peer_context_free_t(void *arg); + +/* + * return value: NULL is init fail +*/ +MESA_tcp_handle MESA_tcp_init (void); + +/* + * return: 0: succ < 0:fail + * -8: Opttype类型未知 +*/ +int MESA_tcp_set ( MESA_tcp_handle handle,int optype, void* value); +int MESA_tcp_send (MESA_tcp_handle handle, + uint32_t dst_ip, uint16_t dst_port, + void* pmsg, int msglen, + int thread_id); +int MESA_tcp_send_snipping (MESA_tcp_handle handle, + uint32_t dst_ip, uint16_t dst_port, + meta_tcp_snipping_t *snip, int32_t sn_n, + int thread_id); + +/* + * return: > 0: succ + * == 0: 表示接收超时 + * < 0:fail + * -1:基本出错 + * -3:连接被动关闭 + * -5: 线程ID超过限制值 + * -9:MESA_tcp_recv_chunk和MESA_tcp_recv同时被使用 +*/ +int MESA_tcp_recv (MESA_tcp_handle handle, + void* msgbuf, int buflen, + uint32_t* src_ip, uint16_t* src_port); + +/* + * return: 0: succ + * < 0:fail + * -1:基本出错 + * -5: 线程ID超过限制值 + * -9:MESA_tcp_recv_chunk和MESA_tcp_recv同时被使用 +*/ +int MESA_tcp_recv_chunk(MESA_tcp_handle handle, + uint32_t *ip, uint16_t *port, + void **data_chunk, uint32_t *data_len, + enum mesa_tcp_state *tcp_state, void **peer_context, + uint32_t pthread_id); +int MESA_tcp_r_chunk (MESA_tcp_handle handle, uint32_t pthread_id, mesa_chunk_t *out); +void MESA_tcp_chunk_free (void *data); +int MESA_tcp_set_peer(MESA_tcp_handle handle, + uint32_t ip, uint16_t port, + enum mesa_tcp_peer optype, + char* data,int datalen); +int MESA_tcp_withdraw (MESA_tcp_handle handle, + uint32_t ip , uint32_t port, + void *data, uint32_t data_len); +int MESA_tcp_getlasterror (MESA_tcp_handle handle, + char* msgbuf, int msg_len, + uint32_t ip, uint16_t port); +int MESA_tcp_close (MESA_tcp_handle handle, + uint32_t ip, uint16_t port, + int time_out, + int tid); +int MESA_tcp_destroy (MESA_tcp_handle handle); + + +long MESA_tcp_get_memory_size (MESA_tcp_handle handle); +int MESA_tcp_get_local_ip (MESA_tcp_handle handle); + +/* + ip,port 都是网络字节序 +*/ +MESA_tcp_handle MESA_tcp_init_v1 (void); +int MESA_tcp_set_v1 ( MESA_tcp_handle handle,int optype, void* value); + +/* +return value: + -1, add hash fail + -2, connect fail + -3, tcp interlinkage is broke + -4, epoll mod event fail + -5, limits thread amount + -6, limit buffer size +*/ +int MESA_tcp_send_v1 (MESA_tcp_handle handle, + uint32_t dst_ip, uint16_t dst_port, + void* pmsg, int msglen); + +/* + 只支持单线程调用。 +*/ +int MESA_tcp_recv_v1 (MESA_tcp_handle handle, + void* msgbuf, int buflen, + uint32_t* src_ip, uint16_t* src_port); +int MESA_tcp_close_v1 (MESA_tcp_handle handle, uint32_t ip, uint16_t port); +int MESA_tcp_getlasterror_v1 (MESA_tcp_handle handle, + char* msgbuf, int msg_len, + uint32_t ip, uint16_t port); +int MESA_tcp_destroy_v1 (MESA_tcp_handle handle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/MESA/Maat_command.h b/include/MESA/Maat_command.h new file mode 100644 index 0000000..5e0c6e1 --- /dev/null +++ b/include/MESA/Maat_command.h @@ -0,0 +1,192 @@ +#ifndef H_MAAT_COMMAND_H_INCLUDE +#define H_MAAT_COMMAND_H_INCLUDE +#ifndef __cplusplus +#error("This file should be compiled with C++ compiler") +#endif +#include "Maat_rule.h" +enum MAAT_OPERATION +{ + MAAT_OP_DEL=0, + MAAT_OP_ADD, + MAAT_OP_RENEW_TIMEOUT //Rule expire time is changed to now+cmd->expire_after +}; +enum MAAT_GROUP_RELATION +{ + PARENT_TYPE_COMPILE=0, + PARENT_TYPE_GROUP +}; +enum MAAT_REGION_TYPE +{ + REGION_EXPR, + REGION_IP, + REGION_INTERVAL, + REGION_DIGEST, + REGION_SIMILARITY +}; +enum MAAT_EXPR_TYPE +{ + EXPR_TYPE_STRING=0, + EXPR_TYPE_AND, + EXPR_TYPE_REGEX, + EXPR_TYPE_OFFSET +}; +enum MAAT_MATCH_METHOD +{ + MATCH_METHOD_SUB=0, + MATCH_METHOD_RIGHT, + MATCH_METHOD_LEFT, + MATCH_METHOD_COMPLETE +}; + +enum MAAT_CASE_TYPE +{ + UNCASE_PLAIN=0, + CASE_HEXBIN, + CASE_PLAIN +}; +enum MAAT_ADDR_TYPE +{ + ADDR_TYPE_IPv4=4, + ADDR_TYPE_IPv6=6 +}; +enum MAAT_ADDR_DIRECTION +{ + ADDR_DIR_DOUBLE=0, + ADDR_DIR_SINGLE=1 +}; +struct Maat_rgn_str_t +{ + const char *keywords; + const char *district;// optional for expr_plus, otherwise set to NULL. + enum MAAT_EXPR_TYPE expr_type; + enum MAAT_MATCH_METHOD match_method; + enum MAAT_CASE_TYPE hex_bin; +}; +struct Maat_rgn_addr_t +{ + enum MAAT_ADDR_TYPE addr_type; + const char* src_ip; + const char* mask_src_ip; + const char* dst_ip; + const char* mask_dst_ip; + unsigned short src_port; + unsigned short mask_src_port; + unsigned short dst_port; + unsigned short mask_dst_port; + unsigned short protocol; + enum MAAT_ADDR_DIRECTION direction; +}; +struct Maat_rgn_intv_t +{ + unsigned int low_boundary; + unsigned int up_boundary; +}; +struct Maat_rgn_digest_t +{ + unsigned long long orgin_len; + const char* digest_string; + short confidence_degree; +}; +struct Maat_rgn_sim_t +{ + char* target; + short threshold;// 1~100 +}; +struct Maat_region_t +{ + const char* table_name; + int region_id; //If MAAT_OPT_CMD_AUTO_NUMBERING==1, maat will assigned one. Or users must appoint a unique number. + enum MAAT_REGION_TYPE region_type; + union + { + struct Maat_rgn_str_t expr_rule; + struct Maat_rgn_addr_t ip_rule; + struct Maat_rgn_intv_t interval_rule; + struct Maat_rgn_digest_t digest_rule; + struct Maat_rgn_sim_t similarity_rule; + }; +}; +struct Maat_group_t +{ + const char* table_name; + const char* virtual_table_name; + int group_id; //If MAAT_OPT_CMD_AUTO_NUMBERING==1, maat will assigned one. Or users must assign a unique number. + int parent_id; + int not_flag; + enum MAAT_GROUP_RELATION parent_type; + int region_num; + struct Maat_region_t *regions; +}; +struct Maat_cmd_t +{ + //This Struct MUST alloced by Maat_create_cmd(), then released by Maat_free_cmd(). + struct Maat_rule_t compile; // for MAAT_OP_DEL, only compile.config_id is necessary. + int group_num; // for MAAT_OP_DEL, set to 0. + int expire_after; //expired after $expire_after$ seconds, set to 0 for never timeout. + int label_id; //>0, to be indexed and quried by Maat_cmd_select; =0 not index + struct Maat_group_t* groups;// Add regions with Maat_add_region2cmd +}; +struct Maat_line_t +{ + const char* table_name; + const char* table_line; + int rule_id; // for MAAT_OP_DEL, only rule_id and table_name are necessary. + int label_id; + int expire_after; //expired after $timeout$ seconds, set to 0 for never timeout. +}; +struct Maat_cmd_t* Maat_create_cmd(const struct Maat_rule_t* rule, int group_num); +int Maat_cmd_set_opt(struct Maat_cmd_t* cmd, enum MAAT_RULE_OPT type, const char* val, int size); +//input: which_group 0~group_num +//input: region can be freed after added. +void Maat_add_region2cmd(struct Maat_cmd_t* cmd,int which_group,const struct Maat_region_t* region); + +void Maat_free_cmd(struct Maat_cmd_t* cmd); +int Maat_format_cmd(struct Maat_cmd_t* cmd, char* buffer, int size); +//Input string of REGION_EXPR and REGION_SIMILARITY need to be escapeed. +char* Maat_str_escape(char* dst,int size,const char*src); + +//Deletion failed due to not complete synchronize with Redis. +//To make sure the delete command is excecuted, user should try again after MAAT_OPT_SCANDIR_INTERVAL_MS ms. +//Returns number of successfully updated rule. +//The following functions are NOT thread safe. +int Maat_cmd(Maat_feather_t feather,struct Maat_cmd_t* cmd,enum MAAT_OPERATION op); + +//pipeline model +int Maat_cmd_append(Maat_feather_t feather,struct Maat_cmd_t* cmd,enum MAAT_OPERATION op); + +//Return number of successfully updated rule. +//Return -1 for failed. +int Maat_cmd_commit(Maat_feather_t feather); + + +int Maat_cmd_set_group(Maat_feather_t feather, int group_id, const struct Maat_region_t* region, enum MAAT_OPERATION op); + +//Returns number of successfully updated rule. +//Return -1 for failed. +int Maat_cmd_set_line(Maat_feather_t feather,const struct Maat_line_t* line_rule, enum MAAT_OPERATION op); +int Maat_cmd_set_lines(Maat_feather_t feather,const struct Maat_line_t** line_rule, int line_num ,enum MAAT_OPERATION op); +int Maat_cmd_set_file(Maat_feather_t feather,const char* key, const char* value, size_t size, enum MAAT_OPERATION op); + +//Return the value of key after the increment. +//If the key does not exist, it is set to 0 before performing the operation. +long long Maat_cmd_incrby(Maat_feather_t feather,const char* key, int increment); +struct Maat_cmd_key +{ + char* table_name; + int rule_id; +}; +void Maat_cmd_key_free(struct Maat_cmd_key**keys, int number); +int Maat_cmd_key_select(Maat_feather_t feather, int label_id, struct Maat_cmd_key** keys); +int Maat_cmd_select(Maat_feather_t feather, int label_id, int * output_ids, unsigned int size); +int Maat_cmd_flushDB(Maat_feather_t feather); + +int Maat_command_raw_set_compile(Maat_feather_t feather, enum MAAT_OPERATION op, const struct Maat_rule_t* compile, const char* table_name, const char * huge_service_defined, int group_num); +int Maat_command_raw_set_region(Maat_feather_t feather, enum MAAT_OPERATION op, const struct Maat_region_t* region, int group_id); +int Maat_command_raw_set_group(Maat_feather_t feather, enum MAAT_OPERATION op, const struct Maat_group_t* group); + +int Maat_cmd_get_new_group_id(Maat_feather_t feather); +int Maat_cmd_get_new_region_id(Maat_feather_t feather); + + +#endif + diff --git a/include/MESA/Maat_rule.h b/include/MESA/Maat_rule.h new file mode 100644 index 0000000..c1fe6b5 --- /dev/null +++ b/include/MESA/Maat_rule.h @@ -0,0 +1,334 @@ + +/* +*****************Maat Deep Packet Inspection Policy Framework******** +* Maat is the Goddess of truth and justice in ancient Egyptian concept. +* Her feather was the measure that determined whether the souls (considered +* to reside in the heart) of the departed would reach the paradise of afterlife +* successfully. +* Author: zhengchao@iie.ac.cn, MESA +* Version 2018-12-07 Plugin Extra Data. +* NOTE: MUST compile with G++ +* All right reserved by Institute of Infomation Engineering,Chinese Academic of Science 2014~2018 +********************************************************* +*/ +#ifndef H_MAAT_RULE_H_INCLUDE +#define H_MAAT_RULE_H_INCLUDE +#ifndef __cplusplus +#error("This file should be compiled with C++ compiler") +#endif +#include +enum MAAT_CHARSET +{ + CHARSET_NONE=0, + CHARSET_GBK, + CHARSET_BIG5, + CHARSET_UNICODE, + CHARSET_UTF8, // 4 + CHARSET_BIN, //5 + CHARSET_UNICODE_ASCII_ESC, // Unicode Escape format, prefix backslash-u hex, e.g. "\u627;" + CHARSET_UNICODE_ASCII_ALIGNED,//Unicode Escape format, prefix backslash-u with 4 bytes aligned, e.g. "\u0627" + CHARSET_UNICODE_NCR_DEC, //SGML Numeric character reference,decimal base, e.g. "ا" + CHARSET_UNICODE_NCR_HEX, //SGML Numeric character reference,hexdecimal base, e.g. "ا" + CHARSET_URL_ENCODE_GB2312, //URL encode with GB2312, e.g. the chinese word "china" was encoded to %D6%D0%B9%FA + CHARSET_URL_ENCODE_UTF8, //11, URL encode with UTF8,e.g. the chinese word "china" was encoded to %E4%B8%AD%E5%9B%BD + CHARSET_WINDOWS1251, + __CHARSET_MAX +}; +enum MAAT_ACTION +{ + MAAT_ACTION_BLOCK=0, + MAAT_ACTION_MONIT, + MAAT_ACTION_WHITE +}; +enum MAAT_POS_TYPE +{ + MAAT_POSTYPE_EXPR=0, + MAAT_POSTYPE_REGEX +}; +typedef void* scan_status_t; +typedef void* stream_para_t; +typedef void* Maat_feather_t; + + +#define MAX_SERVICE_DEFINE_LEN 128 +#define MAX_HUGE_SERVICE_DEFINE_LEN (1024*4) +struct Maat_rule_t +{ + int config_id; + int service_id; + char do_log; + char do_blacklist; + char action; + char reserved; + int serv_def_len; + char service_defined[MAX_SERVICE_DEFINE_LEN]; +}; +#define MAAT_RULE_UPDATE_TYPE_FULL 1 +#define MAAT_RULE_UPDATE_TYPE_INC 2 +typedef void Maat_start_callback_t(int update_type,void* u_para); +typedef void Maat_update_callback_t(int table_id,const char* table_line,void* u_para); +typedef void Maat_finish_callback_t(void* u_para); + + + + + +//--------------------HITTING DETAIL DESCRIPTION BEGIN + +#define MAAT_MAX_HIT_RULE_NUM 8 +#define MAAT_MAX_EXPR_ITEM_NUM 8 +#define MAAT_MAX_HIT_POS_NUM 8 +#define MAAT_MAX_REGEX_GROUP_NUM 8 + +//NOTE position buffer as hitting_regex_pos and hit_pos,are ONLY valid before next scan or Maat_stream_scan_string_end +struct regex_pos_t +{ + int group_num; + int hitting_regex_len; + const char* hitting_regex_pos; + int grouping_len[MAAT_MAX_REGEX_GROUP_NUM]; + const char* grouping_pos[MAAT_MAX_REGEX_GROUP_NUM]; +}; +struct str_pos_t +{ + int hit_len; + const char* hit_pos; +}; +struct sub_item_pos_t +{ + enum MAAT_POS_TYPE ruletype; + int hit_cnt; + union + { + struct regex_pos_t regex_pos[MAAT_MAX_HIT_POS_NUM]; + struct str_pos_t substr_pos[MAAT_MAX_HIT_POS_NUM]; + }; +}; + +struct Maat_region_pos_t +{ + + int region_id; + int sub_item_num; + struct sub_item_pos_t sub_item_pos[MAAT_MAX_EXPR_ITEM_NUM]; +}; + +struct Maat_hit_detail_t +{ + int config_id;//set <0 if half hit; + int hit_region_cnt; + struct Maat_region_pos_t region_pos[MAAT_MAX_HIT_RULE_NUM]; +}; +//--------------------HITTING DETAIL DESCRIPTION END + +//Abondon interface ,left for compatible. +Maat_feather_t Maat_summon_feather(int max_thread_num, + const char* table_info_path, + const char* ful_cfg_dir, + const char* inc_cfg_dir, + void*logger);//MESA_handle_logger +//Abondon interface ,left for compatible. +Maat_feather_t Maat_summon_feather_json(int max_thread_num, + const char* table_info_path, + const char* json_rule, + void* logger); + +Maat_feather_t Maat_feather(int max_thread_num,const char* table_info_path,void* logger); +int Maat_initiate_feather(Maat_feather_t feather); + +enum MAAT_INIT_OPT +{ + MAAT_OPT_SCANDIR_INTERVAL_MS=1, //VALUE is interger, SIZE=sizeof(int). DEFAULT:1,000 milliseconds. + MAAT_OPT_EFFECT_INVERVAL_MS, //VALUE is interger, SIZE=sizeof(int). DEFAULT:60,000 milliseconds. + MAAT_OPT_FULL_CFG_DIR, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1.DEFAULT: no default. + MAAT_OPT_INC_CFG_DIR, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1.DEFAULT: no default. + MAAT_OPT_JSON_FILE_PATH, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1.DEFAULT: no default. + MAAT_OPT_STAT_ON, //VALUE is NULL, SIZE is 0. MAAT_OPT_STAT_FILE_PATH must be set. Default: stat OFF. + MAAT_OPT_PERF_ON, //VALUE is NULL, SIZE is 0. MAAT_OPT_STAT_FILE_PATH must be set. Default: stat OFF. + MAAT_OPT_STAT_FILE_PATH, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: no default. + MAAT_OPT_SCAN_DETAIL, //VALUE is interger *, SIZE=sizeof(int). 0: not return any detail;1: return hit pos, not include regex grouping. + // 2 return hit pos and regex grouping pos;DEFAULT:0 + MAAT_OPT_INSTANCE_NAME, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1, no more than 11 bytes.DEFAULT: MAAT_$tableinfo_path$. + MAAT_OPT_DECRYPT_KEY, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. No DEFAULT. + MAAT_OPT_REDIS_IP, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. No DEFAULT. + MAAT_OPT_REDIS_PORT, //VALUE is a unsigned short or a signed int, host order, SIZE= sizeof(unsigned short) or sizeof(int). No DEFAULT. + MAAT_OPT_REDIS_INDEX, //VALUE is interger *, 0~15, SIZE=sizeof(int). DEFAULT: 0. + MAAT_OPT_CMD_AUTO_NUMBERING, //VALUE is a interger *, 1 or 0, SIZE=sizeof(int). DEFAULT: 1. + MAAT_OPT_DEFERRED_LOAD, //VALUE is NULL,SIZE is 0. Default: Deffered initialization OFF. + MAAT_OPT_CUMULATIVE_UPDATE_OFF, //VALUE is NULL,SIZE is 0. Default: CUMMULATIVE UPDATE ON. + MAAT_OPT_LOAD_VERSION_FROM, //VALUE is a long long, SIZE=sizeof(long long). Default: Load the Latest. Only valid in redis mode, and maybe failed for too old. + //This option also disables background update. + MAAT_OPT_ENABLE_UPDATE, //VALUE is interger, SIZE=sizeof(int). 1: Enabled, 0:Disabled. DEFAULT: Backgroud update is enabled. Runtime setting is allowed. + MAAT_OPT_ACCEPT_TAGS, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. Format is a JSON, e.g.{"tags":[{"tag":"location","value":"Beijing/ChaoYang/Huayan/22A"},{"tag":"isp","value":"telecom"}]} + MAAT_OPT_FOREIGN_CONT_DIR, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. Specifies a local diretory to store foreign content. Default: []table_info_path]_files + MAAT_OPT_HITPATH_ON //VALUE is NULL, SIZE is 0. Default: hitpath is OFF. +}; +//return -1 if failed, return 0 on success; +int Maat_set_feather_opt(Maat_feather_t feather,enum MAAT_INIT_OPT type,const void* value,int size); +enum MAAT_STATE_OPT +{ + MAAT_STATE_VERSION=1, //Get current maat version, if maat is in update progress, the updating version is returned. VALUE is long long, SIZE=sizeof(long long). + MAAT_STATE_LAST_UPDATING_TABLE, //Query at Maat_finish_callback_t to determine whether this table is the last one to update. VALUE is interger, SIZE=sizeof(int), 1:yes, 0: no + MAAT_STATE_IN_UPDATING +}; +int Maat_read_state(Maat_feather_t feather, enum MAAT_STATE_OPT type, void* value, int size); + +void Maat_burn_feather(Maat_feather_t feather); + +//return table_id(>=0) if success,otherwise return -1; +int Maat_table_register(Maat_feather_t feather,const char* table_name); +//return 1 if success,otherwise return -1 incase invalid table_id or registed function number exceed 32; +int Maat_table_callback_register(Maat_feather_t feather,short table_id, + Maat_start_callback_t *start,//MAAT_RULE_UPDATE_TYPE_*,u_para + Maat_update_callback_t *update,//table line ,u_para + Maat_finish_callback_t *finish,//u_para + void* u_para); + +#define MAX_HIT_REGION_NUM_PER_GROUP 128 + +struct Maat_hit_path_t +{ + int Nth_scan; + int region_id; + int sub_group_id; + int top_group_id; + int virtual_table_id; // 0 is not a virtual table. + int compile_id; +}; +enum MAAT_SCAN_OPT +{ + MAAT_SET_SCAN_DISTRICT=1, //VALUE is a const char*, SIZE= strlen(string). DEFAULT: no default. + MAAT_SET_SCAN_LAST_REGION, //VALUE is NULL, SIZE=0. This option indicates that the follow scan is the last region of current scan combination. + MAAT_GET_SCAN_HIT_PATH //VALUE is struct Maat_hit_path_t*, an array of struct Maat_hit_path_t, SIZE= sizeof(struct Maat_hit_path_t)*N, + //Maat_get_scan_status returns actual got number. +}; +//return 0 if success, return -1 when failed; +int Maat_set_scan_status(Maat_feather_t feather, scan_status_t* mid, enum MAAT_SCAN_OPT type, const void* value, int size); + +//return >=0 if success, return -1 when failed; +int Maat_get_scan_status(Maat_feather_t feather, scan_status_t* mid, enum MAAT_SCAN_OPT type, void* value, int size); + +//Return hit rule number, return -1 when error occurs,return -2 when hit current region +//mid MUST set to NULL before fist call +int Maat_scan_intval(Maat_feather_t feather,int table_id + ,unsigned int intval + ,struct Maat_rule_t*result,int rule_num + ,scan_status_t *mid,int thread_num); +int Maat_scan_addr(Maat_feather_t feather,int table_id + ,struct ipaddr* addr + ,struct Maat_rule_t*result,int rule_num + ,scan_status_t *mid,int thread_num); +int Maat_scan_proto_addr(Maat_feather_t feather,int table_id + ,struct ipaddr* addr,unsigned short int proto + ,struct Maat_rule_t*result,int rule_num + ,scan_status_t *mid,int thread_num); +int Maat_full_scan_string(Maat_feather_t feather,int table_id + ,enum MAAT_CHARSET charset,const char* data,int data_len + ,struct Maat_rule_t*result,int* found_pos,int rule_num + ,scan_status_t* mid,int thread_num); +//hit_detail could be NULL if not cared. +int Maat_full_scan_string_detail(Maat_feather_t feather,int table_id + ,enum MAAT_CHARSET charset,const char* data,int data_len + ,struct Maat_rule_t*result,int rule_num,struct Maat_hit_detail_t *hit_detail,int detail_num + ,int* detail_ret,scan_status_t* mid,int thread_num); + +stream_para_t Maat_stream_scan_string_start(Maat_feather_t feather,int table_id,int thread_num); +int Maat_stream_scan_string(stream_para_t* stream_para + ,enum MAAT_CHARSET charset,const char* data,int data_len + ,struct Maat_rule_t*result,int* found_pos,int rule_num + ,scan_status_t* mid); +//hited_detail could be NULL if not cared. +int Maat_stream_scan_string_detail(stream_para_t* stream_para + ,enum MAAT_CHARSET charset,const char* data,int data_len + ,struct Maat_rule_t*result,int rule_num,struct Maat_hit_detail_t *hit_detail,int detail_num + ,int* detail_ret,scan_status_t* mid); +void Maat_stream_scan_string_end(stream_para_t* stream_para); + +stream_para_t Maat_stream_scan_digest_start(Maat_feather_t feather,int table_id,unsigned long long total_len,int thread_num); +int Maat_stream_scan_digest(stream_para_t* stream_para + ,const char* data,int data_len,unsigned long long offset + ,struct Maat_rule_t*result,int rule_num + ,scan_status_t* mid); +void Maat_stream_scan_digest_end(stream_para_t* stream_para); + +int Maat_similar_scan_string(Maat_feather_t feather,int table_id + ,const char* data,int data_len + ,struct Maat_rule_t*result,int rule_num + ,scan_status_t* mid,int thread_num); + +void Maat_clean_status(scan_status_t* mid); + +typedef void* MAAT_RULE_EX_DATA; +// The idx parameter is the index: this will be the same value returned by Maat_rule_get_ex_new_index() when the functions were initially registered. +// Finally the argl and argp parameters are the values originally passed to the same corresponding parameters when Maat_rule_get_ex_new_index() was called. +typedef void Maat_rule_EX_new_func_t(int idx, const struct Maat_rule_t* rule, const char* srv_def_large, + MAAT_RULE_EX_DATA* ad, long argl, void *argp); +typedef void Maat_rule_EX_free_func_t(int idx, const struct Maat_rule_t* rule, const char* srv_def_large, + MAAT_RULE_EX_DATA* ad, long argl, void *argp); +typedef void Maat_rule_EX_dup_func_t(int idx, MAAT_RULE_EX_DATA *to, MAAT_RULE_EX_DATA *from, long argl, void *argp); + +int Maat_rule_get_ex_new_index(Maat_feather_t feather, const char* compile_table_name, + Maat_rule_EX_new_func_t* new_func, + Maat_rule_EX_free_func_t* free_func, + Maat_rule_EX_dup_func_t* dup_func, + long argl, void *argp); +//returned data is duplicated by dup_func of Maat_rule_get_ex_new_index, caller is responsible to free the data. +MAAT_RULE_EX_DATA Maat_rule_get_ex_data(Maat_feather_t feather, const struct Maat_rule_t* rule, int idx); + +//Sort rules by their evaluation order. +//rule_array will be modified with sorted rule. +//Return sortted rule number, maybe less than n_rule if some rules are invalid. +size_t Maat_rule_sort_by_evaluation_order(Maat_feather_t feather, struct Maat_rule_t* rule_array, size_t n_rule); + + +//Helper function for parsing space or tab seperated line. +//Nth_column: the Nth column is numberd from 1. +//Return 0 if success. +int Maat_helper_read_column(const char* line, int Nth_column, size_t *column_offset, size_t *column_len); + + +//Following functions are similar to Maat_rule_get_ex_data, except they are effective on plugin table. +typedef void* MAAT_PLUGIN_EX_DATA; +typedef void Maat_plugin_EX_new_func_t(int table_id, const char* key, const char* table_line, MAAT_PLUGIN_EX_DATA* ad, long argl, void *argp); +typedef void Maat_plugin_EX_free_func_t(int table_id, MAAT_PLUGIN_EX_DATA* ad, long argl, void *argp); +typedef void Maat_plugin_EX_dup_func_t(int table_id, MAAT_PLUGIN_EX_DATA *to, MAAT_PLUGIN_EX_DATA *from, long argl, void *argp); +typedef int Maat_plugin_EX_key2index_func_t(const char* key); + +int Maat_plugin_EX_register(Maat_feather_t feather, int table_id, + Maat_plugin_EX_new_func_t* new_func, + Maat_plugin_EX_free_func_t* free_func, + Maat_plugin_EX_dup_func_t* dup_func, + Maat_plugin_EX_key2index_func_t* key2index_func, + long argl, void *argp); +//Data is duplicated by dup_func of Maat_plugin_EX_register, caller is responsible to FREE the data. +MAAT_PLUGIN_EX_DATA Maat_plugin_get_EX_data(Maat_feather_t feather, int table_id, const char* key); + + +int Maat_ip_plugin_EX_register(Maat_feather_t feather, int table_id, + Maat_plugin_EX_new_func_t* new_func, + Maat_plugin_EX_free_func_t* free_func, + Maat_plugin_EX_dup_func_t* dup_func, + long argl, void *argp); + +struct ip_address +{ + int ip_type; //4: IPv4, 6: IPv6 + union + { + unsigned int ipv4; //network order + unsigned int ipv6[4]; + }; +}; + +int Maat_ip_plugin_get_EX_data(Maat_feather_t feather, int table_id, const struct ip_address* ip, MAAT_PLUGIN_EX_DATA* ex_data_array, size_t n_ex_data); + + +enum MAAT_RULE_OPT +{ + MAAT_RULE_SERV_DEFINE //VALUE is a char* buffer,SIZE= buffer size. +}; +int Maat_read_rule(Maat_feather_t feather, const struct Maat_rule_t* rule, enum MAAT_RULE_OPT type, void* value, int size); + + +#endif // H_MAAT_RULE_H_INCLUDE + diff --git a/include/MESA/field_stat2.h b/include/MESA/field_stat2.h new file mode 100644 index 0000000..97e791e --- /dev/null +++ b/include/MESA/field_stat2.h @@ -0,0 +1,89 @@ +#ifndef H_SCREEN_STAT_H_INCLUDE +#define H_SCREEN_STAT_H_INCLUDE +#include + +#ifndef __cplusplus +#error("This file should be compiled with C++ compiler") +#endif + +enum field_dsp_style_t +{ + FS_STYLE_FIELD=0, + FS_STYLE_COLUMN, + FS_STYLE_LINE, + FS_STYLE_STATUS, + FS_STYLE_HISTOGRAM +}; +enum field_calc_algo +{ + FS_CALC_CURRENT=0, + FS_CALC_SPEED +}; +enum field_op +{ + FS_OP_ADD=1, + FS_OP_SET, + FS_OP_SUB +}; + +enum stats_output_format +{ + FS_OUTPUT_STATSD=1, + FS_OUTPUT_INFLUX_LINE=2 +}; + +typedef void* screen_stat_handle_t; + +enum FS_option +{ + OUTPUT_DEVICE, //VALUE is a const char*, indicate a file path string, SIZE = strlen(string+'\0')+1.DEFAULT:output to stdout. + PRINT_MODE, //VALUE is an interger,1:Rewrite ,2: Append. SIZE=4,DEFALUT:REWRITE. + STAT_CYCLE, //VALUE is an interger idicate interval seconds of every output, SIZE=4 ,DEFUALT:2 seconds. + PRINT_TRIGGER, //VALUE is an interger,1:Do print,0: Don't print.SIZE=4.DEFAULT:1. + CREATE_THREAD, //VALUE is an interger,1: Create a print thread,0:not create,output by call passive_output function, + //and the STAT_CYCLE is meaningless.SIZE=4,DEFAULT:0. + ID_INVISBLE, //value is field_id/status_id/column_id, not output this string, SIZE=4,DEFAULT: shutdown NO one. + FLUSH_BY_DATE, //value is 1(ture) or 0(false),SIZE=4,DEFAULT: Do not flush by date. + APP_NAME, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT is "?". + STATS_SERVER_IP, //VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. No DEFAULT. + STATS_SERVER_PORT, //VALUE is a unsigned short or a signed int, host order, SIZE= sizeof(unsigned short) or sizeof(int). No DEFAULT. + STATS_FORMAT, //VALUE is an interger, SIZE=sizeof(int), DEFAULT:1. + MAX_STAT_FIELD_NUM, //VALUE is an interger, SIZE=sizeof(int), DEFAULT:1024. + HISTOGRAM_GLOBAL_BINS //VALUE is a const char*, define a histogram bins for default field, SIZE = strlen(string+'\0')+1. DEFAULT: "0.5,0.8,0.9,0.95,0.99鈥. +}; + +//Always success. +screen_stat_handle_t FS_create_handle(void); + +int FS_set_para(screen_stat_handle_t handle, enum FS_option type,const void* value,int size); +void FS_start(screen_stat_handle_t handle); +void FS_stop(screen_stat_handle_t* handle); + +//return field_id/line_id/column_id greater than zero if success,return an interger less than zero if failed. +//should NOT include "|:\n\r.\t<>[]#!@"or space in the parameter name. +//Runtime rregister column is NOT allowed. +int FS_register(screen_stat_handle_t handle,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name); + +//numerator_id and denominator_id must be column/field/status style. +//scaling: negative value: zoom in; positive value: zoom out; +int FS_register_ratio(screen_stat_handle_t handle,int numerator_id,int denominator_id,int scaling,enum field_dsp_style_t style,enum field_calc_algo calc_type,const char* name); + +//@param bins format is comma spited number, e.g."0.1,0.5,0.8,0.9,0.95,0.99" +//return 0 on success, <0 on failed. +int FS_histogram_set_bins(screen_stat_handle_t handle, int id, const char* bins); + +//@param lowest_trackable_value >1 +//@param highest_trackable_value>lowest_trackable_value * 2 +//@param 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* MESA framework */ +#include "cJSON.h" +#include "MESA_handle_logger.h" +#include "MESA_htable.h" +#include "MESA_prof_load.h" +#include "MESA_list.h" +#include "MESA_list_count.h" +#include "MESA_list_queue.h" +#include "MESA_ring_queue.h" +#include "wiredLB.h" +#include "wired_cfg.h" +//#include "field_stat2.h" //must compile with g++, add it in source file. + +/* sapp platform header */ +#include "sapp_std.h" +#include "sapp_limits.h" +#include "sapp_state.h" +#include "sapp_cla.h" +#include "sapp_timer.h" + +#include "stream.h" + +#endif + diff --git a/include/MESA/sapp_cla.h b/include/MESA/sapp_cla.h new file mode 100644 index 0000000..fa4d0ad --- /dev/null +++ b/include/MESA/sapp_cla.h @@ -0,0 +1,42 @@ +#ifndef _SAPP_CLA_H_ +#define _SAPP_CLA_H_ 1 + +#include "sapp_std.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + For get command-line arguments(CLA). + + Note: + The string value 'opt_string_value' is read-only, + caller must not modify or free it after call sapp_get_cla_raw(). + + return value: + -1: not found opt_long_name; + 0: opt_long_name is set but no argument value. + 1: opt_long_name is set and has valid argument store in *opt_string_value. +*/ +int sapp_get_cla_raw(const char *opt_long_name, char ** const opt_string_value); + + +/* + For get command-line arguments(CLA). + + return value: + -1: not found opt_long_name; + 0: opt_long_name is set but no argument value. + 1: opt_long_name is set and has valid argument store in *opt_long_value. +*/ +int sapp_get_cla_long(const char *opt_long_name, long long *opt_long_value); + + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/include/MESA/sapp_limits.h b/include/MESA/sapp_limits.h new file mode 100644 index 0000000..13fcd22 --- /dev/null +++ b/include/MESA/sapp_limits.h @@ -0,0 +1,24 @@ +#ifndef _SAPP_LIMITS_H_ +#define _SAPP_LIMITS_H_ 1 + +#ifndef MAX_THREAD_NUM +#define MAX_THREAD_NUM 128 +#endif + +#define SAPP_MAX_THREADS MAX_THREAD_NUM + +#define SAPP_SUPPORT_LAYER_NUM_MAX (15) /* sapp骞冲彴鏀寔鐨勬渶澶у祵濂楀眰鏁, 涓巗truct streaminfo_private->layer_index鐩稿叧 */ +#define SAPP_PRUNE_LAYER_NUM_MAX (10) /* sapp骞冲彴鏀寔鐨勬渶澶т慨鍓厤缃潯鏁 */ + +#ifndef MTU_MAX +#define MTU_MAX 2000 +#endif + + +#define SAPP_MAX_PLUG_ENTRY_NUM (256) /* 鎵鏈夋彃浠剁殑entry鏁伴噺鏈澶у */ + +#define STATS_STR_LEN (32) + + +#endif + diff --git a/include/MESA/sapp_state.h b/include/MESA/sapp_state.h new file mode 100644 index 0000000..5b54428 --- /dev/null +++ b/include/MESA/sapp_state.h @@ -0,0 +1,27 @@ +#ifndef _SAPP_STATE_H_ +#define _SAPP_STATE_H_ 1 +#ifdef __cplusplus +extern "C" { +#endif + +#if 0 //move to stream_control.h +enum sapp_state_t{ + SAPP_STATE_JUST_START, /* main() called by shell command */ + SAPP_STATE_CONFIG_PARSE, + SAPP_STATE_PLATFORM_INITING, + SAPP_STATE_PLATFORM_INITED, + SAPP_STATE_PKT_IO_INITING, + SAPP_STATE_PKT_IO_INITED, + SAPP_STATE_PLUG_INITING, + SAPP_STATE_PLUG_INITED, + SAPP_STATE_PROCESSING, + SAPP_STATE_READY_TO_EXIT, /* only for pcap dumpfile */ +}; +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/MESA/sapp_std.h b/include/MESA/sapp_std.h new file mode 100644 index 0000000..4c3222a --- /dev/null +++ b/include/MESA/sapp_std.h @@ -0,0 +1,24 @@ +#ifndef _SAPP_STD_H_ +#define _SAPP_STD_H_ 1 + +typedef struct { + unsigned short type; + unsigned char user_arg1; + unsigned char user_arg2; + unsigned int length; + union{ + char char_value; + unsigned char uchar_value; + short short_value; + unsigned short ushort_value; + int int_value; + unsigned int uint_value; + long long long_value; + unsigned long long ulong_value; + char *string_value; /* standard C string with EOF('\0'), length include EOF, differ with strlen() */ + void *bin_value; /* unprintable character, binary data, or custom complex struct. */ + }; +}sapp_tlv_t; + +#endif + diff --git a/include/MESA/sapp_timer.h b/include/MESA/sapp_timer.h new file mode 100644 index 0000000..0842ef0 --- /dev/null +++ b/include/MESA/sapp_timer.h @@ -0,0 +1,90 @@ +#ifndef _SAPP_TIMER_H_ +#define _SAPP_TIMER_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sapp_limits.h" + +#if 0 + + +typedef enum{ + STO_EFFECTIVE_SCOPE, /* value type is int, refer to STO_EFFECTIVE_SCOPE_xxx */ + STO_PKT_PROCESS_THREAD_NUM, /* value type is int */ +}sapp_timer_opt; + +#endif + +enum st_return_errno{ + ST_RET_SUCC = 0, + ST_RET_ERROR = -1, + ST_RET_CANT_OP_PLATFORM_TIMER = -2, + ST_RET_INVALID_ARGS = -3, + ST_RET_NEED_MANDATORY_OPT = -4, + ST_RET_DIFF_THREAD_CONTEXT = -5, +}; + + +typedef enum{ + STEO_EFFECTIVE_THREAD_ID, /* value type is int */ + STEO_TIMEOUT_VAL, /* value type is struct timeval, refer to */ + STEO_CALLBACK_FUN, /* value type is sapp_timer_cbfun_t* */ + STEO_CALLBACK_FUN_ARG, /* value type is void* */ + STEO_CALLBACK_COUNT, /* value type is int */ +}sapp_event_opt; + +typedef void * sapp_timer_handle; +typedef void * sapp_timer_event; + +/* + NOTE: + This timer is active in sapp packet process threads context, + similar to the entry function of plugins, is multithread. +*/ +sapp_timer_handle sapp_get_platform_timer(int tid); + +/* + NOTE: + This timer is created by sapp, + plugins only add timer event in sapp initialization phase, + in addition, the accuracy maybe decline if too many timer event add to one timer. + plugins also call sapp_standalone_timer_new() to create a private timer for it own use. +*/ +sapp_timer_handle sapp_get_platform_standalone_timer(void); + + +/* NOTE: this timer is active in a standalone thread context, is single thread. */ +sapp_timer_handle sapp_standalone_timer_new(void); + + +/* + NOTE: + In sapp platform packet process thread context, the pkt_process_thread_id is in region: [0, max_thread_num-1]; + In stand_alone thread context, the pkt_process_thread_id is -1; +*/ +typedef void sapp_timer_cbfun_t(sapp_timer_handle h, sapp_timer_event ev, int pkt_process_thread_id, void *user_arg); + +/* + NOTE: + If you want use sapp platform timer, must call sapp_get_platform_timer(), not sapp_timer_new(). + If you want a independent private timer, must call sapp_timer_new(). +*/ +sapp_timer_event sapp_timer_event_new(sapp_timer_handle h); + +//int sapp_timer_set_opt(sapp_timer_handle h, sapp_timer_opt t_opt, void *t_value, int t_value_len); +int sapp_event_set_opt(sapp_timer_event ev, sapp_event_opt ev_opt, void *ev_value, int ev_value_len); + + +int sapp_timer_add(sapp_timer_handle h, sapp_timer_event ev); +int sapp_timer_del(sapp_timer_handle h, sapp_timer_event ev); +int sapp_timer_start(sapp_timer_handle h); +int sapp_timer_destroy(sapp_timer_handle h); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/include/MESA/stream.h b/include/MESA/stream.h new file mode 100644 index 0000000..15686d7 --- /dev/null +++ b/include/MESA/stream.h @@ -0,0 +1,104 @@ +#ifndef _APP_STREAM_H_ +#define _APP_STREAM_H_ + +#include "stream_inc/stream_base.h" +#include "stream_inc/stream_proxy.h" +#include "stream_inc/stream_project.h" +#include "stream_inc/stream_bridge.h" +#include "stream_inc/stream_inject.h" +#include "stream_inc/stream_control.h" +#include "stream_inc/stream_entry.h" +#include "stream_inc/stream_rawpkt.h" +#include "stream_inc/stream_tunnel.h" +#include "stream_inc/sapp_inject.h" + + +#define STREAM_H_VERSION (20210425) + +#endif + +/*********************************************************************************** + Update log: + 2015-02-03 lijia, + 修改stream_base.h, + 增加类型定义PKT_TYPE_IP_FRAG; + 增加stream_addr_list_ntop, stream_addr_list_pton系列函数. + + 2015-01-23 lqy + 修改stream_base.h, 将pkttyp进行了扩展,增加了多个tcppkt的定义 + 把pktipfragtype 从pkttype中独立为一个变量 + + 2015-01-04 lijia, + 修改stream_base.h, 将pkttype移动至struct layer_addr结构中, + 将routedir扩展为uchar类型; + 新增MESA_dir_reverse()函数, 用于发包时反向routedir. + stream.h增加版本号和MD5验证值. + + 2014-12-30 lqy, + 将原stream.h按功能类别拆分为7个stream_xxx.h, + 将平台内部变量隐藏, public类型对插件可见, private为内部使用对外不可见. + + 2015-11-12 lijia, + 增加新函数MESA_set_stream_opt(), + 用于设置当前流的独立参数. + + 2015-12-30 lijia, + 修改stream_base.h, + 将struct tcpdetail, struct udpdetail中的包数、字节数统计移动至project. + 为了向后兼容, 暂时保留这些变量保证内存排列和旧版一致, 只是不再更新, 数值也无意义. + + 2016-01-18 lijia, + 增加英文注释, 避免某些环境下SHELL无法显示中文的问题. + + 2016-01-18 lijia, + stream_base.h增加printaddr_r可重入版本, 可用于非捕包处理线程打印地址. + + 2016-03-23 lijia, + stream_base.h增加layer_addr_dup, layer_addr_free. + + 2016-04-18 lijia, + stream_control.h增加MSO_TCP_ISN_C2S, MSO_TCP_ISN_S2C. + + 2016-04-27 lijia, + 修改stream_inject.h描述. + + 2016-07-08 lijia, + 修改stream_control.h, 增加选项MSO_TCP_SYN_OPT, MSO_TCP_SYNACK_OPT. + 新增接口MESA_get_tcp_pkt_opts(). + + 2016-07-14 李佳, + 新增get_rawpkt_opt_from_streaminfo(), 用于没有原始包指针的插件获取原始包中的信息。 + + 2016-07-25 lijia + 新增enum stream_carry_tunnel_t, 用于表示当前流底层隧道类型. + + 2016-09-01 lijia + 1)新增函数接口streaminfo_dup, streaminfo_free; + 2)新增stream_tunnel.h, 用于soq项目关于隧道协议相关信息的获取; + + 2016-09-06 lijia + 1)新增STREAM_TYPE_OPENVPN, STREAM_TYPE_PPTP. + + 2016-09-26 lijia + 1)新增STREAM_TYPE_PPTP. + + 2016-10-09 lijia + 1)修改stream_inject.h, 增加MESA_kill_tcp_feedback()等带反馈功能的函数接口. + + 2016-10-11 lijia + 1)修改stream_tunnel.h, 增加IPSEC_OPT_IS_NAT, L2TP_OPT_CHAP_USER_NAME. + + 2016-12-01 lijia + 1)修改stream_tunnel.h, 增加PPTP_CONTENT_TYPE, L2TP_CONTENT_TYPE. + 2)修改stream_base.h, 增加ADDR_TYPE_PPTP地址类型, 和结构struct layer_addr_pptp. + + 2016-12-01 lijia + 1)修改stream_base.h, 增加layer_addr_ntop, layer_addr_ntop_r地址转换函数. + + 2017-09-11 lijia + 1)stream_control.h增加sapp_get_platform_opt()接口, 供外部插件获取平台内部参数. + + 2019-11-18 lijia + 1)stream_base.h增加插件返回值, APP_STATE_KILL_FOLLOW, APP_STATE_KILL_OTHER. +*************************************************************************************/ + diff --git a/include/MESA/stream_inc/gdev_keepalive.h b/include/MESA/stream_inc/gdev_keepalive.h new file mode 100644 index 0000000..8211c40 --- /dev/null +++ b/include/MESA/stream_inc/gdev_keepalive.h @@ -0,0 +1,37 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#include "stream_inc/stream_base.h" + + +enum gdev_keepalive_opt_t{ + GDEV_KEEPALIVE_OPT_SERVICE_CTRL, /* 单独控制某类业务号是否保活 opt_val is struct gdev_keepalive_service_ctrl */ + GDEV_KEEPALIVE_OPT_GLOBAL_SWITCH, /* 全局性保活开关, opt_val is int */ + GDEV_KEEPALIVE_OPT_RCV_PKT_PPS, /* 收到的保活包总数/秒, opt_val is long */ + GDEV_KEEPALIVE_OPT_SND_PKT_PPS, /* 收到的保活包总数/秒, opt_val is long */ +}; + +struct gdev_keepalive_service_ctrl{ + int service_num; /* 业务号, service number */ + int keepalive_switch; /* 1:保活, enable keepalive; 0:不保活, disable keepalive */ +}; + + +int gdev_keepalive_set_opt(const SAPP_TLV_T *tlv_value); + +int gdev_keepalive_get_opt(SAPP_TLV_T *tlv_value); + + +/* 由源端口获取当前包所属业务号 */ +unsigned char vxlan_sport_map_to_service_id(unsigned short sport_host_order); + +/* 由vxlan_id获取当前包所属业务号 */ +unsigned char vxlan_id_map_to_service_id(int vxlan_id_host_order); + + +#ifdef __cplusplus +} +#endif + + diff --git a/include/MESA/stream_inc/sapp_inject.h b/include/MESA/stream_inc/sapp_inject.h new file mode 100644 index 0000000..cbcaab1 --- /dev/null +++ b/include/MESA/stream_inc/sapp_inject.h @@ -0,0 +1,37 @@ +#ifndef _SAPP_INJECT_H_ +#define _SAPP_INJECT_H_ 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include "stream_base.h" + +enum sapp_inject_opt{ + SIO_DEFAULT = (1<<0), /* 调用者只传入纯负载, 由平台根据协议规范构造当前层的传输层和IP头部, 如果是隧道, 还包括所有嵌套层的头部 */ + SIO_EXCLUDE_THIS_LAYER_HDR = (1<<1), /* 除负载外, 当前层的传输层和IP头部也由调用者构造, 平台仅构造除当前层的承载层头部, 如果是隧道, 还包括所有嵌套层的头部 */ +}; + +/* + ARGS: + stream: 当前流结构体指针; + payload: 要发送的负载指针; + payload_len: 要发送的负载长度; + snd_routedir: 要发送数据的route方向, + 如果发送的包与当前包同向, snd_routedir = stream->routedir, + 如果发送的包与当前包反向, snd_routedir = MESA_dir_reverse(stream->routedir). + + return value: + <=0 : error. + > 0 : 发送的数据包实际总长度(payload_len + 底层包头长度); +*/ +int sapp_inject_pkt(struct streaminfo *stream, enum sapp_inject_opt sio, const void *payload, int payload_len, unsigned char snd_routedir); + + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/MESA/stream_inc/stream_base.h b/include/MESA/stream_inc/stream_base.h new file mode 100644 index 0000000..afca3e7 --- /dev/null +++ b/include/MESA/stream_inc/stream_base.h @@ -0,0 +1,634 @@ +#ifndef _APP_STREAM_BASE_H_ +#define _APP_STREAM_BASE_H_ + +#define STREAM_BASE_H_VERSION (20210621) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef UINT8 +typedef unsigned char UINT8; +#endif +#ifndef UCHAR +typedef unsigned char UCHAR; +#endif +#ifndef UINT16 +typedef unsigned short UINT16; +#endif + +#ifndef UINT32 +typedef unsigned int UINT32; +#endif +#ifndef UINT64 +typedef unsigned long long UINT64; +#endif + +/* CHN : 流的方向定义 */ +/* ENG : stream direction definition*/ +#define DIR_C2S 0x01 +#define DIR_S2C 0x02 +#define DIR_DOUBLE 0x03 + +/* CHN : 网络底层传输方向定义,串联模式有意义 */ +/* ENG : network topology route direction, is valid in serial mode */ +#define DIR_ROUTE_UP 0x00 +#define DIR_ROUTE_DOWN 0x01 + +/* CHN : 单包的类型定义 */ +/* ENG : single packet type definition */ +#define PKT_TYPE_NORMAL (0x0) /* normal, common */ +#define PKT_TYPE_IPREBUILD (1<<0) /* ip frag reassembled packet; ip碎片重组报文 */ +#define PKT_TYPE_TCPUNORDER (1<<1) /* TCP out of order packet; TCP乱序报文 */ +#define PKT_TYPE_TCPREORDER (1<<2) /* TCP sequential packet; TCP乱序排序好的数据包 */ +#define PKT_TYPE_TCPRETRANS (1<<3) /* TCP retransmit packet; TCP重传报文 */ +#define PKT_TYPE_IP_FRAG (1<<4) /* IP frag packet; IP分片包 */ +#define PKT_TYPE_IP_FRAG_LAST (1<<5) /* last IP frag packet; 同属于一个原始完整IP包的最后一个IP分片包 */ + +/* CHN : 地址类型定义, 可通过函数 addr_type_to_string() 转成字符串形式. */ +/* ENG : address type, transform to string mode by call addr_type_to_string(). */ +enum addr_type_t{ + __ADDR_TYPE_INIT = 0, + ADDR_TYPE_IPV4, /* 1, struct stream_tuple4_v4 */ + ADDR_TYPE_IPV6, /* 2, struct stream_tuple4_v6 */ + ADDR_TYPE_VLAN, /* 3, 802.1Q */ + ADDR_TYPE_MAC, /* 4 */ + ADDR_TYPE_ARP = 5, /* 5 */ + ADDR_TYPE_GRE, /* 6 */ + ADDR_TYPE_MPLS, /* 7 */ + ADDR_TYPE_PPPOE_SES, /* 8 */ + ADDR_TYPE_TCP, /* 9 */ + ADDR_TYPE_UDP = 10, /* 10 */ + ADDR_TYPE_L2TP, /* 11 */ + __ADDR_TYPE_IP_PAIR_V4, /* 12, ipv4 layer in tunnel mode */ + __ADDR_TYPE_IP_PAIR_V6, /* 13, ipv6 layer in tunnel mode */ + ADDR_TYPE_PPP, /* 14 */ + ADDR_TYPE_PPTP, /* 15 */ + ADDR_TYPE_MAC_IN_MAC, /* 16 */ + ADDR_TYPE_GPRS_TUNNEL, /* 17 */ + ADDR_TYPE_VXLAN, /* 18 */ + __ADDR_TYPE_MAX, /* 19 */ +}; + +#define TCP_TAKEOVER_STATE_FLAG_OFF 0 +#define TCP_TAKEOVER_STATE_FLAG_ON 1 + + +/* CHN : 应用层看到的链接状态定义 */ +/* ENG : stream state for protocol or business plug*/ +#define OP_STATE_PENDING 0 +#define _OP_STATE_OBSOLETE 1 /* is obsolete */ +#define OP_STATE_CLOSE 2 +#define OP_STATE_DATA 3 + +/* CHN : 应用层返回结果定义 */ +/* ENG : return value of plug */ +#define APP_STATE_GIVEME 0x00 +#define APP_STATE_DROPME 0x01 +#define APP_STATE_FAWPKT 0x00 +#define APP_STATE_DROPPKT 0x10 + + +#define APP_STATE_KILL_FOLLOW 0x40 /* 强制CLOSE当前插件后续的所有插件 */ +#define APP_STATE_KILL_OTHER 0x80 /* 强制CLOSE除当前插件外的所有插件 */ + + +/* CHN : 流的类型定义 */ +/* ENG : stream type */ +enum stream_type_t{ + STREAM_TYPE_NON = 0, /* No stream concept indeed, such as vlan, IP, etc.; 无流的概念, 如VLAN, IP层等 */ + STREAM_TYPE_TCP, + STREAM_TYPE_UDP, /* there is no stream of UDP in RFC, but in MESA platform, we build a UDP stream with same tuple4 packet */ + STREAM_TYPE_VLAN, + STREAM_TYPE_SOCKS4, + STREAM_TYPE_SOCKS5, + STREAM_TYPE_HTTP_PROXY, + STREAM_TYPE_PPPOE, + STREAM_TYPE_L2TP, + STREAM_TYPE_OPENVPN, + STREAM_TYPE_PPTP, + STREAM_TYPE_ISAKMP, +}; + +/* + CHN: 流的底层承载隧道类型, + 不同于stream_type_t, 比如当前流为STREAM_TYPE_TCP, 但底层隧道类型可能是STREAM_TUNNLE_PPTP. + 因为隧道可能是多种不同类型嵌套组合, 只记录最底层(离MAC层最近的)隧道类型. +*/ +enum stream_carry_tunnel_t{ + STREAM_TUNNLE_NON = 0, /* default is 0, not tunnel; 默认为0, 非隧道; */ + STREAM_TUNNLE_6OVER4 = 1 << 0, + STREAM_TUNNLE_4OVER6 = 1 << 1, + STREAM_TUNNLE_GRE = 1 << 2, + STREAM_TUNNLE_IP_IN_IP = 1 << 3, + STREAM_TUNNLE_PPTP = 1 << 4, + STREAM_TUNNLE_L2TP = 1 << 5, + STREAM_TUNNLE_TEREDO = 1 << 6, + STREAM_TUNNEL_GPRS_TUNNEL = 1 << 7, + STREAM_TUNNEL_MULTI_MAC = 1 << 8, /* is obsoulte */ +}; + +typedef struct raw_ipfrag_list{ + void *frag_packet; /* 非ip包头, 从底层网卡获取的原始包头 */ + int pkt_len; + int type; /* IPv4 or IPv6 */ + struct raw_ipfrag_list *next; +}raw_ipfrag_list_t; + + +#ifndef STRUCT_TUPLE4_DEFINED +#define STRUCT_TUPLE4_DEFINED (1) +/* compat for start, papp; 兼容start, papp */ +struct tuple4 { + u_int saddr; + u_int daddr; + u_short source; + u_short dest; +}; +#endif + +struct tuple6 +{ + UCHAR saddr[16] ; + UCHAR daddr[16] ; + UINT16 source; + UINT16 dest; +}; + +/* network-order */ +struct stream_tuple4_v4{ + UINT32 saddr; /* network order */ + UINT32 daddr; /* network order */ + UINT16 source; /* network order */ + UINT16 dest; /* network order */ +}; + + +#ifndef IPV6_ADDR_LEN +#define IPV6_ADDR_LEN (sizeof(struct in6_addr)) +#endif + +struct stream_tuple4_v6 +{ + UCHAR saddr[IPV6_ADDR_LEN] ; + UCHAR daddr[IPV6_ADDR_LEN] ; + UINT16 source; /* network order */ + UINT16 dest; /* network order */ +}; + + +#define GRE_TAG_LEN (4) +struct layer_addr_gre +{ + UINT16 call_id; /* network order */ +}; + + +#define VLAN_ID_MASK (0x0FFF) +#define VLAN_TAG_LEN (4) +#define MAX_VLAN_ADDR_LAYER (2) + + +struct single_layer_vlan_addr{ /* refer to https://en.wikipedia.org/wiki/IEEE_802.1Q */ + unsigned short TPID; /* Tag protocol identifier, network order */ + unsigned char PCP; /* Priority code point */ + unsigned char DEI; /* Drop eligible indicator */ + unsigned short VID; /* VLAN identifier, network order */ +}; + + +struct layer_addr_vlan +{ + struct single_layer_vlan_addr c2s_addr_array[MAX_VLAN_ADDR_LAYER]; + struct single_layer_vlan_addr s2c_addr_array[MAX_VLAN_ADDR_LAYER]; + UCHAR c2s_layer_num; + UCHAR s2c_layer_num; +}; + + +struct layer_addr_pppoe_session +{ +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int ver:4; + unsigned int type:4; +#elif __BYTE_ORDER == __BIG_ENDIAN + unsigned int type:4; + unsigned int ver:4; +#endif + unsigned char code; + unsigned short session_id; +}; + +#ifndef MAC_ADDR_LEN +#define MAC_ADDR_LEN (6) +#endif + +struct layer_addr_mac +{ + /* + C2S和S2C方向来自不同的链路和设备, 会导致两个方向的mac地址全不一样, 反向注入时不能用传统方式, 即简单的颠倒src和dst, + 修改定义如下, mirror模式下, 还是存储在src_addr中, + API不同了, ABI还是向前兼容的, 结构体内存分布与之前的一致. + */ + struct ethhdr src_addr; + struct ethhdr dst_addr; + + //UCHAR dst_mac[MAC_ADDR_LEN]; /* network order */ + //UCHAR src_mac[MAC_ADDR_LEN]; /* network order */ +}; + +struct layer_addr_ipv4 +{ + UINT32 saddr; /* network order */ + UINT32 daddr; /* network order */ + /* 2014-04-21 lijia add, + 为了节约内存空间、和处理效率, 不强制按协议层次处理, + IP层和TCP层做为一个层, + 对于隧道外层IP, 端口信息为0; + */ + UINT16 source; /* network order */ + UINT16 dest; /* network order */ +}; + +struct layer_addr_ipv6 +{ + UCHAR saddr[IPV6_ADDR_LEN] ; /* network order */ + UCHAR daddr[IPV6_ADDR_LEN] ; /* network order */ + /* 2014-04-21 lijia add, + 为了节约内存空间、和处理效率, 不强制按协议层次处理, + IP层和TCP层做为一个层, + 对于隧道外层IP, 端口信息为0; + */ + UINT16 source;/* network order */ + UINT16 dest;/* network order */ +}; + +struct layer_addr_tcp +{ + UINT16 source; /* network order */ + UINT16 dest; /* network order */ +}; + +struct layer_addr_udp +{ + UINT16 source; /* network order */ + UINT16 dest; /* network order */ +}; + + +struct layer_ppp_hdr{ + unsigned char address; + unsigned char control; + unsigned short protocol; /* network order */ +}__attribute__((packed)); + +/* 一般情况下, address,control都是固定不变的,都是0xFF,0x03, ppp hdr是可以压缩以节约贷款,只传输一个字节的protocol字段 */ +struct layer_compress_ppp_hdr{ + unsigned char protocol; +}; + + +struct layer_addr_l2tp_v2_t{ + UINT16 tunnelid_C2S; /* network order, 以传输层创建流的方向为准 */ + UINT16 tunnelid_S2C; /* network order, 以传输层创建流的方向为准 */ + UINT16 sessionid_C2S; /* network order, 以传输层创建流的方向为准 */ + UINT16 sessionid_S2C; /* network order, 以传输层创建流的方向为准 */ + unsigned char seq_present_C2S; + unsigned char seq_present_S2C; + unsigned char ppp_hdr_compress_enable; + union{ + struct layer_ppp_hdr ppp_hdr; + struct layer_compress_ppp_hdr compress_ppp_hdr; + }; +}; + +struct layer_addr_l2tp_v3_t{ + UINT32 sessionlid; /* network order */ +}; + +struct layer_addr_l2tp +{ + UCHAR version; /* v2 or v3 */ + union + { + struct layer_addr_l2tp_v2_t l2tp_addr_v2; + struct layer_addr_l2tp_v3_t l2tp_addr_v3; + }l2tpun; +}; + +#define MAX_MPLS_ADDR_LAYER 4 + +struct single_layer_mpls_addr{ /* refer to RFC3032 */ + unsigned int label; /* network order */ + unsigned char experimental; + unsigned char bottom; + unsigned char ttl; +}; + +/* + MPLS有可能是多层嵌套, sapp把多层合并处理, 目前最大支持4层, 层次序号由外到内排列, 0表示最外层, 3表示最内层 + 对于一个内层TCP/UDP流来说, 底层MPLS两个方向的地址可能不一样, 分别记为cs2_addr, s2c_addr. +*/ +struct layer_addr_mpls +{ + struct single_layer_mpls_addr c2s_addr_array[MAX_MPLS_ADDR_LAYER]; + struct single_layer_mpls_addr s2c_addr_array[MAX_MPLS_ADDR_LAYER]; + char c2s_layer_num; /* 实际mpls层数 */ + char s2c_layer_num; /* 实际mpls层数 */ + char c2s_has_ctrl_word; + char s2c_has_ctrl_word; + unsigned int c2s_mpls_ctrl_word; /* refer to RFC4623 */ + unsigned int s2c_mpls_ctrl_word; /* refer to RFC4623 */ +}; + + +struct layer_addr_pptp +{ + UINT16 C2S_call_id; /* C2S以传输层协议方向为准, TCP SYN为C2S, UDP源端口大的为C2S, callid, network order */ + UINT16 S2C_call_id; /* S2Ck以传输层协议方向为准, TCP SYN/ACK为S2C, UDP目的端口大的为S2C, callid, network order */ +}; + +struct layer_addr_gtp +{ + unsigned int teid_c2s; /* network order */ + unsigned int teid_s2c; /* network order */ +}__attribute__ ((aligned (1))); + +#define MAC_IN_MAC_HDR_LEN (sizeof(struct mesa_ethernet_hdr) + sizeof(struct mesa_ethernet_hdr)) +struct layer_addr_mac_in_mac +{ + UCHAR outer_dst_mac[MAC_ADDR_LEN]; /* 最外层mac地址, network order */ + UCHAR outer_src_mac[MAC_ADDR_LEN]; /* 最外层mac地址, network order */ + UCHAR inner_dst_mac[MAC_ADDR_LEN]; /* 内层mac地址, network order */ + UCHAR inner_src_mac[MAC_ADDR_LEN]; /* 内层mac地址, network order */ +}; + +struct layer_addr_vxlan +{ + UINT16 vlan_id; /* network order */ + UCHAR dir; + UCHAR link_id; + UCHAR link_type; +}; + + +struct layer_addr +{ + UCHAR addrtype; /* definition in enum addr_type_t */ + UCHAR addrlen; + UCHAR pkttype; /* packet special features, definition in MACRO PKT_TYPE_xxx */ + UCHAR pktipfragtype; /* ip frag packetfeatures, definition in MACRO PKT_TYPE_xxx */ + + UCHAR __pad[4]; /* pad for alignment */ + union + { + struct stream_tuple4_v4 *tuple4_v4; + struct stream_tuple4_v6 *tuple4_v6; + struct layer_addr_ipv4 *ipv4; + struct layer_addr_ipv6 *ipv6; + struct layer_addr_vlan *vlan; + struct layer_addr_mac *mac; + struct layer_addr_gre *gre; + struct layer_addr_tcp *tcp; + struct layer_addr_udp *udp; + struct layer_addr_pppoe_session *pppoe_ses; + struct layer_addr_l2tp *l2tp; + struct layer_addr_pptp *pptp; + struct layer_addr_mac_in_mac *mimac; + struct layer_addr_gtp *gtp; + struct layer_addr_mpls *mpls; + struct layer_addr_vxlan *vxlan; + void *paddr; + }; + +}; + +/* CHN : 保留此结构用于和papp兼容, 用作指针时, 可与struct layer_addr强转 */ +/* ENG : compat for papp, can be transform to struct layer_addr pointer */ +struct ipaddr +{ + UCHAR addrtype; /* definition in enum addr_type_t */ + UCHAR addrlen; + UCHAR pkttype; /* packet special features, definition in MACRO PKT_TYPE_xxx */ + UCHAR pktipfragtype; /* ip frag packetfeatures, definition in MACRO PKT_TYPE_xxx */ + UCHAR __pad[4]; /* pad for alignment */ + union + { + struct stream_tuple4_v4 *v4; + struct stream_tuple4_v6 *v6; + void *paddr; + }; + +}; + +struct tcpdetail +{ + void *pdata; + UINT32 datalen; + UINT32 lostlen; /* lost data len, not accumulated, current procedure */ + UINT32 serverpktnum; /* C2S, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */ + UINT32 clientpktnum; /* S2C, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */ + UINT32 serverbytes; /* C2S, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */ + UINT32 clientbytes; /* S2C, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */ + UINT64 createtime; + UINT64 lastmtime; +}; + +struct udpdetail +{ + void *pdata; + UINT32 datalen; + UINT32 pad; + UINT32 serverpktnum; /* C2S, you should better use stream_project.h : struct udp_flow_stat */ + UINT32 clientpktnum; /* S2C, you should better use stream_project.h : struct udp_flow_stat */ + UINT32 serverbytes; /* C2S, you should better use stream_project.h : struct udp_flow_stat */ + UINT32 clientbytes; /* S2C, you should better use stream_project.h : struct udp_flow_stat */ + UINT64 createtime; + UINT64 lastmtime; +}; + +struct streaminfo +{ + struct layer_addr addr; + struct streaminfo *pfather; /* this stream's carry layer stream; 上层流结构体 */ + UCHAR type; /* stream type, definition in enum stream_type_t */ + UCHAR threadnum; + UCHAR dir; /* valid in all stream life, current stream direction state, 0x01:c-->s; 0x02:s-->c; 0x03 c<-->s; */ + UCHAR curdir; /* valid in current procedure, current packet direction, 0x01:c-->s; 0x02:s-->c */ + UCHAR opstate; /* stream state, definition in MACRO OP_STATE_xxx */ + UCHAR pktstate; /* for TCPALL plug, stream state, definition in MACRO OP_STATE_xxx */ + UCHAR routedir; /* network topology route direction, is valid in serial mode */ + UCHAR stream_state; /* stream management state, for example, in TCP stream, maybe SYN, DATA, NOUSE */ + UINT32 hash_index; /* stream hash index, maybe reduplicate with other stream when hash algorithm collide */ + UINT32 stream_index; /* stream global index per thread */ + union + { + struct tcpdetail *ptcpdetail; + struct udpdetail *pudpdetail; + void *pdetail; + }; + }; + + +typedef struct { + unsigned int type; + unsigned int length; + union{ + char char_value; + short short_value; + int int_value; + long long_value; + char array_value[8]; + void *ptr_value; /* more than 8bytes data, or complex struct. */ + }; +}SAPP_TLV_T; + +#ifdef __cplusplus +extern "C" { +#endif + +/* CHN : 内存管理相关函数, 基于平台的插件必须使用此类函数申请或释放内存 */ +/* ENG : memory management function, plugs must call these functions instead of malloc, free in */ +void *dictator_malloc(int thread_seq,size_t size); +void dictator_free(int thread_seq,void *pbuf); +void *dictator_realloc(int thread_seq, void* pbuf, size_t size); + +/* CHN : 获取当前系统运行的并发处理线程总数 */ +/* ENG : get current total thread of platfomr */ +int get_thread_count(void); + +/* CHN : 将地enum addr_type_t址类型转换成可打印的字符串形式 */ +/* ENG : transform binary addr_type_t to string mode */ +const char *addr_type_to_string(enum addr_type_t type); + +/* + ENG : transform tuple4 to string mode, must used in packet process thread context; + CHN : 将layer_addr地址转换成字符串形式, 必须用在包处理线程. +*/ +const char *printaddr (const struct layer_addr *paddrinfo, int threadindex); + +/* + ENG : a reentrant version of printaddr, thread safe; + CHN : printaddr的可重入版本, 是线程安全的. +*/ +const char *printaddr_r(const struct layer_addr *paddrinfo, char *out_buf, int out_buf_len); + + +/* + ENG : transform layer address to string mode, must used in packet process thread context, + the return value is read-only, user can't free it; + CHN : 将layer_addr地址转换成字符串形式, 必须用在包处理线程, 返回的指针为只读, 使用者不必free. +*/ +const char *layer_addr_ntop(const struct streaminfo *pstream); + +/* + ENG : a reentrant version of layer_addr_ntop, thread safe, return a pointer to the destination string 'out_buf'; + CHN : layer_addr_ntop_r的可重入版本, 是线程安全的, 返回的指针执向使用者提供的out_buf, 便于代码组织. +*/ +char *layer_addr_ntop_r(const struct streaminfo *pstream, char *out_buf, int out_buf_len); + +/* + ENG : transform layer type to abbr string mode, is reentrant, the return value is read-only, user can't free it;. + CHN : 将layer_addr地址类型转换成缩写字符串形式, 可重入线程安全, 返回的指针为只读, 使用者不必free.. +*/ +const char *layer_addr_prefix_ntop(const struct streaminfo *pstream); + + +/* + ENG : duplicate a same layer_addr struct, memory obtained with malloc(3); + CHN : 复制一个完全相同的layer_addr结构体, 内存通过malloc(3)获取. +*/ +struct layer_addr * layer_addr_dup(const struct layer_addr *paddrinfo); + +/* + ENG: used to free all memory of paddrinfo; + CHN: 用于释放paddrinfo内存. +*/ +void layer_addr_free(struct layer_addr *paddrinfo); + + +/* + ENG : duplicate a same streaminfo list, memory obtained with malloc(3); + CHN : 复制一个完全相同的streaminfo结构体及父流结构, 内存通过malloc(3)获取. +*/ +struct streaminfo *streaminfo_dup(const struct streaminfo *stream); + +/* + ENG: used to free all memory of streaminfo; + CHN: 用于释放结构体及父流结构的内存. +*/ +void streaminfo_free(struct streaminfo *stream); + + +/* + addr list transform function, like inet_ntop(), inet_pton(), + use '<' as delimitation between layer, + if direction is double, for ip, port, use '-' as delimitation between source and destination, + + for example: + "T4T:6005-16730:转换后的结果实际占用内存长度, stream_addr_list_ntop()包含了字符串末尾的'\0'; + -1:dst缓存空间长度不足; + -2:格式错误; + -3:其他错误; +*/ +int stream_addr_list_ntop(const struct streaminfo *pstream, char *dst, int size); +int stream_addr_list_pton(const char *addr_list_str, void *dst, int size, int thread_index); + +/* + TCP,UDP流模式下, 获取当前IP包的原始分片包. +*/ +const raw_ipfrag_list_t *get_raw_frag_list(const struct streaminfo *stream); + +/* + IP插件模式下, 获取当前IP包的原始分片包. +*/ +const raw_ipfrag_list_t *ip_plug_get_raw_ipfrag_list(int thread_num, enum addr_type_t addr_type); + + +/* + 因为隧道、嵌套协议等原因, 输入一个纯四元组, 实际有可能查询到多个streaminfo, + 比如以下两个流: + (1) tuple4->gtp->ip->udp->ethernet; + (2) tuple4->l2tp->ip->udp->ethernet; + 如果隧道内层使用私有地址, 在一些极端凑巧的情况下, 流1和流2的内层tuple4可能是一样的, 但sapp会创建两个不同的streaminfo. + + 输入参数: + thread_index: 线程id; + tuple4v4 or tuple4v6: 四元组地址, 源、目的地址顺序无要求, C2S, S2c方向均可; + streamtype: 只支持两种类型, STREAM_TYPE_TCP or STREAM_TYPE_UDP; + array_max_num: 数组streaminfo_array的最大元素个数. + + 输出参数: + streaminfo_array: 查询到的符合输入四元组地址的streaminfo结构体指针. + + 返回值: + -1: error; + 0: 没有对应的streaminfo结构; + >0: 实际找到streaminfo结构的数量; +*/ +int find_streaminfo_by_addrv4(int thread_index, const struct stream_tuple4_v4 *tuplev4, enum stream_type_t streamtype, struct streaminfo *streaminfo_array[], int array_max_num); +int find_streaminfo_by_addrv6(int thread_index, const struct stream_tuple4_v6 *tuplev6, enum stream_type_t streamtype, struct streaminfo *streaminfo_array[], int array_max_num); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/MESA/stream_inc/stream_bridge.h b/include/MESA/stream_inc/stream_bridge.h new file mode 100644 index 0000000..3164854 --- /dev/null +++ b/include/MESA/stream_inc/stream_bridge.h @@ -0,0 +1,100 @@ +#ifndef _SAPP_STREAM_BRIDGE_H_ +#define _SAPP_STREAM_BRIDGE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +/***************************************** stream bridge API ************************************************* + + stream_bridge_xxx鎺ュ彛鐢ㄤ簬鍦ㄤ笉鍚屾彃浠朵箣闂, 鍒涘缓涓涓氶亾, 鏀寔鍚屾鍜屽紓姝ヤ袱绉嶆柟寮忎簰鐩搁氫俊, 鏀寔澶氬澶氱殑鍏崇郴. + + 鍚屾妯″紡閲囩敤callback娉ㄥ唽鏂瑰紡, 閬垮厤鐩存帴浣跨敤extern澹版槑鍑芥暟, 鍔ㄦ併佺伒娲汇佸彲鎵╁睍. + 寮傛妯″紡鏄湪streaminfo涓繚鐣欎竴浠芥暟鎹, 鍔熻兘鍚屼箣鍓嶇殑project_req_xxx绯诲垪鎺ュ彛. + + 鍋囪鎻掍欢plug A,X,Y,Z閮芥敞鍐屽悓涓涓猙ridge name:"bridge_demo", bridge_id=1, + + plug A浣跨敤寮傛妯″紡鍦╯treaminfo, bridge=1鐨勭┖闂村瓨鍌ㄤ簡涓浠芥暟鎹, receiver X,Y,Z鍙互鍦╯treaminfo鐢熷瓨鍛ㄦ湡鍐呭彇鏁版嵁. + ------------------- + | streaminfo | plug X + |-----------------| / + plug A-->|bridge1 -> data1 |/--plug Y + |-----------------|\ + |bridge2 -> data2 | \ plug Z + |-----------------| + |bridge3 -> data3 | + ------------------- + + + plugA鍙戦佷竴鏉″悓姝ユ秷鎭, receiver X,Y,Z閮藉彲浠ヤ緷娆℃敹鍒. + + -------------------- plug X + | / + plug A ->| bridge_id = 1 /--plug Y + | \ + | \ plug Z + -------------------- + +*******************************************************************************************************************/ + + +/* + bridge_name: 鍏ㄥ眬鍞竴, 涓庝箣鍓嶇殑project浣跨敤涓嶅悓鐨勫懡鍚嶇┖闂, 鍙互閲嶅悕, + 浣嗘槸bridge_id涓巔roject_req_id涓嶈兘閫氱敤!!! + + rw_mode绫讳技fopen鍑芥暟鐨勫弬鏁, 鍙敮鎸佷袱涓ā寮: + "r": 鍙,bridge_name涓嶅瓨鍦ㄥ垯杩斿洖閿欒; + "w": bridge_name涓嶅瓨鍦ㄥ垯鍒涘缓涓涓柊鐨刡ridge, + 娉ㄦ剰, 濡傛灉鍏朵粬鎻掍欢宸茬粡鍒涘缓浜嗗悓鍚峛ridge, 鍐嶆鐢"w"妯″紡鎵撳紑, 涓嶈兘鍍廸open浠ユ埅鏂ā寮忛噸鏂版墦寮涓涓枃浠, 鍏跺疄bridge_id鏄竴鏍风殑! + 寤鸿鍏堢敤"r"妯″紡楠岃瘉鏄惁鏈夋棤鍚屽悕bridge; + + 杩斿洖鍊兼槸bridge_id, + >=0 : success + <0 : error +*/ +int stream_bridge_build(const char *bridge_name, const char *rw_mode); + + +typedef void stream_bridge_free_cb_t(const struct streaminfo *stream, int bridge_id, void *data); +typedef int stream_bridge_sync_cb_t(const struct streaminfo *stream, int bridge_id, void *data); + + +/* + 娉ㄦ剰: free鍑芥暟鏈澶氬彧鑳芥湁涓涓, 鍚庨潰浼氳鐩栧墠闈㈢殑鍑芥暟鎸囬拡, 澶氭閲嶅娉ㄥ唽鍙繚鐣欐渶鍚庝竴涓! +*/ +int stream_bridge_register_data_free_cb(int bridge_id, stream_bridge_free_cb_t *free_cb_fun); + +/* sync鍥炶皟鍑芥暟鍙互鏄涓, 璋冪敤stream_bridge_sync_data_put()鏃, 浼氳皟鐢ㄦ墍鏈夋敞鍐岀殑callback鍑芥暟 */ +int stream_bridge_register_data_sync_cb(int bridge_id, stream_bridge_sync_cb_t *sync_cb_fun); + +/* + 杩斿洖鍊: + 0: 娌℃湁stream_bridge_sync_cb_t鍑芥暟; + -1: error + N: 鎴愬姛璋冪敤stream_bridge_sync_cb_t鍑芥暟鐨勬暟閲; +*/ +int stream_bridge_sync_data_put(const struct streaminfo *stream, int bridge_id, void *data); + +/* 绛夊悓浜庝箣鍓嶇殑project_req_add_xxx, 娉ㄦ剰濡傛灉data鏄痬alloc鐨勫唴瀛, 瑕佹敞鍐宻tream_bridge_free_cb_t, streaminfo鍦╟lose鏃朵細鑷姩free */ +int stream_bridge_async_data_put(const struct streaminfo *stream, int bridge_id, void *data); + +/* + 杩斿洖鍊: + 闈濶ULL: 鎻掍欢鏇剧粡璋冪敤stream_bridge_async_data_put()瀛樺偍鐨刣ata鍊. + NULL : 姝ゆ椂浼氫骇鐢熶竴绉嶆涔, 濡傛灉stream_bridge_async_data_put()灏辨槸瀛樹簡涓涓┖鎸囬拡, 鎴栬呭埄鐢–鐨勭壒鎬, 瀛樹簡涓涓暣鏁0, + 濡備綍鍖哄埆鏄敊璇繕鏄師濮嬫暟鎹氨鏄0锛 + + 濡傛灉杩斿洖鍊兼槸NULL鐨勬儏鍐典笅, 鎻掍欢瑕佸啀鍒ゆ柇涓涓媏rrno, errno == ENODATA (61), 璇存槑纭疄娌℃湁鎻掍欢鏇剧粡瀛樺偍杩囨暟鎹, 鏄釜閿欒. +*/ +void *stream_bridge_async_data_get(const struct streaminfo *stream, int bridge_id); /* 绛夊悓浜庝箣鍓嶇殑project_get_xxx */ + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/MESA/stream_inc/stream_control.h b/include/MESA/stream_inc/stream_control.h new file mode 100644 index 0000000..75e3bb6 --- /dev/null +++ b/include/MESA/stream_inc/stream_control.h @@ -0,0 +1,342 @@ +#ifndef _APP_STREAM_CONTROL_H_ +#define _APP_STREAM_CONTROL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define STREAM_CONTROL_H_VERSION (20210818) + +#define TCP_CTEAT_LINK_BYSYN 0x01 /* for MESA_stream_opt->MSO_TCP_CREATE_LINK_MODE */ +#define TCP_CTEAT_LINK_BYDATA 0x02 /* for MESA_stream_opt->MSO_TCP_CREATE_LINK_MODE */ + +/* + option of stream, + + MSO_IGNORE_RST_FIN: will not be terminated by RST, FIN packet, only if timeout or in LRU tail, it will be eliminated. +*/ +enum MESA_stream_opt{ + __MSO_PAD = 0, /* placeholder */ + MSO_MAX_UNORDER = 1, /* opt_val type must be struct max_unorder_opt */ + MSO_NEED_ACK, /* opt_val type must be unsigned char, value only be [0,1] */ + MSO_TAKEOVER, /* opt_val type must be int, value only be [0,1] */ + MSO_TIMEOUT, /* opt_val type must be unsigned short */ + MSO_IGNORE_RST_FIN, /* opt_val type must be unsigned char, value only be [0,1] */ + MSO_TCP_CREATE_LINK_MODE, /* opt_val must be unsigned char, refer to TCP_CTEAT_LINK_xxx */ + MSO_TCP_ISN_C2S, /* Host-order, opt_val type must be unsigned int */ + MSO_TCP_ISN_S2C, /* Host-order, opt_val type must be unsigned int */ + MSO_TCP_SYN_OPT, /* opt_val must be struct tcp_option **, opt_val_len [OUT} is struct tcp_option number, valid only if SYN packet is captured */ + MSO_TCP_SYNACK_OPT, /* opt_val must be struct tcp_option **, opt_val_len [OUT} is struct tcp_option number, valid only if SYN/ACK packet is captured */ + MSO_STREAM_TUNNEL_TYPE, /* opt_val must be unsigned short, refer to enum stream_carry_tunnel_t */ + MSO_STREAM_CLOSE_REASON, /* opt_val type must be unsigned char, refer to stream_close_reason_t */ + MSO_STREAM_VXLAN_INFO, /* opt_val type must be struct vxlan_info, only support for MAC-in-MAC encapsulation in mirror mode */ + MSO_TCPALL_VALID_AFTER_KILL, /* opt_val type must be unsigned char, value only be [0,1]; Warning, this option is obsolete, use MESA_rst_tcp() instead */ + MSO_GLOBAL_STREAM_ID, /* opt_val type must be unsigned long long, is value-result argument, IN: device_id, value range[0, 4095]; OUT:global stream id */ + MSO_DROP_STREAM, /* opt_val type must be int, value only be [0,1]; similar to DROPPKT, but effective scope is all subsequent packets of this stream. */ + MSO_TCP_RST_REMEDY, /* opt_val type must be int, value only be [0,1]; if not set this, default is disable. */ + MSO_TOTAL_INBOUND_PKT, /* inbound packet number of this stream, opt_val type must be unsigned long long */ + MSO_TOTAL_INBOUND_BYTE, /* inbound packet byte of this stream, opt_val type must be unsigned long long */ + MSO_TOTAL_OUTBOUND_PKT, /* outbound packet pkt of this stream, opt_val type must be unsigned long long */ + MSO_TOTAL_OUTBOUND_BYTE,/* outbound packet byte of this stream, opt_val type must be unsigned long long */ + MSO_STREAM_CREATE_TIMESTAMP_MS,/* first pkt arrive timestamp of this stream, opt_val type must be unsigned long long */ + MSO_TOTAL_INBOUND_BYTE_RAW, /* inbound packet byte of this stream, raw packet len, include ip hdr, ethernet hdr... opt_val type must be unsigned long long */ + MSO_TOTAL_OUTBOUND_BYTE_RAW,/* outbound packet byte of this stream, raw packet len, include ip hdr, ethernet hdr... opt_val type must be unsigned long long */ + MSO_STREAM_UP_LAYER_TUNNEL_TYPE, /* opt_val must be unsigned short, refer to enum stream_carry_tunnel_t */ + MSO_STREAM_PLUG_PME, /* opt_val type must be struct mso_plug_pme, this is a value-result argument, the caller should set plug_name and plug_entry_type, only support: TCP, TCP_ALL, UDP */ + MSO_DROP_CURRENT_PKT, /* opt_val type must be int, value only be [0,1], notice the difference between MSO_DROP_CURRENT_PKT and MSO_DROP_STREAM, MSO_DROP_CURRENT_PKT only discard current packet, but MSO_DROP_STREAM discard all subsequent packets of stream */ + MSO_HAVE_DUP_PKT, /* opt_val type must be int, value only be [0, 1, -2], if the current stream found duplicate packets ? 0:no; 1:yes; -2: not sure */ + __MSO_MAX, +}; + +/* for MSO_STREAM_CLOSE_REASON, + don't confuse, these values is not consecutive indeed, because some value(1,2) is obsoleted! +*/ +enum stream_close_reason_t{ + STREAM_CLOSE_REASON_SYN_REUSE = 0, /* for TCP tuple4 reuse */ + STREAM_CLOSE_REASON_NORMAL = 3, /* for TCP FIN, FIN/ACK */ + STREAM_CLOSE_REASON_RESET = 4, /* for TCP RESET */ + STREAM_CLOSE_REASON_TIMEOUT = 5, /* timeout */ + STREAM_CLOSE_REASON_LRUOUT = 6, /* stream table full, kick out */ + STREAM_CLOSE_REASON_DEPRIVE = 7, /* deprive by some plug who return KILL_FOLLOW or KILL_OTHER */ + STREAM_CLOSE_REASON_DUMPFILE = 8, /* only for pcap dumpfile mode */ +}; + + +enum sapp_platform_opt{ + SPO_TOTAL_RCV_PKT, /* total recv packet number, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_BYTE, /* total recv packet byte, opt_val type must be unsigned long long */ + SPO_REALTIME_RCV_PKT, /* realtime recv packet number, opt_val type must be unsigned long long */ + SPO_REALTIME_RCV_BYTE, /* realtime recv packet byte, opt_val type must be unsigned long long */ + SPO_THREAD_COUNT, /* total thread count, opt_val type must be int */ + SPO_CURTIME_TIMET, /* current time, opt_val type must be time_t */ + SPO_CURTIME_STRING, /* current time, opt_val type must be char[], opt_val_len must more than strlen("1970-01-01 01:01:01") */ + SPO_START_TIME, /* platform start time, opt_val type must be time_t */ + SPO_RUN_TIME, /* platform running time, opt_val type must be time_t */ + SPO_RAND_NUMBER, /* get a rand number, opt_val type must be long long */ + SPO_FIELD_STAT_HANDLE, /* field stat output handle, opt_val type must be void * */ + SPO_INDEPENDENT_THREAD_ID, /* plug independent thread which is created by pthread_create(), opt_val type must be int */ + SPO_DEPLOYMENT_MODE_STR, /* opt_val type is char[], optional value is:["mirror", "inline", "transparent"] */ + SPO_TCP_STREAM_NEW, /* total created tcp streams from start, opt_val type must be unsigned long long */ + SPO_TCP_STREAM_CLOSE, /* total closed tcp streams from start, opt_val type must be unsigned long long */ + SPO_TCP_STREAM_ESTAB, /* realtime established tcp streams, opt_val type must be unsigned long long */ + SPO_TOTAL_INBOUND_PKT, /* total inbound packet number, opt_val type must be unsigned long long */ + SPO_TOTAL_INBOUND_BYTE, /* total inbound packet bytes, opt_val type must be unsigned long long */ + SPO_TOTAL_OUTBOUND_PKT, /* total outbound packet number, opt_val type must be unsigned long long */ + SPO_TOTAL_OUTBOUND_BYTE, /* total outbound packet bytes, opt_val type must be unsigned long long */ + SPO_UDP_STREAM_NEW, /* total created udp streams from start, opt_val type must be unsigned long long */ + SPO_UDP_STREAM_CLOSE, /* total closed udp streams from start, opt_val type must be unsigned long long */ + SPO_UDP_STREAM_CONCURRENT, /* realtime Concurrent udp streams, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_INBOUND_IPV4_PKT, /* total recv ipv4 packet number, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_INBOUND_IPV4_BYTE, /* total recv ipv4 packet number, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_OUTBOUND_IPV4_PKT, /* total recv ipv4 packet bytes, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_OUTBOUND_IPV4_BYTE, /* total recv ipv4 packet bytes, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_INBOUND_IPV6_PKT, /* total recv ipv6 packet number, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_INBOUND_IPV6_BYTE, /* total recv ipv6 packet number, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_OUTBOUND_IPV6_PKT, /* total recv ipv6 packet bytes, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_OUTBOUND_IPV6_BYTE, /* total recv ipv6 packet bytes, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_INBOUND_TCP_PKT, /* total recv tcp packet number, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_INBOUND_TCP_BYTE, /* total recv tcp packet number, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_OUTBOUND_TCP_PKT, /* total recv tcp packet bytes, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_OUTBOUND_TCP_BYTE, /* total recv tcp packet bytes, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_INBOUND_UDP_PKT, /* total recv udp packet number, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_INBOUND_UDP_BYTE, /* total recv udp packet number, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_OUTBOUND_UDP_PKT, /* total recv udp packet bytes, opt_val type must be unsigned long long */ + SPO_TOTAL_RCV_OUTBOUND_UDP_BYTE, /* total recv udp packet bytes, opt_val type must be unsigned long long */ + SPO_CURTIME_TIMET_MS, /* current time in millisecond, opt_val type must be long long */ + SPO_CURRENT_STATE, /* running stage of sapp, opt_val type is enum sapp_state_t */ + SPO_CONFIG_ROOT_DIR, /* config file root directory, opt_val type must be char[], opt_val_len is value-result argument */ + SPO_DATA_ROOT_DIR, /* data or state file root directory, opt_val type must be char[], opt_val_len is value-result argument */ + SPO_DEPLOYMENT_MODE, /* Similar to SPO_DEPLOYMENT_MODE_STR, opt_val type is sapp_deploment_mode_t */ +}; + + +/* + option of device, +*/ +enum sapp_device_opt{ + __SDO_PAD = 0, /* placeholder */ + SDO_MAC_ADDR, /* device mac addr, opt_val type must be at least char[6] */ + SDO_IPV4_ADDR, /* device ipv4 addr in network order, opt_val type must be int */ + SDO_MTU, /* device MTU, opt_val type must be int */ + __SDO_MAX, +}; + +/* for MSO_MAX_UNORDER */ +struct max_unorder_opt{ + unsigned short stream_dir; /* refer to stream_base.h, DIR_C2S, DIR_S2C, DIR_DOUBLE */ + unsigned short max_unorder_val; +}; + +#define MAX_TCP_OPT_LEN (38) /* TCP头部长度最长为60字节, 去除标准头部剩余选项部分最长40字节, 选项数据部分最长38字节 */ +#define MAX_TCP_OPT_NUM (20) /* 单个TCP包最大选项数量 */ + +enum tcp_option_value{ + TCP_OPT_EOL = 0, + TCP_OPT_NOP = 1, + TCP_OPT_MSS = 2, + TCP_OPT_WIN_SCALE = 3, + TCP_OPT_SACK = 4, + TCP_OPT_SACK_EDGE = 5, + TCP_OPT_TIME_STAMP = 8, /* refer to struct tcp_option_ts */ + TCP_OPT_MD5 = 19, + TCP_OPT_MULTI_PATH_TCP = 0x1E, + TCP_OPT_RIVER_PROBE = 0x4c, +}; + +struct tcp_option_ts{ + unsigned int ts_self; + unsigned int ts_echo_reply; +}; + +struct tcp_option{ + unsigned char type; + unsigned char len; /* pure payload len, not contain type and this len field */ + union{ + unsigned char char_value; + unsigned short short_value; + unsigned int int_value; + unsigned long long long_value; + char *variable_value; + struct tcp_option_ts opt_ts_val; + }; +} __attribute__((packed, aligned(1))); + +struct tcp_option_ext{ + unsigned char type; + unsigned char len; + union{ + unsigned char char_value; + unsigned short short_value; + unsigned int int_value; + unsigned long long long_value; + char variable_value[MAX_TCP_OPT_LEN]; + struct tcp_option_ts opt_ts_val; + }; +} __attribute__((packed, aligned(1))); + + +/* 2018-10-24 lijia add, for pangu 项目mac_in_mac回流. + 理论上, sapp平台不应该关心和业务密切相关的东西, 比如mac里哪个字段是link_id, 哪个是dev_id, + 但这个玩意太底层了, 平台借用GDEV发送RST包也要填充这些值, 必须平台处理!! +*/ +/* 为了方便业务插件获取mac_in_mac地址里的具体信息, 不再使用原始的bit位域, 转换成变量形式 */ +struct vxlan_info{ + unsigned char encap_type; /* 原始二层封装格式 */ + unsigned char entrance_id; /* 设备所在出入口ID */ + unsigned char dev_id; /* 设备ID */ + unsigned char link_id; /* 链路ID */ + unsigned char link_dir; /* 链路方向, 指当前四元组的IP被捕获时的传输方向, 对于TCP, SYN包的传输方向; 对于UDP, 端口大IP的传输方向 */ + unsigned char inner_smac[18]; /* 内层真实SMAC, string类型, 例: "11:22:33:44:55:66" */ + unsigned char inner_dmac[18]; /* 内层真实DMAC, string类型, 例: "11:22:33:44:55:66" */ + unsigned char inner_smac_hex[6]; /* 内层真实SMAC, 原始二进制类型 */ + unsigned char inner_dmac_hex[6]; /* 内层真实DMAC, 原始二进制类型 */ +}; + + +enum sapp_state_t{ + SAPP_STATE_JUST_START, /* main() called by shell command */ + SAPP_STATE_CONFIG_PARSE, + SAPP_STATE_PLATFORM_INITING, + SAPP_STATE_PLATFORM_INITED, /* 3 */ + SAPP_STATE_PLUG_INITING, + SAPP_STATE_PLUG_INITED, /* 5 */ + SAPP_STATE_PKT_IO_INITING, + SAPP_STATE_PKT_IO_INITED, + SAPP_STATE_PROCESSING, /* 8 */ + SAPP_STATE_READY_TO_EXIT, /* 9, pcap dumpfile mode, or recv custom signal */ +}; + + +struct mso_plug_pme{ + const char *plug_name; /* argument: IN, comes from plug.inf-->[PLUGINFO]-->PLUGNAME */ + const char *plug_entry_type; /* argument: IN, only support: TCP, TCP_ALL, UDP. */ + void *plug_pme; /* argument: OUT, plug private memory address of current stream */ +}; + +enum sapp_deploment_mode_t{ + DEPOLYMENT_MODE_MIRROR = 1, + DEPOLYMENT_MODE_TRANSPARENT = 2, + DEPOLYMENT_MODE_INLINE = 3, +}; + + + +/* + plug call MESA_set_stream_opt() to set feature of specified stream. + opt: option type, refer to enum MESA_stream_opt; + opt_val: option value, depend on opt type; + opt_val_len: opt_val size; + + return value: + 0 :OK; + <0:error; +*/ +int MESA_set_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int opt_val_len); + + +/* + plug call MESA_get_stream_opt() to get feature of specified stream. + opt: option type, refer to enum MESA_stream_opt; + opt_val: option value, depend on opt type; + opt_val_len: value-result argment, IN:opt_val buf size, OUT:opt_val actual size; + + return value: + 0 :OK; + <0:error; +*/ +int MESA_get_stream_opt(const struct streaminfo *pstream, enum MESA_stream_opt opt, void *opt_val, int *opt_val_len); + + +/* + Get options from tcphdr, and store them in raw_result. + return value: + = 0: no option; + > 0: opt number; + < 0: error. +*/ +int MESA_get_tcp_pkt_opts(const struct tcphdr *tcphdr, struct tcp_option *raw_result, int res_num); + + +/* + Get options from tcphdr, and store them in raw_result. + return value: + = 0: no option; + > 0: opt number; + < 0: error. +*/ +int MESA_get_tcp_pkt_opts_ext(const struct tcphdr *tcphdr, struct tcp_option_ext *raw_result, int res_num); + +/* + plug call sapp_get_platform_opt() to get feature of platform. + opt: option type, refer to enum sapp_platform_opt; + opt_val: option value, depend on opt type; + opt_val_len: value-result argment, IN:opt_val buf size, OUT:opt_val actual size; + + return value: + 0 :OK; + <0:error; +*/ +int sapp_get_platform_opt(enum sapp_platform_opt opt, void *opt_val, int *opt_val_len); + + +/* + Get some options of hardware . + opt: option type, refer to enum sapp_device_opt; + opt_val: option value, depend on opt type; + opt_val_len: value-result argment, IN:opt_val buf size, OUT:opt_val actual size; + + return value: + 0 :OK; + <0:error; +*/ +int sapp_get_device_opt(const char *device, enum sapp_device_opt opt_type, void *opt_val, int *opt_val_len); + +/*************************************************************************************** + NOTE: + 在被动模式下, 插件无需关心route_dir的绝对值, 只需要理解同向和反向即可, + 但主动发包必须要精确理解route_dir是0还是1, 因外界网络拓扑模式不同, 可能随时会变化, + 所以设置此接口, 插件只需传入人易理解的方向human_dir, 返回当前链路的link route dir, + 注意首次部署时, etc/sapp.toml->inbound_route_dir一定要设置正确. + + args: 表示发包目标相对于当前设备所在的地理位置, + 'E' or 'e': 表示数据包传输方向是从Internal to External. + 'I' or 'i': 表示数据包传输方向是从External to Internal. + + return value: + 0 or 1: success. + -1 : error. +****************************************************************************************/ +int MESA_dir_human_to_link(int human_dir); + +/* + args: + 链路传输方向: 0或1, 通常来自stream->routedir; + + 返回值: + 'E' or 'e': 表示数据包传输方向是从Internal to External. + 'I' or 'i': 表示数据包传输方向是从External to Internal. + 'x': 参数错误; +*/ +int MESA_dir_link_to_human(int link_route_dir); + + + +/**************************************************************************************** + CHN : 因为历史遗留问题,此类函数保留仅为向后兼容,请使用新接口:MESA_set_stream_opt(). + ENG : for compat old version, keep these functions, but we suggest you use new API MESA_set_stream_opt(). +*****************************************************************************************/ +int tcp_set_single_stream_max_unorder(const struct streaminfo *stream, UCHAR dir, unsigned short unorder_num); +int tcp_set_single_stream_needack(const struct streaminfo *pstream); +int tcp_set_single_stream_takeoverflag(const struct streaminfo *pstream,int flag); +int stream_set_single_stream_timeout(const struct streaminfo *pstream,unsigned short timeout); +int get_thread_count(void); +/**************************************************************************************** +**************************************************************************************** +****************************************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/MESA/stream_inc/stream_entry.h b/include/MESA/stream_inc/stream_entry.h new file mode 100644 index 0000000..9fda956 --- /dev/null +++ b/include/MESA/stream_inc/stream_entry.h @@ -0,0 +1,98 @@ +#ifndef _APP_STREAM_ENTRY_H_ +#define _APP_STREAM_ENTRY_H_ + +#define STREAM_ENTRY_H_VERSION (20190818) + +/* + CHN : 业务层调用解析层时session_state状态; +*/ +#define SESSION_STATE_PENDING 0x01 +#define SESSION_STATE_DATA 0x02 +#define SESSION_STATE_CLOSE 0x04 + +//解析层调用业务层时的返回值; +#define PROT_STATE_GIVEME 0x01 +#define PROT_STATE_DROPME 0x02 +#define PROT_STATE_DROPPKT 0x04 + +//解析层插件调用业务层插件时传入参数 +typedef struct _plugin_session_info +{ + unsigned short plugid; //plugid,平台分配 + char session_state; //会话状态,PENDING,DATA,CLOSE + char _pad_; //补齐 + int buflen; //当前字段长度 + long long prot_flag; //当前字段的flag值 + void *buf; //当前字段 + void* app_info; //解析层上下文信息 +}stSessionInfo; + + + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef char (*STREAM_CB_FUN_T)(const struct streaminfo *pstream,void **pme, int thread_seq,const void *ip_hdr); +typedef char (*IPv4_CB_FUN_T)(const struct streaminfo *pstream,unsigned char routedir,int thread_seq, const void *ipv4_hdr); +typedef char (*IPv6_CB_FUN_T)(const struct streaminfo *pstream,unsigned char routedir,int thread_seq, const void *ipv6_hdr); + + +typedef char (*SAPP_PKT_CB_FUN_T)(const struct streaminfo *pstream, const void *this_hdr, const void *raw_pkt); +typedef char (*SAPP_STREAM_FUN_T)(const struct streaminfo *pstream, const void *this_hdr, const void *raw_pkt, void **pme); + + +/*参数描述: + a_*, pstream: 本流上下文信息; + raw_pkt: 原始包指针,获取相关信息使用get_opt_from_rawpkt()接口; + pme: 私有数据指针; + thread_seq:线程序号; + +函数返回值描述:为下面四个值的运算 + + APP_STATE_GIVEME:继续向本函数送包。 + APP_STATE_DROPME:不再向本函数送包。 + APP_STATE_FAWPKT:回注该数据包 + APP_STATE_DROPPKT:不回注该数据包 +*/ +char IPv4_ENTRY_EXAMPLE(const struct streaminfo *pstream,unsigned char routedir,int thread_seq, const void *ipv4_hdr); +char IPv6_ENTRY_EXAMPLE(const struct streaminfo *pstream,unsigned char routedir,int thread_seq,const void *ipv6_hdr); +char TCP_ENTRY_EXAMPLE(const struct streaminfo *a_tcp, void **pme, int thread_seq,const void *ip_hdr); +char UDP_ENTRY_EXAMPLE(const struct streaminfo *a_udp, void **pme, int thread_seq,const void *ip_hdr); + +char SAPP_PKT_EXAMPLE(const struct streaminfo *pstream, const void *this_hdr, const void *raw_pkt); +char SAPP_STREAM_EXAMPLE(const struct streaminfo *pstream, const void *this_hdr, const void *raw_pkt, void **pme); + +#define POLLING_STATE_WORK 0x80 +#define POLLING_STATE_IDLE 0x40 + +/* + 每隔一定时间, 平台会调用当前接口, 无论网络中是否有数据包. + stream, pme, a_packet固定都是NULL, thread_seq即收包线程的序号. + + 返回值: + POLLING_STATE_WORK: 此次回调插件做了若干有意义的事情; + POLLING_STATE_IDLE: 此次回调插件什么都没做, 或者想做而没做成, 比如非阻塞模式收包, 但实际没有收到包; +*/ +char POLLING_ENTRY(struct streaminfo *stream, void **pme, int thread_seq,void *a_packet); + + +/* + CHN : 业务层回调接口 ; + ENG : business plug API ; +*/ + +char PROT_PROCESS(stSessionInfo* session_info, void **pme, int thread_seq,struct streaminfo *a_stream,const void *a_packet); + +int libsapp_setup_env(int argc, char *argv[]); +void libsapp_destroy_env(void); + + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/include/MESA/stream_inc/stream_inject.h b/include/MESA/stream_inc/stream_inject.h new file mode 100644 index 0000000..68259f0 --- /dev/null +++ b/include/MESA/stream_inc/stream_inject.h @@ -0,0 +1,282 @@ +#ifndef _APP_STREAM_INJECT_H_ +#define _APP_STREAM_INJECT_H_ + +#include +#include +#include "stream_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define STREAM_INJECT_H_VERSION (20191120) + + +/* + CHN : 链接GK相关函数 + ENG : to force terminate a stream; + + MESA_kill_tcp: use RST to terminate a TCP stream; + MESA_kill_tcp_synack: send phony SYN/ACK packet to cheat client and server. + MESA_kill_connection: for non-TCP stream, such as UDP stream, only available in serial mode. + + return value: + >= 0: success. + -1 : error. +*/ +int MESA_kill_tcp(struct streaminfo *stream, const void *raw_pkt); +int MESA_kill_tcp_synack(struct streaminfo *stream, const void *raw_pkt); +int MESA_kill_connection(struct streaminfo *stream, const void *ext_raw_pkt); + +struct rst_tcp_para{ + unsigned char th_flags; /* TCP头部标志位, 可选值为[TH_RST, TH_RST|TH_ACK] */ + unsigned char rst_pkt_num; /* 调用一次MESA_rst_tcp()发送的rst包数量, 可选值[1,2,3], 针对单个方向, 即rst_pkt_num=2, dir=DIR_DOUBLE时,总发包数量是4个 */ + /* + dir: + 发送rst包方向, 可选值为[DIR_C2S, DIR_S2C, DIR_DOUBLE], 此值参考:streaminfo->curdir, + 如果待发送的包与当前包同向, dir = stream->curdir, + 如果待发送的包与当前包反向, dir = stream->curdir ^ 3, 即反向. + 如果是双向发送, dir = DIR_DOUBLE; + */ + unsigned char dir; + unsigned char __pad_no_use; /* padding for alignment */ + + /* + rst包指纹信息, 推荐值seed1=65535, seed2为素数, 如13,17,19等; + signature_seed1=0 && signature_seed1=0, 表示本次调用不指定signature, 使用全局配置, 规则如下: + if(sapp.toml->stream.tcp.inject.signature_enabled == 1){ + signature_seed1 = sapp.toml->stream.tcp.inject.signature_seed1; + signature_seed2 = sapp.toml->stream.tcp.inject.signature_seed2; + }else{ + signature_seed1 = rand(); + signature_seed2 = rand(); + } + */ + unsigned short signature_seed1; + unsigned short signature_seed2; +}; + +/* + args: + stream: 当前流上下文; + paras : 发送rst相关参数, 详见struct rst_tcp_para结构体说明; + para_len: sizeof(struct rst_tcp_para), 预留后续升级需求, 根据此长度判断版本. + + MESA_rst_tcp与MESA_kill_tcp区别: + MESA_kill_tcp实际上是几个动作的大杂烩: 发送RST包, 类似返回了APP_STATE_KILL_OTHER, 及DROP当前流后续所有包; + MESA_rst_tcp只专心做一件事情: 发送RST包! + + note: 除上面的参数之外, kill_tcp还有一个特性是FD补救, + 即可能因为丢包、序号错误、网络延时等原因, 导致单次FD不生效, 调用MESA_kill_tcp之后可以自动进行FD补救, + 但对于MESA_rst_tcp来说, 所有行为只对当前包有效, + remedy功能是作用于整个stream的, 需要调用MESA_set_stream_opt(), opt=MSO_TCP_RST_REMEDY 完成. + + return value: + >= 0: success. + -1 : error. +*/ +int MESA_rst_tcp(struct streaminfo *stream, struct rst_tcp_para *paras, int para_len); + + + +/* + 带反馈功能的MESA_kill_xxx系列函数. + 附加功能为: + 将实际发送的数据包copy到feedback_buf空间内, 并设置feedback_buf_len为实际数据包长度. + + 注意: feedback_buf_len为传入传出参, 传入表示feedback_buf长度, 传出表示实际发送的数据包长度. + + return value: + >= 0: success. + -1 : error. + -2 : feedback_buf or feedback_buf_len error. +*/ +int MESA_kill_tcp_feedback(struct streaminfo *stream, const void *raw_pkt, char *feedback_buf, int *feedback_buf_len); +int MESA_kill_tcp_synack_feedback(struct streaminfo *stream, const void *raw_pkt, char *feedback_buf, int *feedback_buf_len); +int MESA_kill_connection_feedback(struct streaminfo *stream, const void *raw_pkt, char *feedback_buf, int *feedback_buf_len); + +/* + CHN : 反向route_dir函数, 为了兼容papp; + ENG : compat for papp, dir reverse. + */ +unsigned char MESA_dir_reverse(unsigned char raw_route_dir); + +/*************************************************************************************** + NOTE: + 在被动模式下, 插件无需关心route_dir的绝对值, 只需要理解同向和反向即可, + 但主动发包必须要精确理解route_dir是0还是1, 因外界网络拓扑模式不同, 可能随时会变化, + 所以设置此接口, 插件只需传入人易理解的方向, 返回当前链路的link route dir, + 注意etc/sapp.toml inbound_route_dir要设置正确. + + args: 表示发包目标相对于当前设备所在的地理位置, + 'E' or 'e': 表示发包方向是从Internal to External. + 'I' or 'i': 表示发包方向是从External to Internal. + + return value: + 0 or 1: success. + -1 : error. +****************************************************************************************/ +int MESA_dir_human_to_link(int human_dir); + +/* + ARG: + stream: 流结构体指针; + payload: 要发送的数据指针; + payload_len: 要发送的数据负载长度; + raw_pkt: 原始包指针; + snd_routedir: 要发送数据的route方向, + 如果待发送的包与当前包同向, snd_routedir = stream->routedir, + 如果待发送的包与当前包反向, snd_routedir = MESA_dir_reverse(stream->routedir). + return value: + -1: error. + >0: 发送的数据包实际总长度(payload_len + 底层包头长度); +*/ +int MESA_inject_pkt(struct streaminfo *stream, const char *payload, int payload_len, const void *raw_pkt, UCHAR snd_routedir); + + +/* + 带反馈功能的MESA_inject_pkt_feedback函数, 功能同MESA_inject_pkt(). + 将实际发送的数据包copy到feedback_buf空间内, 并设置feedback_buf_len为实际数据包长度. + + 注意: feedback_buf_len为传入传出参, 传入表示feedback_buf长度, 传出表示实际发送的数据包长度. + + return value: + >= 0: success. + -1 : error. + -2 : feedback_buf or feedback_buf_len error. +*/ +int MESA_inject_pkt_feedback(struct streaminfo *stream, const char *payload, int payload_len, + const void *ext_raw_pkt, UCHAR snd_routedir, + char *feedback_buf, int *feedback_buf_len); + +int MESA_sendpacket_ethlayer(int thread_index,const char *buf, int buf_len, unsigned int target_id);//papp online, shuihu + +/* 发送已构造好的完整IP包, 校验和等均需调用者计算 */ +int MESA_sendpacket_iplayer(int thread_index,const char *buf, int buf_len, __uint8_t dir); + +/* 发送已构造好的完整IPv4包, 用于vxlan环境, options用于填充和vxlan相关的选项 */ +int MESA_sendpacket_iplayer_options(int thread_index,const char *data, int data_len, u_int8_t dir, SAPP_TLV_T *options, int opt_num); + +/* 发送已构造好的完整IPv6包, 校验和等均需调用者计算, 用于vxlan环境, options用于填充和vxlan相关的选项 */ +int MESA_sendpacket_ipv6_layer_options(int thread_index,const char *data, int data_len, u_int8_t dir, SAPP_TLV_T *options, int opt_num); +/* 发送指定参数IP包, 可指定负载内容, 校验和由平台自动计算, + sip, dip为主机序. */ +int MESA_fakepacket_send_ipv4(int thread_index,__uint8_t ttl,__uint8_t protocol, + u_int32_t sip_host_order, u_int32_t dip_host_order, + const char *payload, int payload_len,__uint8_t dir); + +int MESA_fakepacket_send_ipv4_options(const struct streaminfo *stream, uint8_t protocol, + uint32_t sip_host_order, uint32_t dip_host_order, + const char *payload, int payload_len, uint8_t dir, + SAPP_TLV_T *options, int opt_num); + +int MESA_fakepacket_send_ipv4_detail(int thread_index,u_int8_t ttl, + u_int8_t protocol,u_int32_t sip, u_int32_t dip, u_int16_t ipid, + const char *payload, int payload_len,u_int8_t dir); + +int MESA_fakepacket_send_ipv6_options(const struct streaminfo *stream, uint8_t protocol, + struct in6_addr *sip, struct in6_addr *dip, + const char *payload, int payload_len, uint8_t dir, + SAPP_TLV_T *options, int opt_num); +/* 发送指定参数TCP包, 可指定负载内容, 校验和由平台自动计算, + sip, dip,sport,dport,sseq,sack都为主机序. */ +int MESA_fakepacket_send_tcp(int thread_index,u_int sip_host_order,u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control,const char* payload,int payload_len, u_int8_t dir); + +int MESA_fakepacket_send_tcp_detail(int thread_index,u_int sip_host_order,u_int dip_host_order, + u_short ipid, u_char ip_ttl, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control, u_short tcp_win, const char* payload,int payload_len, u_int8_t dir); +int MESA_fakepacket_send_tcp_options(const struct streaminfo *stream, + u_int sip_host_order,u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control, + const char* payload,int payload_len, u_int8_t dir, + SAPP_TLV_T *options, int opt_num); +int MESA_fakepacket_send_ipv6_tcp_options(const struct streaminfo *stream, + struct in6_addr *sip, struct in6_addr *dip, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control, + const char* payload,int payload_len, u_int8_t dir, + SAPP_TLV_T *options, int opt_num); +/* 发送指定参数UDP包, 可指定负载内容, 校验和由平台自动计算, + sip, dip,sport,dport都为主机序. */ +int MESA_fakepacket_send_udp(int thread_index, u_int sip_host_order, u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir); + +int MESA_fakepacket_send_udp_detail(int thread_index, u_int sip_host_order, u_int dip_host_order, + u_short ipid, u_int8_t ip_ttl, u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir); +int MESA_fakepacket_send_udp_options(const struct streaminfo *stream, + u_int sip_host_order, u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir, + SAPP_TLV_T *options, int opt_num); +int MESA_fakepacket_send_ipv6_udp_options(const struct streaminfo *stream, + struct in6_addr *sip, struct in6_addr *dip, + u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir, + SAPP_TLV_T *options, int opt_num); +/* + 转发/发送当前上下文数据包, + target_id: 用于指定转发/发送目标, 由配置文件conf->send_raw_pkt.conf指定最终目标网卡或设备号. +*/ +int sapp_forward_current_pkt(const struct streaminfo *stream, unsigned int target_id); + +enum sapp_send_pkt_opt_type{ + SAPP_SEND_OPT_IP_ID = 0x10, + SAPP_SEND_OPT_IP_TTL = 0x11, + + SAPP_SEND_OPT_TCP_WIN = 0x20, + + SAPP_SEND_OPT_GDEV_DMAC = 0x1101, /* GDEV-DMAC, 整个包的最外层DMAC */ + SAPP_SEND_OPT_GDEV_SMAC = 0x1102, /* local-SMAC, 整个包的最外层SMAC */ + SAPP_SEND_OPT_GDEV_DIP = 0x1103, /* GDEV-DIP, network order */ + SAPP_SEND_OPT_GDEV_SIP = 0x1104, /* local-SIP, network order */ + SAPP_SEND_OPT_GDEV_UDP_DPORT=0x1105, /* GDEV udp dst port, network order */ + SAPP_SEND_OPT_GDEV_UDP_SPORT= 0x1106, /* local udp src port, network order */ + SAPP_SEND_OPT_VXLAN_FLAGS = 0x1201, /* vxlan 标志位 */ + SAPP_SEND_OPT_VXLAN_VPN_ID = 0x1202, /* vxlan vlan_id/vpn_id */ + SAPP_SEND_OPT_VXLAN_LINK_ID = 0x1203, /* vxlan 链路id */ + SAPP_SEND_OPT_VXLAN_LINK_ENCAP_TYPE = 0x1204, /* vxlan原始二层封装格式 */ + SAPP_SEND_OPT_VXLAN_ONLINE_TEST_FLAG = 0x1205, /* vxlan在线测试位 */ + SAPP_SEND_OPT_VXLAN_LINK_DIR = 0x1206, /* vxlan链路方向位 */ + SAPP_SEND_OPT_INNER_LINK_ENCAP_TYPE = 1301, /* 内层二层封装格式 */ + SAPP_SEND_OPT_INNER_SMAC = 0x1302, /* 内层源MAC */ + SAPP_SEND_OPT_INNER_DMAC = 0x1303, /* 内层目的MAC */ + SAPP_SEND_OPT_INNER_VLANID = 0x1304, /* 内层如果有VLAN需设置 */ + SAPP_SEND_OPT_VIRTUAL_LINK_ID = 0x1305, /* 设置虚拟链路号, 同时需要置TUNNAT_CZ_ACTION_ENCAP_VIRTUAL_LINK_ID*/ + SAPP_SEND_OPT_REHASH_INDEX = 0x1306, /*设置rehash index, 同时需要置TUNNAT_CZ_ACTION_ENCAP_VIRTUAL_LINK_ID*/ +}; + +int MESA_fakepacket_send_ipv4_options(const struct streaminfo *stream, uint8_t protocol, + uint32_t sip_host_order, uint32_t dip_host_order, + const char *payload, int payload_len, uint8_t dir, + SAPP_TLV_T *options, int opt_num); + +int MESA_fakepacket_send_tcp_options(const struct streaminfo *stream, + u_int sip_host_order,u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + u_int sseq_host_order,u_int sack_host_order, + u_char control, + const char* payload,int payload_len, u_int8_t dir, + SAPP_TLV_T *options, int opt_num); + +int MESA_fakepacket_send_udp_options(const struct streaminfo *stream, + u_int sip_host_order, u_int dip_host_order, + u_short sport_host_order,u_short dport_host_order, + const char *payload, int payload_len,u_int8_t dir, + SAPP_TLV_T *options, int opt_num); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/MESA/stream_inc/stream_project.h b/include/MESA/stream_inc/stream_project.h new file mode 100644 index 0000000..f28fc17 --- /dev/null +++ b/include/MESA/stream_inc/stream_project.h @@ -0,0 +1,160 @@ +#ifndef _STREAM_PROJECT_H_ +#define _STREAM_PROJECT_H_ + +#include "stream_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define STREAM_PROJECT_H_VERSION (20210422) + +#define PROJECT_REQ_NAME_MAX_LEN (64) + +typedef void (project_req_free_t)(int thread_seq, void *project_req_value); + +#define PROJECT_VAL_TYPE_CHAR "char" +#define PROJECT_VAL_TYPE_SHORT "short" +#define PROJECT_VAL_TYPE_INT "int" +#define PROJECT_VAL_TYPE_LONG "long" +#define PROJECT_VAL_TYPE_STRUCT "struct" + +/* + CHN : 用于存储全部IP分片原始包 + ENG : for store all ip frag packet in non-ip-frag entry. +*/ +#define PROJECT_REQ_IPV4_FRAG_LIST "ipv4_frag_list" +#define PROJECT_REQ_IPV6_FRAG_LIST "ipv6_frag_list" + + +/* + CHN : 此宏定义表示TCP流量统计功能在project_list.conf中名称, 对应的project_id需要使用如下函数获取: + ENG : this MARCO is use for tcp flow statistics, should enable this in project_list.conf. + project_customer_register(PROJECT_REQ_TCP_FLOW, "struct"); +*/ +#define PROJECT_REQ_TCP_FLOW "tcp_flow_stat" + + +#define PROJECT_REQ_TCP_DEDUCE_FLOW "tcp_deduce_flow_stat" + +/* + CHN : UDP流量统计功能平台固定开启, 不依赖project_list.conf控制, 对应的project_id需要使用如下函数获取: + ENG : this MARCO is use for tcp flow statistics, it's always enable. + project_customer_register(PROJECT_REQ_UDP_FLOW, "struct"); +*/ +#define PROJECT_REQ_UDP_FLOW "udp_flow_stat" + +/* + CHN : 将包数,字节数统计值从pdetail中移动到project,字节数扩展为64bit. + ENG : before 2015-12-31, this statistics in struct streaminfo, after 2015-12-31, you must get these use project_req_get_struct(). +*/ +struct tcp_flow_stat +{ + UINT32 C2S_all_pkt; /* All tcp packets, include SYN, ACK, FIN, RST, etc. */ + UINT32 C2S_data_pkt; /* TCP reassemble packet, payload size more than zero, no retransmit packet */ + UINT32 S2C_all_pkt; + UINT32 S2C_data_pkt; + UINT64 C2S_all_byte; /* All tcp packet's data size, include retransmit packet */ + UINT64 C2S_data_byte; + UINT64 S2C_all_byte; + UINT64 S2C_data_byte; + + /* 以下是2020-11-17新增, 包括所有底层包头的原始包长度, 之前的内存结构不变, 向前兼容 */ + UINT64 C2S_all_byte_raw; + UINT64 S2C_all_byte_raw; +}; + +struct udp_flow_stat +{ + UINT32 C2S_pkt; + UINT32 S2C_pkt; + UINT64 C2S_byte; + UINT64 S2C_byte; + + /* 以下是2020-11-17新增, 包括所有底层包头的原始包长度, 之前的内存结构不变, 向前兼容 */ + UINT64 C2S_all_byte_raw; + UINT64 S2C_all_byte_raw; +}; + +/* + must call this function in initialization, only one times, + the 'free_cb' should be NULL if 'project_req_val_type' is simple type, + otherwise must implement it by youself. + + args: + project_req_name: for example, "terminal_tag", "stream_id", "tcp_flow_stat". + project_req_val_type: support "char","short","int","long","struct". + free_cb: used to free resource when 'project_req_val_type' is "struct". + + return value: 'project_req_id' of this project_req_name, must use this id in following functions. + >= 0 : success; + -1 : error. +*/ +int project_producer_register(const char *project_req_name, const char *project_req_val_type, project_req_free_t *free_cb); + +/* args and return value same with project_producer_register() */ +int project_customer_register(const char *project_req_name, const char *project_req_val_type); + + +/* + Function project_req_add_struct(): 'project_req_value' must be a pointer to heap memory(obtain by malloc). + + return value: + 0 : success; + -1: error. +*/ +int project_req_add_char(struct streaminfo *stream, int project_req_id, char project_req_value); +int project_req_add_short(struct streaminfo *stream, int project_req_id, short project_req_value); +int project_req_add_int(struct streaminfo *stream, int project_req_id, int project_req_value); +int project_req_add_long(struct streaminfo *stream, int project_req_id, long project_req_value); + +int project_req_add_uchar(struct streaminfo *stream, int project_req_id, unsigned char project_req_value); +int project_req_add_ushort(struct streaminfo *stream, int project_req_id, unsigned short project_req_value); +int project_req_add_uint(struct streaminfo *stream, int project_req_id, unsigned int project_req_value); +int project_req_add_ulong(struct streaminfo *stream, int project_req_id, unsigned long project_req_value); + + +int project_req_add_struct(struct streaminfo *stream, int project_req_id, const void *project_req_value); + + +/* + return value: + -1(or all bit is '1' in Hex mode, 0xFF, 0xFFFF, etc.): + maybe error, maybe the actual project_req_value is -1 indeed, + must check tht 'errno' in this case, + the 'errno' will be set to 'ERANGE' indicate an error. + other: success, get the stored value. + + For example: + int value = project_req_get_int(stream, req_id); + if((-1 == value) && (ERANGE == errno)){ + error_handle(); + }else{ + // this is not an error!! + do_something(); + } +*/ +char project_req_get_char(const struct streaminfo *stream, int project_req_id); +short project_req_get_short(const struct streaminfo *stream, int project_req_id); +int project_req_get_int(const struct streaminfo *stream, int project_req_id); +long project_req_get_long(const struct streaminfo *stream, int project_req_id); + +unsigned char project_req_get_uchar(const struct streaminfo *stream, int project_req_id); +unsigned short project_req_get_ushort(const struct streaminfo *stream, int project_req_id); +unsigned int project_req_get_uint(const struct streaminfo *stream, int project_req_id); +unsigned long project_req_get_ulong(const struct streaminfo *stream, int project_req_id); + +/* + return value: + NULL : error; + others: success. +*/ +const void *project_req_get_struct(const struct streaminfo *stream, int project_req_id); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/MESA/stream_inc/stream_proxy.h b/include/MESA/stream_inc/stream_proxy.h new file mode 100644 index 0000000..4f8408e --- /dev/null +++ b/include/MESA/stream_inc/stream_proxy.h @@ -0,0 +1,53 @@ +#ifndef _STREAM_PROXY_H_ +#define _STREAM_PROXY_H_ + +#include "stream_base.h" + +#define STREAM_PROXY_H_VERSION (20151230) + + +#define PROXY_STATE_SEL 0 +#define PROXY_STATE_LINK_IN 1 + +// 代理信息 +struct proxydetail +{ + UINT16 iType; // 代理类型, 0 表示无效 + UINT16 uiPort; // 代理的真实服务器端口 + UINT16 uiUserLen; + UINT16 uiPwdLen; + UINT16 uiApendLen; + + UCHAR pad; + UCHAR dealstate; //代理处理状态 + UINT32 uiIP; // 代理的真实服务器IP地址v4, 按网络字节序 + UCHAR *pIpv6; // 代理的真实服务器IP地址, v6地址 + UCHAR *pUser; // 代理用户名 + UCHAR *pPwd; // 代理密码 + UCHAR *append; // 其它附属信息,比如url + void *apme; //应用层上下文 + void *pAllpktpme; //无状态的tcp管理上下文 + UINT32 serverpktnum; + UINT32 clientpktnum; + UINT32 serverbytes; + UINT32 clientbytes; +} ; + +#ifdef __cplusplus +extern "C" { +#endif + +/*把一个代理的信息虚拟成一个fatherstream,并且挂载到stream上*/ +void set_proxy_fstream(struct streaminfo *pstream,struct streaminfo *pProxy); + +/*当代理自身的信息处理完成后,进行 内层 调用*/ +int deal_tcp_in_proxy_stream(struct streaminfo *a_tcp,void * a_packet,struct streaminfo *pProxy); + +/*回调上层信息,释放代理保存的相关信息*/ +void free_tcp_proxy_stream(struct streaminfo *pstream,struct streaminfo *pProxy); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/MESA/stream_inc/stream_rawpkt.h b/include/MESA/stream_inc/stream_rawpkt.h new file mode 100644 index 0000000..df39545 --- /dev/null +++ b/include/MESA/stream_inc/stream_rawpkt.h @@ -0,0 +1,112 @@ +#ifndef _APP_STREAM_RAWPKT_H_ +#define _APP_STREAM_RAWPKT_H_ + +#define STREAM_RAWPKT_H_VERSION (20201104) + +#include "stream_base.h" + +enum{ + RAW_PKT_GET_DATA = 1, //return value is 0: out_value should be void **; return value is 1: out_value type is raw_ipfrag_list_t **; + RAW_PKT_GET_RAW_PKT_TYPE, //value type: enum addr_type_t in stream_base.h, out_value should be enum addr_type_t* + RAW_PKT_GET_TOT_LEN, //value type: int , out_value should be int * + RAW_PKT_GET_TIMESTAMP, //value type: struct timeval , out_value should be struct timeval * + RAW_PKT_GET_THIS_LAYER_HDR, //value type: void *, out_value should be void ** + RAW_PKT_GET_THIS_LAYER_REMAIN_LEN, //value type: int , out_value should be int * + RAW_PKT_GET_GDEV_IP, // network-order, value type is int, out_value should be int * + RAW_PKT_GET_VXLAN_ID, // network-order, LINK_ID, not VPN_ID, value type is int, out_value should be int * + RAW_PKT_GET_VXLAN_SPORT, // network-order, value type is short, out_value should be short * + RAW_PKT_GET_VXLAN_ENCAP_TYPE, //value type is char, + RAW_PKT_GET_VXLAN_LINK_DIR, //value type is char, + RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC, //value type is char[6], + RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC, //value type is char[6], + RAW_PKT_GET_VIRTUAL_LINK_ID, //value type is uint64 *, out_value should be uint64 * + RAW_PKT_GET_REHASH_INDEX, // value type is uint64 *, out_value should be uint64 * + RAW_PKT_GET_VXLAN_VPNID, // network-order, VPN_ID, value type is int, out_value should be int * + RAW_PKT_GET_VXLAN_LOCAL_IP, // network-order, VXLAN Local IP, value type is int, out_value should be int * + + RAW_PKT_GET_ORIGINAL_LOWEST_ETH_SMAC, /* value type is char[6],真实原始包最外层的smac地址,mirror模式下, 等同于RAW_PKT_GET_DATA, 或者使用stream->pfather自行偏移; inline + vxlan + mrtunnat模式下, 等同于RAW_PKT_GET_VXLAN_OUTER_GDEV_MAC; */ + RAW_PKT_GET_ORIGINAL_LOWEST_ETH_DMAC, /* value type is char[6],真实原始包最外层的dmac地址,mirror模式下, 等同于RAW_PKT_GET_DATA, 或者使用stream->pfather自行偏移; inline + vxlan + mrtunnat模式下, 等同于RAW_PKT_GET_VXLAN_OUTER_LOCAL_MAC; */ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + get option from raw packet. + +for example: + CHN : 获取原始包数据, (根据捕包类型的不同, 可能从MAC开始, 也可能从IP头部开始, 需要使用RAW_PKT_GET_RAW_PKT_TYPE获取); + ENG : get raw packet header, header's type depend on raw pacekt type, you should use RAW_PKT_GET_RAW_PKT_TYPE first; + + void *raw_pkt_data; + ret = get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_DATA, &raw_pkt_data); + if(0 == ret){ + (struct mesa_ethernet_hdr *)raw_pkt_data; + }else if(1 == ret){ + (raw_ipfrag_list_t *)raw_pkt_data; + }else{ + error! + } + + CHN : 获取原始包总长度; + ENG : get raw packet size; + int tot_len; + get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_TOT_LEN, &tot_len); + + CHN : 获取本层包头起始地址: + ENG : get this layer header; + void *this_layer_hdr; + get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_THIS_LAYER_HDR, &this_layer_hdr); + + CHN : 获取原始包时间戳, 如果网卡或底层捕包库不支持时间戳功能, 值为全0: + ENG : get raw packet timestamp, maybe zero if network card or library not support. + struct timeval pkt_stamp; + get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_TIMESTAMP, &pkt_stamp); + + return value: + 1:only for RAW_PKT_GET_DATA type, value is raw_ipfrag_list_t; + 0:success; + -1:error, or not support. +*/ +int get_opt_from_rawpkt(const void *rawpkt, int type, void *out_value); + +/* + CHN: 功能同上, 传入参数不同. + ENG: Function ibid, except args pstream. +*/ +int get_rawpkt_opt_from_streaminfo(const struct streaminfo *pstream, int type, void *out_value); + +/* + 获取本层流在原始包中对应的头部地址, + 注意: 如果本层流类型为TCP或UDP, 调用此函数后, 得到原始包中对应的承载本层传输层的IP头部地址. +*/ +const void *get_this_layer_header(const struct streaminfo *pstream); + +/* + CHN : 数据包头部偏移函数. + ENG : + + 参数: + raw_data: 当前层的头部指针; + raw_layer_type: 当前层的地址类型, 详见: enum addr_type_t ; + expect_layer_type: 期望跳转到的地址类型, 详见: enum addr_type_t ; + + 返回值: + NULL: 无此地址; + NON-NULL: 对应层的头部地址. + + + 举例: + 假设当前层为Ethernet, 起始包头地址为this_layer_hdr, 想跳转到IPv6层头部: + struct ip6_hdr *ip6_header; + ip6_header = MESA_jump_layer(this_layer_hdr, ADDR_TYPE_MAC, ADDR_TYPE_IPV6); +*/ +const void *MESA_jump_layer(const void *raw_data, int raw_layer_type, int expect_layer_type); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/MESA/stream_inc/stream_tunnel.h b/include/MESA/stream_inc/stream_tunnel.h new file mode 100644 index 0000000..bada140 --- /dev/null +++ b/include/MESA/stream_inc/stream_tunnel.h @@ -0,0 +1,104 @@ +#ifndef _APP_STREAM_TUNNEL_H_ +#define _APP_STREAM_TUNNEL_H_ 1 + +#define STREAM_TUNNEL_H_VERSION (20161201) + +#ifdef __cplusplus +extern "C" { +#endif + +enum tunnel_channel_type_t{ + TUNNEL_CHANNEL_TYPE_CONTROL = 1, /* 隧道协议控制通道 */ + TUNNEL_CHANNEL_TYPE_DATA = 2, /* 隧道协议数据通道 */ +}; + +enum tunnel_content_type_t{ + TUNNEL_CONTENT_TYPE_CLEAR = 1, /* 明文数据 */ + TUNNEL_CONTENT_TYPE_COMPRESS = 2, /* 压缩数据 */ + TUNNEL_CONTENT_TYPE_ENCRYPT = 3, /* 加密数据 */ +}; + +#define PPTP_ENCRYPT_MPPE (1) +#define PPTP_ENCRYPT_IPSEC (2) +#define PPTP_ENCRYPT_PAP (3) +#define PPTP_ENCRYPT_CHAP (4) +#define PPTP_ENCRYPT_MS_CHAP (5) +#define PPTP_ENCRYPT_EAP_TLS (6) + +#define PPTP_ENCRYPT_MPPC (100) /* 压缩算法, 但日志库表中不存在, 使用100, 预留上述值的扩展空间 */ + +typedef struct{ + int link_type; + int encrypt_pro; + int authentication_pro; + int protocol_compress_enable; + int addr_ctrl_compress_enable; + int content_type; /* refer to tunnel_content_type_t */ +}pptp_info_t; + + +#define L2TP_ENCRYPT_OTHER (0) +#define L2TP_ENCRYPT_IPSEC (1) +#define L2TP_ENCRYPT_NONE (2) + +typedef struct{ + int link_type; + int encrypt_pro; + int authentication_pro; + int protocol_compress_enable; + int addr_ctrl_compress_enable; + int content_type; /* tunnel_content_type_t */ + char *chap_username; /* string end with '\0' */ +}l2tp_info_t; + +#define IPSEC_VERSION_ISAKMP_V1 (1) +#define IPSEC_VERSION_IKE_V2 (2) + + +typedef struct{ + unsigned long long init_cookie; + unsigned long long resp_cookie; + unsigned short encry_algo; + unsigned short hash_algo; + unsigned short auth_method; + unsigned char upon_udp_nat; /* 是否基于UDP-4500端口的NAT */ + unsigned char exchange_type; + unsigned char major_version; + unsigned char minor_version; +}isakmp_info_t; + +typedef enum{ + /* NOTE: 很多协议相关的值并不连续, 因为需求不断再增加, 已有的定义不能改动, 只能再后面追加新值 */ + TUNNEL_PHONY_PROT_FLAG = 1<<0, /* phony flag, meaningless */ + IPSEC_OPT_IKE_VERSION = 1<<1, /* opt_val type is int* */ + IPSEC_OPT_ENCRYPT_ALGO = 1<<2, /* opt_val type is int* */ + IPSEC_OPT_HASH_ALGO = 1<<3, /* opt_val type is int* */ + PPTP_OPT_LINK_TYPE = 1<<4, /* opt_val type is int* */ + PPTP_OPT_ENCRYPT_PRO = 1<<5, /* opt_val type is int* */ + PPTP_OPT_AUTHEN_PRO = 1<<6, /* opt_val type is int* */ + PPTP_OPT_COMPRESS_PRO = 1<<7, /* opt_val type is int* */ + L2TP_OPT_LINK_TYPE = 1<<8, /* opt_val type is int* */ + L2TP_OPT_ENCRYPT_PRO = 1<<9, /* opt_val type is int* */ + IPSEC_OPT_EXCHG_MODE = 1<<10, /* opt_val type is uint8*, just a 8bit integer, not string */ + IPSEC_OPT_IS_NAT = 1<<11, /* opt_val type is uint8*, just a 8bit integer, not string */ + L2TP_OPT_CHAP_USER_NAME = 1<<12, /* opt_val type is string, end with '\0' */ + PPTP_CONTENT_TYPE = 1<<13, /* opt_val type is int*, refer to enum tunnel_content_type_t */ + L2TP_CONTENT_TYPE = 1<<14, /* opt_val type is int*, refer to enum tunnel_content_type_t */ +}tunnel_info_opt_t; + + +struct MESA_tunnel_info{ + int tunnel_type; /* refer to stream_base.h --> enum stream_type_t */ + union{ + pptp_info_t pptp_info; + l2tp_info_t l2tp_info; + isakmp_info_t isakmp_info; + }; +}; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/MESA/wiredLB.h b/include/MESA/wiredLB.h new file mode 100644 index 0000000..21daa20 --- /dev/null +++ b/include/MESA/wiredLB.h @@ -0,0 +1,70 @@ + +/* +*****************Wired Load Balancer******** +* Load balance form producer to the consumer. +* Cooperate with consul, which is a service discovery infrastructure. +* See document for detail instructions. +* Author: zhengchao@iie.ac.cn, MESA +* All right reserved by www.mesalab.cn 2018~2021 +********************************************************* +*/ + +#ifndef H_WIRED_LOAD_BALANCER_H_INCLUDE +#define H_WIRED_LOAD_BALANCER_H_INCLUDE +#include +#ifdef __cplusplus +extern "C" { +#endif +#define WLB_CONSUMER 0 +#define WLB_PRODUCER 1 +#define WLB_MAX_TAG_SIZE 1024 +#define ADDRSRLEN_MAX 46 + +enum WLB_OPTION +{ + WLB_OPT_ENABLE_OVERRIDE=0, // VALUE is an int, 1 for enable, 0 for disable. DEFAULT: 0. + WLB_OPT_HEALTH_CHECK_PORT, // VALUE is a unsigned short, SIZE=sizeof(unsigned short). DEFAULT:52100. + WLB_OPT_HEALTH_CHECK_INTERVAL, // VALUE is a unsigned short, SIZE=sizeof(unsigned short). DEFAULT:10 seconds. + WLB_CONS_OPT_DATA_PORT, // VALUE is an unsigned short, SIZE=sizeof(unsigned short). DEFAULT: 0. + WLB_CONS_OPT_PRIMARY_ADDR, // VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: use consul agent listen address. + WLB_CONS_OPT_SECONDARY_ADDR, // VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: no default. + WLB_CONS_OPT_CAPACITY, // VALUE is an int that range from 1 to 100, SIZE=sizeof(int). DEFAULT: 32. + WLB_CONS_OPT_COST, // VALUE is an int that range from 1 to 100, SIZE=sizeof(int). DEFAULT: 32. + WLB_CONS_OPT_USER_TAG, // VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: "null". Size must Not exceed WLB_MAX_TAG_SIZE. + WLB_PROD_OPT_OVERRIDE_PRIMARY_IP, // VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: "null", format: "10.2.0.1-250;123.57.35.100-250;" + WLB_PROD_OPT_OVERRIDE_SECONDARY_IP, // VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: "null", same format as WLB_PROD_OPT_OVERRIDE_PRIMARY_IP. + WLB_PROD_OPT_OVERRIDE_DATAPORT, // VALUE is an unsigned short, SIZE=sizeof(unsigned short). DEFAULT: 0. + WLB_PROD_OPT_OVERRIDE_USER_TAG, // Same requirement as WLB_CONS_OPT_USER_TAG. + WLB_PROD_OPT_DATACENTER // VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: "null",list consumer of specific datacenter, case sensitive, format: "mesa-wired-bj" +}; +typedef void* WLB_handle_t; + +struct WLB_consumer_t +{ + char ip_addr[ADDRSRLEN_MAX]; + unsigned short data_port; + char user_tag[WLB_MAX_TAG_SIZE]; +}; +// Lookup is THREAD SAFE. +int wiredLB_lookup(WLB_handle_t handle, const void* key, int len, struct WLB_consumer_t* consumer); + +int wiredLB_list(WLB_handle_t handle,size_t n_cons, struct WLB_consumer_t* cons_array); + + +//Report is THREAD SAFE, NULL is allowed for runtime_info. +void wiredLB_report(WLB_handle_t handle,long proc_bytes, long proc_count, const char* runtime_info); + +//[IN] topic, MADATORY, use utf-8 for non English character. +//[IN] group_name, OPTIONALl, could be NULL, use utf-8 for non English character. +//[IN] role, WLB_COSUMER or WLB_PRODUCER +WLB_handle_t wiredLB_create(const char* topic, const char* group_name, int role); +int wiredLB_set_opt(WLB_handle_t handle, enum WLB_OPTION opt, const void* value, size_t size); +int wiredLB_init(WLB_handle_t handle); +void wiredLB_destroy(WLB_handle_t handle); + + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/include/MESA/wired_cfg.h b/include/MESA/wired_cfg.h new file mode 100644 index 0000000..14bfd62 --- /dev/null +++ b/include/MESA/wired_cfg.h @@ -0,0 +1,38 @@ +#ifndef H_WIRED_CFG_H_INCLUDE +#define H_WIRED_CFG_H_INCLUDE +#include +#ifdef __cplusplus +extern "C" { +#endif +#define WCFG_RET_ERR -1 +#define WCFG_RET_NOT_EXIST 0 +#define WCFG_RET_OK 1 + +enum WCFG_OPTION +{ + LOCAL_ONLY=0, + REMOTE_TIMEOUT +}; + +void * wired_cfg_create(const char* app_name, const char* cfg_path); + +// return DCFG_RET_xx +int wired_cfg_set_opt(void*handle, enum WCFG_OPTION option, const char* val, size_t size); + +// return DCFG_RET_xx +int wired_cfg_init(void* handle); + +// convert the value as your own wish with sscanf +// handle [IN] which aquired by wired_cfg_create +// section [IN] section name in initialization file +// key [IN] keyword name in initialization file +// value [OUT] returned string +// size [IN] buffer size(bytes) +//default_value[IN] default string +int wired_cfg_read(void*handle, const char* section, const char* key,char* value, size_t size,const char* default_value); + +void wired_cfg_destroy(void* handle); +#ifdef __cplusplus +} +#endif +#endif -- cgit v1.2.3