summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile44
-rw-r--r--src/cJSON.c596
-rw-r--r--src/cJSON.h143
-rw-r--r--src/include/MESA/MESA_handle_logger.h75
-rw-r--r--src/include/MESA/MESA_htable.h419
-rw-r--r--src/include/MESA/MESA_list_queue.h115
-rw-r--r--src/include/MESA/MESA_prof_load.h179
-rw-r--r--src/include/MESA/Maat_command.h174
-rw-r--r--src/include/MESA/Maat_rule.h285
-rw-r--r--src/include/MESA/field_stat2.h84
-rw-r--r--src/include/MESA/stream.h36
-rw-r--r--src/include/MESA/stream_inc/stream_base.h358
-rw-r--r--src/include/MESA/stream_inc/stream_control.h29
-rw-r--r--src/include/MESA/stream_inc/stream_entry.h79
-rw-r--r--src/include/MESA/stream_inc/stream_inject.h71
-rw-r--r--src/include/MESA/stream_inc/stream_project.h112
-rw-r--r--src/include/MESA/stream_inc/stream_proxy.h53
-rw-r--r--src/include/MESA/stream_inc/stream_rawpkt.h69
-rw-r--r--src/include/url_classification.h94
-rw-r--r--src/ntc_restiful_master.cpp216
-rw-r--r--src/ntc_restiful_master.h54
21 files changed, 3285 insertions, 0 deletions
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..9dea465
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,44 @@
+CCC=g++
+
+VPATH=./cJSON
+
+INC_PATH=-I./include -I./include/hiredis-vip -I./include/librdkafka
+CFLAGS=-Wall -g -fPIC -std=c++11 $(INC_PATH)
+#CFLAGS+=-DREDIS_SINGLE_MODE
+#CFLAGS+=-DFRAG_INDEX_VOIP
+#CFLAGS+=-DFRAG_INDEX_AV
+
+LDFLAGS =
+LIBS = -lhiredis_vip -lrdkafka -lmaatframe -lMESA_handle_logger -lMESA_htable -lMESA_prof_load -lpthread -lMESA_field_stat2 -lrulescan -lrt -lpcre -lsqlite3 -levent
+#LIBS += ./lib/libmaatframe.a
+#LIBS += -lmaatframe
+#LIBS += ./lib/libhiredis_vip.a
+#LIBS += -lhiredis_vip
+#LIBS += -lmaatframe -lrulescan
+#LIBS += -lrulescan
+#LIBS += ./lib/libmaatframe.a
+#LIBS += -lrdkafka
+#LIBS += ./lib/librdkafka.a
+#LIBS +=./lib/libhiredis_vip.a
+
+OBJS = cJSON.o ip_discovery_master.o web_focus_restiful.o
+DEPS = $(OBJS:.o=.d)
+
+TARGET_EXE=web_focus
+
+ALL:$(TARGET_EXE)
+
+$(TARGET_EXE):$(OBJS)
+ $(CCC) $(LDFLAGS) $^ -o $@ $(LIBS)
+ cp $@ ../bin/
+
+.c.o:
+ $(CCC) $(CFLAGS) -c $<
+
+.cpp.o:
+ $(CCC) $(CFLAGS) -c $<
+
+-include $(DEPS)
+
+clean:
+ rm -rf $(OBJS) $(DEPS) $(TARGET_EXE)
diff --git a/src/cJSON.c b/src/cJSON.c
new file mode 100644
index 0000000..35452cb
--- /dev/null
+++ b/src/cJSON.c
@@ -0,0 +1,596 @@
+/*
+ Copyright (c) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+/* cJSON */
+/* JSON parser in C. */
+
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <float.h>
+#include <limits.h>
+#include <ctype.h>
+#include "cJSON.h"
+
+static const char *ep;
+
+const char *cJSON_GetErrorPtr(void) {return ep;}
+
+static int cJSON_strcasecmp(const char *s1,const char *s2)
+{
+ if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
+ for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
+ return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
+}
+
+static void *(*cJSON_malloc)(size_t sz) = malloc;
+static void (*cJSON_free)(void *ptr) = free;
+
+static char* cJSON_strdup(const char* str)
+{
+ size_t len;
+ char* copy;
+
+ len = strlen(str) + 1;
+ if (!(copy = (char*)cJSON_malloc(len))) return 0;
+ memcpy(copy,str,len);
+ return copy;
+}
+
+void cJSON_InitHooks(cJSON_Hooks* hooks)
+{
+ if (!hooks) { /* Reset hooks */
+ cJSON_malloc = malloc;
+ cJSON_free = free;
+ return;
+ }
+
+ cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
+ cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
+}
+
+/* Internal constructor. */
+static cJSON *cJSON_New_Item(void)
+{
+ cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
+ if (node) memset(node,0,sizeof(cJSON));
+ return node;
+}
+
+/* Delete a cJSON structure. */
+void cJSON_Delete(cJSON *c)
+{
+ cJSON *next;
+ while (c)
+ {
+ next=c->next;
+ if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
+ if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
+ if (c->string) cJSON_free(c->string);
+ cJSON_free(c);
+ c=next;
+ }
+}
+
+/* Parse the input text to generate a number, and populate the result into item. */
+static const char *parse_number(cJSON *item,const char *num)
+{
+ double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
+
+ if (*num=='-') sign=-1,num++; /* Has sign? */
+ if (*num=='0') num++; /* is zero */
+ if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
+ if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
+ if (*num=='e' || *num=='E') /* Exponent? */
+ { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
+ while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
+ }
+
+ n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
+
+ item->valuedouble=n;
+ item->valueint=(int)n;
+ item->type=cJSON_Number;
+ return num;
+}
+
+/* Render the number nicely from the given item into a string. */
+static char *print_number(cJSON *item)
+{
+ char *str;
+ double d=item->valuedouble;
+ if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
+ {
+ str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
+ if (str) sprintf(str,"%d",item->valueint);
+ }
+ else
+ {
+ str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
+ if (str)
+ {
+ if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
+ else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
+ else sprintf(str,"%f",d);
+ }
+ }
+ return str;
+}
+
+static unsigned parse_hex4(const char *str)
+{
+ unsigned h=0;
+ if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
+ h=h<<4;str++;
+ if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
+ h=h<<4;str++;
+ if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
+ h=h<<4;str++;
+ if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
+ return h;
+}
+
+/* Parse the input text into an unescaped cstring, and populate item. */
+static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+static const char *parse_string(cJSON *item,const char *str)
+{
+ const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
+ if (*str!='\"') {ep=str;return 0;} /* not a string! */
+
+ while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
+
+ out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
+ if (!out) return 0;
+
+ ptr=str+1;ptr2=out;
+ while (*ptr!='\"' && *ptr)
+ {
+ if (*ptr!='\\') *ptr2++=*ptr++;
+ else
+ {
+ ptr++;
+ switch (*ptr)
+ {
+ case 'b': *ptr2++='\b'; break;
+ case 'f': *ptr2++='\f'; break;
+ case 'n': *ptr2++='\n'; break;
+ case 'r': *ptr2++='\r'; break;
+ case 't': *ptr2++='\t'; break;
+ case 'u': /* transcode utf16 to utf8. */
+ uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */
+
+ if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
+
+ if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
+ {
+ if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
+ uc2=parse_hex4(ptr+3);ptr+=6;
+ if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
+ uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
+ }
+
+ len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
+
+ switch (len) {
+ case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
+ case 1: *--ptr2 =(uc | firstByteMark[len]);
+ }
+ ptr2+=len;
+ break;
+ default: *ptr2++=*ptr; break;
+ }
+ ptr++;
+ }
+ }
+ *ptr2=0;
+ if (*ptr=='\"') ptr++;
+ item->valuestring=out;
+ item->type=cJSON_String;
+ return ptr;
+}
+
+/* Render the cstring provided to an escaped version that can be printed. */
+static char *print_string_ptr(const char *str)
+{
+ const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
+
+ if (!str) return cJSON_strdup("");
+ ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
+
+ out=(char*)cJSON_malloc(len+3);
+ if (!out) return 0;
+
+ ptr2=out;ptr=str;
+ *ptr2++='\"';
+ while (*ptr)
+ {
+ if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
+ else
+ {
+ *ptr2++='\\';
+ switch (token=*ptr++)
+ {
+ case '\\': *ptr2++='\\'; break;
+ case '\"': *ptr2++='\"'; break;
+ case '\b': *ptr2++='b'; break;
+ case '\f': *ptr2++='f'; break;
+ case '\n': *ptr2++='n'; break;
+ case '\r': *ptr2++='r'; break;
+ case '\t': *ptr2++='t'; break;
+ default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
+ }
+ }
+ }
+ *ptr2++='\"';*ptr2++=0;
+ return out;
+}
+/* Invote print_string_ptr (which is useful) on an item. */
+static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
+
+/* Predeclare these prototypes. */
+static const char *parse_value(cJSON *item,const char *value);
+static char *print_value(cJSON *item,int depth,int fmt);
+static const char *parse_array(cJSON *item,const char *value);
+static char *print_array(cJSON *item,int depth,int fmt);
+static const char *parse_object(cJSON *item,const char *value);
+static char *print_object(cJSON *item,int depth,int fmt);
+
+/* Utility to jump whitespace and cr/lf */
+static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
+
+/* Parse an object - create a new root, and populate. */
+cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
+{
+ const char *end=0;
+ cJSON *c=cJSON_New_Item();
+ ep=0;
+ if (!c) return 0; /* memory fail */
+
+ end=parse_value(c,skip(value));
+ if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
+
+ /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
+ if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
+ if (return_parse_end) *return_parse_end=end;
+ return c;
+}
+/* Default options for cJSON_Parse */
+cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
+
+/* Render a cJSON item/entity/structure to text. */
+char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
+char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
+
+/* Parser core - when encountering text, process appropriately. */
+static const char *parse_value(cJSON *item,const char *value)
+{
+ if (!value) return 0; /* Fail on null. */
+ if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
+ if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
+ if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
+ if (*value=='\"') { return parse_string(item,value); }
+ if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
+ if (*value=='[') { return parse_array(item,value); }
+ if (*value=='{') { return parse_object(item,value); }
+
+ ep=value;return 0; /* failure. */
+}
+
+/* Render a value to text. */
+static char *print_value(cJSON *item,int depth,int fmt)
+{
+ char *out=0;
+ if (!item) return 0;
+ switch ((item->type)&255)
+ {
+ case cJSON_NULL: out=cJSON_strdup("null"); break;
+ case cJSON_False: out=cJSON_strdup("false");break;
+ case cJSON_True: out=cJSON_strdup("true"); break;
+ case cJSON_Number: out=print_number(item);break;
+ case cJSON_String: out=print_string(item);break;
+ case cJSON_Array: out=print_array(item,depth,fmt);break;
+ case cJSON_Object: out=print_object(item,depth,fmt);break;
+ }
+ return out;
+}
+
+/* Build an array from input text. */
+static const char *parse_array(cJSON *item,const char *value)
+{
+ cJSON *child;
+ if (*value!='[') {ep=value;return 0;} /* not an array! */
+
+ item->type=cJSON_Array;
+ value=skip(value+1);
+ if (*value==']') return value+1; /* empty array. */
+
+ item->child=child=cJSON_New_Item();
+ if (!item->child) return 0; /* memory fail */
+ value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+
+ while (*value==',')
+ {
+ cJSON *new_item;
+ if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
+ child->next=new_item;new_item->prev=child;child=new_item;
+ value=skip(parse_value(child,skip(value+1)));
+ if (!value) return 0; /* memory fail */
+ }
+
+ if (*value==']') return value+1; /* end of array */
+ ep=value;return 0; /* malformed. */
+}
+
+/* Render an array to text */
+static char *print_array(cJSON *item,int depth,int fmt)
+{
+ char **entries;
+ char *out=0,*ptr,*ret;int len=5;
+ cJSON *child=item->child;
+ int numentries=0,i=0,fail=0;
+
+ /* How many entries in the array? */
+ while (child) numentries++,child=child->next;
+ /* Explicitly handle numentries==0 */
+ if (!numentries)
+ {
+ out=(char*)cJSON_malloc(3);
+ if (out) strcpy(out,"[]");
+ return out;
+ }
+ /* Allocate an array to hold the values for each */
+ entries=(char**)cJSON_malloc(numentries*sizeof(char*));
+ if (!entries) return 0;
+ memset(entries,0,numentries*sizeof(char*));
+ /* Retrieve all the results: */
+ child=item->child;
+ while (child && !fail)
+ {
+ ret=print_value(child,depth+1,fmt);
+ entries[i++]=ret;
+ if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
+ child=child->next;
+ }
+
+ /* If we didn't fail, try to malloc the output string */
+ if (!fail) out=(char*)cJSON_malloc(len);
+ /* If that fails, we fail. */
+ if (!out) fail=1;
+
+ /* Handle failure. */
+ if (fail)
+ {
+ for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
+ cJSON_free(entries);
+ return 0;
+ }
+
+ /* Compose the output array. */
+ *out='[';
+ ptr=out+1;*ptr=0;
+ for (i=0;i<numentries;i++)
+ {
+ strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
+ if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
+ cJSON_free(entries[i]);
+ }
+ cJSON_free(entries);
+ *ptr++=']';*ptr++=0;
+ return out;
+}
+
+/* Build an object from the text. */
+static const char *parse_object(cJSON *item,const char *value)
+{
+ cJSON *child;
+ if (*value!='{') {ep=value;return 0;} /* not an object! */
+
+ item->type=cJSON_Object;
+ value=skip(value+1);
+ if (*value=='}') return value+1; /* empty array. */
+
+ item->child=child=cJSON_New_Item();
+ if (!item->child) return 0;
+ value=skip(parse_string(child,skip(value)));
+ if (!value) return 0;
+ child->string=child->valuestring;child->valuestring=0;
+ if (*value!=':') {ep=value;return 0;} /* fail! */
+ value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+
+ while (*value==',')
+ {
+ cJSON *new_item;
+ if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
+ child->next=new_item;new_item->prev=child;child=new_item;
+ value=skip(parse_string(child,skip(value+1)));
+ if (!value) return 0;
+ child->string=child->valuestring;child->valuestring=0;
+ if (*value!=':') {ep=value;return 0;} /* fail! */
+ value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
+ if (!value) return 0;
+ }
+
+ if (*value=='}') return value+1; /* end of array */
+ ep=value;return 0; /* malformed. */
+}
+
+/* Render an object to text. */
+static char *print_object(cJSON *item,int depth,int fmt)
+{
+ char **entries=0,**names=0;
+ char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
+ cJSON *child=item->child;
+ int numentries=0,fail=0;
+ /* Count the number of entries. */
+ while (child) numentries++,child=child->next;
+ /* Explicitly handle empty object case */
+ if (!numentries)
+ {
+ out=(char*)cJSON_malloc(fmt?depth+4:3);
+ if (!out) return 0;
+ ptr=out;*ptr++='{';
+ if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
+ *ptr++='}';*ptr++=0;
+ return out;
+ }
+ /* Allocate space for the names and the objects */
+ entries=(char**)cJSON_malloc(numentries*sizeof(char*));
+ if (!entries) return 0;
+ names=(char**)cJSON_malloc(numentries*sizeof(char*));
+ if (!names) {cJSON_free(entries);return 0;}
+ memset(entries,0,sizeof(char*)*numentries);
+ memset(names,0,sizeof(char*)*numentries);
+
+ /* Collect all the results into our arrays: */
+ child=item->child;depth++;if (fmt) len+=depth;
+ while (child)
+ {
+ names[i]=str=print_string_ptr(child->string);
+ entries[i++]=ret=print_value(child,depth,fmt);
+ if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
+ child=child->next;
+ }
+
+ /* Try to allocate the output string */
+ if (!fail) out=(char*)cJSON_malloc(len);
+ if (!out) fail=1;
+
+ /* Handle failure */
+ if (fail)
+ {
+ for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
+ cJSON_free(names);cJSON_free(entries);
+ return 0;
+ }
+
+ /* Compose the output: */
+ *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
+ for (i=0;i<numentries;i++)
+ {
+ if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
+ strcpy(ptr,names[i]);ptr+=strlen(names[i]);
+ *ptr++=':';if (fmt) *ptr++='\t';
+ strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
+ if (i!=numentries-1) *ptr++=',';
+ if (fmt) *ptr++='\n';*ptr=0;
+ cJSON_free(names[i]);cJSON_free(entries[i]);
+ }
+
+ cJSON_free(names);cJSON_free(entries);
+ if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
+ *ptr++='}';*ptr++=0;
+ return out;
+}
+
+/* Get Array size/item / object item. */
+int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
+cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
+cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
+
+/* Utility for array list handling. */
+static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
+/* Utility for handling references. */
+static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
+
+/* Add item to array/object. */
+void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
+void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
+void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
+void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
+
+cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
+ if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
+void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
+cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
+void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
+
+/* Replace array/object items with new ones. */
+void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
+ newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
+ if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
+void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
+
+/* Create basic types: */
+cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
+cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
+cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
+cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
+cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
+cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
+cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
+cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
+
+/* Create Arrays: */
+cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
+
+/* Duplication */
+cJSON *cJSON_Duplicate(cJSON *item,int recurse)
+{
+ cJSON *newitem,*cptr,*nptr=0,*newchild;
+ /* Bail on bad ptr */
+ if (!item) return 0;
+ /* Create new item */
+ newitem=cJSON_New_Item();
+ if (!newitem) return 0;
+ /* Copy over all vars */
+ newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
+ if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
+ if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
+ /* If non-recursive, then we're done! */
+ if (!recurse) return newitem;
+ /* Walk the ->next chain for the child. */
+ cptr=item->child;
+ while (cptr)
+ {
+ newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
+ if (!newchild) {cJSON_Delete(newitem);return 0;}
+ if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
+ else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
+ cptr=cptr->next;
+ }
+ return newitem;
+}
+
+void cJSON_Minify(char *json)
+{
+ char *into=json;
+ while (*json)
+ {
+ if (*json==' ') json++;
+ else if (*json=='\t') json++; // Whitespace characters.
+ else if (*json=='\r') json++;
+ else if (*json=='\n') json++;
+ else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line.
+ else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments.
+ else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
+ else *into++=*json++; // All other characters.
+ }
+ *into=0; // and null-terminate.
+}
diff --git a/src/cJSON.h b/src/cJSON.h
new file mode 100644
index 0000000..867b7c3
--- /dev/null
+++ b/src/cJSON.h
@@ -0,0 +1,143 @@
+/*
+ Copyright (c) 2009 Dave Gamble
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+*/
+
+#ifndef cJSON__h
+#define cJSON__h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* cJSON Types: */
+#define cJSON_False 0
+#define cJSON_True 1
+#define cJSON_NULL 2
+#define cJSON_Number 3
+#define cJSON_String 4
+#define cJSON_Array 5
+#define cJSON_Object 6
+
+#define cJSON_IsReference 256
+
+/* The cJSON structure: */
+typedef struct cJSON {
+ struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
+ struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
+
+ int type; /* The type of the item, as above. */
+
+ char *valuestring; /* The item's string, if type==cJSON_String */
+ int valueint; /* The item's number, if type==cJSON_Number */
+ double valuedouble; /* The item's number, if type==cJSON_Number */
+
+ char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
+} cJSON;
+
+typedef struct cJSON_Hooks {
+ void *(*malloc_fn)(size_t sz);
+ void (*free_fn)(void *ptr);
+} cJSON_Hooks;
+
+/* Supply malloc, realloc and free functions to cJSON */
+extern void cJSON_InitHooks(cJSON_Hooks* hooks);
+
+
+/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
+extern cJSON *cJSON_Parse(const char *value);
+/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
+extern char *cJSON_Print(cJSON *item);
+/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
+extern char *cJSON_PrintUnformatted(cJSON *item);
+/* Delete a cJSON entity and all subentities. */
+extern void cJSON_Delete(cJSON *c);
+
+/* Returns the number of items in an array (or object). */
+extern int cJSON_GetArraySize(cJSON *array);
+/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
+extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
+/* Get item "string" from object. Case insensitive. */
+extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
+
+/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
+extern const char *cJSON_GetErrorPtr(void);
+
+/* These calls create a cJSON item of the appropriate type. */
+extern cJSON *cJSON_CreateNull(void);
+extern cJSON *cJSON_CreateTrue(void);
+extern cJSON *cJSON_CreateFalse(void);
+extern cJSON *cJSON_CreateBool(int b);
+extern cJSON *cJSON_CreateNumber(double num);
+extern cJSON *cJSON_CreateString(const char *string);
+extern cJSON *cJSON_CreateArray(void);
+extern cJSON *cJSON_CreateObject(void);
+
+/* These utilities create an Array of count items. */
+extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
+extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
+extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
+extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
+
+/* Append item to the specified array/object. */
+extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
+extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
+/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
+extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
+extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
+
+/* Remove/Detatch items from Arrays/Objects. */
+extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
+extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
+extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
+extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
+
+/* Update array items. */
+extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
+extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
+
+/* Duplicate a cJSON item */
+extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
+/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
+need to be released. With recurse!=0, it will duplicate any children connected to the item.
+The item->next and ->prev pointers are always zero on return from Duplicate. */
+
+/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
+extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
+
+extern void cJSON_Minify(char *json);
+
+/* Macros for creating things quickly. */
+#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
+#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
+#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
+#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
+#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
+#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
+
+/* When assigning an integer value, it needs to be propagated to valuedouble too. */
+#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/include/MESA/MESA_handle_logger.h b/src/include/MESA/MESA_handle_logger.h
new file mode 100644
index 0000000..c7e031d
--- /dev/null
+++ b/src/include/MESA/MESA_handle_logger.h
@@ -0,0 +1,75 @@
+#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
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#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;
+ * 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/src/include/MESA/MESA_htable.h b/src/include/MESA/MESA_htable.h
new file mode 100644
index 0000000..ac7c2b2
--- /dev/null
+++ b/src/include/MESA/MESA_htable.h
@@ -0,0 +1,419 @@
+#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 (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);
+
+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 "./hash_list_collide.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_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/src/include/MESA/MESA_list_queue.h b/src/include/MESA/MESA_list_queue.h
new file mode 100644
index 0000000..08ce32b
--- /dev/null
+++ b/src/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/src/include/MESA/MESA_prof_load.h b/src/include/MESA/MESA_prof_load.h
new file mode 100644
index 0000000..84c5deb
--- /dev/null
+++ b/src/include/MESA/MESA_prof_load.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/src/include/MESA/Maat_command.h b/src/include/MESA/Maat_command.h
new file mode 100644
index 0000000..eb61899
--- /dev/null
+++ b/src/include/MESA/Maat_command.h
@@ -0,0 +1,174 @@
+#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_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
+{
+ //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 nubmer 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 nubmer 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 nubmer 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);
+#endif
+
diff --git a/src/include/MESA/Maat_rule.h b/src/include/MESA/Maat_rule.h
new file mode 100644
index 0000000..30a25c9
--- /dev/null
+++ b/src/include/MESA/Maat_rule.h
@@ -0,0 +1,285 @@
+
+/*
+*****************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: [email protected], 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 <MESA/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
+#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_FOREIGN_CONT_LINGER //VALUE is interger *, SIZE=sizeof(int). Greater than 0: delete after VALUE seconds; 0: delete foreign content right after the notification callbacks; Less than 0: NEVER delete. Default: 0.
+ };
+//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);
+
+
+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 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);
+//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);
+
+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);
+
+//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);
+
+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/src/include/MESA/field_stat2.h b/src/include/MESA/field_stat2.h
new file mode 100644
index 0000000..2307603
--- /dev/null
+++ b/src/include/MESA/field_stat2.h
@@ -0,0 +1,84 @@
+#ifndef H_SCREEN_STAT_H_INCLUDE
+#define H_SCREEN_STAT_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,
+ 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
+};
+
+
+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.
+ 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,could be over ride by FS_histogram_set_bins,
+ //SIZE = strlen(string+'\0')+1.DEFAULT: "10,100,1000,10000".
+};
+
+//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<significant_figures<4
+int FS_register_histogram(screen_stat_handle_t handle, enum field_calc_algo calc_type, const char* name,
+ long long lowest_trackable_value,
+ long long highest_trackable_value,
+ int significant_figures);
+
+//id: when id's type is FIELD , column_id is ignored.
+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/src/include/MESA/stream.h b/src/include/MESA/stream.h
new file mode 100644
index 0000000..d3f9570
--- /dev/null
+++ b/src/include/MESA/stream.h
@@ -0,0 +1,36 @@
+#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_inject.h"
+#include "stream_inc/stream_control.h"
+#include "stream_inc/stream_entry.h"
+#include "stream_inc/stream_rawpkt.h"
+
+#define STREAM_H_VERSION (20150104)
+
+#define STREAM_BASE_MD5 "a0b1401145663b3079c9d0c25044ae70"
+#define STREAM_CONTROL_MD5 "ccdb2d8089a9d2568f9269f3b4aef751"
+#define STREAM_ENTRY_MD5 "4247a86972abd02ecbbe4cc960323bd2"
+#define STREAM_INJECT_MD5 "182f48639cbd340ec26321b960e29e46"
+#define STREAM_PROJECT_MD5 "75a0d392850e7fd963e6cee993fe0dd1"
+#define STREAM_PROXY_MD5 "2261f41264098f9a83475a6e8ef01e1a"
+#define STREAM_RAWPKT_MD5 "c9c517ca0593f9c9df95928e5cef4c7d"
+
+#endif
+
+/***********************************************************************************
+ Update log:
+ 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Ϊ�ڲ�ʹ�ö��ⲻ�ɼ�.
+*************************************************************************************/
+
diff --git a/src/include/MESA/stream_inc/stream_base.h b/src/include/MESA/stream_inc/stream_base.h
new file mode 100644
index 0000000..b34ba8c
--- /dev/null
+++ b/src/include/MESA/stream_inc/stream_base.h
@@ -0,0 +1,358 @@
+#ifndef _APP_STREAM_BASE_H_
+#define _APP_STREAM_BASE_H_
+
+
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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
+
+//�������
+#define DIR_C2S 0x01
+#define DIR_S2C 0x02
+#define DIR_DOUBLE 0x03
+
+//���������
+#define DIR_ROUTE_UP 0x00
+#define DIR_ROUTE_DOWN 0x01
+
+//���������Ͷ���
+#define PKT_TYPE_NORMAL (0x0)
+#define PKT_TYPE_IPREBUILD (1<<0) //ip��Ƭ���鱨��
+#define PKT_TYPE_TCPUNORDER (1<<1) //TCP������
+
+//��ַ���Ͷ���, ��ͨ������ addr_type_to_string() ת���ַ�����ʽ.
+enum addr_type_t{
+ __ADDR_TYPE_INIT = 0,
+ ADDR_TYPE_IPV4, /* 1, ����IPv4��ַ����Ԫ����Ϣ */
+ ADDR_TYPE_IPV6, /* 2, ����IPv6��ַ����Ԫ����Ϣ */
+ ADDR_TYPE_VLAN, /* 3 */
+ 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��ַ�� */
+ __ADDR_TYPE_IP_PAIR_V6, /* 13, ��IPv6��ַ�� */
+ ADDR_TYPE_PPP, /* 14 */
+ __ADDR_TYPE_MAX, /* 15 */
+};
+
+#define TCP_TAKEOVER_STATE_FLAG_OFF 0
+#define TCP_TAKEOVER_STATE_FLAG_ON 1
+
+
+//Ӧ�ò㿴��������״̬����
+#define OP_STATE_PENDING 0
+#define OP_STATE_REMOVE_ME 1
+#define OP_STATE_CLOSE 2
+#define OP_STATE_DATA 3
+
+//Ӧ�ò㷵�ؽ������
+#define APP_STATE_GIVEME 0x00
+#define APP_STATE_DROPME 0x01
+#define APP_STATE_FAWPKT 0x00
+#define APP_STATE_DROPPKT 0x10
+
+//�������Ͷ���
+enum stream_type_t{
+ STREAM_TYPE_NON = 0, /* �����ĸ���, ��VLAN, IP��� */
+ STREAM_TYPE_TCP,
+ STREAM_TYPE_UDP,
+ STREAM_TYPE_VLAN,
+ STREAM_TYPE_SOCKS4,
+ STREAM_TYPE_SOCKS5,
+ STREAM_TYPE_HTTP_PROXY,
+ STREAM_TYPE_PPPOE,
+};
+
+
+
+typedef struct raw_ipfrag_list{
+ void *frag_packet;
+ int pkt_len;
+ int type; /* IPv4 or IPv6 */
+ struct raw_ipfrag_list *next;
+}raw_ipfrag_list_t;
+
+
+
+
+/* 2014-11-19 lijia modify */
+#ifndef STRUCT_TUPLE4_DEFINED
+#define STRUCT_TUPLE4_DEFINED (1)
+/* ����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 gre_id;
+};
+
+
+#define VLAN_ID_MASK (0x0FFF)
+#define VLAN_TAG_LEN (4)
+struct layer_addr_vlan
+{
+ UINT16 vlan_id; /* network order */
+};
+
+#define VLAN_ID_LEN 4
+struct tuplevlan
+{
+ UCHAR vlan_id[VLAN_ID_LEN];
+};
+
+struct layer_addr_pppoe_session
+{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ver:4;
+ unsigned int type:4;
+#endif
+#if __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
+{
+ UCHAR src_mac[MAC_ADDR_LEN]; /* network order */
+ UCHAR dst_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��ֻ��ָ��ָ��˿��ڴ�,
+ �����ȡ��Ԫ��ʱ, ������Ҫget_tuple4()����.
+ �����������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��ֻ��ָ��ָ��˿��ڴ�,
+ �����ȡ��Ԫ��ʱ, ������Ҫget_tuple4()����.
+ �����������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_addr_l2tp
+{
+ UINT32 tunnelid; /* network order */
+ UINT32 sessionid; /* network order */
+};
+
+struct layer_addr_mpls
+{
+ unsigned int mpls_pkt;
+};
+
+
+struct layer_addr
+{
+ UCHAR addrtype; // ��ַ����, ��� enum addr_type_t
+ UCHAR addrlen;
+ UCHAR pkttype; //�������� ,�μ��궨��PKT_TYPE_xxx
+ UCHAR __pad[5]; //����8�ֽڶ���
+ // Ϊ�˷���Ӧ�ò��ȡ��ַ, �˴�ʹ��������, ʡȥָ������ǿ��ת������
+ 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;
+ void *paddr;
+ };
+
+};
+
+// �����˽ṹ���ں�papp����, ����ָ��ʱ, ����struct layer_addrǿת.
+struct ipaddr
+{
+ UCHAR addrtype; // ��ַ����, ��� enum addr_type_t
+ UCHAR addrlen;
+ UCHAR pkttype; //�������� ,�μ��궨��PKT_TYPE_xxx
+ UCHAR __pad[5]; //����8�ֽڶ���
+ union
+ {
+ struct stream_tuple4_v4 *v4;
+ struct stream_tuple4_v6 *v6;
+ void *paddr;
+ };
+
+};
+
+struct tcpdetail
+{
+ void *pdata; //����
+ UINT32 datalen; //���ݳ���
+ UINT32 lostlen;
+ UINT32 serverpktnum;
+ UINT32 clientpktnum;
+ UINT32 serverbytes;
+ UINT32 clientbytes;
+ UINT64 createtime;
+ UINT64 lastmtime;
+};
+
+struct udpdetail
+{
+ void *pdata; //����
+ UINT32 datalen; //���ݳ���
+ UINT32 pad; //Ԥ����Ϣ
+ UINT32 serverpktnum;
+ UINT32 clientpktnum;
+ UINT32 serverbytes;
+ UINT32 clientbytes;
+ UINT64 createtime;
+ UINT64 lastmtime;
+};
+
+struct streaminfo
+{
+ struct layer_addr addr; //����Э���ַ��Ϣ
+ struct streaminfo *pfather;//�ϲ����ṹ��
+ UCHAR type; // ��������
+ UCHAR threadnum; // �����߳�
+ UCHAR dir; // ��������������Ч, ���ĵ���˫�������0x01:c-->s; 0x02:s-->c; 0x03 c<-->s;
+ UCHAR curdir; // ������Ч, ��ǰ�����ϲ������߼�����, 0x01:c-->s; 0x02:s-->c
+ UCHAR opstate; //��ǰ��������״̬
+ UCHAR pktstate; //���ӵİ�����
+ UCHAR routedir; // ����������, ������Ч, ���˹�ָ��, �����ڷ���ʱ����Ƿ������������Ƿ���ͬ, ��������
+ UCHAR stream_state; // ÿ������ǰ���ڵĶ���״̬
+ UINT32 hash_index; // ÿ������hash����
+ UINT32 stream_index; // ÿ��stream�ڵ��߳�ȫ�ֵ�����
+ union
+ {
+ struct tcpdetail *ptcpdetail;
+ struct udpdetail *pudpdetail;
+ void *pdetail; //������ϸ��Ϣ
+ };
+ };
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//�ڴ������غ���
+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);
+
+//��ȡ��ǰϵͳ���еIJ��������߳�����
+int get_thread_count(void);
+
+/* ����ַ����ת���ɿɴ�ӡ���ַ�����ʽ */
+const char *addr_type_to_string(enum addr_type_t type);
+
+const char *printaddr (struct layer_addr *paddrinfo,int threadindex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/include/MESA/stream_inc/stream_control.h b/src/include/MESA/stream_inc/stream_control.h
new file mode 100644
index 0000000..f81502d
--- /dev/null
+++ b/src/include/MESA/stream_inc/stream_control.h
@@ -0,0 +1,29 @@
+#ifndef _APP_STREAM_CONTROL_H_
+#define _APP_STREAM_CONTROL_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+//���õ������ӵ���ز�����Ϣ
+int tcp_set_single_stream(const struct streaminfo *stream,UCHAR optype,void *value,int valuelen);
+/*
+//���õ������ӣ������������򻺴���Ŀ
+����ֵ 0: ���óɹ���-1:����ʧ��
+*/
+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);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/include/MESA/stream_inc/stream_entry.h b/src/include/MESA/stream_inc/stream_entry.h
new file mode 100644
index 0000000..0bd5c39
--- /dev/null
+++ b/src/include/MESA/stream_inc/stream_entry.h
@@ -0,0 +1,79 @@
+#ifndef _APP_STREAM_ENTRY_H_
+#define _APP_STREAM_ENTRY_H_
+
+
+//ҵ�����ý�����ʱ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_*�� ������������Ϣ;
+ f_*: ��������Ӧ�ĸ�����Ϣ;
+ raw_pkt: ԭʼ��ָ��, ʵ������Ϊ'raw_pkt_t';
+ pme: ˽������ָ�룬������չ�ã���ʱΪNULL;
+ thread_seq���߳����;
+
+��������ֵ������Ϊ�����ĸ�ֵ������
+
+ APP_STATE_GIVEME�������򱾺����Ͱ���
+ APP_STATE_DROPME�������򱾺����Ͱ���
+ APP_STATE_FAWPKT����ע�����ݰ�
+ APP_STATE_DROPPKT������ע�����ݰ�
+*/
+char IPv4_ENTRY_EXAMPLE(const struct streaminfo *f_stream,unsigned char routedir,int thread_seq, const void *raw_pkt);
+char IPv6_ENTRY_EXAMPLE(const struct streaminfo *f_stream,unsigned char routedir,int thread_seq,const void *raw_pkt);
+char TCP_ENTRY_EXAMPLE(const struct streaminfo *a_tcp, void **pme, int thread_seq,const void *raw_pkt);
+char UDP_ENTRY_EXAMPLE(const struct streaminfo *a_udp, void **pme, int thread_seq,const void *raw_pkt);
+
+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);
+
+
+//ҵ���ص��ӿ�
+char PROT_PROCESS(stSessionInfo* session_info, void **pme, int thread_seq,struct streaminfo *a_stream,const void *a_packet);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+
diff --git a/src/include/MESA/stream_inc/stream_inject.h b/src/include/MESA/stream_inc/stream_inject.h
new file mode 100644
index 0000000..4890ee6
--- /dev/null
+++ b/src/include/MESA/stream_inc/stream_inject.h
@@ -0,0 +1,71 @@
+#ifndef _APP_STREAM_INJECT_H_
+#define _APP_STREAM_INJECT_H_
+
+#include "stream_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//���ӹܿ���غ���
+
+int MESA_kill_tcp(struct streaminfo *stream, const void *raw_pkt);
+int MESA_kill_tcp_synack(struct streaminfo *stream, const void *raw_pkt);
+
+/* 2014-11-15 lijia add, for drop NO-TCP protocol in serial mode.
+ return value:
+ >= 0: success.
+ -1 : error.
+*/
+int MESA_kill_connection(struct streaminfo *stream, const void *ext_raw_pkt);
+
+/* ����route_dir����, */
+unsigned char MESA_dir_reverse(unsigned char raw_route_dir);
+
+/*
+ ARG:
+ stream: ���ṹ��ָ��;
+ payload: Ҫ���͵�����ָ��;
+ payload_len: Ҫ���͵����ݸ��س���;
+ raw_pkt: ԭʼ��ָ��;
+ snd_routedir: Ҫ�������ݵķ���, ԭʼ������Ϊ:stream->routedir ,
+ �����ԭʼ��ͬ��, snd_dir = stream->routedir,
+ �����ԭʼ������, snd_dir = 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);
+
+
+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, u_int8_t dir);
+
+/* ����ָ������IP��, ��ָ����������, У�����ƽ̨�Զ�����,
+ sip, dip������. */
+int MESA_fakepacket_send_ipv4(int thread_index,u_int8_t ttl,u_int8_t protocol,
+ u_int32_t sip_host_order, u_int32_t dip_host_order,
+ const char *payload, int payload_len,u_int8_t dir);
+
+/* ����ָ������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);
+
+/* ����ָ������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);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/include/MESA/stream_inc/stream_project.h b/src/include/MESA/stream_inc/stream_project.h
new file mode 100644
index 0000000..9a23212
--- /dev/null
+++ b/src/include/MESA/stream_inc/stream_project.h
@@ -0,0 +1,112 @@
+#ifndef _PROJECT_REQUIREMENT_H_
+#define _PROJECT_REQUIREMENT_H_
+
+#include "stream_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#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"
+
+
+int project_requirement_global_init(void);
+
+/*
+ must call this function in initialization, only one times,
+ the 'free_cb' should be NULL if 'project_req_val_type' is simple type,
+ otherwise please implement it by youself.
+
+ args:
+ project_req_name: for example, "terminal_tag", "stream_id".
+ 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):
+ 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.
+ others: success.
+
+ for example:
+ int value = project_req_get_int(stream, req_id);
+ if((-1 == value) && (ERANGE == errno)){
+ error_handle();
+ }else{
+ do_somgthing();
+ }
+
+ for example2:
+ unsigned short value = project_req_get_ushort(stream, req_id);
+ if((0xFF == value) && (ERANGE == errno)){
+ error_handle();
+ }else{
+ do_somgthing();
+ }
+
+*/
+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/src/include/MESA/stream_inc/stream_proxy.h b/src/include/MESA/stream_inc/stream_proxy.h
new file mode 100644
index 0000000..54023ed
--- /dev/null
+++ b/src/include/MESA/stream_inc/stream_proxy.h
@@ -0,0 +1,53 @@
+#ifndef _STREAM_PROXY_H_
+#define _STREAM_PROXY_H_
+
+#include "stream_base.h"
+
+
+
+
+#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/src/include/MESA/stream_inc/stream_rawpkt.h b/src/include/MESA/stream_inc/stream_rawpkt.h
new file mode 100644
index 0000000..bba9988
--- /dev/null
+++ b/src/include/MESA/stream_inc/stream_rawpkt.h
@@ -0,0 +1,69 @@
+#ifndef _APP_STREAM_RAWPKT_H_
+#define _APP_STREAM_RAWPKT_H_
+
+enum{
+ RAW_PKT_GET_DATA = 1, //value type: void *, out_value should be void **
+ 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 *
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+for example:
+ ��ȡԭʼ���ܳ���:
+ int tot_len;
+ get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_TOT_LEN, &tot_len);
+
+ ��ȡ�����ͷ��ʼ��ַ:
+ void *this_layer_hdr;
+ get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_THIS_LAYER_HDR, &this_layer_hdr);
+
+ ��ȡԭʼ��ʱ���:
+ struct timeval pkt_stamp;
+ get_opt_from_rawpkt(voidpkt, RAW_PKT_GET_TIMESTAMP, &pkt_stamp);
+
+ return value:
+ 0:success;
+ -1:error, or not support.
+*/
+int get_opt_from_rawpkt(const void *rawpkt, int type, void *out_value);
+
+
+/* ��ȡ��������ԭʼ���ж�Ӧ��ͷ����ַ,
+ ���豾��������ΪTCP, ���ô˺�����, �õ�ԭʼ���ж�Ӧ��TCPͷ����ַ.
+*/
+const void *get_this_layer_header(const struct streaminfo *pstream);
+
+/*
+ ԭʼ��ͷ��ƫ�ƺ���.
+
+ ����:
+ raw_data: ��ǰ���ͷ��ָ��;
+ raw_layer_type: ��ǰ��ĵ�ַ����;
+ expect_layer_type: ������ת���ĵ�ַ����;
+
+ ����ֵ:
+ NULL: �޴˵�ַ;
+ NON-NULL: ��Ӧ���ͷ����ַ.
+
+
+ ����:
+ ���赱ǰ��ΪEthernet, ��ʼ��ͷ��ַΪthis_layer_hdr, ����ת��IPv6��ͷ��:
+ struct ip6_hdr *ip6_header;
+ ip6_header = MESA_net_jump_to_layer(this_layer_hdr, ADDR_TYPE_MAC, ADDR_TYPE_IPV6);
+*/
+const void *MESA_net_jump_to_layer(const void *raw_data, int raw_layer_type, int expect_layer_type);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/include/url_classification.h b/src/include/url_classification.h
new file mode 100644
index 0000000..9bb72e8
--- /dev/null
+++ b/src/include/url_classification.h
@@ -0,0 +1,94 @@
+#ifndef __URL_CLASSIFICATION_H__
+#define __URL_CLASSIFICATION_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+enum URL_CLASSIFICATION_TYPE
+{
+ URL_CLASSTYPE_ADULT=0,
+ URL_CLASSTYPE_VIRUS,
+ URL_CLASSTYPE_PHISHING,
+ URL_CLASSTYPE_DUGS,
+ URL_CLASSTYPE_ACCEMIC_FRAUD,
+ URL_CLASSTYPE_TASTELESS,
+ URL_CLASSTYPE_HATE,
+ URL_CLASSTYPE_PEOXIES,
+ URL_CLASSTYPE_DATING,
+ URL_CLASSTYPE_MUSIC,
+ URL_CLASSTYPE_NEWS,
+ URL_CLASSTYPE_AUDIO_VIDEO,
+ URL_CLASSTYPE_ENTERTANMENT,
+
+ //To be Continued, to be modified.
+ URL_CLASSTYPE_NUM, //���͸���
+};
+
+typedef void* URLClassDB_handler_t;
+
+/*����: ��ѯij�������URL��������
+ *����ֵ: ������0����δ��ѯ����
+ */
+int URLClassDB_count_class(URLClassDB_handler_t handler, enum URL_CLASSIFICATION_TYPE type);
+
+/*����: ��ѯij��URL�����ķ���
+ *����: @url
+ *���: @array_num���������
+ *����ֵ: ���飬��������Ҫfree��
+ */
+enum URL_CLASSIFICATION_TYPE *URLClassDB_query_url_type(URLClassDB_handler_t handler, const char *url, int *array_num);
+
+/*����: ��ȡij�������������Ϣ
+ *����ֵ: ij�������JSON��ʽ��������JSON�ṹ���������䡣����
+ * {"en_name":"adult","ru_name":"���ѧۧ�� �էݧ� �ӧ٧���ݧ���","cn_name":"������վ"}
+ */
+const char *URLClassDB_get_class_description(URLClassDB_handler_t handler, enum URL_CLASSIFICATION_TYPE type);
+
+/*����: ���¹�ע�ķ����б�
+ *����: @types_array�������
+ @array_num���������
+ *����ֵ: 0: �ɹ���
+ * -1: ʧ�ܣ�
+ */
+int URLClassDB_update_classes(URLClassDB_handler_t handler, const enum URL_CLASSIFICATION_TYPE *types_array, int array_num);
+
+typedef void (*update_class_callback)(int succ, void *user);
+/*����: ���¹�ע�ķ����б����ڲ������̣߳������߳��ڻص�update_class_callback��
+ *����: @types_array�������
+ @array_num���������
+ *����ֵ: 0: �ɹ���
+ * -1: ʧ�ܣ�
+ */
+int URLClassDB_update_classes_asyn(URLClassDB_handler_t handler, update_class_callback cb, void *user,
+ const enum URL_CLASSIFICATION_TYPE *types_array, int array_num);
+
+enum URLCLASSDB_INIT_OPT
+{
+ URLCLASSDB_OPT_TMP_DIR=0, //Where to store temporary files which are generated by this module. VALUE is a const char*, MUST end with '\0', SIZE= strlen(string+'\0')+1. DEFAULT: Current directory.
+};
+int URLClassDB_set_opttype(URLClassDB_handler_t handler, enum URLCLASSDB_INIT_OPT opt, const void* value, int size);
+
+/*����: ����һ����ѯ/ɨ��ʵ��
+ *����ֵ: ʵ���ľ��
+ */
+URLClassDB_handler_t URLClassDB_instance_new(const char *dat_dir, const char *log_dir);
+
+/*����: ����һ��ʵ��
+ *����ֵ: 0: �ɹ���
+ * -1: ʧ�ܣ�
+ */
+int URLClassDB_instance_starts(URLClassDB_handler_t handler);
+
+/*����: ����һ����ѯ/ɨ��ʵ��
+ */
+void URLClassDB_instance_destroy(URLClassDB_handler_t handler);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/ntc_restiful_master.cpp b/src/ntc_restiful_master.cpp
new file mode 100644
index 0000000..55961cc
--- /dev/null
+++ b/src/ntc_restiful_master.cpp
@@ -0,0 +1,216 @@
+#include "ntc_restiful_master.h"
+#include <assert.h>
+#include <time.h>
+
+
+
+#if TEST_MODE
+const char* kafka_topic[__TOPIC_MAX]={"IPD_HTTP_IP_LOG", "IPD_SSL_IP_LOG", "IPD_DNS_IP_LOG", "NTC_CONN_RECORD_LOG", "NTC_COLLECT_RADIUS_LOG"};
+#else
+const char* kafka_topic[__TOPIC_MAX]={"IPD-HTTP-IP-LOG", "IPD-SSL-IP-LOG", "IPD-DNS-IP-LOG", "NTC-CONN-RECORD-LOG", "NTC-COLLECT-RADIUS-LOG"};
+#endif
+
+const char* g_conf_file = "./conf/ntc_restiful.conf";
+global_info_t g_info;
+const char *module_name = "ntc_restiful";
+
+void free_data(void *data)
+{
+ free(data);
+ data = NULL;
+}
+
+
+void init_parameters(const char* g_conf_file)
+{
+ int ret=0;
+ //log
+ MESA_load_profile_int_def(g_conf_file, "SYSTEM", "log_level", &g_info.log_level, 10);
+ MESA_load_profile_string_def(g_conf_file, "SYSTEM", "log_path", g_info.run_log_path, MAX_PATH_LEN, "./log/ntc_restiful.log");
+
+ //restiful
+ MESA_load_profile_string_def(g_conf_file, "RESTIFUL", "restiful_listen_ip", g_info.restiful_listen_ip, MAX_IP_LEN, "127.0.0.1");
+ short restiful_port_tmp = 0;
+ MESA_load_profile_short_def(g_conf_file, "RESTIFUL", "restiful_listen_port", &restiful_port_tmp, 80);
+ g_info.restiful_listen_port = (unsigned short)restiful_port_tmp;
+ MESA_load_profile_uint_def(g_conf_file, "RESTIFUL", "restiful_listen_timeout", &g_info.restiful_listen_timeout, 120);
+
+}
+void read_maat_init_param(const char* profile, const char* section, struct maat_init_param* param)
+{
+ int tmp;
+ MESA_load_profile_string_nodef(profile, section, "instance_name", param->instance_name, sizeof(param->instance_name));
+ MESA_load_profile_string_nodef(profile, section, "table_info_path", param->table_info_path, sizeof(param->table_info_path));
+ MESA_load_profile_string_def(profile, section, "redis_ip", param->redis_ip, 32, "127.0.0.1");
+ MESA_load_profile_int_def(profile, section, "redis_port",&(tmp), 6379);
+ param->redis_port=(unsigned short)tmp;
+ MESA_load_profile_int_def(profile, section, "redis_index",&(param->redis_index), 0);
+ return;
+}
+Maat_feather_t maat_init(const struct maat_init_param* param, void* logger, int thread_num)
+{
+ //init maat_read_redis
+ int scan_interval_ms=10;
+ int effective_interval_ms=30;
+ Maat_feather_t target=NULL;
+ target=Maat_feather(thread_num, param->table_info_path, logger);
+ Maat_set_feather_opt(target,MAAT_OPT_INSTANCE_NAME, param->instance_name, strlen(param->instance_name)+1);
+/*
+#if TEST_MODE
+ Maat_set_feather_opt(target, MAAT_OPT_JSON_FILE_PATH, "conf/maat_test.json", strlen("conf/maat_test.json"));
+#else
+*/
+ Maat_set_feather_opt(target, MAAT_OPT_REDIS_IP, param->redis_ip, strlen(param->redis_ip)+1);
+ Maat_set_feather_opt(target, MAAT_OPT_REDIS_PORT, &(param->redis_port), sizeof(unsigned short ));
+ Maat_set_feather_opt(target, MAAT_OPT_REDIS_INDEX, &(param->redis_index), sizeof(int));
+//#endif
+ Maat_set_feather_opt(target, MAAT_OPT_SCANDIR_INTERVAL_MS,&scan_interval_ms, sizeof(scan_interval_ms));
+ Maat_set_feather_opt(target, MAAT_OPT_EFFECT_INVERVAL_MS,&effective_interval_ms, sizeof(effective_interval_ms));
+ Maat_initiate_feather(target);
+ return target;
+}
+
+
+void url_hit_compile_handler(struct evhttp_request *req, void *arg)
+{
+ cJSON* output = cJSON_CreateObject();
+ //get uri
+ int http_return_code = HTTP_OK;//200
+ const char* uri;
+ uri = evhttp_request_uri(req);
+ char* decoded_uri;
+ decoded_uri = evhttp_decode_uri(uri);
+ //get request param
+ char* url;
+ struct evkeyvalq params;
+ evhttp_parse_query(decoded_uri, &params);
+ char* url = (char*)evhttp_find_header(&params, "url");
+ if(NULL == url)
+ {
+ cJSON_AddStringToObject(output, "errmsg", "wrong format. eg.http://192.168.10.8:8080/v1/url_hit_compile?url=www.baidu.com");
+ http_return_code = HTTP_BADREQUEST;//400
+ goto OUTPUT;
+ }
+
+ //maat_scan
+ Maat_rule_t result[MAX_CONFIG_NUM];
+ memset((void*)result, 0, sizeof(Maat_rule_t));
+ int found_pos=0;
+ scan_status_t *mid = NULL;
+ int hit_num = Maat_full_scan_string(g_info.maat_feather, g_info.url_config_table, CHARSET_NONE, url, strlen(url), result, &found_pos, MAX_CONFIG_NUM, mid, 1);
+ if(hit_num > 0)
+ {
+ cJSON_AddNumberToObject(output, "hit_num", hit_num);
+ cJSON* pz_id_array = cJSON_CreateArray();
+ int i;
+ for(i = 0; i < hit_num; i++)
+ {
+ cJSON_AddItemToArray(pz_id_array, cJSON_CreateNumber(result[i].config_id));
+ }
+ cJSON_AddItemToObject(output, "pz_id_set", pz_id_array);
+ }
+
+ //output
+OUTPUT:
+ evhttp_add_header(req->output_headers, "Server", "NTC_restiful");
+ evhttp_add_header(req->output_headers, "Content-Type", "application/json");
+ evhttp_add_header(req->output_headers, "Connection", "close");
+ struct evbuffer *buf = evbuffer_new();
+ char* output_str = cJSON_Print(output);
+ evbuffer_add_printf(buf, "%s", output_str);
+ evhttp_send_reply(req, http_return_code, "OK", buf);
+ evbuffer_free(buf);
+ cJSON_Delete(output);
+ free(decoded_uri);
+ free(output_str);
+}
+
+
+void url_label_handler(struct evhttp_request *req, void *arg)
+{
+ cJSON* output = cJSON_CreateObject();
+ //get uri
+ int http_return_code = HTTP_OK;//200
+ const char* uri;
+ uri = evhttp_request_uri(req);
+ char* decoded_uri;
+ decoded_uri = evhttp_decode_uri(uri);
+ //get request param
+ char* url;
+ struct evkeyvalq params;
+ evhttp_parse_query(decoded_uri, &params);
+ char* url = (char*)evhttp_find_header(&params, "url");
+ char* label = (char*)evhttp_find_header(&params, "label");
+
+ if(NULL == url && NULL == label)
+ {//todo: is label input Chinese?
+ cJSON_AddStringToObject(output, "errmsg", "wrong format. eg.http://192.168.10.8:8080/v1/label?url=www.baidu.com or http://192.168.10.8:8080/v1/label?label=����");
+ http_return_code = HTTP_BADREQUEST;//400
+ goto OUTPUT;
+ }
+
+ if(NULL != url)
+ {
+
+ }
+
+ if(NULL != label)
+ {
+
+ }
+
+ //output
+OUTPUT:
+ evhttp_add_header(req->output_headers, "Server", "NTC_restiful");
+ evhttp_add_header(req->output_headers, "Content-Type", "application/json");
+ evhttp_add_header(req->output_headers, "Connection", "close");
+ struct evbuffer *buf = evbuffer_new();
+ char* output_str = cJSON_Print(output);
+ evbuffer_add_printf(buf, "%s", output_str);
+ evhttp_send_reply(req, http_return_code, "OK", buf);
+ evbuffer_free(buf);
+ cJSON_Delete(output);
+ free(decoded_uri);
+ free(output_str);
+}
+
+
+int main(int argc, char **argv)
+{
+ memset(&g_info, 0, sizeof(global_info_t));
+ init_parameters(g_conf_file);
+ //init log
+ g_info.runtime_log = MESA_create_runtime_log_handle(g_info.run_log_path, g_info.log_level);
+ if(g_info.runtime_log== NULL)
+ {
+ printf("<%s>%d: MESA_create_runtime_log_handle failed ...\n", __FILE__, __LINE__);
+ assert(0);
+ }
+
+ read_maat_init_param(g_conf_file, "MAAT", &(g_info.maat_param));
+ g_info.maat_feather=maat_init( &(g_info.maat_param), g_info.runtime_log, 1);
+ //todo:table name
+ g_info.url_config_table = Maat_table_register(g_info.maat_feather, "URL_PZ");
+ if(g_info.url_config_table < 0)
+ {
+ MESA_handle_runtime_log(g_info.runtime_log, RLOG_LV_FATAL, module_name, "<%s>%d: register maat_table failed", __FILE__, __LINE__);
+ assert(0);
+ }
+
+ //init restiful
+ event_init();
+ struct evhttp* httpd;
+ httpd = evhttp_start(g_info.restiful_listen_ip, g_info.restiful_listen_port);
+ evhttp_set_timeout(httpd, g_info.restiful_listen_timeout);
+
+ evhttp_set_cb(httpd, "/v1/url_hit_compile", url_hit_compile_handler, NULL);
+
+ evhttp_set_cb(httpd, "/v1/label", url_label_handler, NULL);
+
+ event_dispatch();
+ evhttp_free(httpd);
+
+ pthread_join(kafka_focus_domain_consumer_pid[0], NULL);
+
+ return 0;
+}
diff --git a/src/ntc_restiful_master.h b/src/ntc_restiful_master.h
new file mode 100644
index 0000000..cf8dc99
--- /dev/null
+++ b/src/ntc_restiful_master.h
@@ -0,0 +1,54 @@
+#ifndef H_IP_DISCOVERY_MASTER_H
+#define H_IP_DISCOVERY_MASTER_H
+#include <pthread.h>
+#include <stdlib.h>
+
+#include <MESA/MESA_handle_logger.h>
+#include <MESA/MESA_prof_load.h>
+#include <MESA/Maat_rule.h>
+#include <MESA/Maat_command.h>
+#include <pthread.h>
+#include <event.h>
+#include <evhttp.h>
+#include "cJSON.h"
+#include "url_classification.h"
+
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define MAX_CONFIG_NUM 128
+
+struct maat_init_param
+{
+ char instance_name[32];
+ char table_info_path[MAX_PATH_LEN];
+ char redis_ip[32];
+ unsigned short redis_port;
+ int redis_index;
+};
+
+
+typedef struct __global_info
+{
+ //log
+ char run_log_path[256];
+ void *runtime_log;
+ int log_level;
+
+ //maat
+ struct maat_init_param maat_param;
+ Maat_feather_t maat_feather;
+ int url_config_table;
+
+ //restiful
+ char restiful_listen_ip[MAX_IP_LEN];
+ unsigned short restiful_listen_port;
+ unsigned int restiful_listen_timeout;//in seconds
+}global_info_t;
+
+#endif