summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgit commit -m first <[email protected]>2019-06-12 15:06:20 +0800
committergit commit -m first <[email protected]>2019-06-12 15:06:20 +0800
commit10e810b629148dcc96159d96045edccb94af600a (patch)
treed8e4724d2f1ea208f05fa6d96be8ad6413b6df3b /src
add source code
Diffstat (limited to 'src')
-rw-r--r--src/.comm_audit.cpp.swpbin0 -> 16384 bytes
-rw-r--r--src/cJSON.c763
-rw-r--r--src/comm_audit.cpp968
3 files changed, 1731 insertions, 0 deletions
diff --git a/src/.comm_audit.cpp.swp b/src/.comm_audit.cpp.swp
new file mode 100644
index 0000000..499ead6
--- /dev/null
+++ b/src/.comm_audit.cpp.swp
Binary files differ
diff --git a/src/cJSON.c b/src/cJSON.c
new file mode 100644
index 0000000..772f9af
--- /dev/null
+++ b/src/cJSON.c
@@ -0,0 +1,763 @@
+/*
+ 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) = rt_malloc;
+// static void (*cJSON_free)(void *ptr) = rt_free;
+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 = rt_malloc;
+// cJSON_free = rt_free;
+// return;
+// }
+
+// cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:rt_malloc;
+// cJSON_free = (hooks->free_fn)?hooks->free_fn:rt_free;
+// }
+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->type&cJSON_StringIsConst) && 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;
+}
+
+static int pow2gt (int x) { --x; x|=x>>1; x|=x>>2; x|=x>>4; x|=x>>8; x|=x>>16; return x+1; }
+
+typedef struct {char *buffer; int length; int offset; } printbuffer;
+
+static char* ensure(printbuffer *p,int needed)
+{
+ char *newbuffer;int newsize;
+ if (!p || !p->buffer) return 0;
+ needed+=p->offset;
+ if (needed<=p->length) return p->buffer+p->offset;
+
+ newsize=pow2gt(needed);
+ newbuffer=(char*)cJSON_malloc(newsize);
+ if (!newbuffer) {cJSON_free(p->buffer);p->length=0,p->buffer=0;return 0;}
+ if (newbuffer) memcpy(newbuffer,p->buffer,p->length);
+ cJSON_free(p->buffer);
+ p->length=newsize;
+ p->buffer=newbuffer;
+ return newbuffer+p->offset;
+}
+
+static int update(printbuffer *p)
+{
+ char *str;
+ if (!p || !p->buffer) return 0;
+ str=p->buffer+p->offset;
+ return p->offset+strlen(str);
+}
+
+/* Render the number nicely from the given item into a string. */
+static char *print_number(cJSON *item,printbuffer *p)
+{
+ char *str=0;
+ double d=item->valuedouble;
+ if (d==0)
+ {
+ if (p) str=ensure(p,2);
+ else str=(char*)cJSON_malloc(2); /* special case for 0. */
+ if (str) strcpy(str,"0");
+ }
+ else if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
+ {
+ if (p) str=ensure(p,21);
+ else str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
+ if (str) sprintf(str,"%d",item->valueint);
+ }
+ else
+ {
+ if (p) str=ensure(p,64);
+ 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,printbuffer *p)
+{
+ const char *ptr;char *ptr2,*out;int len=0,flag=0;unsigned char token;
+
+ for (ptr=str;*ptr;ptr++) flag|=((*ptr>0 && *ptr<32)||(*ptr=='\"')||(*ptr=='\\'))?1:0;
+ if (!flag)
+ {
+ len=ptr-str;
+ if (p) out=ensure(p,len+3);
+ else out=(char*)cJSON_malloc(len+3);
+ if (!out) return 0;
+ ptr2=out;*ptr2++='\"';
+ strcpy(ptr2,str);
+ ptr2[len]='\"';
+ ptr2[len+1]=0;
+ return out;
+ }
+
+ if (!str)
+ {
+ if (p) out=ensure(p,3);
+ else out=(char*)cJSON_malloc(3);
+ if (!out) return 0;
+ strcpy(out,"\"\"");
+ return out;
+ }
+ ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
+
+ if (p) out=ensure(p,len+3);
+ else 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,printbuffer *p) {return print_string_ptr(item->valuestring,p);}
+
+/* Predeclare these prototypes. */
+static const char *parse_value(cJSON *item,const char *value);
+static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p);
+static const char *parse_array(cJSON *item,const char *value);
+static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p);
+static const char *parse_object(cJSON *item,const char *value);
+static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p);
+
+/* 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,0);}
+char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0,0);}
+
+char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt)
+{
+ printbuffer p;
+ p.buffer=(char*)cJSON_malloc(prebuffer);
+ p.length=prebuffer;
+ p.offset=0;
+ return print_value(item,0,fmt,&p);
+ return p.buffer;
+}
+
+
+/* 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,printbuffer *p)
+{
+ char *out=0;
+ if (!item) return 0;
+ if (p)
+ {
+ switch ((item->type)&255)
+ {
+ case cJSON_NULL: {out=ensure(p,5); if (out) strcpy(out,"null"); break;}
+ case cJSON_False: {out=ensure(p,6); if (out) strcpy(out,"false"); break;}
+ case cJSON_True: {out=ensure(p,5); if (out) strcpy(out,"true"); break;}
+ case cJSON_Number: out=print_number(item,p);break;
+ case cJSON_String: out=print_string(item,p);break;
+ case cJSON_Array: out=print_array(item,depth,fmt,p);break;
+ case cJSON_Object: out=print_object(item,depth,fmt,p);break;
+ }
+ }
+ else
+ {
+ 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,0);break;
+ case cJSON_String: out=print_string(item,0);break;
+ case cJSON_Array: out=print_array(item,depth,fmt,0);break;
+ case cJSON_Object: out=print_object(item,depth,fmt,0);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,printbuffer *p)
+{
+ char **entries;
+ char *out=0,*ptr,*ret;int len=5;
+ cJSON *child=item->child;
+ int numentries=0,i=0,fail=0;
+ size_t tmplen=0;
+
+ /* How many entries in the array? */
+ while (child) numentries++,child=child->next;
+ /* Explicitly handle numentries==0 */
+ if (!numentries)
+ {
+ if (p) out=ensure(p,3);
+ else out=(char*)cJSON_malloc(3);
+ if (out) strcpy(out,"[]");
+ return out;
+ }
+
+ if (p)
+ {
+ /* Compose the output array. */
+ i=p->offset;
+ ptr=ensure(p,1);if (!ptr) return 0; *ptr='['; p->offset++;
+ child=item->child;
+ while (child && !fail)
+ {
+ print_value(child,depth+1,fmt,p);
+ p->offset=update(p);
+ if (child->next) {len=fmt?2:1;ptr=ensure(p,len+1);if (!ptr) return 0;*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;p->offset+=len;}
+ child=child->next;
+ }
+ ptr=ensure(p,2);if (!ptr) return 0; *ptr++=']';*ptr=0;
+ out=(p->buffer)+i;
+ }
+ else
+ {
+ /* 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,0);
+ 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++)
+ {
+ tmplen=strlen(entries[i]);memcpy(ptr,entries[i],tmplen);ptr+=tmplen;
+ 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,printbuffer *p)
+{
+ 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;
+ size_t tmplen=0;
+ /* Count the number of entries. */
+ while (child) numentries++,child=child->next;
+ /* Explicitly handle empty object case */
+ if (!numentries)
+ {
+ if (p) out=ensure(p,fmt?depth+4:3);
+ else 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;
+ }
+ if (p)
+ {
+ /* Compose the output: */
+ i=p->offset;
+ len=fmt?2:1; ptr=ensure(p,len+1); if (!ptr) return 0;
+ *ptr++='{'; if (fmt) *ptr++='\n'; *ptr=0; p->offset+=len;
+ child=item->child;depth++;
+ while (child)
+ {
+ if (fmt)
+ {
+ ptr=ensure(p,depth); if (!ptr) return 0;
+ for (j=0;j<depth;j++) *ptr++='\t';
+ p->offset+=depth;
+ }
+ print_string_ptr(child->string,p);
+ p->offset=update(p);
+
+ len=fmt?2:1;
+ ptr=ensure(p,len); if (!ptr) return 0;
+ *ptr++=':';if (fmt) *ptr++='\t';
+ p->offset+=len;
+
+ print_value(child,depth,fmt,p);
+ p->offset=update(p);
+
+ len=(fmt?1:0)+(child->next?1:0);
+ ptr=ensure(p,len+1); if (!ptr) return 0;
+ if (child->next) *ptr++=',';
+ if (fmt) *ptr++='\n';*ptr=0;
+ p->offset+=len;
+ child=child->next;
+ }
+ ptr=ensure(p,fmt?(depth+1):2); if (!ptr) return 0;
+ if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
+ *ptr++='}';*ptr=0;
+ out=(p->buffer)+i;
+ }
+ else
+ {
+ /* 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,0);
+ entries[i++]=ret=print_value(child,depth,fmt,0);
+ 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';
+ tmplen=strlen(names[i]);memcpy(ptr,names[i],tmplen);ptr+=tmplen;
+ *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_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (!(item->type&cJSON_StringIsConst) && item->string) cJSON_free(item->string);item->string=(char*)string;item->type|=cJSON_StringIsConst;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_InsertItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) {cJSON_AddItemToArray(array,newitem);return;}
+ newitem->next=c;newitem->prev=c->prev;c->prev=newitem;if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;}
+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/comm_audit.cpp b/src/comm_audit.cpp
new file mode 100644
index 0000000..5ffaa05
--- /dev/null
+++ b/src/comm_audit.cpp
@@ -0,0 +1,968 @@
+/*
+ * comm_audit.cpp
+ *
+ * Created on: 2017-8-14
+ * Last Modified: 2017-11-24
+ * Author: zhangxi
+ */
+
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <atomic>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "project_requirement.h"
+#include "identify.h"
+#include "cJSON.h"
+#include "comm_audit.h"
+#include "maxminddb.h"
+//#define LOG_DEBUG 0
+
+using namespace std;
+
+int COMM_AUDIT_VERSION_20171124 = 0;
+
+comm_prog_configure_t g_comm_prog_configure;
+comm_prog_runtime_parameter_t g_comm_prog_para;
+atomic_flag lock = ATOMIC_FLAG_INIT;
+
+static int log_nums;
+static int times = 0;
+static int log = 0;
+static int now = 0;
+// static char FDIR[12]={0};
+
+
+//获取IP归属地
+int get_ip_coun(char * filename, char *ip_address, char ** name_en)
+{
+ MMDB_s mmdb;
+ int status = MMDB_open(filename, MMDB_MODE_MMAP, &mmdb);
+
+ if(MMDB_SUCCESS != status)
+ {
+ //fprintf(stderr, "\n Can't open %s - %s\n",filename, MMDB_strerror(status));
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "ERROR", "Can't open %s - %s\n",filename, MMDB_strerror(status));
+ if(MMDB_IO_ERROR == status)
+ {
+ //fprintf(stderr, "IO error: %s\n", strerror(errno));
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "ERROR","IO error: %s\n", strerror(errno));
+ }
+ return 1; //error
+ }
+
+ int gai_error, mmdb_error;
+
+ MMDB_lookup_result_s result =
+ MMDB_lookup_string(&mmdb, ip_address, &gai_error, &mmdb_error);
+
+ if (0 != gai_error)
+ {
+ fprintf(stderr, "\n Error from getaddrinfo for %s - %s\n\n", ip_address, gai_strerror(gai_error));
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "ERROR","Error from getaddrinfo for %s - %s", ip_address, gai_strerror(gai_error));
+ return 2; //error
+ }
+
+ if (MMDB_SUCCESS != mmdb_error)
+ {
+ fprintf(stderr,"\n Got an error from libmaxminddb: %s\n\n", MMDB_strerror(mmdb_error));
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "ERROR","Got an error from libmaxminddb: %s", MMDB_strerror(mmdb_error));
+ return 3; //error
+ }
+
+ MMDB_entry_data_s entry_data;
+
+ int exit_code = 0;
+ if (result.found_entry)
+ {
+
+ int status = MMDB_get_value(&result.entry, &entry_data, "COUNTRY", NULL);
+
+ if (MMDB_SUCCESS != status)
+ {
+ fprintf(stderr,"Got an error looking up the entry data - %s\n", MMDB_strerror(status));
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "ERROR","Got an error looking up the entry data - %s\n", MMDB_strerror(status));
+ exit_code = 4;
+ goto end;
+ }
+
+ if (entry_data.has_data)
+ {
+ *name_en = (char *)malloc(sizeof(entry_data.data_size + 1));
+ memset(*name_en, '\0', sizeof(entry_data.data_size + 1));
+ memcpy(*name_en, entry_data.utf8_string, entry_data.data_size);
+ //printf ("%s\n", name_en);
+ }
+ }
+ else
+ {
+ //fprintf(stderr,"\n No entry for this IP address (%s) was found\n\n", ip_address);
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "ERROR","No entry for this IP address (%s) was found", ip_address);
+ exit_code = 5;
+ }
+
+end:
+ MMDB_close(&mmdb);
+ //exit(exit_code);
+ return exit_code;
+}
+
+
+//读取json格式文件
+void parseJson(char * buf)
+{
+ if(NULL == buf)
+ {
+ return;
+ }
+ cJSON * json = cJSON_Parse(buf);
+ if (!json)
+ {
+ printf("JSON FILE READ FAIL! PLEASE CHECK net_log_upload_pz.txt's FORMAT.\n");
+ printf("USE LAST UPLOAD_PZ NOW.\n");
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "UPLOAD_PZ JSON FILE READ FAIL!ERROR NUM IS %s.", strerror(errno));
+ }
+ else
+ {
+ int size = cJSON_GetArraySize(json);
+ cJSON *object;
+ for(int i = 0; i < size; i++)
+ {
+ object = cJSON_GetArrayItem(json,i);
+ int interval = cJSON_GetObjectItem(object, "interval")->valueint;
+ int max_num = cJSON_GetObjectItem(object, "num")->valueint;
+ if(interval != g_comm_prog_configure.write_interval || max_num != g_comm_prog_configure.write_max_num)
+ {
+ g_comm_prog_configure.write_interval = interval;
+ g_comm_prog_configure.write_max_num = max_num;
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "INFO", "UPLOAD_PZ JSON FILE READ SUCC! interval is %d, num is %d.", g_comm_prog_configure.write_interval, g_comm_prog_configure.write_max_num);
+ }
+ }
+ }
+
+ cJSON_Delete(json);
+}
+
+
+void read_json_file(int num)
+{
+
+ string read_path = g_comm_prog_configure.upload_pz_path;
+ if (read_path[read_path.size() - 1] != '/')
+ read_path+='/';
+
+ fstream handle;
+ string in_file_name = read_path + "net_log_upload_pz.txt";
+ handle.open(in_file_name.c_str(), ios::binary|ios::in);
+ if(handle.is_open())
+ {
+ char *buf = new char[MAX_LEN];
+ handle.read(buf, MAX_LEN);
+ parseJson(buf);
+ handle.close();
+
+ delete buf;
+ }
+
+}
+
+// 定时读取json线程
+void *set_timer(void * pParam)
+{
+ signal(SIGALRM, read_json_file);
+
+ struct itimerval tick;
+ tick.it_value.tv_sec = 1; //1秒钟后将启动定时器
+ tick.it_value.tv_usec = 0;
+ tick.it_interval.tv_sec = g_comm_prog_configure.read_interval; //定时器启动后,每隔指定秒数将执行相应的函数
+ tick.it_interval.tv_usec = 0;
+
+ //setitimer将触发SIGALRM信号
+ int ret = setitimer(ITIMER_REAL, &tick, NULL);
+
+ if ( ret != 0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "SET TIMER ERROR! ERROR NUM IS %s.", strerror(errno));
+ return NULL;
+ }
+
+ while(1){sleep(1);}
+
+}
+
+// 写数据
+int send_data(htable_data_t* send_data, FILE *fp)
+{
+ log = 1;
+ long long EndTime;
+ EndTime = time(NULL);
+
+ char stime[24];
+ struct tm stm;
+ time_t sTime = (time_t)send_data->start_time;
+ localtime_r(&sTime, &stm);
+ sprintf(stime, "%d-%02d-%02d %d:%d:%d", stm.tm_year+1900, stm.tm_mon+1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec);
+
+ char etime[24];
+ struct tm ptm;
+ time_t eTime;
+ if(send_data->end_time == 0)
+ eTime = (time_t)EndTime;
+ else
+ eTime = (time_t)send_data->end_time;
+ localtime_r(&eTime, &ptm);
+ sprintf(etime, "%d-%02d-%02d %d:%d:%d", ptm.tm_year+1900, ptm.tm_mon+1, ptm.tm_mday, ptm.tm_hour, ptm.tm_min, ptm.tm_sec);
+ // memcpy(stat_info->time_data.end_time, etime, 24);
+
+ char sendInnerIP[IPLEN]={0};
+ inet_ntop(AF_INET, &send_data->inner_ip, sendInnerIP ,IPLEN);
+ // sprintf(sendInnerIP, "%s", inet_ntop(AF_INET, &send_data->inner_ip, sendInnerIP ,IPLEN));
+ char sendExtIP[IPLEN]={0};
+ inet_ntop(AF_INET, &send_data->ext_ip, sendExtIP ,IPLEN);
+ // sprintf(sendExtIP, "%s", inet_ntop(AF_INET, &send_data->ext_ip, sendExtIP ,IPLEN));
+
+ string app = APP_TYPE(send_data->app);
+ string protocol = STREAM_TYPE(send_data->protocol);
+ string tcp_flag = TCP_FLAG(send_data->tcp_flag);
+
+ fprintf(fp, "%s#%u#%s#%s#%u#%s#%s#%s#%s#%llu#%llu#%llu#%llu#%s#%s\n",
+ sendInnerIP,
+ ntohs(send_data->inner_port),
+ send_data->inner_mac,
+ sendExtIP,
+ ntohs(send_data->ext_port),
+ send_data->ext_mac,
+ protocol.c_str(),
+ app.c_str(),
+ tcp_flag.c_str(),
+ send_data->in_bytes,
+ send_data->out_bytes,
+ send_data->in_pkts,
+ send_data->out_pkts,
+ stime,
+ etime
+ );
+ // log_nums条记录写入一个txt
+ if(log_nums < g_comm_prog_configure.write_max_num-1)
+ log_nums++;
+ else
+ {
+ log_nums = 0;
+ times++;
+ }
+
+ return 0;
+}
+
+// 遍历哈希表写文件
+void iterate_cb(const uchar * key, uint size, void * data, void *arg)
+{
+ htable_data_t* info = (htable_data_t*)data;
+ char * writetime = ((del_para_t*)arg)->writetime;
+ int thread_seq = ((del_para_t*)arg)->thread_seq;
+ char writefile[50];
+ writefile[0]='\0';
+
+ // string write_path = g_comm_prog_configure.upload_log_path;
+ // if (write_path[write_path.size() - 1] != '/')
+ // write_path+='/';
+ // #ifdef LOG_DEBUG
+ // cout<<"write_path:"<<write_path<<endl;
+ // #endif
+
+ string tmp_log_path = g_comm_prog_configure.tmp_log_path;
+ if (tmp_log_path[tmp_log_path.size() - 1] != '/')
+ tmp_log_path+='/';
+#ifdef LOG_DEBUG
+ cout<<"tmp_log_path:"<<tmp_log_path<<endl;
+#endif
+
+ sprintf(writefile, "%s%s-%d.txt", tmp_log_path.c_str(), writetime, times);
+#ifdef LOG_DEBUG
+ cout<<"writefile:"<<writefile<<endl;
+#endif
+
+ FILE *fp = fopen(writefile, "a+");
+ if(fp != NULL)
+ {
+ send_data(info, fp);
+ }
+ else
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "FOPEN ERROR! ERROR NUM IS %s.", strerror(errno));
+ }
+ fclose(fp);
+ fp = NULL;
+
+ /*
+ if(log_nums == 0 && log == 1)
+ {
+ g_comm_prog_para.last_send_time = time(NULL);
+
+ char cmd[200] = {0};
+ sprintf(cmd, "cd %s; gzip -q %s-%d.txt; mv *.gz %s%s", g_comm_prog_configure.tmp_log_path, writetime, times-1, write_path.c_str(), FDIR);
+ // system(cmd);
+ FILE * ret = popen(cmd, "w");
+ if(!ret)
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "%s IS FAILED! ERROR NUM IS %s",cmd, strerror(errno));
+ else
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_INFO, "INFO", "Pack %s/%s.gz is submit.", FDIR, writetime);
+ pclose(ret);
+ }
+ */
+
+ if(MESA_htable_del(g_comm_prog_para.htable_handle[thread_seq][1], key, size, NULL) < 0)
+ {
+ perror("MESA_htable_del()");
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "MESA_htable_del error!");
+ }
+}
+
+// 写日志线程
+void * thread_time(void * pParam)
+{
+ while(1)
+ {
+
+ int last;
+ if(g_comm_prog_configure.write_interval <= 0)
+ {
+ g_comm_prog_configure.write_interval = 1;
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_INFO, "INFO", "write_interval arg is not more than 0! reset interval to 1.");
+ }
+
+ time_t sTime = (time_t)g_comm_prog_para.last_send_time;
+ struct tm stm;
+ localtime_r(&sTime, &stm);
+ last = stm.tm_hour * 10000 + stm.tm_min * 100 + stm.tm_sec;
+
+ // sprintf(FDIR, "%d-%02d-%02d", stm.tm_year+1900, stm.tm_mon+1, stm.tm_mday);
+ // char mkdir[50]={0};
+ // sprintf(mkdir, "mkdir -p %s/%s", g_comm_prog_configure.upload_log_path, FDIR);
+ // FILE * ret = popen(mkdir, "w");
+ // if(!ret)
+ // MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "%s FAILED! ERROR IS %s",mkdir, strerror(errno));
+ // pclose(ret);
+
+ char FNAME[10];
+ char TXT[8];
+ sprintf(FNAME, "%d-%d-%d", stm.tm_hour, stm.tm_min, stm.tm_sec);
+ //sprintf(TXT, "%d-%d-%d", stm.tm_hour, stm.tm_min, stm.tm_sec);
+ sprintf(TXT, "%d%02d%02d", stm.tm_year+1900, stm.tm_mon+1, stm.tm_mday);
+ //sprintf(etime, "%d-%d-%d %d:%d:%d", ptm.tm_year+1900, ptm.tm_mon+1, ptm.tm_mday, ptm.tm_hour, ptm.tm_min, ptm.tm_sec);
+
+ // times = 1;
+ log_nums = 0;
+ if(g_comm_prog_configure.write_max_num <= 0)
+ {
+ g_comm_prog_configure.write_max_num = 1000;
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_INFO, "INFO", "write_interval arg is not more than 0! reset interval to 1000.");
+ }
+
+ sleep(g_comm_prog_configure.sleep);
+
+ // pthread_mutex_lock(&g_comm_prog_para.mutex);
+ while (lock.test_and_set(std::memory_order_acquire)); // spin
+ for(int i = 0; i < g_comm_prog_para.thread_num; i++)
+ {
+ MESA_htable_handle tmp = g_comm_prog_para.htable_handle[i][0];
+ g_comm_prog_para.htable_handle[i][0] = g_comm_prog_para.htable_handle[i][1];
+ g_comm_prog_para.htable_handle[i][1] = tmp;
+ }
+ lock.clear(std::memory_order_release); // release lock
+ // pthread_mutex_unlock(&g_comm_prog_para.mutex);
+
+ for(int i = 0; i < g_comm_prog_para.thread_num; i++)
+ {
+ del_para_t arg;
+ arg.writetime = TXT;
+ arg.thread_seq = i;
+ MESA_htable_iterate(g_comm_prog_para.htable_handle[i][1], iterate_cb, (void *)&arg);
+ }
+
+ sTime = (time_t)g_comm_prog_para.last_send_time;
+ localtime_r(&sTime, &stm);
+ last = stm.tm_hour * 10000 + stm.tm_min * 100 + stm.tm_sec;
+
+ long long NowTime = time(NULL);
+ time_t eTime = (time_t)NowTime;
+ struct tm ptm;
+ localtime_r(&eTime, &ptm);
+ now = ptm.tm_hour * 10000 + ptm.tm_min * 100 + ptm.tm_sec;
+
+
+ if(log == 1)
+ {
+ if(now - last >= g_comm_prog_configure.write_interval * 100)
+ {
+ /*
+ char cmd[200] = {0};
+ string log_path = g_comm_prog_configure.upload_log_path;
+ if (log_path[log_path.size() - 1] != '/')
+ log_path+='/';
+#ifdef LOG_DEBUG
+cout<<"log_path:"<<log_path<<endl;
+#endif
+
+sprintf(cmd, "cd %s; count=`ls|grep .txt|wc -l`; if [[ $count -gt 0 ]]; then tar -zcf %s%s/%s.tar.gz *.txt; rm -f *.txt; fi;", \
+g_comm_prog_configure.tmp_log_path, log_path.c_str(), FDIR, FNAME);
+#ifdef LOG_DEBUG
+cout<<cmd<<endl;
+#endif
+
+FILE * ret = popen(cmd, "w");
+if(!ret)
+MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "MKDIR IS FAILED! ERROR IS %s",strerror(errno));
+else
+MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_INFO, "INFO", "Pack %s/%s.tar.gz is submit.", FDIR, FNAME);
+pclose(ret);
+*/
+ times++;
+ g_comm_prog_para.last_send_time = time(NULL);
+ }
+ else if(now < last)
+ {
+ times = 1;
+ g_comm_prog_para.last_send_time = time(NULL);
+ }
+ }
+ }
+ return NULL;
+
+}
+
+
+static long search_cb(void* data, const uchar* key, uint size, void* arg)
+{
+ if(data == NULL)
+ return -1;
+
+ struct streaminfo * a_stream = (struct streaminfo *)((htable_search_arg *)arg)->stream;
+ void * a_packet = (void *)((htable_search_arg *)arg)->packet;
+ int is_end = ((htable_search_arg *)arg)->is_end;
+ htable_data_t * info = (htable_data_t *)data;
+
+ if(a_stream->type == STREAM_TYPE_TCP)
+ {
+ struct tcpdetail* a_tcp = (struct tcpdetail*)(a_stream->ptcpdetail);
+ if(a_stream->curdir == DIR_C2S)//C2S:INNER TO EXTERN
+ {
+ info->out_bytes += a_tcp->datalen;
+ info->out_pkts++;
+ }
+ else
+ {
+ info->in_bytes += a_tcp->datalen;
+ info->in_pkts++;
+ }
+ // struct tcpdetail* a_tcp = (struct tcpdetail*)(a_stream->ptcpdetail);
+ // info->tcp_flag = info->tcp_flag & a_stream->stream_state;
+ if(a_packet != NULL)
+ {
+ struct tcphdr* tcp_header = (struct tcphdr*)(a_packet + sizeof(struct iphdr));
+ info->tcp_flag = 32*tcp_header->urg + 16*tcp_header->ack + 8*tcp_header->psh + 4*tcp_header->rst + \
+ 2*tcp_header->syn + tcp_header->fin;
+ }
+ }
+ else
+ {
+ struct udpdetail* a_udp = (struct udpdetail*)(a_stream->pudpdetail);
+ if(a_stream->curdir == DIR_C2S)//C2S:INNER TO EXTERN
+ {
+ info->out_bytes += a_udp->datalen;
+ info->out_pkts++;
+ }
+ else
+ {
+ info->in_bytes += a_udp->datalen;
+ info->in_pkts++;
+ }
+ info->tcp_flag = 0;
+ }
+ if(is_end)
+ info->end_time = time(NULL);
+
+ return 0;
+}
+
+
+
+int judge_ip_location(unsigned int inner_ip, char ** inner_name_en, unsigned int ext_ip, char ** ext_name_en)
+{
+ char innerIP[IPLEN] = {0};
+ char extIP[IPLEN] = {0};
+ int res1 = 0;
+ int res2 = 0;
+ //char * inner_name_en = NULL;
+ //char * ext_name_en = NULL;
+ inet_ntop(AF_INET, &inner_ip, innerIP ,IPLEN);
+ inet_ntop(AF_INET, &ext_ip, extIP ,IPLEN);
+ res1 = get_ip_coun(g_comm_prog_configure.mmdb_path, innerIP, inner_name_en);
+ res2 = get_ip_coun(g_comm_prog_configure.mmdb_path, extIP, ext_name_en);
+ if(0 != res1 && 0 != res2)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_INFO, "JUDGE_IP", "judge_innerip_location INNER[%s] EXT[%s] error!", innerIP, extIP);
+ return 0;
+ }
+ if ((NULL!=*inner_name_en && 0!=strncmp(*inner_name_en, "China", 5)) || (NULL!=*ext_name_en && 0 != strncmp(*ext_name_en, "China", 5))) //有境外IP
+ {
+ return 1;
+ }
+ else //全部都是境内IP
+ {
+ return 2;
+ }
+}
+
+
+void time_mode_op(struct streaminfo* a_stream, int thread_seq, void * a_packet, int state, int is_end)
+{
+ stDntyProInfo * pro_info = (stDntyProInfo *)project_req_get_struct(a_stream,g_comm_prog_para.project_id_pro);
+ if(pro_info == NULL)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "project_req_get_struct is NULL. LACK OF IDENTIFY'S CONF!");
+ return ;
+ }
+
+ long ret;
+ int judge_res = 0;
+
+ htable_search_arg arg;
+ arg.stream = a_stream;
+ arg.packet = a_packet;
+
+ // pthread_mutex_lock(&g_comm_prog_para.mutex);
+ if(NULL == MESA_htable_search_cb(g_comm_prog_para.htable_handle[thread_seq][0], (unsigned char*)&a_stream->addr, sizeof(a_stream->addr), search_cb, (void *)&arg, &ret))
+ {
+ htable_data_t * value = (htable_data_t*)calloc(1, sizeof(htable_data_t));
+ if(a_stream->addr.addrtype == ADDR_TYPE_IPV4)
+ {
+ value->inner_ip = a_stream->addr.tuple4_v4->saddr;
+ value->inner_port = a_stream->addr.tuple4_v4->source;
+ value->ext_ip = a_stream->addr.tuple4_v4->daddr;
+ value->ext_port = a_stream->addr.tuple4_v4->dest;
+ if(g_comm_prog_configure.flag == 0) //flag == 0, 只记录包含境外IP的通联数据
+ {
+ char * inner_name_en = NULL;
+ char * ext_name_en = NULL;
+ judge_res = judge_ip_location(value->inner_ip, &inner_name_en, value->ext_ip, &ext_name_en);
+ if(judge_res == 0) //查找IP归属失败,仍然记录
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "find IP[%u or %u] location error!.", value->inner_ip, value->ext_ip);
+ }
+ else if(judge_res == 1) //有境外IP,需要记录
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "find IP1[%u:%s] IP2[%u:%s].", value->inner_ip,inner_name_en, value->ext_ip, ext_name_en);
+ }
+ else if(judge_res == 2) //全都是境内IP,不做记录,直接返回
+ {
+ return ;
+ }
+ }
+ }
+ if(a_stream->type == STREAM_TYPE_TCP)
+ {
+ struct tcpdetail* a_tcp = (struct tcpdetail*)(a_stream->ptcpdetail);
+ if(a_stream->routedir == DIR_C2S)//C2S:INNER TO EXTERN
+ {
+ value->in_bytes = 0;
+ value->in_pkts = 0;
+ value->out_bytes = a_tcp->datalen;
+ value->out_pkts = 1;
+ }
+ else
+ {
+ value->in_bytes = a_tcp->datalen;
+ value->in_pkts = 1;
+ value->out_bytes = 0;
+ value->out_pkts = 0;
+ }
+ if(a_packet != NULL)
+ {
+ struct tcphdr* tcp_header = (struct tcphdr*)(a_packet + sizeof(struct iphdr));
+ value->tcp_flag = 32*tcp_header->urg + 16*tcp_header->ack + 8*tcp_header->psh + 4*tcp_header->rst + 2*tcp_header->syn + tcp_header->fin;
+ }
+ }
+ else
+ {
+ struct udpdetail* a_udp = (struct udpdetail*)(a_stream->pudpdetail);
+ if(a_stream->routedir == DIR_C2S)//C2S:INNER TO EXTERN
+ {
+ value->in_bytes = 0;
+ value->in_pkts = 0;
+ value->out_bytes = a_udp->datalen;
+ value->out_pkts = 1;
+ }
+ else
+ {
+ value->in_bytes = a_udp->datalen;
+ value->in_pkts = 1;
+ value->out_bytes = 0;
+ value->out_pkts = 0;
+ }
+ value->tcp_flag = 0;
+ }
+
+ value->protocol = a_stream->type;
+ value->app = pro_info->protocol_type;
+
+ struct streaminfo *father = a_stream->pfather;
+ while(father)
+ {
+ if(father->addr.addrtype != ADDR_TYPE_MAC)
+ {
+ father = father->pfather;
+ continue;
+ }
+ else
+ {
+ memset(value->inner_mac, 0, 60);
+ sprintf(value->inner_mac, "%02x-%02x-%02x-%02x-%02x-%02x", father->addr.mac->src_mac[0], father->addr.mac->src_mac[1],\
+ father->addr.mac->src_mac[2], father->addr.mac->src_mac[3], father->addr.mac->src_mac[4], father->addr.mac->src_mac[5]);
+ memset(value->ext_mac, 0, 60);
+ sprintf(value->ext_mac, "%02x-%02x-%02x-%02x-%02x-%02x", father->addr.mac->dst_mac[0], father->addr.mac->dst_mac[1],\
+ father->addr.mac->dst_mac[2], father->addr.mac->dst_mac[3], father->addr.mac->dst_mac[4], father->addr.mac->dst_mac[5]);
+ break;
+ }
+ }
+
+ value->start_time = time(NULL);
+ value->end_time = 0;
+
+ if(MESA_htable_add(g_comm_prog_para.htable_handle[thread_seq][0], (const unsigned char *)&a_stream->addr, \
+ sizeof(a_stream->addr), (void *)value) < 0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "htable_add error.ERROR IS %s.", strerror(errno));
+ free(value);
+ value = NULL;
+ }
+ }
+ // pthread_mutex_unlock(&g_comm_prog_para.mutex);
+ // free(arg);
+ // arg = NULL;
+}
+
+
+char op_state_data(struct streaminfo *a_stream, void **pme, int thread_seq, void *a_packet, int state, int is_end)
+{
+ // struct tcpdetail *pdetail = (struct tcpdetail*)a_stream->ptcpdetail;
+ // comm_audit_t* stat_info = (comm_audit_t*)(*pme);
+ // assert(stat_info != NULL);
+
+ if(a_packet == NULL && state != OP_STATE_CLOSE)
+ return APP_STATE_GIVEME;
+
+ time_mode_op(a_stream, thread_seq, a_packet, state, is_end);
+
+ return APP_STATE_GIVEME;
+}
+
+// char op_state_pending(struct streaminfo *a_stream, void **pme, int thread_seq,void *a_packet, int state, int is_end)
+// {
+// // init_pme_info(pme);
+
+// op_state_data(a_stream, pme, thread_seq, a_packet, state, is_end);
+
+// return APP_STATE_GIVEME;
+// }
+
+
+char op_state_close(struct streaminfo *a_stream, void **pme, int thread_seq,void *a_packet, int state, int is_end)
+{
+ op_state_data(a_stream, pme, thread_seq, a_packet, state, is_end);
+
+ // free_pme_info(pme);
+
+ return APP_STATE_DROPME;
+}
+
+
+char COMM_AUDIT_ENTRY(struct streaminfo *a_stream, void **pme, int thread_seq, void *a_packet)
+{
+ if(g_comm_prog_configure.flag == 2) //flag == 2,不记录任何通联数据,直接返回
+ {
+ return APP_STATE_DROPME;
+ }
+ char ret = APP_STATE_GIVEME;
+ int state;
+ if(a_stream->type == STREAM_TYPE_TCP)
+ state = a_stream->pktstate;
+ else
+ state = a_stream->opstate;
+ int is_end = 0;
+ switch(state)
+ {
+ case OP_STATE_PENDING:
+ case OP_STATE_DATA:
+ ret = op_state_data(a_stream, pme, thread_seq, a_packet, state, is_end);
+ break;
+
+ case OP_STATE_CLOSE:
+ is_end=1;
+ ret = op_state_close(a_stream, pme, thread_seq, a_packet, state, is_end);
+ break;
+
+ default:
+ ret = APP_STATE_DROPME;
+ break;
+ }
+
+ return ret;
+}
+
+void htable_del1(const uchar * key, uint size, void * data, void * arg)
+{
+ int thread_seq = *(int*)arg;
+ if(MESA_htable_del(g_comm_prog_para.htable_handle[thread_seq][0], key, size, NULL) < 0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "MESA_htable_del error!");
+ }
+}
+
+void htable_del2(const uchar * key, uint size, void * data, void * arg)
+{
+ int thread_seq = *(int*)arg;
+ if(MESA_htable_del(g_comm_prog_para.htable_handle[thread_seq][1], key, size, NULL) < 0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "MESA_htable_del error!");
+ }
+}
+
+void COMM_AUDIT_DESTROY()
+{
+
+ // free(g_comm_prog_configure.upload_log_path);
+ free(g_comm_prog_configure.tmp_log_path);
+ free(g_comm_prog_configure.upload_pz_path);
+
+ for(int i = 0; i < g_comm_prog_para.thread_num; i++)
+ {
+ if(MESA_htable_iterate(g_comm_prog_para.htable_handle[i][0], htable_del1, (void*)&i) < 0)
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "COMM_AUDIT_DESTROY. MESA_htable_iterate error!");
+ // printf("iterate error!\n");
+ if(MESA_htable_destroy(g_comm_prog_para.htable_handle[i][0], NULL) < 0)
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "COMM_AUDIT_DESTROY. MESA_htable_destroy error!");
+ // printf("destroy error!\n");
+
+ if(MESA_htable_iterate(g_comm_prog_para.htable_handle[i][1], htable_del2, (void*)&i) < 0)
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "COMM_AUDIT_DESTROY. MESA_htable_iterate error!");
+ // printf("iterate error!\n");
+ if(MESA_htable_destroy(g_comm_prog_para.htable_handle[i][1], NULL) < 0)
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "COMM_AUDIT_DESTROY. MESA_htable_destroy error!");
+ // printf("destroy error!\n");
+ }
+ for(int i = 0; i < g_comm_prog_para.thread_num; i++)
+ free(g_comm_prog_para.htable_handle[i]);
+ free(g_comm_prog_para.htable_handle);
+
+ pthread_exit(NULL);
+ //printf("destroy COMM_AUDIT_DESTROY success!\n");
+
+}
+
+void htable_free(void * data)
+{
+ htable_data_t * info = (htable_data_t *)data;
+ free(info);
+ data = NULL;
+}
+
+int init_hash_table()
+{
+ MESA_htable_handle ** handle = (MESA_htable_handle**)malloc(g_comm_prog_para.thread_num*sizeof(MESA_htable_handle*));
+ for(int i = 0; i < g_comm_prog_para.thread_num; i++)
+ handle[i] = (MESA_htable_handle*)malloc(2 * sizeof(MESA_htable_handle));
+ for(int i = 0; i < g_comm_prog_para.thread_num; i++)
+ {
+ MESA_htable_create_args_t htable_args1;
+ memset(&htable_args1, 0, sizeof(htable_args1));
+ htable_args1.recursive = 1;
+ htable_args1.thread_safe = 0;
+ htable_args1.hash_slot_size = 4096*4096;
+ htable_args1.max_elem_num = g_comm_prog_configure.htable_size;
+ htable_args1.data_free = htable_free;
+ htable_args1.data_expire_with_condition = NULL;
+ htable_args1.eliminate_type = HASH_ELIMINATE_ALGO_LRU;
+ htable_args1.expire_time = 0;
+ handle[i][0] = MESA_htable_create(&htable_args1, sizeof(htable_args1));
+ if(handle[i][0] == NULL)
+ return -1;
+
+ MESA_htable_create_args_t htable_args2;
+ memset(&htable_args2, 0, sizeof(htable_args2));
+ htable_args2.recursive = 1;
+ htable_args2.thread_safe = 0;
+ htable_args2.hash_slot_size = 4096*4096;
+ htable_args2.max_elem_num = g_comm_prog_configure.htable_size;
+ htable_args2.data_free = htable_free;
+ htable_args2.data_expire_with_condition = NULL;
+ htable_args2.eliminate_type = HASH_ELIMINATE_ALGO_LRU;
+ htable_args2.expire_time = 0;
+ handle[i][1] = MESA_htable_create(&htable_args2, sizeof(htable_args2));
+ if(handle[i][1] == NULL)
+ return -1;
+ }
+
+ g_comm_prog_para.htable_handle = handle;
+ return 0;
+}
+
+int comm_read_conf(const char *file_name)
+{
+ short log_level = 30;
+ char log_filename[256];
+ log_filename[0]='\0';
+ int ret;
+
+ if(MESA_load_profile_short_nodef(file_name, "DEFAULT", "log_level", (short*)&log_level)<0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "comm_read_conf", "conf [DEFAULT] log_level error!");
+ return -1;
+ }
+ if(MESA_load_profile_string_nodef(file_name, "DEFAULT", "log_path", log_filename, sizeof(log_filename))<0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "comm_read_conf", "conf [DEFAULT] log_path error!");
+ return -1;
+ }
+ g_comm_prog_para.log_handle = MESA_create_runtime_log_handle(log_filename, log_level);
+ if(g_comm_prog_para.log_handle == NULL)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "comm_read_conf", "Create log_handle error!");
+ return -1;
+ }
+
+ if((ret=MESA_load_profile_int_nodef(file_name, "DEFAULT", "htable_size", (int*)&g_comm_prog_configure.htable_size))<0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "comm_read_conf", "conf [DEFAULT] htable_size error!");
+ return -1;
+ }
+ if((ret=MESA_load_profile_int_nodef(file_name, "DEFAULT", "sleep", (int*)&g_comm_prog_configure.sleep))<0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "comm_read_conf", "conf [DEFAULT] sleep error!");
+ return -1;
+ }
+ if(g_comm_prog_configure.sleep <= 0)
+ {
+ g_comm_prog_configure.sleep = 10;
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_INFO, "comm_read_conf",\
+ "conf [DEFAULT] sleep is not more than 0! Reset interval to 10.");
+ }
+
+
+ // g_comm_prog_configure.upload_log_path = (char *)calloc(1, 256*sizeof(char));
+ // if((ret=MESA_load_profile_string_nodef(file_name, "UPLOAD_LOG", "upload_log_path", g_comm_prog_configure.upload_log_path, 256*sizeof(char)))<0)
+ // {
+ // MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "comm_read_conf", "conf [UPLOAD_LOG] upload_log_path error!");
+ // return -1;
+ // }
+ // char upload_log_path[50]={0};
+ // sprintf(upload_log_path, "mkdir -p %s", g_comm_prog_configure.upload_log_path);
+ // FILE * pret = popen(upload_log_path, "w");
+ // if(!pret)
+ // MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "%s IS FAILED! ERROR IS %s",upload_log_path, strerror(errno));
+ // pclose(pret);
+
+ g_comm_prog_configure.tmp_log_path = (char *)calloc(1, 256*sizeof(char));
+ if((ret=MESA_load_profile_string_nodef(file_name, "UPLOAD_LOG", "tmp_log_path", g_comm_prog_configure.tmp_log_path, 256*sizeof(char)))<0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "comm_read_conf", "conf [UPLOAD_LOG] tmp_log_path error!");
+ return -1;
+ }
+ char tmp_log_path[50]={0};
+ sprintf(tmp_log_path, "mkdir -p %s", g_comm_prog_configure.tmp_log_path);
+ FILE * pret = popen(tmp_log_path, "w");
+ if(!pret)
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "%s IS FAILED! ERROR IS %s",tmp_log_path, strerror(errno));
+ pclose(pret);
+
+
+ g_comm_prog_configure.upload_pz_path = (char *)calloc(1, 256*sizeof(char));
+ if((ret=MESA_load_profile_string_nodef(file_name, "UPLOAD_PZ", "upload_pz_path", g_comm_prog_configure.upload_pz_path,256*sizeof(char)))<0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "comm_read_conf", "conf [UPLOAD_PZ] upload_pz_path error!");
+ return -1;
+ }
+
+ if((ret=MESA_load_profile_int_nodef(file_name,"UPLOAD_PZ","read_upload_pz_interval",&g_comm_prog_configure.read_interval))<0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "comm_read_conf", "conf [UPLOAD_PZ] read_upload_pz_interval error!");
+ return -1;
+ }
+
+ if((ret=MESA_load_profile_int_nodef(file_name,"UPLOAD_PZ","default_upload_interval",&g_comm_prog_configure.write_interval))<0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "comm_read_conf", "conf [UPLOAD_PZ] default_upload_interval error!");
+ return -1;
+ }
+
+ if((ret=MESA_load_profile_int_nodef(file_name,"UPLOAD_PZ","defailt_upload_max_num",&g_comm_prog_configure.write_max_num))<0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "comm_read_conf", "conf [UPLOAD_PZ] defailt_upload_max_num error!");
+ return -1;
+ }
+
+ if((ret=MESA_load_profile_int_nodef(file_name,"IPDB_PZ","flag",&g_comm_prog_configure.flag))<0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "comm_read_conf", "conf [IPDB_PZ] flag error!");
+ return -1;
+ }
+
+ g_comm_prog_configure.mmdb_path = (char *)calloc(1, 256*sizeof(char));
+ if((ret=MESA_load_profile_string_nodef(file_name, "IPDB_PZ", "mmdb_path", g_comm_prog_configure.mmdb_path, 256*sizeof(char)))<0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "comm_read_conf", "conf [IPDB_PZ] mmdb_path error!");
+ return -1;
+ }
+ return 0;
+}
+
+int COMM_AUDIT_INIT()
+{
+ int ret;
+ if(-1 == comm_read_conf("./djconf/comm_audit.conf"))
+ return -1;
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_INFO, "COMM_AUDIT_INIT", "COMM_AUDIT_INIT conf read over!");
+
+ g_comm_prog_para.project_id_pro = project_customer_register(DNTY_PPROJECT_PRO, DNTY_PPROJECT_TYPE);
+ if(g_comm_prog_para.project_id_pro < 0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "COMM_AUDIT_INIT. project_req_register error. LACK OF IDENTIFY'S CONF!");
+ return -1;
+ }
+
+
+ int thread_num = get_thread_count();
+ g_comm_prog_para.thread_num = thread_num;
+#ifdef LOG_DEBUG
+ printf("thread_num:%d\n", g_comm_prog_para.thread_num);
+#endif
+ ret = init_hash_table();
+ if(ret < 0)
+ {
+ MESA_handle_runtime_log(g_comm_prog_para.log_handle, RLOG_LV_FATAL, "FATAL", "COMM_AUDIT_INIT. init_hash_table error!");
+ //printf("init_hash_table() error!\n");
+ return -1;
+ }
+
+ g_comm_prog_para.last_send_time = time(NULL);
+ // pthread_mutex_init(&g_comm_prog_para.mutex, NULL);
+
+
+ //创建写文件线程
+ pthread_t hd_write;
+ pthread_create(&hd_write, NULL, thread_time, NULL);
+
+ //创建读json配置线程
+ pthread_t hd_read;
+ pthread_create(&hd_read, NULL, set_timer, NULL);
+
+ // printf("init COMM_AUDIT_INIT success!\n");
+
+ return 0;
+}
+