配置的组织关系放在Redis中。
This commit is contained in:
131
inc/Maat_command.h
Normal file
131
inc/Maat_command.h
Normal file
@@ -0,0 +1,131 @@
|
||||
#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 "Maat_rule.h"
|
||||
enum MAAT_OPERATION
|
||||
{
|
||||
MAAT_OP_DEL=0,
|
||||
MAAT_OP_ADD
|
||||
};
|
||||
enum MAAT_REGION_TYPE
|
||||
{
|
||||
REGION_EXPR,
|
||||
REGION_IP,
|
||||
REGION_INTERVAL,
|
||||
REGION_DIGEST,
|
||||
REGION_SIMILARITY
|
||||
};
|
||||
enum MAAT_EXPR_TYPE
|
||||
{
|
||||
EXPR_TYPE_STRING=0,
|
||||
EXPR_TYPE_AND,
|
||||
EXPR_TYPE_REGEX,
|
||||
EXPR_TYPE_OFFSET
|
||||
};
|
||||
enum MAAT_MATCH_METHOD
|
||||
{
|
||||
MATCH_METHOD_SUB=0,
|
||||
MATCH_METHOD_RIGHT,
|
||||
MATCH_METHOD_LEFT,
|
||||
MATCH_METHOD_COMPLETE
|
||||
};
|
||||
|
||||
enum MAAT_CASE_TYPE
|
||||
{
|
||||
UNCASE_PLAIN=0,
|
||||
CASE_HEXBIN,
|
||||
CASE_PLAIN
|
||||
};
|
||||
enum MAAT_ADDR_TYPE
|
||||
{
|
||||
ADDR_TYPE_IPv4=4,
|
||||
ADDR_TYPE_IPv6=6
|
||||
};
|
||||
enum MAAT_ADDR_DIRECTION
|
||||
{
|
||||
ADDR_DIR_DOUBLE=0,
|
||||
ADDR_DIR_SINGLE=1
|
||||
};
|
||||
struct Maat_rgn_str_t
|
||||
{
|
||||
const char *keywords;
|
||||
const char *district;
|
||||
enum MAAT_EXPR_TYPE expr_type;
|
||||
enum MAAT_MATCH_METHOD match_method;
|
||||
enum MAAT_CASE_TYPE case_type;
|
||||
};
|
||||
struct Maat_rgn_addr_t
|
||||
{
|
||||
enum MAAT_ADDR_TYPE addr_type;
|
||||
char* src_ip;
|
||||
char* mask_src_ip;
|
||||
char* dst_ip;
|
||||
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;
|
||||
char* digest_string;
|
||||
short confidence_degree;
|
||||
};
|
||||
struct Maat_rgn_sim_t
|
||||
{
|
||||
char* target_string;
|
||||
short confidence_degree;
|
||||
};
|
||||
struct Maat_region_t
|
||||
{
|
||||
char* table_name;
|
||||
int region_id; //Any, maat will assigned one.
|
||||
enum MAAT_REGION_TYPE region_type;
|
||||
union
|
||||
{
|
||||
struct Maat_rgn_str_t expr_rule;
|
||||
struct Maat_rgn_addr_t addr_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; //Any, maat will assigned one.
|
||||
char* table_name;//optional, if not specified, maat will assigned to the first GROUP table in table_info.conf.
|
||||
char* group_name;//optional, for group reuse.
|
||||
struct Maat_region_t *regions;
|
||||
};
|
||||
struct Maat_command_t
|
||||
{
|
||||
struct Maat_rule_t compile;// for MAAT_OP_DEL, only compile.config_id is necessary.
|
||||
char* table_name; //optional, if not specified, maat will assigned to the first COMPILE table in table_info.conf.
|
||||
int group_num; // for MAAT_OP_DEL, Any.
|
||||
struct Maat_group_t* groups;// for MAAT_OP_DEL, SET to NULL.
|
||||
};
|
||||
struct Maat_command_t* Maat_create_comand(const struct Maat_rule_t* rule, const char*table_name, int group_num);
|
||||
int Maat_set_command(struct Maat_command_t* cmd,int which_group,const struct Maat_region_t* region);
|
||||
|
||||
void Maat_free_command(struct Maat_command_t* cmd);
|
||||
int Maat_format_command(struct Maat_command_t* cmd, char* buffer, int size);
|
||||
|
||||
// The command functions are NOT thread safe.
|
||||
int Maat_command(Maat_feather_t feather,struct Maat_command_t* cmd,enum MAAT_OPERATION op);
|
||||
|
||||
//pipeline model
|
||||
int Maat_append_command(Maat_feather_t feather,struct Maat_command_t* cmd,enum MAAT_OPERATION op);
|
||||
int Maat_commit_command(Maat_feather_t feather);
|
||||
#endif
|
||||
|
||||
@@ -140,13 +140,15 @@ enum MAAT_INIT_OPT
|
||||
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 indifferent,SIZE is indifferent.MAAT_OPT_STAT_FILE_PATH must be set.Default: stat OFF.
|
||||
MAAT_OPT_PERF_ON, //VALUE is indifferent,SIZE is indifferent.MAAT_OPT_STAT_FILE_PATH must be set.Default: stat OFF.
|
||||
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;
|
||||
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_DECRYPT_KEY, //VALUE is a const char*,MUST end with '\0',SIZE= strlen(string+'\0')+1. No DEFAULT.
|
||||
MAAT_OPT_REDIS_IP, //VALUE is a const char*,MUST end with '\0',SIZE= strlen(string+'\0')+1. No DEFAULT.
|
||||
MAAT_OPT_REDIS_PORT //VALUE is a unsigned short, host order, SIZE= sizeof(unsigned short). No DEFAULT.
|
||||
};
|
||||
//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);
|
||||
|
||||
@@ -441,6 +441,11 @@ Maat_feather_t Maat_feather(int max_thread_num,const char* table_info_path,void*
|
||||
if(feather->p_table_info[i]->table_type==TABLE_TYPE_GROUP)
|
||||
{
|
||||
feather->GROUP_MODE_ON=1;
|
||||
memcpy(feather->group_tn,feather->p_table_info[i].table_name[0],sizeof(feather->group_tn));
|
||||
}
|
||||
if(feather->p_table_info[i]->table_type==TABLE_TYPE_COMPILE)
|
||||
{
|
||||
memcpy(feather->compile_tn,feather->p_table_info[i].table_name[0],sizeof(feather->compile_tn));
|
||||
}
|
||||
for(j=0;j<feather->p_table_info[i]->conj_cnt;j++)
|
||||
{
|
||||
@@ -471,6 +476,7 @@ Maat_feather_t Maat_feather(int max_thread_num,const char* table_info_path,void*
|
||||
feather->maat_version=0;
|
||||
feather->last_full_version=0;
|
||||
pthread_mutex_init(&(feather->plugin_table_reg_mutex),NULL);
|
||||
pthread_mutex_init(&(feather->redis_write_lock),NULL);
|
||||
snprintf(feather->table_info_fn,sizeof(feather->table_info_fn),"%s",table_info_path);
|
||||
return feather;
|
||||
}
|
||||
@@ -555,9 +561,26 @@ int Maat_set_feather_opt(Maat_feather_t feather,enum MAAT_INIT_OPT type,const vo
|
||||
(const char*)value);
|
||||
break;
|
||||
case MAAT_OPT_DECRYPT_KEY:
|
||||
_feather->decrypt_key=(unsigned char*)malloc(size*sizeof(unsigned char));
|
||||
if(size>sizeof(_feather->decrypt_key))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
memcpy(_feather->decrypt_key,value,size);
|
||||
break;
|
||||
case MAAT_OPT_REDIS_IP:
|
||||
if(size>sizeof(_feather->redis_ip))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
memcpy(_feather->redis_ip,value,size);
|
||||
break;
|
||||
case MAAT_OPT_REDIS_PORT:
|
||||
if(size!=sizeof(unsigned short))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
_feather->redis_port=*((unsigned short*)value);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@@ -566,6 +589,32 @@ int Maat_set_feather_opt(Maat_feather_t feather,enum MAAT_INIT_OPT type,const vo
|
||||
int Maat_initiate_feather(Maat_feather_t feather)
|
||||
{
|
||||
_Maat_feather_t* _feather=(_Maat_feather_t*)feather;
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec=0;
|
||||
timeout.tv_usec=100*1000; // 100 ms
|
||||
if(strlen(_feather->redis_ip)>0&&_feather->redis_port!=0)
|
||||
{
|
||||
_feather->REDIS_MODE_ON=1;
|
||||
_feather->redis_read_ctx=redisConnectWithTimeout(_feather->redis_ip,_feather->redis_port,timeout);
|
||||
if(_feather->redis_read_ctx==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module
|
||||
,"Redis connect %s:%d failed."
|
||||
,_feather->redis_ip,_feather->redis_port);
|
||||
return -1;
|
||||
}
|
||||
redisEnableKeepAlive(_feather->redis_read_ctx);
|
||||
redis_monitor_traverse(_feather->maat_version
|
||||
,_feather->redis_read_ctx
|
||||
,maat_start_cb
|
||||
,maat_update_cb
|
||||
,maat_finish_cb
|
||||
, _feather
|
||||
,_feather->decrypt_key //Not used.
|
||||
,_feather->logger);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(strlen(_feather->full_dir)==0)
|
||||
{
|
||||
MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module ,
|
||||
@@ -581,6 +630,7 @@ int Maat_initiate_feather(Maat_feather_t feather)
|
||||
_feather,
|
||||
_feather->decrypt_key,
|
||||
_feather->logger);
|
||||
}
|
||||
if(_feather->update_tmp_scanner==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module ,
|
||||
@@ -922,7 +972,7 @@ int Maat_scan_intval(Maat_feather_t feather,int table_id
|
||||
{
|
||||
clock_gettime(CLOCK_MONOTONIC,&start);
|
||||
}
|
||||
p_table=acqurie_table(_feather,table_id,TABLE_TYPE_INTVAL);
|
||||
p_table=acqurie_table(_feather,table_id,TABLE_TYPE_INTERVAL);
|
||||
if(p_table==NULL)
|
||||
{
|
||||
_feather->scan_err_cnt++;
|
||||
@@ -1647,4 +1697,3 @@ void Maat_clean_status(scan_status_t* mid)
|
||||
*mid=NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
844
src/entry/Maat_command.cpp
Normal file
844
src/entry/Maat_command.cpp
Normal file
@@ -0,0 +1,844 @@
|
||||
#include "Maat_command.h"
|
||||
#include "config_monitor.h"
|
||||
#include "hiredis.h"
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <assert.h>
|
||||
|
||||
const char* maat_redis_monitor="MAAT_REDIS_MONITOR";
|
||||
const char* maat_redis_command="MAAT_REDIS_COMMAND";
|
||||
|
||||
const char* rm_key_prefix[2]={"OBSOLETE_RULE","EFFECTIVE_RULE"};
|
||||
const char* redis_OK_reply="+OK\r\n";
|
||||
const char* PREFIX_COMPILE_INDEX="INDEX_COMPILE";
|
||||
const char* PREFIX_GROUP_INDEX="INDEX_GROUP";
|
||||
const char* PREFIX_REGION_INDEX="INDEX_REGION";
|
||||
|
||||
|
||||
struct serial_rule_t //rm= Redis Maat
|
||||
{
|
||||
int op;//0: delete, 1: add.
|
||||
int rule_id;
|
||||
enum MAAT_TABLE_TYPE table_type;
|
||||
char* table_name[256];
|
||||
char* table_line;
|
||||
};
|
||||
|
||||
struct _Maat_cmd_t
|
||||
{
|
||||
struct Maat_command_t cmd;
|
||||
enum MAAT_OPERATION op;
|
||||
int ref_cnt;
|
||||
int group_ref_cnt[MAAT_MAX_EXPR_ITEM_NUM];
|
||||
int group_rgn_cnt[MAAT_MAX_EXPR_ITEM_NUM];
|
||||
struct _Maat_cmd_t* next;
|
||||
};
|
||||
enum MAAT_TABLE_TYPE region_table_type(const struct Maat_region_t* p)
|
||||
{
|
||||
enum MAAT_TABLE_TYPE ret=0;
|
||||
switch(p->region_type)
|
||||
{
|
||||
case REGION_IP:
|
||||
ret=TABLE_TYPE_IP;
|
||||
break;
|
||||
case REGION_EXPR:
|
||||
if(p->expr_rule.district==NULL)
|
||||
{
|
||||
ret=TABLE_TYPE_EXPR;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret=TABLE_TYPE_EXPR_PLUS;
|
||||
}
|
||||
break;
|
||||
case REGION_INTERVAL:
|
||||
ret=TABLE_TYPE_INTERVAL;
|
||||
break;
|
||||
case REGION_DIGEST:
|
||||
ret=TABLE_TYPE_DIGEST;
|
||||
break;
|
||||
case REGION_SIMILARITY:
|
||||
ret=TABLE_TYPE_SIMILARITY;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void free_serial_rules(void* p)
|
||||
{
|
||||
struct serial_rule_t* rule=(struct serial_rule_t*)p;
|
||||
if(rule->table_line!=NULL)
|
||||
{
|
||||
free(rule->table_line);
|
||||
rule->table_line=NULL;
|
||||
}
|
||||
free(rule);
|
||||
return;
|
||||
}
|
||||
void set_serial_rule(struct serial_rule_t* rule,enum MAAT_OPERATION op,enum MAAT_TABLE_TYPE table_type,int id,const char* table_name,const char* line)
|
||||
{
|
||||
rule->op=op;
|
||||
rule->rule_id=id;
|
||||
rule->table_type=table_type;
|
||||
assert(srtlen(table_name)<sizeof(rule->table_name));
|
||||
memcpy(rule->table_name,table_name,strlen(table_name));
|
||||
if(line!=NULL)
|
||||
{
|
||||
rule->table_line=_maat_strdup(line);
|
||||
}
|
||||
return;
|
||||
}
|
||||
int get_rm_key_list(unsigned int version,redisContext *c,struct serial_rule_t** list,void* logger, unsigned int* new_version,int *update_type)
|
||||
{
|
||||
redisReply* ctrl_reply=NULL,*data_reply=NULL;
|
||||
char err_buff[256];
|
||||
char op_str[4],table_name[256];
|
||||
int rule_id;
|
||||
long long version_in_redis=0;
|
||||
int i=0,ret=0,retry=0;
|
||||
struct serial_rule_t *p_rm_rule=NULL;
|
||||
|
||||
if(version==0)
|
||||
{
|
||||
goto FULL_UPDATE;
|
||||
}
|
||||
while(retry<1)
|
||||
{
|
||||
ctrl_reply=(redisReply*)redisCommand(c, "GET MAAT_VERSION");
|
||||
if(ctrl_reply!=NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(c->err==REDIS_ERR_EOF)
|
||||
{
|
||||
__redis_strerror_r(errno,err_buff,sizeof(err_buff));
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_redis_monitor,
|
||||
"GET MAAT_VERSION failed %s. Reconnecting...",err_buff);
|
||||
ret=redisReconnect(c);
|
||||
retry++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
__redis_strerror_r(errno,err_buff,sizeof(err_buff));
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_redis_monitor,
|
||||
"GET MAAT_VERSION failed %s.",err_buff);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
assert(ctrl_reply->type==REDIS_REPLY_INTEGER);
|
||||
assert(ctrl_reply->integer>=version);
|
||||
if(ctrl_reply->integer==version)
|
||||
{
|
||||
freeReplyObject(ctrl_reply);
|
||||
return 0;
|
||||
}
|
||||
version_in_redis=ctrl_reply->integer;
|
||||
*new_version=version_in_redis;
|
||||
freeReplyObject(ctrl_reply);
|
||||
//Returns all the elements in the sorted set at key with a score that version < score <= version_in_redis.
|
||||
//The elements are considered to be ordered from low to high scores(version).
|
||||
ctrl_reply=(redisReply*)redisCommand(c, "ZRANGE MAAT_UPDATE_STATUS (%d %d",version,version_in_redis);
|
||||
if(ctrl_reply==NULL)
|
||||
{
|
||||
__redis_strerror_r(errno,err_buff,sizeof(err_buff));
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_redis_monitor,
|
||||
"GET MAAT_UPDATE_STATUS failed %s.",err_buff);
|
||||
return 0;
|
||||
}
|
||||
assert(ctrl_reply->type==REDIS_REPLY_ARRAY);
|
||||
data_reply=(redisReply*)redisCommand(c, "ZRANK MAAT_UPDATE_STATUS %s",ctrl_reply->element[0]->str);
|
||||
if(data_reply->integer!=version+1)
|
||||
{
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_INFO, maat_redis_monitor,
|
||||
"Noncontinuous VERSION Redis: %lld MAAT: %d.",data_reply->integer,version);
|
||||
freeReplyObject(data_reply);
|
||||
data_reply=NULL;
|
||||
goto FULL_UPDATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_INFO, maat_redis_monitor,
|
||||
"Inc Update form version %d to %lld.",version,version_in_redis);
|
||||
|
||||
}
|
||||
freeReplyObject(data_reply);
|
||||
data_reply=NULL;
|
||||
p_rm_rule=(struct serial_rule_t*)calloc(ctrl_reply->elements,sizeof(struct serial_rule_t));
|
||||
for(i=0;i<ctrl_reply->elements;i++)
|
||||
{
|
||||
assert(ctrl_reply->element[i]->type==REDIS_REPLY_STRING);
|
||||
ret=sscanf(ctrl_reply->element[i]->str,"%s,%s,%d",op_str,p_rm_rule.table_name,&(p_rm_rule[i].rule_id));
|
||||
assert(ret==3);
|
||||
if(strncmp(op_str,"ADD")==0)
|
||||
{
|
||||
p_rm_rule[i].op=1;
|
||||
}
|
||||
else if(strncmp(op_str,"DEL")==0)
|
||||
{
|
||||
p_rm_rule[i].op=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
*list=p_rm_rule;
|
||||
*update_type=CM_UPDATE_TYPE_INC;
|
||||
freeReplyObject(ctrl_reply);
|
||||
return i;
|
||||
FULL_UPDATE:
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_INFO, maat_redis_monitor,
|
||||
"Initiate full udpate from version %d to %lld.",version,version_in_redis);
|
||||
data_reply=(redisReply*)redisCommand(c, "KEYS EFFECTIVE_RULE:*");
|
||||
assert(data_reply->type==REDIS_REPLY_ARRAY);
|
||||
p_rm_rule=(struct serial_rule_t*)calloc(ctrl_reply->elements,sizeof(struct serial_rule_t));
|
||||
for(i=0;i<data_reply->elements;i++)
|
||||
{
|
||||
assert(ctrl_reply->element[i]->type==REDIS_REPLY_STRING);
|
||||
ret=sscanf(ctrl_reply->element[i]->str,"EFFECTIVE_RULE:%s,%d",p_rm_rule[i].table_name,&(p_rm_rule[i].rule_id));
|
||||
p_rm_rule[i].op=1;
|
||||
assert(ret==2);
|
||||
}
|
||||
*list=p_rm_rule;
|
||||
*update_type=CM_UPDATE_TYPE_FULL;
|
||||
freeReplyObject(ctrl_reply);
|
||||
ctrl_reply=NULL;
|
||||
freeReplyObject(data_reply);
|
||||
data_reply=NULL;
|
||||
return i;
|
||||
}
|
||||
void redis_monitor_traverse(unsigned int version,redisContext *c,
|
||||
void (*start)(unsigned int ,int ,void*),//vesion,CM_UPDATE_TYPE_*,u_para
|
||||
void (*update)(const char* ,const char*,void* ),//table name ,line ,u_para
|
||||
void (*finish)(void*),//u_para
|
||||
void* u_para,
|
||||
const unsigned char* dec_key,
|
||||
void* logger)
|
||||
{
|
||||
redisReply* ctrl_reply=NULL,*data_reply=NULL;
|
||||
int rule_num=0,i=0;
|
||||
int ret=0;
|
||||
struct serial_rule_t* rule_list=NULL;
|
||||
int update_type=0;
|
||||
unsigned int new_version=0;
|
||||
rule_num=get_rm_key_list(version, c, &rule_list, logger,&new_version, &update_type);
|
||||
if(rule_num==0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for(i=0;i<rule_num;i++)
|
||||
{
|
||||
ret=redisAppendCommand(c, "GET %s:%s,%d",rm_key_prefix[rule_list[i].op]
|
||||
,rule_list[i].table_name
|
||||
,rule_list[i].rule_id);
|
||||
assert(ret==REDIS_OK);
|
||||
}
|
||||
ret=redisGetReply(c,&data_reply);
|
||||
assert(data_reply->elements==rule_num);
|
||||
start(new_version,update_type);
|
||||
for(i=0;i<data_reply->elements;i++)
|
||||
{
|
||||
update(rule_list[i].table_name,data_reply->element[i].str,u_para);
|
||||
}
|
||||
finish(u_para);
|
||||
freeReplyObject(data_reply);
|
||||
free(rule_list);
|
||||
rule_list=NULL;
|
||||
return;
|
||||
}
|
||||
struct Maat_command_t* Maat_create_comand(const struct Maat_rule_t* rule, int group_num)
|
||||
{
|
||||
struct _Maat_cmd_t* _cmd=(struct _Maat_cmd_t*)calloc(sizeof(struct _Maat_cmd_t),1);
|
||||
memcpy(&(_cmd->cmd.compile),rule,sizeof(_cmd->cmd.compile));
|
||||
_cmd->ref_cnt=1;
|
||||
_cmd->cmd.group_num=group_num;
|
||||
_cmd->cmd.groups=(struct Maat_group_t*)calloc(sizeof(struct Maat_group_t),group_num);
|
||||
|
||||
return (struct Maat_command_t*)_cmd;
|
||||
}
|
||||
void Maat_cmd_set_group(struct Maat_command_t* cmd,int which_group,int region_num,const char* table_name,const char* group_name)
|
||||
{
|
||||
assert(which_group<cmd->group_num);
|
||||
if(table_name!=NULL)
|
||||
{
|
||||
if(cmd->groups[which_group].table_name!=NULL)
|
||||
{
|
||||
free(cmd->groups[which_group].table_name);
|
||||
}
|
||||
cmd->groups[which_group].table_name=_maat_strdup(table_name);
|
||||
}
|
||||
if(group_name!=NULL)
|
||||
{
|
||||
if(cmd->groups[which_group].group_name!=NULL)
|
||||
{
|
||||
free(cmd->groups[which_group].group_name);
|
||||
}
|
||||
cmd->groups[which_group].group_name=_maat_strdup(group_name);
|
||||
}
|
||||
cmd->groups->regions=(struct Maat_region_t*)calloc(sizeof(struct Maat_region_t),region_num);
|
||||
cmd->groups->region_num=region_num;
|
||||
return;
|
||||
}
|
||||
void Maat_copy_region(struct Maat_region_t* dst,const struct Maat_region_t* src)
|
||||
{
|
||||
memcpy(dst,src,sizeof(struct Maat_region_t));
|
||||
if(src->table_name!=NULL)
|
||||
{
|
||||
dst->table_name=_maat_strdup(src->table_name)
|
||||
}
|
||||
switch(dst->region_type)
|
||||
{
|
||||
case REGION_IP:
|
||||
dst->addr_rule.src_ip=_maat_strdup(src->addr_rule.src_ip);
|
||||
dst->addr_rule.mask_src_ip=_maat_strdup(src->addr_rule.mask_src_ip);
|
||||
dst->addr_rule.dst_ip=_maat_strdup(src->addr_rule.dst_ip);
|
||||
dst->addr_rule.mask_src_ip=_maat_strdup(src->addr_rule.mask_src_ip);
|
||||
break;
|
||||
case REGION_EXPR:
|
||||
dst->expr_rule.keywords=_maat_strdup(src->expr_rule.keywords);
|
||||
dst->expr_rule.district=_maat_strdup(src->expr_rule.district);
|
||||
break;
|
||||
case REGION_INTERVAL:
|
||||
break;
|
||||
case REGION_DIGEST:
|
||||
dst->digest_rule.digest_string=_maat_strdup(src->digest_rule.digest_string);
|
||||
break;
|
||||
case REGION_SIMILARITY:
|
||||
assert(0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
void Maat_empty_region(struct Maat_region_t* p)
|
||||
{
|
||||
free(p->table_name);
|
||||
p->table_name=NULL;
|
||||
switch(p->region_type)
|
||||
{
|
||||
case REGION_IP:
|
||||
free(p->addr_rule.src_ip);
|
||||
free(p->addr_rule.mask_src_ip);
|
||||
free(p->addr_rule.dst_ip);
|
||||
free(p->addr_rule.mask_src_ip);
|
||||
break;
|
||||
case REGION_EXPR:
|
||||
free(p->expr_rule.keywords);
|
||||
free(p->expr_rule.district);
|
||||
break;
|
||||
case REGION_INTERVAL:
|
||||
break;
|
||||
case REGION_DIGEST:
|
||||
free(p->digest_rule.digest_string);
|
||||
break;
|
||||
case REGION_SIMILARITY:
|
||||
assert(0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
memset(p,0,sizeof(struct Maat_region_t));
|
||||
return;
|
||||
|
||||
}
|
||||
void Maat_cmd_set_region(struct Maat_command_t* cmd,int which_group,int which_region,const struct Maat_region_t* region)
|
||||
{
|
||||
struct Maat_region_t* p=NULL;
|
||||
assert(which_group<cmd->group_num);
|
||||
assert(which_region<cmd->groups[which_group].region_num);
|
||||
assert(region->table_name!=NULL);
|
||||
p=&(cmd->groups[which_group].regions[which_region]);
|
||||
Maat_copy_region(p, region);
|
||||
return;
|
||||
}
|
||||
|
||||
void Maat_free_command(struct Maat_command_t* cmd)
|
||||
{
|
||||
struct _Maat_cmd_t* _cmd=(struct _Maat_cmd_t*)cmd;
|
||||
int i=0,j=0;
|
||||
_cmd->ref_cnt--;
|
||||
if(_cmd->ref_cnt>0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for(i=0;i<_cmd->cmd.group_num;i++)
|
||||
{
|
||||
for(j=0;j<cmd.groups[i].region_num;j++)
|
||||
{
|
||||
Maat_empty_region(&(cmd.groups[i].regions[j]));
|
||||
}
|
||||
free(cmd.groups[i].table_name);
|
||||
free(cmd.groups[i].group_name);
|
||||
free(cmd.groups[i].regions);
|
||||
cmd.groups[i].regions=NULL;
|
||||
}
|
||||
free(_cmd->cmd.groups);
|
||||
_cmd->cmd.groups=NULL;
|
||||
_cmd->next=NULL;
|
||||
free(_cmd);
|
||||
return;
|
||||
}
|
||||
int Maat_format_command(struct Maat_command_t* rule, char* buffer, int size)
|
||||
{
|
||||
|
||||
}
|
||||
int Maat_command(Maat_feather_t feather,struct Maat_command_t* raw_rule,enum MAAT_OPERATION op)
|
||||
{
|
||||
int ret=0;
|
||||
ret=Maat_append_command(feather,raw_rule,op);
|
||||
if(ret<0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
ret=Maat_commit_command(feather);
|
||||
return ret;
|
||||
}
|
||||
//functioned as strdup, for dictator compatible.
|
||||
char* _maat_strdup(const char* s)
|
||||
{
|
||||
char*d=NULL;
|
||||
if(s==NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
d=(char*)malloc(strlen(s)+1);
|
||||
memcpy(d,s,strlen(s)+1));
|
||||
return d;
|
||||
}
|
||||
void Maat_append_command(Maat_feather_t feather,struct Maat_command_t* cmd,enum MAAT_OPERATION op)
|
||||
{
|
||||
_Maat_feather_t* _feather=(_Maat_feather_t*)feather;
|
||||
struct _Maat_cmd_t* _cmd=(struct _Maat_cmd_t*)cmd;
|
||||
_cmd->ref_cnt++;
|
||||
_cmd->op=op;
|
||||
assert(op==MAAT_OP_DEL||op==MAAT_OP_ADD);
|
||||
if(cmd->table_name==NULL)
|
||||
{
|
||||
cmd->table_name=_maat_strdup(_feather->compile_tn);
|
||||
}
|
||||
if(_feather->cmd_num==0)
|
||||
{
|
||||
assert(_feather->cmd_qtail==_feather->cmd_qhead==NULL);
|
||||
_feather->cmd_qhead=_feather->cmd_qtail=_cmd;
|
||||
}
|
||||
else
|
||||
{
|
||||
_feather->cmd_qtail->next=_cmd;
|
||||
_feather->cmd_qtail=_cmd;
|
||||
}
|
||||
_feather->cmd_num++;
|
||||
return;
|
||||
}
|
||||
//TODO: support plugin rule command.
|
||||
void invalidate_line(char* line, enum MAAT_TABLE_TYPE type)
|
||||
{
|
||||
int offset=0;
|
||||
int i=0,j=0;
|
||||
switch(type)
|
||||
{
|
||||
case TABLE_TYPE_EXPR:
|
||||
offset=7;
|
||||
break;
|
||||
case TABLE_TYPE_IP:
|
||||
offset=14;
|
||||
break;
|
||||
case TABLE_TYPE_COMPILE:
|
||||
offset=8;
|
||||
break;
|
||||
case TABLE_TYPE_PLUGIN:
|
||||
assert(0);
|
||||
break;
|
||||
case TABLE_TYPE_INTERVAL:
|
||||
offset=5;
|
||||
break;
|
||||
case TABLE_TYPE_DIGEST:
|
||||
offset=6;
|
||||
break;
|
||||
case TABLE_TYPE_EXPR_PLUS:
|
||||
offset=8;
|
||||
break;
|
||||
case TABLE_TYPE_GROUP:
|
||||
offset=3;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
for(i=0;i<strlen(line);i++)
|
||||
{
|
||||
if(line[i]==' '||line[i]=='\t')
|
||||
{
|
||||
j++;
|
||||
}
|
||||
if(j==offset)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(i<strlen(line));
|
||||
assert(line[i]=='1');
|
||||
line[i]='0';
|
||||
return;
|
||||
}
|
||||
int calculate_serial_rule_num(struct Maat_command_t* cmd)
|
||||
{
|
||||
int serial_num=0;
|
||||
int i=0,j=0;
|
||||
serial_num++;//compile rule
|
||||
for(i=0;i<cmd->group_num;i++)
|
||||
{
|
||||
serial_num++;
|
||||
for(j=0;j<cmd->groups[i].region_num;j++)
|
||||
{
|
||||
serial_num++;
|
||||
}
|
||||
}
|
||||
return serial_num;
|
||||
}
|
||||
int reconstruct_cmd(redisContext *ctx,struct _Maat_cmd_t* _cmd,void* logger)
|
||||
{
|
||||
int redis_ret=REDIS_ERR,ret=0;
|
||||
int i=0,j=0,grp_idx=0;
|
||||
redisReply* compile_reply=NULL,*group_reply=NULL,*region_reply=NULL;
|
||||
long long group_ref_cnt=0;
|
||||
char table_name[MAX_TABLE_NAME_LEN];
|
||||
struct Maat_command_t* cmd=&(_cmd->cmd);
|
||||
struct Maat_group_t* p_group=NULL;
|
||||
struct Maat_region_t* p_region=NULL;
|
||||
|
||||
|
||||
int config_id=cmd->compile.config_id;
|
||||
compile_reply=redisCommand(ctx,"HKEYS %s:%d",PREFIX_COMPILE_INDEX,config_id);
|
||||
if(compile_reply==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_redis_command
|
||||
,"%s:%d not found."
|
||||
,PREFIX_COMPILE_INDEX,config_id);
|
||||
return -1;
|
||||
}
|
||||
cmd->group_num=compile_reply->elements;
|
||||
assert(cmd->compile.declare_grp_num==cmd->group_num);
|
||||
assert(cmd->groups==NULL);
|
||||
cmd->groups=calloc(sizeof(struct Maat_group_t),cmd->group_num);
|
||||
for(i=0;i<compile_reply->elements;i++)
|
||||
{
|
||||
if(strncmp(compile_reply->element[i].str,"GROUP:",strlen("GROUP:"))!=0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
p_group=&(cmd->groups[grp_idx]);
|
||||
ret=sscanf(compile_reply->element[i].str,"GROUP:%s,%d",table_name,&(p_group->group_id));
|
||||
assert(ret==2);
|
||||
p_group->table_name=_maat_strdup(table_name);
|
||||
|
||||
group_reply=redisCommand(ctx,"HINCRBY %s:%s,%d REF_CNT -1",PREFIX_GROUP_INDEX
|
||||
,p_group->table_name
|
||||
,p_group->group_id);
|
||||
freeReplyObject(group_reply);
|
||||
group_reply=redisCommand(ctx,"HGET %s:%s,%d REF_CNT",PREFIX_GROUP_INDEX
|
||||
,p_group->table_name
|
||||
,p_group->group_id);
|
||||
group_ref_cnt=group_reply->integer;
|
||||
freeReplyObject(group_reply);
|
||||
_cmd->group_ref_cnt[grp_idx]=group_ref_cnt;
|
||||
grp_idx++;
|
||||
if(group_ref_cnt>0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
group_reply=redisCommand(ctx,"HKEYS %s:%s,%d",PREFIX_GROUP_INDEX
|
||||
,p_group->table_name
|
||||
,p_group->group_id);
|
||||
p_group->region_num=group_reply->elements;
|
||||
p_group->regions=(struct Maat_region_t*)calloc(sizeof(struct Maat_region_t),p_group->region_num);
|
||||
for(j=0;j<group_reply->elements;j++)
|
||||
{
|
||||
if(strncmp(group_reply->element[j].str,"REGION:",strlen("REGION:"))!=0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
p_region=&(p_group->regions[p_group->region_num]);
|
||||
ret=sscanf(group_reply->element[j].str,"REGION:%s,%d",table_name,&(p_region->region_id));
|
||||
assert(ret==2);
|
||||
p_region->table_name=_maat_strdup(table_name);
|
||||
region_reply=redisCommand(ctx,"HGET %s %s,%d",PREFIX_REGION_INDEX
|
||||
,p_region->table_name
|
||||
,p_region->region_id);
|
||||
p_region->region_type=region_reply->integer;
|
||||
p_group->region_num++;
|
||||
|
||||
freeReplyObject(region_reply);
|
||||
}
|
||||
freeReplyObject(group_reply);
|
||||
group_reply=NULL;
|
||||
}
|
||||
freeReplyObject(compile_reply);
|
||||
compile_reply=NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int build_serial_rule_from_redis(redisContext *ctx,struct Maat_command_t* cmd,struct serial_rule_t* list, int size)
|
||||
{
|
||||
struct Maat_group_t* p_group=NULL;
|
||||
struct Maat_region_t* p_region=NULL;
|
||||
enum MAAT_TABLE_TYPE table_type=0;
|
||||
redisReply* data_reply=NULL;
|
||||
int rule_num=0;
|
||||
int i=0,j=0;
|
||||
data_reply=redisCommand(ctx,"GET %s:%s,%d",rm_key_prefix[MAAT_OP_ADD]
|
||||
,cmd->table_name
|
||||
,cmd->compile.config_id);
|
||||
invalidate_line(data_reply->str, TABLE_TYPE_COMPILE);
|
||||
set_serial_rule(list+rule_num,MAAT_OP_DEL,TABLE_TYPE_COMPILE,cmd->compile.config_id,cmd->table_name,data_reply->str);
|
||||
rule_num++;
|
||||
freeReplyObject(data_reply);
|
||||
for(i=0;i<cmd->group_num;i++)
|
||||
{
|
||||
p_group=&(cmd->groups[i]);
|
||||
data_reply=redisCommand(ctx,"GET %s:%s,%d",rm_key_prefix[MAAT_OP_ADD]
|
||||
,p_group->table_name
|
||||
,p_group->group_id);
|
||||
invalidate_line(data_reply->str, TABLE_TYPE_GROUP);
|
||||
set_serial_rule(list+rule_num,MAAT_OP_DEL,TABLE_TYPE_GROUP,p_group->group_id,p_group->table_name,data_reply->str);
|
||||
rule_num++;
|
||||
freeReplyObject(data_reply);
|
||||
for(j=0;j<p_group->region_num;j++)
|
||||
{
|
||||
p_region=&(p_group->regions[j]);
|
||||
data_reply=redisCommand(ctx,"GET %s:%s,%d",rm_key_prefix[MAAT_OP_ADD]
|
||||
,p_region->table_name
|
||||
,p_region->region_id);
|
||||
table_type=region_table_type(p_region);
|
||||
invalidate_line(data_reply->str, table_type);
|
||||
set_serial_rule(list+rule_num,MAAT_OP_DEL,p_region->region_id,p_region->table_name,data_reply->str);
|
||||
rule_num++;
|
||||
freeReplyObject(data_reply);
|
||||
}
|
||||
}
|
||||
assert(rule_num<size);
|
||||
return 0;
|
||||
}
|
||||
int build_serial_rule_from_cmd(struct Maat_command_t* cmd,struct serial_rule_t* list, int size)
|
||||
{
|
||||
struct Maat_group_t* p_group=NULL;
|
||||
struct Maat_region_t* p_region=NULL;
|
||||
struct Maat_rule_t* p_m_rule=NULL;
|
||||
redisReply* data_reply=NULL;
|
||||
int rule_num=0,i=0;
|
||||
p_m_rule=&(cmd->compile);
|
||||
char line[1024];
|
||||
snprintf(line,sizeof(line),"%d\t%d\t%hhd\t%hhd\t%hhd\t0\t%s\t1\t%d",p_m_rule->config_id
|
||||
,p_m_rule->service_id
|
||||
,p_m_rule->action
|
||||
,p_m_rule->do_blacklist
|
||||
,p_m_rule->do_log
|
||||
,p_m_rule->service_defined
|
||||
,p_m_rule->declare_grp_num);
|
||||
set_serial_rule(list+rule_num,MAAT_OP_ADD,cmd->compile.config_id,cmd->table_name,line);
|
||||
rule_num++;
|
||||
data_reply=redisCommand(ctx,"GET %s:%s,%d",rm_key_prefix[MAAT_OP_ADD]
|
||||
,cmd->table_name
|
||||
,cmd->compile.config_id);
|
||||
return 0;
|
||||
}
|
||||
int mr_transaction_success(redisReply* data_reply)
|
||||
{
|
||||
int i=0;
|
||||
for(i=0;i<data_reply->elements;i++)
|
||||
{
|
||||
if(data_reply->element[i].type==REDIS_REPLY_NIL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
const int MAAT_REDIS_SYNC_TIME=30*60;
|
||||
int del_cmd_from_redis(redisContext *ctx,struct _Maat_cmd_t* _cmd,void* logger)
|
||||
{
|
||||
int serial_num=0;
|
||||
int i=0;
|
||||
int retry=0,ret=0;
|
||||
long long maat_redis_version=0,group_num=0;
|
||||
struct serial_rule_t *s_rule=NULL;
|
||||
struct Maat_command_t* cmd=&(_cmd->cmd);
|
||||
int redis_ret=REDIS_ERR,ret=0;
|
||||
redisReply* data_reply=NULL;
|
||||
reconstruct_cmd(ctx, _cmd, logger);
|
||||
serial_num=calculate_serial_rule_num(cmd);
|
||||
s_rule=(struct serial_rule_t*)calloc(sizeof(struct serial_rule_t),serial_num);
|
||||
ret=build_serial_rule_from_redis(ctx, cmd, s_rule, serial_num);
|
||||
|
||||
|
||||
retry=0;
|
||||
while(1)
|
||||
{
|
||||
|
||||
data_reply=redisCommand(ctx, "WATCH MAAT_VERSION");
|
||||
freeReplyObject(data_reply);
|
||||
data_reply=redisCommand(ctx, "GET MAAT_VERSION");
|
||||
freeReplyObject(data_reply);
|
||||
maat_redis_version=data_reply->integer;
|
||||
maat_redis_version++;
|
||||
data_reply=redisCommand(ctx,"MULTI");
|
||||
freeReplyObject(data_reply);
|
||||
for(i=0;i<serial_num;i++)
|
||||
{
|
||||
data_reply=redisCommand(ctx,"DEL %s:%s,%d",rm_key_prefix[MAAT_OP_ADD]
|
||||
,s_rule[i].table_name
|
||||
,s_rule[i].rule_id);
|
||||
freeReplyObject(data_reply);
|
||||
|
||||
data_reply=redisCommand(ctx,"SET %s:%s,%d \"%s\"",rm_key_prefix[MAAT_OP_DEL]
|
||||
,s_rule[i].table_name
|
||||
,s_rule[i].rule_id
|
||||
,s_rule[i].table_line);
|
||||
freeReplyObject(data_reply);
|
||||
data_reply=redisCommand(ctx,"EXPIRE %s:%s,%d %d",rm_key_prefix[MAAT_OP_DEL]
|
||||
,s_rule[i].table_name
|
||||
,s_rule[i].rule_id
|
||||
,MAAT_REDIS_SYNC_TIME);
|
||||
freeReplyObject(data_reply);
|
||||
//NX: Don't update already exisiting elements. Always add new elements.
|
||||
data_reply=redisCommand(ctx,"ZADD NX DEL,%s,%d %d",s_rule[i].table_name
|
||||
,s_rule[i].rule_id
|
||||
,maat_redis_version);
|
||||
freeReplyObject(data_reply);
|
||||
|
||||
|
||||
data_reply=redisCommand(ctx,"INCRBY MAAT_VERSION 1");
|
||||
freeReplyObject(data_reply);
|
||||
}
|
||||
|
||||
data_reply=redisCommand(ctx,"EXEC");
|
||||
if(1==mr_transaction_success(data_reply))
|
||||
{
|
||||
freeReplyObject(data_reply);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
retry++;
|
||||
assert(retry<5);
|
||||
freeReplyObject(data_reply);
|
||||
}
|
||||
}
|
||||
for(i=0;i<serial_num;i++)
|
||||
{
|
||||
free_serial_rules(s_rule+i);
|
||||
s_rule[i]=NULL;
|
||||
}
|
||||
free(s_rule);
|
||||
}
|
||||
int add_cmd_to_redis(redisContext *ctx,struct _Maat_cmd_t* _cmd,void* logger)
|
||||
{
|
||||
int ret=0,retry=0,i=0;
|
||||
redisReply* data_reply=NULL;
|
||||
long long maat_redis_version=0;
|
||||
struct Maat_command_t* cmd=&(_cmd->cmd);
|
||||
struct serial_rule_t *s_rule=NULL;
|
||||
int serial_num=calculate_serial_rule_num(cmd);
|
||||
s_rule=(struct serial_rule_t*)calloc(sizeof(struct serial_rule_t),serial_num);
|
||||
ret=build_serial_rule_from_cmd(ctx, cmd, s_rule, serial_num);
|
||||
|
||||
retry=0;
|
||||
while(1)
|
||||
{
|
||||
|
||||
data_reply=redisCommand(ctx, "WATCH MAAT_VERSION");
|
||||
freeReplyObject(data_reply);
|
||||
data_reply=redisCommand(ctx, "GET MAAT_VERSION");
|
||||
freeReplyObject(data_reply);
|
||||
maat_redis_version=data_reply->integer;
|
||||
maat_redis_version++;
|
||||
data_reply=redisCommand(ctx,"MULTI");
|
||||
freeReplyObject(data_reply);
|
||||
for(i=0;i<serial_num;i++)
|
||||
{
|
||||
data_reply=redisCommand(ctx,"SET %s:%s,%d \"%s\"",rm_key_prefix[MAAT_OP_ADD]
|
||||
,s_rule[i].table_name
|
||||
,s_rule[i].rule_id
|
||||
,s_rule[i].table_line);
|
||||
freeReplyObject(data_reply);
|
||||
|
||||
//NX: Don't update already exisiting elements. Always add new elements.
|
||||
data_reply=redisCommand(ctx,"ZADD NX ADD,%s,%d %d",s_rule[i].table_name
|
||||
,s_rule[i].rule_id
|
||||
,maat_redis_version);
|
||||
freeReplyObject(data_reply);
|
||||
}
|
||||
|
||||
data_reply=redisCommand(ctx,"EXEC");
|
||||
if(1==mr_transaction_success(data_reply))
|
||||
{
|
||||
freeReplyObject(data_reply);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
retry++;
|
||||
assert(retry<5);
|
||||
freeReplyObject(data_reply);
|
||||
}
|
||||
}
|
||||
for(i=0;i<serial_num;i++)
|
||||
{
|
||||
free_serial_rules(s_rule+i);
|
||||
s_rule[i]=NULL;
|
||||
}
|
||||
free(s_rule);
|
||||
|
||||
}
|
||||
int Maat_commit_command(Maat_feather_t feather)
|
||||
{
|
||||
_Maat_feather_t* _feather=(_Maat_feather_t*)feather;
|
||||
redisReply* reply=NULL;
|
||||
struct serial_rule_t* update_status=NULL;
|
||||
int status_cnt=0;
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec=0;
|
||||
timeout.tv_usec=100*1000; // 100 ms
|
||||
int ret=0,i=0,redis_ret=REDIS_ERR,retry=0;
|
||||
long long maat_redis_version=0,region_seq=0,group_seq=0;
|
||||
struct _Maat_cmd_t* p=NULL,*n=NULL;
|
||||
if(_feather->redis_write_ctx==NULL)
|
||||
{
|
||||
_feather->redis_write_ctx=redisConnectWithTimeout(_feather->redis_ip, _feather->redis_port,timeout);
|
||||
if(_feather->redis_write_ctx==NULL)
|
||||
{
|
||||
MESA_handle_runtime_log(_feather->logger,RLOG_LV_FATAL,maat_module
|
||||
,"Redis connect %s:%d failed when appending command."
|
||||
,_feather->redis_ip,_feather->redis_port);
|
||||
ret=-1;
|
||||
goto error_out;
|
||||
}
|
||||
}
|
||||
p=feather->cmd_qhead;
|
||||
for(i=0;i<feather->cmd_num;i++)
|
||||
{
|
||||
p=p->next;
|
||||
if(p->op==MAAT_OP_DEL)
|
||||
{
|
||||
del_cmd_from_redis(_feather->redis_write_ctx, p, _feather->logger);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_cmd_to_redis(_feather->redis_write_ctx, p, _feather->logger);
|
||||
}
|
||||
}
|
||||
error_out:
|
||||
p=_feather->cmd_qhead;
|
||||
for(i=0;i<_feather->cmd_num;i++)
|
||||
{
|
||||
n=p->next;
|
||||
Maat_free_command((struct Maat_command_t* )p);
|
||||
p=n;
|
||||
}
|
||||
_feather->cmd_qhead=_feather->cmd_qtail=NULL;
|
||||
_feather->cmd_num=0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
#include "hiredis.h"
|
||||
#include <errno.h>
|
||||
|
||||
const char* maat_redis_monitor="MAAT_REDIS_MONITOR";
|
||||
void redis_monitor_traverse(unsigned int version,redisContext *c,
|
||||
void (*start)(unsigned int ,int ,void*),//vesion,CM_UPDATE_TYPE_*,u_para
|
||||
void (*update)(const char* ,const char*,void* ),//table name ,line ,u_para
|
||||
void (*finish)(void*),//u_para
|
||||
void* u_para,
|
||||
const unsigned char* dec_key,
|
||||
void* logger)
|
||||
{
|
||||
redisReply* ctrl_reply=NULL;
|
||||
char err_buff[256];
|
||||
long long redis_maat_version=0;
|
||||
ctrl_reply=(redisReply*)redisCommand(c, "GET MAAT_VERSION");
|
||||
if(ctrl_reply==NULL)
|
||||
{
|
||||
__redis_strerror_r(errno,err_buff,sizeof(err_buff));
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_redis_monitor,
|
||||
"GET MAAT_VERSION failed %s.",err_buff);
|
||||
return;
|
||||
}
|
||||
assert(ctrl_reply->type==REDIS_REPLY_INTEGER);
|
||||
assert(ctrl_reply->integer>=version);
|
||||
if(ctrl_reply->integer==version)
|
||||
{
|
||||
freeReplyObject(ctrl_reply);
|
||||
return;
|
||||
}
|
||||
redis_maat_version=ctrl_reply->integer;
|
||||
freeReplyObject(ctrl_reply);
|
||||
ctrl_reply=(redisReply*)redisCommand(c, "GET MAAT_UPDATE_STATUS");
|
||||
if(ctrl_reply==NULL)
|
||||
{
|
||||
__redis_strerror_r(errno,err_buff,sizeof(err_buff));
|
||||
MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_redis_monitor,
|
||||
"GET MAAT_UPDATE_STATUS failed %s.",err_buff);
|
||||
return;
|
||||
}
|
||||
assert(ctrl_reply->type==REDIS_REPLY_ARRAY);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "Maat_rule.h"
|
||||
#include "Maat_rule_internal.h"
|
||||
#include "Maat_redis.h"
|
||||
#include "json2iris.h"
|
||||
#include "dynamic_array.h"
|
||||
#include "aligment_int64.h"
|
||||
@@ -28,7 +29,7 @@
|
||||
#include "mesa_fuzzy.h"
|
||||
#include "great_index_engine.h"
|
||||
|
||||
int MAAT_FRAME_VERSION_1_9_20170626=1;
|
||||
int MAAT_FRAME_VERSION_2_0_20170701=1;
|
||||
const char *maat_module="MAAT Frame";
|
||||
|
||||
const char* CHARSET_STRING[]={"NONE","gbk","big5","unicode","utf8","bin",
|
||||
@@ -81,7 +82,7 @@ int is_valid_match_method(enum MAAT_MATCH_METHOD match_method)
|
||||
case MATCH_METHOD_SUB:
|
||||
case MATCH_METHOD_RIGHT:
|
||||
case MATCH_METHOD_LEFT:
|
||||
case MATCH_METHOD_FULL:
|
||||
case MATCH_METHOD_COMPLETE:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
@@ -480,7 +481,7 @@ int read_table_info(struct _Maat_table_info_t** p_table_info,int num,const char*
|
||||
map_register(string2int_map,"ip", TABLE_TYPE_IP);
|
||||
map_register(string2int_map,"compile", TABLE_TYPE_COMPILE);
|
||||
map_register(string2int_map,"plugin", TABLE_TYPE_PLUGIN);
|
||||
map_register(string2int_map,"intval", TABLE_TYPE_INTVAL);
|
||||
map_register(string2int_map,"intval", TABLE_TYPE_INTERVAL);
|
||||
map_register(string2int_map,"digest", TABLE_TYPE_DIGEST);
|
||||
map_register(string2int_map,"expr_plus", TABLE_TYPE_EXPR_PLUS);
|
||||
map_register(string2int_map,"group", TABLE_TYPE_GROUP);
|
||||
@@ -786,7 +787,7 @@ scan_rule_t* create_rs_str_rule(unsigned int sub_type,enum MAAT_MATCH_METHOD mat
|
||||
p_rule->string_rule.r_offset=-1;
|
||||
switch(match_method)
|
||||
{
|
||||
case MATCH_METHOD_FULL:
|
||||
case MATCH_METHOD_COMPLETE:
|
||||
p_rule->string_rule.match_mode=1;
|
||||
break;
|
||||
case MATCH_METHOD_LEFT:
|
||||
@@ -1796,7 +1797,7 @@ int add_intval_rule(struct _Maat_table_info_t* table,struct db_intval_rule_t* in
|
||||
HASH_add_by_id(scanner->group_hash, intval_rule->group_id, group_rule);
|
||||
}
|
||||
expr_id=scanner->exprid_generator++;
|
||||
u_para=add_region_to_group(group_rule,intval_rule->region_id,district_id,expr_id,TABLE_TYPE_INTVAL);
|
||||
u_para=add_region_to_group(group_rule,intval_rule->region_id,district_id,expr_id,TABLE_TYPE_INTERVAL);
|
||||
if(u_para==NULL)
|
||||
{
|
||||
return -1;
|
||||
@@ -1873,7 +1874,7 @@ int del_region_rule(struct _Maat_table_info_t* table,int region_id,int group_id,
|
||||
case TABLE_TYPE_IP:
|
||||
case TABLE_TYPE_EXPR:
|
||||
case TABLE_TYPE_EXPR_PLUS:
|
||||
case TABLE_TYPE_INTVAL:
|
||||
case TABLE_TYPE_INTERVAL:
|
||||
for(i=0;i<expr_num;i++)
|
||||
{
|
||||
op_expr=create_op_expr(expr_id[i],1,NULL,table->table_id);//del expr
|
||||
@@ -2953,7 +2954,7 @@ void maat_update_cb(const char* table_name,const char* line,void *u_para)
|
||||
case TABLE_TYPE_IP:
|
||||
update_ip_rule(feather->p_table_info[table_id], line, scanner,feather->logger,feather->GROUP_MODE_ON);
|
||||
break;
|
||||
case TABLE_TYPE_INTVAL:
|
||||
case TABLE_TYPE_INTERVAL:
|
||||
update_intval_rule(feather->p_table_info[table_id], line, scanner,feather->logger,feather->GROUP_MODE_ON);
|
||||
break;
|
||||
case TABLE_TYPE_DIGEST:
|
||||
@@ -3000,6 +3001,19 @@ void *thread_rule_monitor(void *arg)
|
||||
scan_dir_cnt++;
|
||||
//plugin table register is not allowed during update;
|
||||
pthread_mutex_lock(&(feather->plugin_table_reg_mutex));
|
||||
if(feather->REDIS_MODE_ON==1)
|
||||
{
|
||||
redis_monitor_traverse(feather->maat_version
|
||||
,feather->redis_read_ctx
|
||||
,maat_start_cb
|
||||
,maat_update_cb
|
||||
,maat_finish_cb
|
||||
, feather
|
||||
,feather->decrypt_key //Not used.
|
||||
,feather->logger);
|
||||
}
|
||||
else
|
||||
{
|
||||
config_monitor_traverse(feather->maat_version,
|
||||
inc_cfg_dir,
|
||||
maat_start_cb,
|
||||
@@ -3008,6 +3022,7 @@ void *thread_rule_monitor(void *arg)
|
||||
feather,
|
||||
feather->decrypt_key,
|
||||
feather->logger);
|
||||
}
|
||||
pthread_mutex_unlock(&(feather->plugin_table_reg_mutex));
|
||||
if(feather->update_tmp_scanner!=NULL)
|
||||
{
|
||||
@@ -3082,6 +3097,13 @@ void *thread_rule_monitor(void *arg)
|
||||
aligment_int64_array_free(feather->hit_cnt);
|
||||
aligment_int64_array_free(feather->orphan_group_saving);
|
||||
aligment_int64_array_free(feather->last_region_saving);
|
||||
if(feather->REDIS_MODE_ON==1&&feather->redis_read_ctx!=NULL)
|
||||
{
|
||||
pthread_mutex_lock(&(feather->redis_write_lock));
|
||||
redisFree(feather->redis_read_ctx);
|
||||
feather->redis_read_ctx=NULL;
|
||||
pthread_mutex_unlock(&(feather->redis_write_lock));
|
||||
}
|
||||
free(feather);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define H_MAAT_RULE_INTERNAL_H_INCLUDE
|
||||
|
||||
#include "Maat_rule.h"
|
||||
#include "Maat_command.h"
|
||||
|
||||
#include <MESA/MESA_htable.h>
|
||||
#include <MESA/MESA_list_queue.h>
|
||||
@@ -9,6 +10,7 @@
|
||||
#include "dynamic_array.h"
|
||||
#include "UniversalBoolMatch.h"
|
||||
#include "rulescan.h"
|
||||
#include "hiredis.h"
|
||||
|
||||
#include "mesa_fuzzy.h"
|
||||
#include "great_index_engine.h"
|
||||
@@ -73,28 +75,15 @@ enum MAAT_TABLE_TYPE
|
||||
{
|
||||
TABLE_TYPE_EXPR=0,
|
||||
TABLE_TYPE_IP,
|
||||
TABLE_TYPE_COMPILE,
|
||||
TABLE_TYPE_PLUGIN,
|
||||
TABLE_TYPE_INTVAL,
|
||||
TABLE_TYPE_INTERVAL,
|
||||
TABLE_TYPE_DIGEST,
|
||||
TABLE_TYPE_EXPR_PLUS,
|
||||
TABLE_TYPE_GROUP
|
||||
TABLE_TYPE_SIMILARITY,
|
||||
TABLE_TYPE_GROUP,
|
||||
TABLE_TYPE_COMPILE,
|
||||
TABLE_TYPE_PLUGIN
|
||||
|
||||
};
|
||||
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_FULL
|
||||
};
|
||||
|
||||
struct db_str_rule_t
|
||||
{
|
||||
@@ -355,6 +344,7 @@ struct _Maat_feather_t
|
||||
MESA_lqueue_head garbage_q;
|
||||
int table_cnt;
|
||||
int GROUP_MODE_ON;
|
||||
int REDIS_MODE_ON;
|
||||
int still_working;
|
||||
int scan_interval_ms;
|
||||
int effect_interval_ms;
|
||||
@@ -372,8 +362,18 @@ struct _Maat_feather_t
|
||||
char stat_file[MAX_TABLE_NAME_LEN];
|
||||
char instance_name[MAX_TABLE_NAME_LEN];
|
||||
char table_info_fn[MAX_TABLE_NAME_LEN];
|
||||
char compile_tn[MAX_TABLE_NAME_LEN];
|
||||
char group_tn[MAX_TABLE_NAME_LEN];
|
||||
pthread_mutex_t plugin_table_reg_mutex;
|
||||
unsigned char* decrypt_key;
|
||||
unsigned char decrypt_key[MAX_TABLE_NAME_LEN];
|
||||
unsigned char redis_ip[MAX_TABLE_NAME_LEN];;
|
||||
int redis_port;
|
||||
redisContext *redis_read_ctx;
|
||||
redisContext *redis_write_ctx; // not thread safe.
|
||||
int on_redis_writing;
|
||||
int cmd_num;
|
||||
struct _Maat_cmd_t* cmd_qhead, *cmd_qtail;
|
||||
pthread_mutex_t redis_write_lock; //protect redis_write_ctx
|
||||
//for stat>>>>
|
||||
screen_stat_handle_t stat_handle;
|
||||
int total_stat_id;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
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
|
||||
FITNESS FOR A PARTICULAR PURPOSE EXPR_TYPE_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
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
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
|
||||
FITNESS FOR A PARTICULAR PURPOSE EXPR_TYPE_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
|
||||
|
||||
@@ -113,7 +113,7 @@ int set_iris_descriptor(const char* json_file,cJSON *json,struct iris_descriptio
|
||||
map_register(iris_cfg->str2int_map, "string",TABLE_TYPE_EXPR);
|
||||
map_register(iris_cfg->str2int_map, "expr",TABLE_TYPE_EXPR);
|
||||
map_register(iris_cfg->str2int_map, "expr_plus",TABLE_TYPE_EXPR_PLUS);
|
||||
map_register(iris_cfg->str2int_map, "intval",TABLE_TYPE_INTVAL);
|
||||
map_register(iris_cfg->str2int_map, "intval",TABLE_TYPE_INTERVAL);
|
||||
map_register(iris_cfg->str2int_map, "digest",TABLE_TYPE_DIGEST);
|
||||
|
||||
|
||||
@@ -615,7 +615,7 @@ int write_region_rule(cJSON* region_json,int compile_id,int group_id,iris_descri
|
||||
case TABLE_TYPE_IP:
|
||||
ret=write_ip_rule(table_content, p_iris, table_info->table_path, logger);
|
||||
break;
|
||||
case TABLE_TYPE_INTVAL:
|
||||
case TABLE_TYPE_INTERVAL:
|
||||
ret=write_intval_rule(table_content, p_iris, table_info->table_path, logger);
|
||||
break;
|
||||
case TABLE_TYPE_DIGEST:
|
||||
|
||||
@@ -18,14 +18,14 @@
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS EXPR_TYPE_AND CONTRIBUTORS "AS IS"
|
||||
* EXPR_TYPE_AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY EXPR_TYPE_AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* INTERRUPTION) HOWEVER CAUSED EXPR_TYPE_AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS EXPR_TYPE_AND CONTRIBUTORS "AS IS"
|
||||
* EXPR_TYPE_AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY EXPR_TYPE_AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* INTERRUPTION) HOWEVER CAUSED EXPR_TYPE_AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Reference in New Issue
Block a user