summaryrefslogtreecommitdiff
path: root/support
diff options
context:
space:
mode:
authorlijia <[email protected]>2018-10-24 09:36:45 +0800
committerlijia <[email protected]>2018-10-24 09:36:45 +0800
commit86a43b4d325ddc850fa9dc4711670880f35b11e8 (patch)
tree8356a056ac9bfb8cf14fcf57f113dd306b4277d1 /support
create new project.
Diffstat (limited to 'support')
-rw-r--r--support/include/MESA_atomic_for_view.h38
-rw-r--r--support/include/MESA_handle_logger_for_view.h68
-rw-r--r--support/include/MESA_htable_for_view.h393
-rw-r--r--support/include/MESA_list_count_for_view.h31
-rw-r--r--support/include/MESA_list_for_view.h34
-rw-r--r--support/include/MESA_list_queue_for_view.h115
-rw-r--r--support/include/MESA_prof_load_for_view.h179
-rw-r--r--support/include/MESA_ring_queue_for_view.h107
-rw-r--r--support/include/Maat_command_for_view.h154
-rw-r--r--support/include/Maat_rule_for_view.h228
-rw-r--r--support/include/field_stat2_for_view.h66
-rw-r--r--support/include/本文件夹中的文件仅用于查看_不编译.txt0
-rw-r--r--support/ltsm/Makefile14
-rw-r--r--support/ltsm/ltsm.c485
-rw-r--r--support/ltsm/ltsm.h117
-rw-r--r--support/ltsm/ltsm_with_hash.h81
-rw-r--r--support/ltsm/test_ltsm.c59
17 files changed, 2169 insertions, 0 deletions
diff --git a/support/include/MESA_atomic_for_view.h b/support/include/MESA_atomic_for_view.h
new file mode 100644
index 0000000..6d8c6ef
--- /dev/null
+++ b/support/include/MESA_atomic_for_view.h
@@ -0,0 +1,38 @@
+#ifndef _MESA_ATOMIC_H_
+#define _MESA_ATOMIC_H_
+
+
+#if(__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ >= 411)
+typedef unsigned long MESA_ATOMIC_T;
+#define MESA_ATOMIC_SET(v, i) __sync_lock_test_and_set((&v), i)
+#define MESA_ATOMIC_READ(v) __sync_or_and_fetch((&v), 0)
+#define MESA_ATOMIC_INC(v) __sync_add_and_fetch((&v),1)
+#define MESA_ATOMIC_DEC(v) __sync_sub_and_fetch((&v),1)
+#define MESA_ATOMIC_ADD(v,add) __sync_add_and_fetch((&v),(add))
+#define MESA_ATOMIC_SUB(v,sub) __sync_sub_and_fetch((&v),(sub))
+#else
+#include <alsa/iatomic.h>
+typedef atomic_t MESA_ATOMIC_T;
+#define MESA_ATOMIC_SET(v, i) atomic_set((&v), i)
+#define MESA_ATOMIC_READ(v) atomic_read((&v))
+#define MESA_ATOMIC_INC(v) atomic_inc((&v))
+#define MESA_ATOMIC_DEC(v) atomic_dec((&v))
+#define MESA_ATOMIC_ADD(v, add) atomic_add((add),(&v))
+#define MESA_ATOMIC_SUB(v, sub) atomic_sub((sub),(&v))
+#endif
+
+
+#ifdef __tilegx__
+#include <arch/atomic.h>
+typedef int MESA_ATOMIC_T;
+#define MESA_ATOMIC_SET(v, i) arch_atomic_exchange((&v), i)
+#define MESA_ATOMIC_READ(v) arch_atomic_or((&v), 0)
+#define MESA_ATOMIC_INC(v) arch_atomic_add((&v), 1)
+#define MESA_ATOMIC_DEC(v) arch_atomic_sub((&v), 1)
+#define MESA_ATOMIC_ADD(v, add) arch_atomic_add((&v), add)
+#define MESA_ATOMIC_SUB(v, sub) arch_atomic_sub((&v), sub)
+#endif
+
+
+#endif
+
diff --git a/support/include/MESA_handle_logger_for_view.h b/support/include/MESA_handle_logger_for_view.h
new file mode 100644
index 0000000..c615b53
--- /dev/null
+++ b/support/include/MESA_handle_logger_for_view.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/support/include/MESA_htable_for_view.h b/support/include/MESA_htable_for_view.h
new file mode 100644
index 0000000..76d7a2f
--- /dev/null
+++ b/support/include/MESA_htable_for_view.h
@@ -0,0 +1,393 @@
+#ifndef __MESA_HTABLE_H_
+#define __MESA_HTABLE_H_
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+
+/*
+ * 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 (20171114)
+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);
+
+/* MESA_htable built-in HASH algorithm, MESA_htable use BKDR_hash_algo as default, user can choose any one of the following */
+extern uint BKDR_hash_algo(MESA_htable_handle api_table, const uchar *key, uint size);
+extern uint APHash_algo(MESA_htable_handle api_table, const uchar *key, uint size);
+extern uint murmur3_32_algo(MESA_htable_handle api_table, const uchar* key, 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);
+
+
+/*
+ * 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, default is 0, if this option value bigger than zero, user should set small SLOT_SIZE in initialization for economize memory, htable will auto expand SLOT_SIZE if hash collide item number more than MHO_HASH_LIST_COLLIDE_THRESHOLD. */
+ __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/support/include/MESA_list_count_for_view.h b/support/include/MESA_list_count_for_view.h
new file mode 100644
index 0000000..55523aa
--- /dev/null
+++ b/support/include/MESA_list_count_for_view.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/support/include/MESA_list_for_view.h b/support/include/MESA_list_for_view.h
new file mode 100644
index 0000000..6d7cee8
--- /dev/null
+++ b/support/include/MESA_list_for_view.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/support/include/MESA_list_queue_for_view.h b/support/include/MESA_list_queue_for_view.h
new file mode 100644
index 0000000..6fdbdd7
--- /dev/null
+++ b/support/include/MESA_list_queue_for_view.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/support/include/MESA_prof_load_for_view.h b/support/include/MESA_prof_load_for_view.h
new file mode 100644
index 0000000..9ed5b40
--- /dev/null
+++ b/support/include/MESA_prof_load_for_view.h
@@ -0,0 +1,179 @@
+#ifndef SLIB_LOADPROF_H
+#define SLIB_LOADPROF_H
+#include <sys/types.h>
+
+#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 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/support/include/MESA_ring_queue_for_view.h b/support/include/MESA_ring_queue_for_view.h
new file mode 100644
index 0000000..cc1efe8
--- /dev/null
+++ b/support/include/MESA_ring_queue_for_view.h
@@ -0,0 +1,107 @@
+#ifndef __MESA_RING_QUEUE_H_
+#define __MESA_RING_QUEUE_H_ 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef void * MESA_ring_queue_head;
+
+#define MESA_RING_QUEUE_VERSION_MACRO (20160708)
+extern const unsigned int MESA_RING_QUEUE_VERSION_INT;
+
+/* All of the following functions return value */
+typedef enum{
+ MESA_RQUEUE_RET_OK = 0, /* success */
+ MESA_RQUEUE_RET_COMMON_ERR = -1, /* general��undefined errors */
+ MESA_RQUEUE_RET_ARG_ERR = -2, /* invalid args */
+ MESA_RQUEUE_RET_NUM_FULL = -3, /* queue number full */
+ MESA_RQUEUE_RET_MEM_FULL = -4, /* queue memory full */
+ MESA_RQUEUE_RET_QEMPTY = -5, /* queue empty */
+ MESA_RQUEUE_RET_LEN_ERR = -6, /* length error */
+ MESA_RQUEUE_RET_CANT_GET_LOCK = -7, /* can't get lock in non-block mode */
+ MESA_RQUEUE_RET_GET_LOCK_TMOUT = -8, /* get lock timeout */
+}MESA_ring_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, must more than zero.
+*/
+MESA_ring_queue_head MESA_ring_queue_born(void);
+
+
+enum MESA_rq_opt{
+ RQO_THREAD_SAFE = 0, /* must be int, 1:create ring qqueue with thread safe features, default is 1 */
+ RQO_RING_ELEMENT_NUM, /* must be unsigned int, defalut is 1000. */
+ RQO_PRE_ALLOC_BUF_LEN, /* must be unsigned int, Ԥ�ȷ���ÿ��item���ڴ�, �Ժ�ֻ��memcpy */
+ RQO_MULTI_THREAD_LOCK_FREE, /* must be int, default is 0, conflict with RQO_THREAD_SAFE */
+};
+
+/*
+ to set features of specified MESA_ring_queue_headhandle.
+ 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_ring_queue_set_opt(MESA_ring_queue_head rq, enum MESA_rq_opt opt_type, void *opt_val, int opt_len);
+
+
+/*
+ Construct ring queue and ready to running.
+
+ return value:
+ 0 : success;
+ <0: error.
+*/
+int MESA_ring_queue_mature(MESA_ring_queue_head rq);
+
+
+
+int MESA_ring_queue_get_count(MESA_ring_queue_head head);
+
+/*
+ args description:
+ [IN]:
+ lq_head : the handler of MESA_ring_queue.
+
+ [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_ring_queue_read(MESA_ring_queue_head rq_head, void *data, int *data_len);
+int MESA_ring_queue_get(MESA_ring_queue_head rqhead, void *data, int *data_len);
+int MESA_ring_queue_join(MESA_ring_queue_head rq_head, const void *data, int data_len);
+
+
+/* these functions features same with above no "try",
+ except shall return immediately, in other word is "Non-block mode"!
+ */
+int MESA_ring_queue_try_read(MESA_ring_queue_head rq_head, void *data, int *data_len);
+int MESA_ring_queue_try_get(MESA_ring_queue_head rqhead, void *data, int *data_len);
+int MESA_ring_queue_try_join(MESA_ring_queue_head rq_head, const void *data, int data_len);
+
+
+typedef int (* MESA_rqueue_cb_t)(void *data, long data_len, void *arg);
+void MESA_ring_queue_destroy(MESA_ring_queue_head rq_head, MESA_rqueue_cb_t cb, void *cb_arg);
+const char *MESA_ring_queue_strerror(MESA_ring_queue_errno_t error_num);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/support/include/Maat_command_for_view.h b/support/include/Maat_command_for_view.h
new file mode 100644
index 0000000..1d65383
--- /dev/null
+++ b/support/include/Maat_command_for_view.h
@@ -0,0 +1,154 @@
+#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
+};
+
+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
+{
+ int region_num;
+ int group_id; //If MAAT_OPT_CMD_AUTO_NUMBERING==1, maat will assigned one. Or users must assign a unique number.
+ struct Maat_region_t *regions;
+};
+struct Maat_cmd_t
+{
+ 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 is 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);
+//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);
+// REGION_EXPR and REGION_SIMILARITY need to escape input string.
+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.
+// 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);
+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);
+int Maat_cmd_set_line(Maat_feather_t feather,const struct Maat_line_t* line_rule, 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);
+int Maat_cmd_select(Maat_feather_t feather, int label_id, int * output_ids, unsigned int size);
+#endif
+
diff --git a/support/include/Maat_rule_for_view.h b/support/include/Maat_rule_for_view.h
new file mode 100644
index 0000000..e160a4a
--- /dev/null
+++ b/support/include/Maat_rule_for_view.h
@@ -0,0 +1,228 @@
+
+/*
+*****************Maat Network Flow Rule Manage 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: [email protected],MESA
+* Version 2015-11-09 digest scan
+* 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 "stream.h"
+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. "&#1575;"
+ CHARSET_UNICODE_NCR_HEX, //SGML Numeric character reference,hexdecimal base, e.g. "&#x627;"
+ 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
+};
+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
+struct Maat_rule_t
+{
+ int config_id;
+ int service_id;
+ char do_log;
+ char do_blacklist;
+ char action;
+ char resevered;
+ 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, host order, SIZE= sizeof(unsigned short). No DEFAULT.
+ MAAT_OPT_REDIS_INDEX, //VALUE is interger *, 0~15, SIZE=sizeof(int). DEFAULT: 0.
+ MAAT_OPT_CMD_AUTO_NUMBERING, //VALUE is interger *, 1 or 0, SIZE=sizeof(int). DEFAULT: 1.
+ MAAT_OPT_DEFERRED_LOAD //VALUE is NULL,SIZE is 0. Default: Deffered initialization 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);
+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);
+
+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 cobination.
+};
+//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 hit rule number, return -1 when error occurs,return -2 when hit current region
+//mid MUST set 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);
+//hite_detail could be NULL if unconcern
+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 unconcern
+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);
+
+#endif // H_MAAT_RULE_H_INCLUDE
+
diff --git a/support/include/field_stat2_for_view.h b/support/include/field_stat2_for_view.h
new file mode 100644
index 0000000..7dbf5a5
--- /dev/null
+++ b/support/include/field_stat2_for_view.h
@@ -0,0 +1,66 @@
+#ifndef H_SCREEN_STAT2_H_INCLUDE
+#define H_SCREEN_STAT2_H_INCLUDE
+#include <stdio.h>
+
+#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
+};
+enum field_calc_algo
+{
+ FS_CALC_CURRENT=0,
+ FS_CALC_SPEED
+};
+enum field_op
+{
+ FS_OP_ADD=1,
+ FS_OP_SET
+};
+
+
+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, host order, SIZE= sizeof(unsigned short). No DEFAULT.
+};
+
+//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','|' or ':' in the parameter name.
+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);
+
+//id: when id's type is FIELD , column_id is ignore.
+int FS_operate(screen_stat_handle_t handle,int id,int column_id,enum field_op op,long long value);
+
+void FS_passive_output(screen_stat_handle_t handle);
+
+#endif
+
diff --git a/support/include/本文件夹中的文件仅用于查看_不编译.txt b/support/include/本文件夹中的文件仅用于查看_不编译.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/support/include/本文件夹中的文件仅用于查看_不编译.txt
diff --git a/support/ltsm/Makefile b/support/ltsm/Makefile
new file mode 100644
index 0000000..1cb32b7
--- /dev/null
+++ b/support/ltsm/Makefile
@@ -0,0 +1,14 @@
+all:test_ltsm.so libltsm.a
+
+libltsm.a:ltsm.o
+ ar -r $@ $^;
+ cp $@ ../../lib
+
+test_ltsm.so:test_ltsm.o ltsm.o
+ gcc -fPIC -shared -o $@ $^ -I/opt/MESA/include/MESA
+
+test_ltsm.o:test_ltsm.c
+ gcc -fPIC -c -D__USE_MISC -D_BSD_SOURCE -o $@ $^ -I/opt/MESA/include/MESA
+
+ltsm.o:ltsm.c
+ gcc -fPIC -c -D__USE_MISC -D_BSD_SOURCE -o $@ $^ -I/opt/MESA/include/MESA
diff --git a/support/ltsm/ltsm.c b/support/ltsm/ltsm.c
new file mode 100644
index 0000000..c8af056
--- /dev/null
+++ b/support/ltsm/ltsm.c
@@ -0,0 +1,485 @@
+
+
+#include <netinet/ip.h>
+#include <netinet/in.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+
+/*
+ * The TCP state transition table needs a few words...
+ *
+ * We are the man in the middle. All the packets go through us
+ * but might get lost in transit to the destination.
+ * It is assumed that the destinations can't receive segments
+ * we haven't seen.
+ *
+ * The checked segment is in window, but our windows are *not*
+ * equivalent with the ones of the sender/receiver. We always
+ * try to guess the state of the current sender.
+ *
+ * The meaning of the states are:
+ *
+ * NONE: initial state
+ * SYN_SENT: SYN-only packet seen
+ * SYN_SENT2: SYN-only packet seen from reply dir, simultaneous open
+ * SYN_RECV: SYN-ACK packet seen
+ * ESTABLISHED: ACK packet seen
+ * FIN_WAIT: FIN packet seen
+ * CLOSE_WAIT: ACK seen (after FIN)
+ * LAST_ACK: FIN seen (after FIN)
+ * TIME_WAIT: last ACK seen
+ * CLOSE: closed connection (RST)
+ *
+ * Packets marked as IGNORED (sIG):
+ * if they may be either invalid or valid
+ * and the receiver may send back a connection
+ * closing RST or a SYN/ACK.
+ *
+ * Packets marked as INVALID (sIV):
+ * if we regard them as truly invalid packets
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <netinet/ip.h>
+#include <assert.h>
+#include <time.h>
+#include <arpa/inet.h>
+#include "ltsm.h"
+
+
+
+enum tcp_conntrack {
+ TCP_CONNTRACK_NONE,
+ TCP_CONNTRACK_SYN_SENT,
+ TCP_CONNTRACK_SYN_RECV,
+ TCP_CONNTRACK_ESTABLISHED,
+ TCP_CONNTRACK_FIN_WAIT,
+ TCP_CONNTRACK_CLOSE_WAIT,
+ TCP_CONNTRACK_LAST_ACK,
+ TCP_CONNTRACK_TIME_WAIT,
+ TCP_CONNTRACK_CLOSE,
+ TCP_CONNTRACK_LISTEN, /* obsolete */
+#define TCP_CONNTRACK_SYN_SENT2 TCP_CONNTRACK_LISTEN
+ TCP_CONNTRACK_MAX,
+ TCP_CONNTRACK_IGNORE
+};
+
+
+/* What TCP flags are set from RST/SYN/FIN/ACK. */
+enum tcp_bit_set {
+ TCP_SYN_SET,
+ TCP_SYNACK_SET,
+ TCP_FIN_SET,
+ TCP_ACK_SET,
+ TCP_RST_SET,
+ TCP_NONE_SET,
+};
+
+#define TCP_URG_FLAG 0x20
+#define TCP_ACK_FLAG 0x10
+#define TCP_PSH_FLAG 0x08
+#define TCP_RST_FLAG 0x04
+#define TCP_SYN_FLAG 0x02
+#define TCP_FIN_FLAG 0x01
+#define TCP_FLAG_ALL 0x3F
+
+
+#define sNO TCP_CONNTRACK_NONE
+#define sSS TCP_CONNTRACK_SYN_SENT
+#define sSR TCP_CONNTRACK_SYN_RECV
+#define sES TCP_CONNTRACK_ESTABLISHED
+#define sFW TCP_CONNTRACK_FIN_WAIT
+#define sCW TCP_CONNTRACK_CLOSE_WAIT
+#define sLA TCP_CONNTRACK_LAST_ACK
+#define sTW TCP_CONNTRACK_TIME_WAIT
+#define sCL TCP_CONNTRACK_CLOSE
+#define sS2 TCP_CONNTRACK_SYN_SENT2
+#define sIV TCP_CONNTRACK_MAX
+#define sIG TCP_CONNTRACK_IGNORE
+
+static const struct ltsm_result g_tsm_first_void = {FTSM_VOID, LTSM_VOID}; /* ��SYN��, ��������״̬, ����void */
+static const struct ltsm_result g_tsm_first_start = {TCP_CONNTRACK_SYN_SENT, LTSM_START};
+
+
+static const char *g_ftsm_string[] =
+{
+ "VOID",
+ "FTSM_SYN_SENT",
+ "FTSM_SYN_RCVD",
+ "FTSM_ESTABLISHED",
+ "FTSM_FIN_WAIT",
+ "FTSM_CLOSE_WAIT",
+ "FTSM_LAST_ACK",
+ "FTSM_TIME_WAIT",
+ "FTSM_CLOSED",
+ "FTSM_LISTEN",
+ "__FTSM_MAX",
+};
+
+static const char *g_ltsm_string[] =
+{
+ "LTSM_VOID",
+ "LTSM_START",
+ "LTSM_DATA",
+ "LTSM_CLOSE",
+};
+
+
+
+static const enum light_tcp_state g_ltsm_full2light_table[12] =
+{
+ LTSM_VOID, /* TCP_CONNTRACK_NONE, */
+ LTSM_START, /* TCP_CONNTRACK_SYN_SENT, */
+ LTSM_DATA, /* TCP_CONNTRACK_SYN_RECV, */
+ LTSM_DATA, /* TCP_CONNTRACK_ESTABLISHED, */
+ LTSM_DATA, /* TCP_CONNTRACK_FIN_WAIT, */
+ LTSM_DATA, /* TCP_CONNTRACK_CLOSE_WAIT, */
+ LTSM_DATA, /* TCP_CONNTRACK_LAST_ACK, */
+ LTSM_CLOSE, /* TCP_CONNTRACK_TIME_WAIT, */
+ LTSM_CLOSE, /* TCP_CONNTRACK_CLOSE, */
+ LTSM_VOID, /* TCP_CONNTRACK_LISTEN, */
+ LTSM_VOID, /* TCP_CONNTRACK_MAX, */
+ LTSM_VOID, /* TCP_CONNTRACK_IGNORE */
+};
+
+/*
+ if dir == 0, packet from client; if dir == 1, packet from service.
+
+ new_tcp_state = tcp_conntracks[dir][new_tcp_flag][old_tcp_state];
+*/
+static const uint8_t tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
+ {/* ORIGINAL */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*syn*/ {sSS, sSS, sIG, sIG, sIG, sIG, sIG, sSS, sSS, sS2},
+ /*
+ * sNO -> sSS Initialize a new connection
+ * sSS -> sSS Retransmitted SYN
+ * sS2 -> sS2 Late retransmitted SYN
+ * sSR -> sIG
+ * sES -> sIG Error: SYNs in window outside the SYN_SENT state
+ * are errors. Receiver will reply with RST
+ * and close the connection.
+ * Or we are not in sync and hold a dead connection.
+ * sFW -> sIG
+ * sCW -> sIG
+ * sLA -> sIG
+ * sTW -> sSS Reopened connection (RFC 1122).
+ * sCL -> sSS
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*synack*/ {sIV, sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG, sSR},
+ /*
+ * sNO -> sIV Too late and no reason to do anything
+ * sSS -> sIV Client can't send SYN and then SYN/ACK
+ * sS2 -> sSR SYN/ACK sent to SYN2 in simultaneous open
+ * sSR -> sIG
+ * sES -> sIG Error: SYNs in window outside the SYN_SENT state
+ * are errors. Receiver will reply with RST
+ * and close the connection.
+ * Or we are not in sync and hold a dead connection.
+ * sFW -> sIG
+ * sCW -> sIG
+ * sLA -> sIG
+ * sTW -> sIG
+ * sCL -> sIG
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*fin*/ {sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV},
+ /*
+ * sNO -> sIV Too late and no reason to do anything...
+ * sSS -> sIV Client migth not send FIN in this state:
+ * we enforce waiting for a SYN/ACK reply first.
+ * sS2 -> sIV
+ * sSR -> sFW Close started.
+ * sES -> sFW
+ * sFW -> sLA FIN seen in both directions, waiting for
+ * the last ACK.
+ * Migth be a retransmitted FIN as well...
+ * sCW -> sLA
+ * sLA -> sLA Retransmitted FIN. Remain in the same state.
+ * sTW -> sTW
+ * sCL -> sCL
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*ack*/ {sES, sIV, sES, sES, sCW, sCW, sTW, sTW, sCL, sIV},
+ /*
+ * sNO -> sES Assumed.
+ * sSS -> sIV ACK is invalid: we haven't seen a SYN/ACK yet.
+ * sS2 -> sIV
+ * sSR -> sES Established state is reached.
+ * sES -> sES :-)
+ * sFW -> sCW Normal close request answered by ACK.
+ * sCW -> sCW
+ * sLA -> sTW Last ACK detected.
+ * sTW -> sTW Retransmitted last ACK. Remain in the same state.
+ * sCL -> sCL
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*rst*/ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
+ /*none*/ {sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV}},
+
+ {/******************************** REPLY *******************************/
+
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*syn*/ {sIV, sS2, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sS2},
+ /*
+ * sNO -> sIV Never reached.
+ * sSS -> sS2 Simultaneous open
+ * sS2 -> sS2 Retransmitted simultaneous SYN
+ * sSR -> sIV Invalid SYN packets sent by the server
+ * sES -> sIV
+ * sFW -> sIV
+ * sCW -> sIV
+ * sLA -> sIV
+ * sTW -> sIV Reopened connection, but server may not do it.
+ * sCL -> sIV
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*synack*/ {sIV, sSR, sSR, sIG, sIG, sIG, sIG, sIG, sIG, sSR},
+ /*
+ * sSS -> sSR Standard open.
+ * sS2 -> sSR Simultaneous open
+ * sSR -> sSR Retransmitted SYN/ACK.
+ * sES -> sIG Late retransmitted SYN/ACK?
+ * sFW -> sIG Might be SYN/ACK answering ignored SYN
+ * sCW -> sIG
+ * sLA -> sIG
+ * sTW -> sIG
+ * sCL -> sIG
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*fin*/ {sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV},
+ /*
+ * sSS -> sIV Server might not send FIN in this state.
+ * sS2 -> sIV
+ * sSR -> sFW Close started.
+ * sES -> sFW
+ * sFW -> sLA FIN seen in both directions.
+ * sCW -> sLA
+ * sLA -> sLA Retransmitted FIN.
+ * sTW -> sTW
+ * sCL -> sCL
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*ack*/ {sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIG},
+ /*
+ * sSS -> sIG Might be a half-open connection.
+ * sS2 -> sIG
+ * sSR -> sSR Might answer late resent SYN.
+ * sES -> sES :-)
+ * sFW -> sCW Normal close request answered by ACK.
+ * sCW -> sCW
+ * sLA -> sTW Last ACK detected.
+ * sTW -> sTW Retransmitted last ACK.
+ * sCL -> sCL
+ */
+ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2
+ */
+ /*rst*/ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
+ /*none*/ {sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV}}
+ };
+
+typedef struct{
+ uint32_t sip_net_order;
+ uint32_t dip_net_order;
+ uint16_t sport_net_order;
+ uint16_t dport_net_order;
+ uint8_t old_state;
+ uint8_t cur_state;
+ uint8_t create_dir;
+}ltsm_inner_t;
+
+
+const char *ltsm_fstate_ntop(enum full_tcp_state fstate)
+{
+ if((int)fstate < 0 || (int)fstate >= __FTSM_MAX){
+ return "Invalid";
+ }
+
+ return g_ftsm_string[fstate];
+}
+
+
+const char *ltsm_lstate_ntop(enum light_tcp_state lstate)
+{
+ if((int)lstate < 0 || (int)lstate > LTSM_CLOSE){
+ return "Invalid";
+ }
+
+ return g_ltsm_string[lstate];
+}
+
+
+
+static inline uint32_t ltsm_get_tcpflags(const struct ltsm_tcphdr *th) {
+ if (th->th_flags & TCP_RST_FLAG)
+ return TCP_RST_SET;
+ else if (th->th_flags & TCP_SYN_FLAG)
+ return ((th->th_flags & TCP_ACK_FLAG) ? TCP_SYNACK_SET : TCP_SYN_SET);
+ else if (th->th_flags & TCP_FIN_FLAG)
+ return TCP_FIN_SET;
+ else if (th->th_flags & TCP_ACK_FLAG)
+ return TCP_ACK_SET;
+ else
+ return TCP_NONE_SET;
+}
+
+
+static inline uint32_t ltsm_convert_tcpflags(uint8_t th_flags) {
+ if (th_flags & TCP_RST_FLAG)
+ return TCP_RST_SET;
+ else if (th_flags & TCP_SYN_FLAG)
+ return ((th_flags & TCP_ACK_FLAG) ? TCP_SYNACK_SET : TCP_SYN_SET);
+ else if (th_flags & TCP_FIN_FLAG)
+ return TCP_FIN_SET;
+ else if (th_flags & TCP_ACK_FLAG)
+ return TCP_ACK_SET;
+ else
+ return TCP_NONE_SET;
+}
+
+
+ltsm_stream_handle ltsm_create_handle(void)
+{
+ ltsm_inner_t *ltsm_inner;
+
+ ltsm_inner = calloc(1, sizeof(ltsm_inner_t));
+
+ ltsm_inner->old_state = TCP_CONNTRACK_SYN_SENT;
+
+ return ltsm_inner;
+}
+
+
+
+ltsm_stream_handle ltsm_create_stream_handle(const struct ltsm_iphdr * iphdr)
+{
+ const struct ltsm_tcphdr *tcp_hdr;
+ ltsm_inner_t *ltsm_inner;
+ int dir = 0;
+ uint32_t tcp_flags_set;
+
+ if(IPPROTO_TCP != iphdr->ip_p){
+ return NULL;
+ }
+
+ tcp_hdr = (const struct ltsm_tcphdr *)((char *)iphdr + iphdr->ip_hl*4);
+ if(TH_SYN == tcp_hdr->th_flags){
+ dir = 0;
+ }else if(TH_SYN|TH_ACK == tcp_hdr->th_flags){
+ dir = 1;
+ }else{
+ return NULL;
+ }
+
+ ltsm_inner = calloc(1, sizeof(ltsm_inner_t));
+ ltsm_inner->old_state = TCP_CONNTRACK_NONE;
+ ltsm_inner->sip_net_order = iphdr->ip_src.s_addr;
+ ltsm_inner->dip_net_order = iphdr->ip_dst.s_addr;
+ ltsm_inner->sport_net_order = tcp_hdr->th_sport;
+ ltsm_inner->dport_net_order = tcp_hdr->th_dport;
+
+ tcp_flags_set = ltsm_get_tcpflags(tcp_hdr);
+
+ ltsm_inner->cur_state = tcp_conntracks[dir][tcp_flags_set][ltsm_inner->old_state];
+ ltsm_inner->create_dir = dir;
+
+ return ltsm_inner;
+}
+
+
+uint8_t ltsm_proc_ipv4tcppkt(ltsm_stream_handle s_ltsm, const struct ltsm_iphdr *iphdr)
+{
+ uint8_t tcpstate;
+ ltsm_inner_t *ltsm_inner = (ltsm_inner_t *)s_ltsm;
+ int dir = 0;
+ uint32_t tcp_flags_set;
+ const struct ltsm_tcphdr *tcp_hdr;
+
+ if(IPPROTO_TCP != iphdr->ip_p){
+ return LTSM_VOID;
+ }
+
+ tcp_hdr = (const struct ltsm_tcphdr *)((char *)iphdr + iphdr->ip_hl*4);
+ tcp_flags_set = ltsm_get_tcpflags(tcp_hdr);
+
+ if((ltsm_inner->sip_net_order == iphdr->ip_src.s_addr)
+ && (ltsm_inner->dip_net_order == iphdr->ip_dst.s_addr)
+ && (ltsm_inner->sport_net_order == tcp_hdr->th_sport)
+ && (ltsm_inner->dport_net_order == tcp_hdr->th_dport)){
+ dir = ltsm_inner->create_dir;
+ }else{
+ dir = ltsm_inner->create_dir ^ 1;
+ }
+
+ tcpstate = tcp_conntracks[dir][tcp_flags_set][ltsm_inner->old_state];
+
+ if(tcpstate < TCP_CONNTRACK_MAX){
+ ltsm_inner->old_state = tcpstate;
+ }
+
+ return tcpstate;
+}
+
+void ltsm_destroy_stream_handle(ltsm_stream_handle pltsm)
+{
+ free(pltsm);
+}
+
+void ltsm_destroy_handle(ltsm_stream_handle pltsm)
+{
+ free(pltsm);
+}
+
+
+
+struct ltsm_result ltsm_get_current_state(ltsm_stream_handle pltsm, uint8_t tcp_flags, uint8_t dir)
+{
+ uint8_t tcp_fstate;
+ uint32_t tcp_flags_set;
+ struct ltsm_result res;
+
+ if(NULL == pltsm){
+ if(TH_SYN != tcp_flags){
+ return g_tsm_first_void;
+ }
+
+ return g_tsm_first_start;
+ }
+
+ ltsm_inner_t *ltsm_inner = (ltsm_inner_t *)pltsm;
+
+ tcp_flags_set = ltsm_convert_tcpflags(tcp_flags);
+ tcp_fstate = tcp_conntracks[dir][tcp_flags_set][ltsm_inner->old_state];
+
+ ltsm_inner->old_state = tcp_fstate;
+
+ res.fstate = tcp_fstate;
+ res.lstate = g_ltsm_full2light_table[tcp_fstate];
+
+ return res;
+}
+
+
+uint32_t ltsm_tcp_key_generate(uint32_t sip_net_order, uint32_t dip_net_order, uint16_t sport_net_order, uint16_t dport_net_order)
+{
+
+}
+
+int ltsm_tcp_key_verify(const struct ip * iphdr)
+{
+
+}
+
diff --git a/support/ltsm/ltsm.h b/support/ltsm/ltsm.h
new file mode 100644
index 0000000..340aa2f
--- /dev/null
+++ b/support/ltsm/ltsm.h
@@ -0,0 +1,117 @@
+#ifndef __LTSM_H_
+#define __LTSM_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ LTSM : Light TCP State Machine.
+ Version : 2018-01-16
+*/
+
+/* RFC��׼TCPЭ��ջ״̬������ */
+enum full_tcp_state{
+ FTSM_VOID, /* ���һ�����ĵ�һ��������SYN��, ���ش�ֵ */
+ FTSM_SYN_SENT,
+ FTSM_SYN_RCVD,
+ FTSM_ESTABLISHED,
+ FTSM_FIN_WAIT,
+ FTSM_CLOSE_WAIT,
+ FTSM_LAST_ACK,
+ FTSM_TIME_WAIT,
+ FTSM_CLOSED,
+ FTSM_LISTEN,
+ __FTSM_MAX,
+};
+
+/*
+ ����TCP״̬������,
+ ʵ��ֻ������״̬:�½�����, ��������, ��������,
+ ÿ�����ض�����1��START��1��CLOSE״̬, ���ܰ���0�����ɸ�DATA״̬.
+
+ VOID״̬���ڵ����߿����ж��Ƿ���Ҫ��������.
+*/
+enum light_tcp_state{
+ LTSM_VOID, /* ���һ�����ĵ�һ��������SYN��, ���ش�ֵ */
+ LTSM_START,
+ LTSM_DATA,
+ LTSM_CLOSE,
+};
+
+struct ltsm_iphdr
+ {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ip_hl:4; /* header length */
+ unsigned int ip_v:4; /* version */
+#endif
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int ip_v:4; /* version */
+ unsigned int ip_hl:4; /* header length */
+#endif
+ u_int8_t ip_tos; /* type of service */
+ u_short ip_len; /* total length */
+ u_short ip_id; /* identification */
+ u_short ip_off; /* fragment offset field */
+#define IP_RF 0x8000 /* reserved fragment flag */
+#define IP_DF 0x4000 /* dont fragment flag */
+#define IP_MF 0x2000 /* more fragments flag */
+#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+ u_int8_t ip_ttl; /* time to live */
+ u_int8_t ip_p; /* protocol */
+ u_short ip_sum; /* checksum */
+ struct in_addr ip_src, ip_dst; /* source and dest address */
+ };
+
+struct ltsm_tcphdr
+ {
+ u_int16_t th_sport; /* source port */
+ u_int16_t th_dport; /* destination port */
+ u_int32_t th_seq; /* sequence number */
+ u_int32_t th_ack; /* acknowledgement number */
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+ u_int8_t th_x2:4; /* (unused) */
+ u_int8_t th_off:4; /* data offset */
+# endif
+# if __BYTE_ORDER == __BIG_ENDIAN
+ u_int8_t th_off:4; /* data offset */
+ u_int8_t th_x2:4; /* (unused) */
+# endif
+ u_int8_t th_flags;
+# define TH_FIN 0x01
+# define TH_SYN 0x02
+# define TH_RST 0x04
+# define TH_PUSH 0x08
+# define TH_ACK 0x10
+# define TH_URG 0x20
+ u_int16_t th_win; /* window */
+ u_int16_t th_sum; /* checksum */
+ u_int16_t th_urp; /* urgent pointer */
+};
+
+struct ltsm_result{
+ enum full_tcp_state fstate;
+ enum light_tcp_state lstate;
+};
+
+typedef void * ltsm_stream_handle;
+
+ltsm_stream_handle ltsm_create_handle(void);
+
+#define LTSM_DIR_C2S 0
+#define LTSM_DIR_S2C 1
+
+struct ltsm_result ltsm_get_current_state(ltsm_stream_handle pltsm, uint8_t tcp_flags, uint8_t dir);
+
+const char *ltsm_fstate_ntop(enum full_tcp_state fstate);
+const char *ltsm_lstate_ntop(enum light_tcp_state lstate);
+
+void ltsm_destroy_handle(ltsm_stream_handle pltsm);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/support/ltsm/ltsm_with_hash.h b/support/ltsm/ltsm_with_hash.h
new file mode 100644
index 0000000..0404f3d
--- /dev/null
+++ b/support/ltsm/ltsm_with_hash.h
@@ -0,0 +1,81 @@
+#ifndef LTSM_H_
+#define LTSM_H_
+
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+#include "mesa_net.h"
+/*
+ LTSM : Light TCP State Machine.
+
+*/
+
+/* RFC��׼TCPЭ��ջ״̬������ */
+enum full_tcp_state{
+ FTSM_CLOSED,
+ FTSM_LISTEN,
+ FTSM_SYN_SENT,
+ FTSM_SYN_RCVD,
+ FTSM_ESTABLISHED,
+ FTSM_CLOSE_WAIT,
+ FTSM_LAST_ACK,
+ FTSM_FIN_WAIT1,
+ FTSM_FIN_WAIT2,
+ FTSM_CLOSING,
+ FTSM_TIME_WAIT,
+};
+
+/*
+ ����TCP״̬������,
+ ֻ������״̬:�½�����, ��������, ��������,
+ ÿ�����ض�����1��START��1��CLOSE״̬, ���ܰ���0�����ɸ�DATA״̬.
+*/
+enum light_tcp_state{
+ LTSM_START,
+ LTSM_DATA,
+ LTSM_CLOSE,
+ LTSM_INVALID,
+};
+
+
+enum light_tsm_opt{
+ LTSMO_THREAD_NUM, /* �߳�����, ѡ������:uint32 */
+ LTSMO_CREATE_MODE, /* ������ģʽ, 1:�������SYN; 2:�������ݰ��ɴ���, ѡ������:uint32 */
+ LTSMO_MAX_STREAM_NUM, /* TCP��󲢷�������, forÿ���߳�, ѡ������:uint32 */
+ LTSMO_STREAM_TIMEOUT, /* ����ʱ��̭ʱ��, ��λ:��, 0��ʾ����ʱ. ѡ������:uint32 */
+};
+
+struct ltsm_result{
+ enum full_tcp_state fstate;
+ enum light_tcp_state lstate;
+ void *pme;
+};
+
+typedef void * ltsm_global_handle;
+typedef void * ltsm_stream_handle;
+
+/* ltsmȫ�־����ʼ�� */
+void *ltsm_init(void);
+
+/* ltsm������ز��� */
+int ltsm_set_opt(ltsm_global_handle pltsm, enum light_tsm_opt opt, void *value, int value_len);
+
+/* ltsm���� */
+int ltsm_run(ltsm_global_handle pltsm);
+
+/* IPv4������, ���ص�ǰ��������ltsm״̬�����, pme�����ⲿ�����ߴ洢�Զ�������, �ڴ�������������ͷ� */
+struct ltsm_result *ltsm_proc_ip4pkt(ltsm_global_handle pltsm, int tseq, const struct ip *ip4hdr);
+
+/* IPv4��ͷ+TCP��ͷ����, ���ص�ǰ��������ltsm״̬�����, pme�����ⲿ�����ߴ洢�Զ�������, �ڴ�������������ͷ� */
+struct ltsm_result *ltsm_proc_ip4tcppkt(ltsm_global_handle pltsm, int tseq, const struct ip *ip4hdr, const struct tcphdr *tcp_hdr);
+
+/* IPv6������, ���ص�ǰ��������ltsm״̬�����, pme�����ⲿ�����ߴ洢�Զ�������, �ڴ�������������ͷ� */
+struct ltsm_result *ltsm_proc_ip6pkt(ltsm_global_handle pltsm, int tseq, const struct ip6_hdr *ip6hdr);
+
+/* IPv6��ͷ+TCP��ͷ����, ���ص�ǰ��������ltsm״̬�����, pme�����ⲿ�����ߴ洢�Զ�������, �ڴ�������������ͷ� */
+struct ltsm_result *ltsm_proc_ip6tcppkt(ltsm_global_handle pltsm, int tseq, const struct ip6_hdr *ip6hdr, const struct tcphdr *tcp_hdr);
+
+uint8_t ltsm_proc_ipv4tcppkt(ltsm_stream_handle s_ltsm, const struct mesa_ip4_hdr *iphdr);
+
+void ltsm_destroy_stream_handle(ltsm_stream_handle s_ltsm);
+#endif \ No newline at end of file
diff --git a/support/ltsm/test_ltsm.c b/support/ltsm/test_ltsm.c
new file mode 100644
index 0000000..01935a9
--- /dev/null
+++ b/support/ltsm/test_ltsm.c
@@ -0,0 +1,59 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <assert.h>
+#include <time.h>
+#include <arpa/inet.h>
+
+#include "stream.h"
+#include "ltsm.h"
+
+
+
+
+char LTSM_TCPALL_ENTRY(struct streaminfo *pstream, void **pme, int thread_seq,void *apacket)
+{
+ void *ltsm_handle;
+ struct ltsm_result tcpstate;
+ const struct ltsm_tcphdr *tcp_hdr;
+ const struct ip *iphdr = (const struct ip *)apacket;
+
+ if(apacket != NULL){
+ tcp_hdr = (const struct ltsm_tcphdr *)((char *)iphdr + iphdr->ip_hl*4);
+ }
+
+ if(OP_STATE_PENDING == pstream->pktstate){
+ tcpstate = ltsm_get_current_state(NULL, tcp_hdr->th_flags, pstream->curdir);
+ if(LTSM_START == tcpstate.lstate ){
+ ltsm_handle = ltsm_create_handle();
+ *pme = ltsm_handle;
+ }else{
+ return APP_STATE_DROPME;
+ }
+ }else{
+ ltsm_handle = *pme;
+ if(OP_STATE_CLOSE == pstream->pktstate){
+ ltsm_destroy_handle(ltsm_handle);
+ return APP_STATE_DROPME;
+ }
+ }
+
+
+ tcpstate = ltsm_get_current_state(ltsm_handle, tcp_hdr->th_flags, pstream->curdir - 1);
+
+ printf("stream: %s, flags:0x%x, fstate: %s,\t lstate:%s\n", printaddr(&pstream->addr, thread_seq), tcp_hdr->th_flags, ltsm_fstate_ntop(tcpstate.fstate), ltsm_lstate_ntop(tcpstate.lstate));
+
+ return APP_STATE_GIVEME;
+}
+
+
+int LTSM_INIT(void)
+{
+ return 1;
+}
+
+
+