diff options
| author | 郑超 <[email protected]> | 2019-07-11 17:09:27 +0800 |
|---|---|---|
| committer | 郑超 <[email protected]> | 2019-07-11 17:09:27 +0800 |
| commit | eb7912a85469f71495367b16f084e1aeaa66383e (patch) | |
| tree | 5e81c5448f27b4b971cbb21be30c7ac9749c9aa4 | |
| parent | 0cdf2224b699aec736456d1020b543b9e5553cf9 (diff) | |
| parent | 85509f0988b812610e464e67a78972a856dee5b4 (diff) | |
2.7正式版
Closes #13, #12, and #11
See merge request MESA_framework/maat!31
| -rw-r--r-- | inc/Maat_command.h | 21 | ||||
| -rw-r--r-- | inc/Maat_rule.h | 8 | ||||
| -rw-r--r-- | src/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/entry/Maat_api.cpp | 289 | ||||
| -rw-r--r-- | src/entry/Maat_command.cpp | 179 | ||||
| -rw-r--r-- | src/entry/Maat_rule.cpp | 1517 | ||||
| -rw-r--r-- | src/entry/Maat_stat.cpp | 7 | ||||
| -rw-r--r-- | src/entry/json2iris.cpp | 328 | ||||
| -rw-r--r-- | src/inc_internal/Maat_rule_internal.h | 123 | ||||
| -rw-r--r-- | src/inc_internal/Maat_table_description.h | 1 | ||||
| -rw-r--r-- | src/inc_internal/view_only/rulescan.h | 52 | ||||
| -rw-r--r-- | src/version.map | 1 | ||||
| -rw-r--r-- | test/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | test/maat_json.json | 292 | ||||
| -rw-r--r-- | test/table_info.conf | 7 | ||||
| -rw-r--r-- | test/test_igraph.cpp | 62 | ||||
| -rw-r--r-- | test/test_maatframe.cpp | 549 | ||||
| -rw-r--r-- | test/testdata/jd.com.html | 968 | ||||
| -rw-r--r-- | tools/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | tools/maat_debug_tool.cpp | 174 | ||||
| -rw-r--r-- | vendor/CMakeLists.txt | 16 | ||||
| -rw-r--r-- | vendor/igraph-0.7.1.tar.gz | bin | 0 -> 2967134 bytes |
22 files changed, 3666 insertions, 940 deletions
diff --git a/inc/Maat_command.h b/inc/Maat_command.h index f0c8ce9..816dd63 100644 --- a/inc/Maat_command.h +++ b/inc/Maat_command.h @@ -10,7 +10,11 @@ enum MAAT_OPERATION MAAT_OP_ADD, MAAT_OP_RENEW_TIMEOUT //Rule expire time is changed to now+cmd->expire_after }; - +enum MAAT_GROUP_RELATION +{ + PARENT_TYPE_COMPILE=0, + PARENT_TYPE_GROUP +}; enum MAAT_REGION_TYPE { REGION_EXPR, @@ -104,8 +108,12 @@ struct Maat_region_t }; struct Maat_group_t { - int region_num; + const char* table_name; int group_id; //If MAAT_OPT_CMD_AUTO_NUMBERING==1, maat will assigned one. Or users must assign a unique number. + int parent_id; + int not_flag; + enum MAAT_GROUP_RELATION parent_type; + int region_num; struct Maat_region_t *regions; }; struct Maat_cmd_t @@ -170,5 +178,14 @@ void Maat_cmd_key_free(struct Maat_cmd_key**keys, int number); int Maat_cmd_key_select(Maat_feather_t feather, int label_id, struct Maat_cmd_key** keys); int Maat_cmd_select(Maat_feather_t feather, int label_id, int * output_ids, unsigned int size); int Maat_cmd_flushDB(Maat_feather_t feather); + +int Maat_command_raw_set_compile(Maat_feather_t feather, enum MAAT_OPERATION op, const struct Maat_rule_t* compile, const char* table_name, const char * huge_service_defined, int group_num); +int Maat_command_raw_set_region(Maat_feather_t feather, enum MAAT_OPERATION op, const struct Maat_region_t* region, int group_id); +int Maat_command_raw_set_group(Maat_feather_t feather, enum MAAT_OPERATION op, const struct Maat_group_t* group); + +int Maat_cmd_get_new_group_id(Maat_feather_t feather); +int Maat_cmd_get_new_region_id(Maat_feather_t feather); + + #endif diff --git a/inc/Maat_rule.h b/inc/Maat_rule.h index 1b2f5dc..71eb650 100644 --- a/inc/Maat_rule.h +++ b/inc/Maat_rule.h @@ -185,8 +185,8 @@ int Maat_table_callback_register(Maat_feather_t feather,short table_id, enum MAAT_SCAN_OPT { - MAAT_SET_SCAN_DISTRICT=1, //VALUE is a const char*,SIZE= strlen(string).DEFAULT: no default. - MAAT_SET_SCAN_LAST_REGION //VALUE is NULL, SIZE=0. This option indicates that the follow scan is the last region of current scan cobination. + MAAT_SET_SCAN_DISTRICT=1, //VALUE is a const char*,SIZE= strlen(string). DEFAULT: no default. + MAAT_SET_SCAN_LAST_REGION //VALUE is NULL, SIZE=0. This option indicates that the follow scan is the last region of current scan combination. }; //return 0 if success, return -1 when failed; int Maat_set_scan_status(Maat_feather_t feather,scan_status_t* mid,enum MAAT_SCAN_OPT type,const void* value,int size); @@ -209,7 +209,7 @@ int Maat_full_scan_string(Maat_feather_t feather,int table_id ,enum MAAT_CHARSET charset,const char* data,int data_len ,struct Maat_rule_t*result,int* found_pos,int rule_num ,scan_status_t* mid,int thread_num); -//hite_detail could be NULL if unconcern +//hit_detail could be NULL if not cared. int Maat_full_scan_string_detail(Maat_feather_t feather,int table_id ,enum MAAT_CHARSET charset,const char* data,int data_len ,struct Maat_rule_t*result,int rule_num,struct Maat_hit_detail_t *hit_detail,int detail_num @@ -220,7 +220,7 @@ int Maat_stream_scan_string(stream_para_t* stream_para ,enum MAAT_CHARSET charset,const char* data,int data_len ,struct Maat_rule_t*result,int* found_pos,int rule_num ,scan_status_t* mid); -//hited_detail could be NULL if unconcern +//hited_detail could be NULL if not cared. int Maat_stream_scan_string_detail(stream_para_t* stream_para ,enum MAAT_CHARSET charset,const char* data,int data_len ,struct Maat_rule_t*result,int rule_num,struct Maat_hit_detail_t *hit_detail,int detail_num diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d6a144f..483ddf3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.5) set(MAAT_FRAME_MAJOR_VERSION 2) -set(MAAT_FRAME_MINOR_VERSION 6) +set(MAAT_FRAME_MINOR_VERSION 7) set(MAAT_FRAME_PATCH_VERSION 0) set(MAAT_FRAME_VERSION ${MAAT_FRAME_MAJOR_VERSION}.${MAAT_FRAME_MINOR_VERSION}.${MAAT_FRAME_PATCH_VERSION}) @@ -20,6 +20,7 @@ set_target_properties(maat_frame_static PROPERTIES CLEAN_DIRECT_OUTPUT 1) target_include_directories(maat_frame_static PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/inc_internal/) #target_include_directories(maat_frame_static PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/inc_internal/hiredis) target_link_libraries(maat_frame_static hiredis-vip-static) +target_link_libraries(maat_frame_static igraph-static) # Shared Library Output add_library(maat_frame_shared SHARED ${MAAT_SRC}) @@ -32,6 +33,7 @@ set_target_properties(maat_frame_shared PROPERTIES LINK_FLAGS "-Wl,--version-scr target_include_directories(maat_frame_shared PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/inc_internal/) target_include_directories(maat_frame_shared PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/inc_internal/hiredis) target_link_libraries(maat_frame_shared hiredis-vip-static ${MAAT_DEPEND_DYN_LIB}) +target_link_libraries(maat_frame_shared igraph-static ${MAAT_DEPEND_DYN_LIB}) install(FILES ${PROJECT_SOURCE_DIR}/inc/Maat_rule.h DESTINATION include/MESA/) install(FILES ${PROJECT_SOURCE_DIR}/inc/Maat_command.h DESTINATION include/MESA/) diff --git a/src/entry/Maat_api.cpp b/src/entry/Maat_api.cpp index ecdcb79..e332f45 100644 --- a/src/entry/Maat_api.cpp +++ b/src/entry/Maat_api.cpp @@ -16,7 +16,7 @@ #include "rulescan.h" #include "json2iris.h" -struct Maat_table_desc * acqurie_table(struct _Maat_feather_t* _feather,int table_id,enum MAAT_TABLE_TYPE expect_type) +struct Maat_table_desc * acqurie_table(struct _Maat_feather_t* _feather, int table_id, enum MAAT_TABLE_TYPE expect_type) { struct Maat_table_desc *p_table=NULL; if(table_id>MAX_TABLE_NUM) @@ -34,20 +34,20 @@ struct Maat_table_desc * acqurie_table(struct _Maat_feather_t* _feather,int tabl } if(p_table->table_type!=expect_type) { - if(expect_type!=TABLE_TYPE_EXPR|| - p_table->table_type!=TABLE_TYPE_EXPR_PLUS) + if((expect_type==TABLE_TYPE_EXPR && p_table->table_type!=TABLE_TYPE_EXPR_PLUS)|| + (expect_type==TABLE_TYPE_IP && p_table->table_type!=TABLE_TYPE_IP_PLUS)) { return NULL; } } return p_table; } -inline void INC_SCANNER_REF(Maat_scanner_t*scanner,int thread_num) +inline void INC_SCANNER_REF(Maat_scanner*scanner,int thread_num) { alignment_int64_array_add(scanner->ref_cnt, thread_num, 1); return; } -inline void DEC_SCANNER_REF(Maat_scanner_t*scanner,int thread_num) +inline void DEC_SCANNER_REF(Maat_scanner*scanner,int thread_num) { alignment_int64_array_add(scanner->ref_cnt, thread_num, -1); @@ -64,7 +64,8 @@ void Maat_clean_status(scan_status_t* mid) alignment_int64_array_add(_mid->feather->outer_mid_cnt,_mid->thread_num,-1); if(_mid->inner!=NULL) { - free(_mid->inner->hitted_group_id); + dynamic_array_destroy(_mid->inner->cur_hit_groups, NULL); + free(_mid->inner->all_hit_group_array); free(_mid->inner); alignment_int64_array_add(_mid->feather->inner_mid_cnt,_mid->thread_num,-1); } @@ -117,15 +118,17 @@ int insert_set_id(unsigned long long **set, size_t* size, size_t cnt, unsigned l } } size_t pickup_hit_region_from_compile(struct bool_expr *compile_hit, - const unsigned long long* hitted_id, size_t hit_cnt, int* region_pos, size_t size) + struct dynamic_array_t* hitted_id, size_t hit_cnt, int* region_pos, size_t size) { size_t i=0, j=0; size_t k=0; + unsigned long long group_id=0; for(i=0;i<hit_cnt;i++) { + group_id=(unsigned long long)dynamic_array_read(hitted_id, i); for(j=0; j<compile_hit->item_num; j++) - { - if(hitted_id[i]==compile_hit->items[j].item_id) + { + if(group_id==compile_hit->items[j].item_id) { region_pos[k]=i; k++; @@ -135,114 +138,111 @@ size_t pickup_hit_region_from_compile(struct bool_expr *compile_hit, } return k; } -void fill_maat_rule(struct Maat_rule_t *rule, const struct _head_Maat_rule_t* rule_head, const char* srv_def, int srv_def_len) +void fill_maat_rule(struct Maat_rule_t *rule, const struct Maat_rule_head* rule_head, const char* srv_def, int srv_def_len) { - memcpy(rule, rule_head, sizeof(struct _head_Maat_rule_t)); + memcpy(rule, rule_head, sizeof(struct Maat_rule_head)); memcpy(rule->service_defined, srv_def, MIN(srv_def_len,MAX_SERVICE_DEFINE_LEN)); return; } -static int compare_compile_id(const void *a, const void *b) +static int compare_compile_inner(const void *a, const void *b) { - struct Maat_rule_t *ra=(struct Maat_rule_t *)a; - struct Maat_rule_t *rb=(struct Maat_rule_t *)b; + const struct Maat_compile_group_relation *ra=*(const struct Maat_compile_group_relation **)a; + const struct Maat_compile_group_relation *rb=*(const struct Maat_compile_group_relation **)b; - return (rb->config_id-ra->config_id); + if(ra->group_cnt!=rb->group_cnt) + { + return (ra->group_cnt-rb->group_cnt); + } + else + { + return (rb->compile_id-ra->compile_id); + } } int region_compile(_Maat_feather_t*feather,struct _INNER_scan_status_t *_mid,int is_last_region,void* region_hit,int region_type_size,int group_offset,int region_hit_num,struct Maat_rule_t* result,_compile_result_t *rs_result, int size,int thread_num) { - int scan_ret=0,result_cnt=0; - int ret=0,i=0; + int scan_ret=0, result_cnt=0; + int ret=0, i=0, j=0; size_t r_in_c_cnt=0; - int shortcut_avilable_cnt=0; unsigned char has_not_flag=0; struct bool_matcher* bm=feather->scanner->bool_matcher_expr_compiler; - struct Maat_group_inner_t* group_rule=NULL; - struct Maat_compile_inner_t* array_mi_rule[MAX_SCANNER_HIT_NUM]; - struct Maat_compile_inner_t* _mi_rule=NULL; + struct Maat_group_inner* group_rule=NULL; + struct Maat_compile_group_relation* relation_array[MAX_SCANNER_HIT_NUM]; + struct Maat_compile_group_relation* relation=NULL; + int region_pos[MAX_SCANNER_HIT_NUM]; - _mid->cur_hit_cnt=0; + _mid->cur_hit_group_cnt=0; for(i=0;i<region_hit_num;i++) { - group_rule=*(struct Maat_group_inner_t**)((char*)region_hit+region_type_size*i+group_offset); + group_rule=*(struct Maat_group_inner**)((char*)region_hit+region_type_size*i+group_offset); if(group_rule->group_id<0) { continue; } - if(group_rule->compile_shortcut!=NULL&&group_rule->ref_cnt==1&&shortcut_avilable_cnt<MAX_SCANNER_HIT_NUM) - { - array_mi_rule[shortcut_avilable_cnt]=(struct Maat_compile_inner_t*)(group_rule->compile_shortcut); - shortcut_avilable_cnt++; + assert(group_rule->ref_by_children_cnt>=0); + assert(group_rule->ref_by_parent_cnt>=0); + for(j=0; j<group_rule->top_group_cnt; j++) + { + if(_mid->cur_hit_group_cnt<MAX_SCANNER_HIT_NUM) + { + dynamic_array_write(_mid->cur_hit_groups, _mid->cur_hit_group_cnt, (void*)group_rule->top_groups[j]); + _mid->cur_hit_group_cnt++; + } + ret=insert_set_id(&(_mid->all_hit_group_array), + &(_mid->all_hit_group_array_sz), + _mid->all_hit_group_cnt, + group_rule->top_groups[j]); + _mid->all_hit_group_cnt+=ret; } - _mid->cur_hit_id[_mid->cur_hit_cnt]=group_rule->group_id; - _mid->cur_hit_cnt++; - ret=insert_set_id(&(_mid->hitted_group_id), - &(_mid->hit_group_size), - _mid->hit_group_cnt, - group_rule->group_id); - _mid->hit_group_cnt+=ret; - } - if((region_hit_num>0 &&shortcut_avilable_cnt==region_hit_num) || - shortcut_avilable_cnt==MAX_SCANNER_HIT_NUM) - { - //short cut for rules contains one group - scan_ret=shortcut_avilable_cnt; - alignment_int64_array_add(feather->orphan_group_saving, thread_num, 1); } - else if(0&&shortcut_avilable_cnt==0&®ion_hit_num==1&&_mid->hit_group_cnt==1&&is_last_region==1) - { - //This shortcut is NO longger valid after bool macher support NOT-logic. - //short cut for last scan and combination rules - //region_hit_num==1 : for current scan hitted rules, one and each other group may statisfy a compile rule. - //_mid->hit_group_cnt==1: With pre scan hitted group rules, one group may staisfy a compile rule - scan_ret=0; - } - else + + scan_ret=bool_matcher_match(bm, thread_num, + _mid->all_hit_group_array, _mid->all_hit_group_cnt, + (void **)relation_array, MAX_SCANNER_HIT_NUM); + + if(scan_ret>1) { - scan_ret=bool_matcher_match(bm, thread_num, - _mid->hitted_group_id, _mid->hit_group_cnt, - (void **)array_mi_rule, MAX_SCANNER_HIT_NUM); + qsort(relation_array, scan_ret, sizeof(struct Maat_compile_group_relation**), + compare_compile_inner); } for(i=0;i<scan_ret&&result_cnt<size;i++) { - _mi_rule=array_mi_rule[i]; - if(_mi_rule==NULL) + relation=relation_array[i]; + if(relation==NULL) { continue; } - - if(0==pthread_rwlock_tryrdlock(&(_mi_rule->rwlock))) + assert(relation->magic_num==COMPILE_RELATION_MAGIC); + if(0==pthread_rwlock_tryrdlock(&(relation->rwlock))) { - if(_mi_rule->is_valid==1) + if(relation->compile) { - if(_mi_rule->not_group_cnt>0 && !is_last_region) + if(relation->not_group_cnt>0 && !is_last_region) { _mid->not_grp_compile_hitted_flag=1; } else { - make_group_set(_mi_rule, &(rs_result[result_cnt].group_set), &has_not_flag); - r_in_c_cnt=pickup_hit_region_from_compile(&(rs_result[result_cnt].group_set), _mid->cur_hit_id, _mid->cur_hit_cnt, + make_group_set(relation, &(rs_result[result_cnt].group_set), &has_not_flag); + r_in_c_cnt=pickup_hit_region_from_compile(&(rs_result[result_cnt].group_set), _mid->cur_hit_groups, _mid->cur_hit_group_cnt, region_pos, MAX_SCANNER_HIT_NUM); if(r_in_c_cnt>0 || //compile config hitted becasue of new reigon - _mid->cur_hit_cnt==0) //or ever hit a compile that refer a NOT-logic group + _mid->cur_hit_group_cnt==0) //or ever hit a compile that refer a NOT-logic group { - fill_maat_rule(&(result[result_cnt]), &(_mi_rule->db_c_rule->m_rule_head), - _mi_rule->db_c_rule->service_defined ,_mi_rule->db_c_rule->m_rule_head.serv_def_len); - rs_result[result_cnt].compile_id=_mi_rule->compile_id; + fill_maat_rule(&(result[result_cnt]), &(relation->compile->head), + relation->compile->service_defined ,relation->compile->head.serv_def_len); + rs_result[result_cnt].compile_id=relation->compile_id; result_cnt++; } } } - pthread_rwlock_unlock(&(_mi_rule->rwlock)); + pthread_rwlock_unlock(&(relation->rwlock)); } } if(result_cnt>0) { - qsort(result, result_cnt, sizeof(struct Maat_rule_t), - compare_compile_id); - alignment_int64_array_add(feather->hit_cnt,thread_num,1); + alignment_int64_array_add(feather->hit_cnt, thread_num, 1); } if(region_hit_num==0&&result_cnt>0) { @@ -252,39 +252,34 @@ int region_compile(_Maat_feather_t*feather,struct _INNER_scan_status_t *_mid,int return result_cnt; } -int exprid2region_id(struct Maat_group_inner_t* group_rule,int expr_id,int* district_id) +int exprid2region_id(struct Maat_group_inner* group_rule,int expr_id,int* district_id, Maat_scanner* scanner) { - int i=0,region_id=-1; - struct _Maat_region_inner_t* region_rule=NULL; + int region_id=-1; + struct Maat_region_inner* region_rule=NULL; assert(group_rule->group_id>=0); - pthread_mutex_lock(&(group_rule->mutex)); - for(i=0;i<group_rule->region_boundary;i++) + int array_idx=(int)(long)HASH_fetch_by_id(scanner->exprid_hash, expr_id); + pthread_mutex_lock(&(group_rule->mutex)); + assert(array_idx<group_rule->region_boundary); + region_rule=(struct Maat_region_inner*)dynamic_array_read(group_rule->regions, array_idx); + if(region_rule) { - region_rule=(struct _Maat_region_inner_t*)dynamic_array_read(group_rule->regions, i); - if(region_rule==NULL) - { - continue; - } - if(expr_id>=region_rule->expr_id_lb&&expr_id<=region_rule->expr_id_ub) - { - region_id=region_rule->region_id; - *district_id=region_rule->district_id; - break; - } + assert(expr_id>=region_rule->expr_id_lb&&expr_id<=region_rule->expr_id_ub); + region_id=region_rule->region_id; + *district_id=region_rule->district_id; } pthread_mutex_unlock(&(group_rule->mutex)); return region_id; } -int match_district(struct _OUTER_scan_status_t *_mid,scan_result_t *region_hit,int region_hit_num) +int match_district(struct _OUTER_scan_status_t *_mid,scan_result_t *region_hit,int region_hit_num, Maat_scanner* scanner) { - struct Maat_group_inner_t* group_rule=NULL; + struct Maat_group_inner* group_rule=NULL; int i=0; int district_id=-1,region_id=-1; int ret_region_num=region_hit_num; while(i<ret_region_num) { - group_rule=(struct Maat_group_inner_t*)(region_hit[i].tag); - region_id=exprid2region_id(group_rule, region_hit[i].expr_id,&district_id); + group_rule=(struct Maat_group_inner*)(region_hit[i].tag); + region_id=exprid2region_id(group_rule, region_hit[i].expr_id,&district_id, scanner); if(region_id>0&&district_id!=_mid->district_id) { ret_region_num--; @@ -368,7 +363,8 @@ int hit_pos_RS2Maat(struct sub_item_pos_t* maat_sub_item,int size,rule_result_t* int fill_region_hit_detail(const char* scan_buff,const _INNER_scan_status_t* _mid, scan_result_t *region_hit,int region_cnt, _compile_result_t *compile_hit,int compile_cnt, - struct Maat_hit_detail_t *hit_detail,int detail_num) + struct Maat_hit_detail_t *hit_detail,int detail_num, + struct Maat_scanner* scanner) { int i=0,j=0,k=0; char r_in_c_flag[region_cnt]; @@ -379,20 +375,20 @@ int fill_region_hit_detail(const char* scan_buff,const _INNER_scan_status_t* _mi memset(r_in_c_flag,0,sizeof(r_in_c_flag)); memset(region_pos,0,sizeof(region_pos)); - struct Maat_group_inner_t* group_rule=NULL; + struct Maat_group_inner* group_rule=NULL; //for each hitted compile cfg,find its region_ids for(i=0;i<compile_cnt&&i<detail_num;i++) { hit_detail[i].config_id=compile_hit[i].compile_id; - r_in_c_cnt=pickup_hit_region_from_compile(&(compile_hit[i].group_set), _mid->cur_hit_id, _mid->cur_hit_cnt, + r_in_c_cnt=pickup_hit_region_from_compile(&(compile_hit[i].group_set), _mid->cur_hit_groups, _mid->cur_hit_group_cnt, region_pos, MAX_SCANNER_HIT_NUM); assert(r_in_c_cnt>0);//previous hitted compile was elimited in region_compile for(j=0,k=0;j<r_in_c_cnt&&k<MAAT_MAX_HIT_RULE_NUM;j++) { pos=region_pos[j]; r_in_c_flag[pos]=1; - group_rule=(struct Maat_group_inner_t*)(region_hit[pos].tag); - region_id=exprid2region_id(group_rule,region_hit[pos].expr_id,&district_id); + group_rule=(struct Maat_group_inner*)(region_hit[pos].tag); + region_id=exprid2region_id(group_rule,region_hit[pos].expr_id, &district_id, scanner); if(region_id<0) { continue; @@ -411,10 +407,10 @@ int fill_region_hit_detail(const char* scan_buff,const _INNER_scan_status_t* _mi { if(r_in_c_flag[k]==0) { - group_rule=(struct Maat_group_inner_t*)(region_hit[k].tag); + group_rule=(struct Maat_group_inner*)(region_hit[k].tag); hit_detail[j].config_id=-2; hit_detail[j].hit_region_cnt=1; - hit_detail[j].region_pos[0].region_id=exprid2region_id(group_rule,region_hit[k].expr_id,&district_id); + hit_detail[j].region_pos[0].region_id=exprid2region_id(group_rule,region_hit[k].expr_id,&district_id, scanner); hit_detail[j].region_pos[0].sub_item_num=region_hit[k].rnum; hit_pos_RS2Maat(hit_detail[j].region_pos[0].sub_item_pos,MAAT_MAX_EXPR_ITEM_NUM, region_hit[k].result,region_hit[k].rnum,scan_buff); @@ -427,10 +423,11 @@ struct _INNER_scan_status_t* _make_inner_status(void) { struct _INNER_scan_status_t* inner_mid=NULL; inner_mid=ALLOC(struct _INNER_scan_status_t, 1); - inner_mid->cur_hit_cnt=0; - inner_mid->hit_group_cnt=0; - inner_mid->hit_group_size=4; - inner_mid->hitted_group_id= ALLOC(unsigned long long, inner_mid->hit_group_size); + inner_mid->cur_hit_group_cnt=0; + inner_mid->cur_hit_groups=dynamic_array_create(32, 32); + inner_mid->all_hit_group_cnt=0; + inner_mid->all_hit_group_array_sz=4; + inner_mid->all_hit_group_array= ALLOC(unsigned long long, inner_mid->all_hit_group_array_sz); return inner_mid; } struct _OUTER_scan_status_t* _make_outer_status(_Maat_feather_t *feather, int thread_num) @@ -503,7 +500,12 @@ Maat_feather_t Maat_feather(int max_thread_num,const char* table_info_path,void* return NULL; } _Maat_feather_t* feather=ALLOC(struct _Maat_feather_t, 1); - feather->table_cnt=read_table_description(feather->p_table_info, MAX_TABLE_NUM,table_info_path,max_thread_num,logger); + feather->table_cnt=read_table_description(feather->p_table_info, MAX_TABLE_NUM, table_info_path, max_thread_num, logger); + if(feather->table_cnt==0) + { + free(feather); + return NULL; + } feather->map_tablename2id=map_create(); int i=0,j=0,ret=0; for(i=0;i<MAX_TABLE_NUM;i++) @@ -543,7 +545,6 @@ Maat_feather_t Maat_feather(int max_thread_num,const char* table_info_path,void* feather->outer_mid_cnt=alignment_int64_array_alloc(max_thread_num); feather->inner_mid_cnt=alignment_int64_array_alloc(max_thread_num); feather->hit_cnt=alignment_int64_array_alloc(max_thread_num); - feather->orphan_group_saving=alignment_int64_array_alloc(max_thread_num); feather->not_grp_hit_cnt=alignment_int64_array_alloc(max_thread_num); feather->maat_version=0; feather->last_full_version=0; @@ -636,12 +637,12 @@ int Maat_set_feather_opt(Maat_feather_t feather,enum MAAT_INIT_OPT type,const vo break; case MAAT_OPT_JSON_FILE_PATH: assert(_feather->input_mode==SOURCE_NONE); - ret=json2iris((const char*)value - ,_feather->compile_tn,_feather->group_tn - ,NULL - ,_feather->json_ctx.iris_file - ,sizeof(_feather->json_ctx.iris_file) - ,_feather->logger); + ret=json2iris((const char*)value, + _feather->compile_tn,_feather->group_tn, + NULL, + _feather->json_ctx.iris_file, + sizeof(_feather->json_ctx.iris_file), + _feather->logger); if(ret<0) { return -1; @@ -1042,19 +1043,21 @@ int Maat_table_callback_register(Maat_feather_t feather,short table_id, void rule_ex_data_new_cb(const uchar * key, uint size, void * data, void * user) { struct compile_ex_data_idx *ex_desc=(struct compile_ex_data_idx*)user; - struct Maat_compile_inner_t *compile_inner=(struct Maat_compile_inner_t *)data; + struct Maat_compile_group_relation *relation=(struct Maat_compile_group_relation *)data; + struct Maat_compile_rule* compile_rule=relation->compile; MAAT_RULE_EX_DATA ad=NULL; - if(compile_inner->ref_table==NULL || compile_inner->ref_table->table_id!=ex_desc->table_id || compile_inner->db_c_rule==NULL) + if(compile_rule==NULL|| compile_rule->ref_table->table_id!=ex_desc->table_id) { return; } - pthread_rwlock_wrlock(&(compile_inner->rwlock)); - ad=rule_ex_data_new(&(compile_inner->db_c_rule->m_rule_head), - compile_inner->db_c_rule->service_defined, + + pthread_rwlock_wrlock(&(relation->rwlock)); + ad=rule_ex_data_new(&(relation->compile->head), + relation->compile->service_defined, ex_desc); - compile_inner->ads[ex_desc->idx]=ad; - pthread_rwlock_unlock(&(compile_inner->rwlock)); + compile_rule->ads[ex_desc->idx]=ad; + pthread_rwlock_unlock(&(relation->rwlock)); return; } int Maat_rule_get_ex_new_index(Maat_feather_t feather, const char* compile_table_name, @@ -1104,22 +1107,24 @@ failed: MAAT_RULE_EX_DATA Maat_rule_get_ex_data(Maat_feather_t feather, const struct Maat_rule_t* rule, int idx) { struct _Maat_feather_t *_feather=(struct _Maat_feather_t *)feather; - struct Maat_compile_inner_t *compile_inner=NULL; + struct Maat_compile_group_relation *relation=NULL; + struct Maat_compile_rule* compile=NULL; const struct compile_table_desc* compile_desc=NULL; const struct compile_ex_data_idx* ex_desc=NULL; MAAT_RULE_EX_DATA ad=NULL; - compile_inner=(struct Maat_compile_inner_t *)HASH_fetch_by_id(_feather->scanner->compile_hash, rule->config_id); - if(compile_inner==NULL) + relation=(struct Maat_compile_group_relation *)HASH_fetch_by_id(_feather->scanner->compile_hash, rule->config_id); + if(relation==NULL||relation->compile==NULL) { return NULL; } - pthread_rwlock_rdlock(&(compile_inner->rwlock)); - compile_desc=&(compile_inner->ref_table->compile); + pthread_rwlock_rdlock(&(relation->rwlock)); + compile=relation->compile; + compile_desc=&(compile->ref_table->compile); assert(idx<compile_desc->ex_data_num); ex_desc=compile_desc->ex_desc+idx; - ex_desc->dup_func(ex_desc->idx, &ad, compile_inner->ads+idx, ex_desc->argl,ex_desc->argp); - pthread_rwlock_unlock(&(compile_inner->rwlock)); + ex_desc->dup_func(ex_desc->idx, &ad, compile->ads+idx, ex_desc->argl,ex_desc->argp); + pthread_rwlock_unlock(&(relation->rwlock)); return ad; } struct wrap_plugin_EX_data @@ -1152,7 +1157,7 @@ MESA_htable_handle wrap_plugin_EX_hash_new(long long estimate_size, Maat_plugin_ MESA_htable_create_args_t hargs; memset(&hargs,0,sizeof(hargs)); - hargs.thread_safe=0; + hargs.thread_safe=8; hargs.hash_slot_size = slot_size; hargs.max_elem_num = 0; hargs.eliminate_type = HASH_ELIMINATE_ALGO_FIFO; @@ -1310,7 +1315,6 @@ MAAT_PLUGIN_EX_DATA Maat_plugin_get_EX_data(Maat_feather_t feather, int table_id return NULL; } table_rt= _feather->scanner->table_rt[table_id]; - pthread_rwlock_rdlock(&table_rt->plugin.rwlock); wrap_data=(struct wrap_plugin_EX_data*)MESA_htable_search(table_rt->plugin.key2ex_hash, (const unsigned char*)key, strlen(key)); if(wrap_data!=NULL) @@ -1318,7 +1322,6 @@ MAAT_PLUGIN_EX_DATA Maat_plugin_get_EX_data(Maat_feather_t feather, int table_id plugin_desc->ex_desc.dup_func(table_id, &(exdata), &(wrap_data->exdata), plugin_desc->ex_desc.argl, plugin_desc->ex_desc.argp); } - pthread_rwlock_unlock(&table_rt->plugin.rwlock); return exdata; } @@ -1337,7 +1340,7 @@ int Maat_full_scan_string_detail(Maat_feather_t feather,int table_id struct Maat_table_desc *p_table=NULL; struct expr_table_desc* expr_desc=NULL; struct timespec start,end; - Maat_scanner_t* my_scanner=NULL; + Maat_scanner* my_scanner=NULL; if(data==NULL||data_len<=0) { return 0; @@ -1410,7 +1413,7 @@ int Maat_full_scan_string_detail(Maat_feather_t feather,int table_id } if(hit_region_cnt>0&&p_table->table_type==TABLE_TYPE_EXPR_PLUS) { - hit_region_cnt=match_district(_mid,region_result,hit_region_cnt); + hit_region_cnt=match_district(_mid,region_result,hit_region_cnt, my_scanner); } if(hit_region_cnt>0 || scan_status_should_compile_NOT(_mid)) { @@ -1435,7 +1438,7 @@ int Maat_full_scan_string_detail(Maat_feather_t feather,int table_id *detail_ret=fill_region_hit_detail(data,_mid->inner, region_result,hit_region_cnt, compile_result,compile_ret, - hit_detail,detail_num); + hit_detail,detail_num, my_scanner); } } if(_feather->perf_on==1) @@ -1477,7 +1480,7 @@ int Maat_scan_intval(Maat_feather_t feather,int table_id scan_result_t *region_result=NULL; _compile_result_t compile_result[rule_num]; struct _Maat_feather_t* _feather=(_Maat_feather_t*)feather; - struct Maat_scanner_t* my_scanner=NULL; + struct Maat_scanner* my_scanner=NULL; intval_scan_data.rule_type=RULETYPE_INT; intval_scan_data.sub_type=make_sub_type(table_id,CHARSET_NONE, 0); intval_scan_data.int_data=intval; @@ -1567,7 +1570,7 @@ int Maat_scan_proto_addr(Maat_feather_t feather,int table_id Maat_table_desc* p_table=NULL; struct _Maat_feather_t* _feather=(_Maat_feather_t*)feather; - struct Maat_scanner_t* my_scanner=NULL; + struct Maat_scanner* my_scanner=NULL; struct timespec start,end; if(_feather->perf_on==1) { @@ -1688,7 +1691,7 @@ int Maat_scan_addr(Maat_feather_t feather,int table_id stream_para_t Maat_stream_scan_string_start(Maat_feather_t feather,int table_id,int thread_num) { struct _Maat_feather_t* _feather=(_Maat_feather_t*)feather; - struct Maat_scanner_t* scanner=NULL; + struct Maat_scanner* scanner=NULL; struct Maat_table_desc *p_table=NULL; assert(thread_num<_feather->scan_thread_num); @@ -1746,7 +1749,7 @@ int Maat_stream_scan_string_detail(stream_para_t* stream_para ,int* detail_ret,scan_status_t* mid) { struct _stream_para_t* sp=(struct _stream_para_t*)(*stream_para); - struct Maat_scanner_t* scanner=sp->feather->scanner; + struct Maat_scanner* scanner=sp->feather->scanner; int sub_type=0; int region_ret=0,hit_region_cnt=0,compile_ret=0; @@ -1855,7 +1858,7 @@ int Maat_stream_scan_string_detail(stream_para_t* stream_para } if(hit_region_cnt>0&&p_table->table_type==TABLE_TYPE_EXPR_PLUS) { - hit_region_cnt=match_district(_mid,region_result,hit_region_cnt); + hit_region_cnt=match_district(_mid, region_result, hit_region_cnt, scanner); } if(hit_region_cnt>0 || scan_status_should_compile_NOT(_mid)) { @@ -1882,14 +1885,14 @@ int Maat_stream_scan_string_detail(stream_para_t* stream_para *detail_ret=fill_region_hit_detail(sp->scan_buff,_mid->inner, region_result,hit_region_cnt, compile_result,compile_ret, - hit_detail,detail_num); + hit_detail,detail_num, scanner); } else { *detail_ret=fill_region_hit_detail(data,_mid->inner, region_result,hit_region_cnt, compile_result,compile_ret, - hit_detail,detail_num); + hit_detail,detail_num, scanner); } } } @@ -1929,7 +1932,7 @@ int Maat_stream_scan_string(stream_para_t* stream_para void Maat_stream_scan_string_end(stream_para_t* stream_para) { struct _stream_para_t* sp=(struct _stream_para_t*)(*stream_para); - struct Maat_scanner_t* scanner=sp->feather->scanner; + struct Maat_scanner* scanner=sp->feather->scanner; struct Maat_table_runtime* table_rt=NULL; if(scanner!=NULL) { @@ -1971,7 +1974,7 @@ void Maat_stream_scan_string_end(stream_para_t* stream_para) stream_para_t Maat_stream_scan_digest_start(Maat_feather_t feather,int table_id,unsigned long long total_len,int thread_num) { struct _Maat_feather_t* _feather=(_Maat_feather_t*)feather; - struct Maat_scanner_t* scanner=NULL; + struct Maat_scanner* scanner=NULL; sfh_instance_t * tmp_fuzzy_handle=NULL; struct Maat_table_desc *p_table=NULL; p_table=acqurie_table(_feather, table_id, TABLE_TYPE_DIGEST); @@ -2130,7 +2133,7 @@ fast_out: void Maat_stream_scan_digest_end(stream_para_t* stream_para) { struct _stream_para_t* sp=(struct _stream_para_t*)(*stream_para); - struct Maat_scanner_t* scanner=sp->feather->scanner; + struct Maat_scanner* scanner=sp->feather->scanner; struct Maat_table_runtime *table_rt=sp->feather->scanner->table_rt[sp->table_id]; alignment_int64_array_add(table_rt->stream_num, sp->thread_num,-1); if(scanner!=NULL) @@ -2153,11 +2156,11 @@ int Maat_read_rule(Maat_feather_t feather, const struct Maat_rule_t* rule, enum { int ret=0; struct _Maat_feather_t *_feather=(struct _Maat_feather_t *)feather; - struct Maat_compile_inner_t *compile_inner=NULL; + struct Maat_compile_group_relation *compile_inner=NULL; switch(type) { case MAAT_RULE_SERV_DEFINE: - compile_inner=(struct Maat_compile_inner_t *)HASH_fetch_by_id(_feather->scanner->compile_hash, rule->config_id); + compile_inner=(struct Maat_compile_group_relation *)HASH_fetch_by_id(_feather->scanner->compile_hash, rule->config_id); if(compile_inner==NULL) { ret=0; @@ -2165,8 +2168,8 @@ int Maat_read_rule(Maat_feather_t feather, const struct Maat_rule_t* rule, enum else { pthread_rwlock_rdlock(&(compile_inner->rwlock)); - ret=MIN(size,compile_inner->db_c_rule->m_rule_head.serv_def_len); - memcpy(value,compile_inner->db_c_rule->service_defined,ret); + ret=MIN(size,compile_inner->compile->head.serv_def_len); + memcpy(value,compile_inner->compile->service_defined,ret); pthread_rwlock_unlock(&(compile_inner->rwlock)); } break; @@ -2227,7 +2230,7 @@ int Maat_similar_scan_string(Maat_feather_t feather,int table_id GIE_result_t region_result[MAX_SCANNER_HIT_NUM]; _compile_result_t compile_result[rule_num]; struct _Maat_feather_t* _feather=(_Maat_feather_t*)feather; - struct Maat_scanner_t* my_scanner=NULL; + struct Maat_scanner* my_scanner=NULL; Maat_table_desc* p_table=NULL; struct timespec start,end; if(_feather->perf_on==1) diff --git a/src/entry/Maat_command.cpp b/src/entry/Maat_command.cpp index cbeebed..a86d303 100644 --- a/src/entry/Maat_command.cpp +++ b/src/entry/Maat_command.cpp @@ -192,6 +192,9 @@ int get_valid_flag_offset(const char* line, enum MAAT_TABLE_TYPE type,int valid_ case TABLE_TYPE_IP:
column_seq=14;
break;
+ case TABLE_TYPE_IP_PLUS:
+ column_seq=18;
+ break;
case TABLE_TYPE_COMPILE:
column_seq=8;
break;
@@ -239,13 +242,39 @@ int invalidate_line(char* line, enum MAAT_TABLE_TYPE type,int valid_column_seq) line[i]='0';
return 0;
}
-void serialize_region(const struct Maat_region_t* p,int group_id, char* buff,int size)
+void serialize_group(const struct Maat_group_t* p_group, enum MAAT_OPERATION op, char* buff, size_t sz)
+{
+ if(op==MAAT_OP_RENEW_TIMEOUT) op=MAAT_OP_ADD;
+ snprintf(buff, sz, "%d\t%d\t%d\t%d\t%d", p_group->group_id,
+ p_group->parent_id,
+ op,
+ p_group->not_flag,
+ p_group->parent_type);
+ return;
+}
+void serialize_compile(const struct Maat_rule_t* p_m_rule, const char* huge_service_defined, int group_num, enum MAAT_OPERATION op, char* buff, size_t sz)
+{
+ if(op==MAAT_OP_RENEW_TIMEOUT) op=MAAT_OP_ADD;
+ const char* service_define=huge_service_defined?huge_service_defined:(strlen(p_m_rule->service_defined)?p_m_rule->service_defined:"null");
+
+ snprintf(buff, sz,"%d\t%d\t%hhd\t%hhd\t%hhd\t0\t%s\t%d\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,
+ service_define,
+ op,
+ group_num);
+ return;
+}
+void serialize_region(const struct Maat_region_t* p, int group_id, char* buff, size_t sz)
{
- UNUSED int ret=0;
+ UNUSED size_t ret=0;
switch(p->region_type)
{
case REGION_IP:
- ret=snprintf(buff,size,"%d\t%d\t%d\t%s\t%s\t%hu\t%hu\t%s\t%s\t%hu\t%hu\t%d\t%d\t1"
+ ret=snprintf(buff,sz,"%d\t%d\t%d\t%s\t%s\t%hu\t%hu\t%s\t%s\t%hu\t%hu\t%d\t%d\t1"
,p->region_id
,group_id
,p->ip_rule.addr_type
@@ -263,7 +292,7 @@ void serialize_region(const struct Maat_region_t* p,int group_id, char* buff,int case REGION_EXPR:
if(p->expr_rule.district==NULL)
{
- ret=snprintf(buff,size,"%d\t%d\t%s\t%d\t%d\t%d\t1"
+ ret=snprintf(buff,sz,"%d\t%d\t%s\t%d\t%d\t%d\t1"
,p->region_id
,group_id
,p->expr_rule.keywords
@@ -273,7 +302,7 @@ void serialize_region(const struct Maat_region_t* p,int group_id, char* buff,int }
else //expr_plus
{
- ret=snprintf(buff,size,"%d\t%d\t%s\t%s\t%d\t%d\t%d\t1"
+ ret=snprintf(buff,sz,"%d\t%d\t%s\t%s\t%d\t%d\t%d\t1"
,p->region_id
,group_id
,p->expr_rule.keywords
@@ -284,14 +313,14 @@ void serialize_region(const struct Maat_region_t* p,int group_id, char* buff,int }
break;
case REGION_INTERVAL:
- ret=snprintf(buff,size,"%d\t%d\t%u\t%u\t1"
+ ret=snprintf(buff,sz,"%d\t%d\t%u\t%u\t1"
,p->region_id
,group_id
,p->interval_rule.low_boundary
,p->interval_rule.up_boundary);
break;
case REGION_DIGEST:
- ret=snprintf(buff,size,"%d\t%d\t%llu\t%s\t%hd\t1"
+ ret=snprintf(buff,sz,"%d\t%d\t%llu\t%s\t%hd\t1"
,p->region_id
,group_id
,p->digest_rule.orgin_len
@@ -299,7 +328,7 @@ void serialize_region(const struct Maat_region_t* p,int group_id, char* buff,int ,p->digest_rule.confidence_degree);
break;
case REGION_SIMILARITY:
- ret=snprintf(buff,size,"%d\t%d\t%s\t%hd\t1"
+ ret=snprintf(buff,sz,"%d\t%d\t%s\t%hd\t1"
,p->region_id
,group_id
,p->similarity_rule.target
@@ -308,7 +337,7 @@ void serialize_region(const struct Maat_region_t* p,int group_id, char* buff,int default:
assert(0);
}
- assert(ret<size);
+ assert(ret<sz);
return;
}
void empty_serial_rules(struct serial_rule_t* rule)
@@ -329,15 +358,15 @@ void empty_serial_rules(struct serial_rule_t* rule) memset(rule,0,sizeof(struct serial_rule_t));
return;
}
-void set_serial_rule(struct serial_rule_t* rule,enum MAAT_OPERATION op,int rule_id,int label_id,const char* table_name,const char* line, long long timeout)
+void set_serial_rule(struct serial_rule_t* rule, enum MAAT_OPERATION op,int rule_id,int label_id,const char* table_name,const char* line, long long timeout)
{
+ memset(rule, 0, sizeof(struct serial_rule_t));
rule->op=op;
rule->rule_id=rule_id;
rule->label_id=label_id;
rule->timeout=timeout;
assert(strlen(table_name)<sizeof(rule->table_name));
- memset(rule->table_name, 0, sizeof(rule->table_name));
- memcpy(rule->table_name,table_name,strlen(table_name));
+ strncpy(rule->table_name, table_name, sizeof(rule->table_name));
if(line!=NULL)
{
rule->table_line=_maat_strdup(line);
@@ -836,35 +865,35 @@ int reconstruct_cmd(struct _Maat_feather_t *feather, struct _Maat_cmd_inner_t* _ struct Maat_group_t* group_cmd=NULL;
struct Maat_region_t* region_cmd=NULL;
- struct Maat_compile_inner_t *compile_inner=NULL;
- struct Maat_group_inner_t* group_inner=NULL;
- struct _Maat_region_inner_t* region_inner=NULL;
+ struct Maat_compile_group_relation *relation=NULL;
+ struct Maat_group_inner* group_inner=NULL;
+ struct Maat_region_inner* region_inner=NULL;
void* logger=feather->logger;
int config_id=cmd->compile.config_id;
if(feather->scanner==NULL)
{
- MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_command
+ MESA_handle_runtime_log(logger, RLOG_LV_INFO, maat_command
,"MAAT not ready.");
return -1;
}
- compile_inner=(struct Maat_compile_inner_t *)HASH_fetch_by_id(feather->scanner->compile_hash, config_id);
- //Operation on compile_inner is thread safe, no immediate memory free when delete a compile rule or a scanner.
- //In another words, if the compile_inner is accessable from compile means, its was valid in at least 10 seconds (garbage bury).
- if(compile_inner==NULL)
+ relation=(struct Maat_compile_group_relation *)HASH_fetch_by_id(feather->scanner->compile_hash, config_id);
+ //Operation on relation is thread safe, no immediate memory free when delete a compile rule or a scanner.
+ //In another words, if the relation is accessable from compile means, its was valid in at least 10 seconds (garbage bury).
+ if(relation==NULL)
{
- MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_command
+ MESA_handle_runtime_log(logger, RLOG_LV_INFO, maat_command
,"config %d not exist."
,config_id);
return -1;
}
- pthread_rwlock_rdlock(&(compile_inner->rwlock));
- cmd->group_num=compile_inner->group_cnt;
+ pthread_rwlock_rdlock(&(relation->rwlock));
+ cmd->group_num=relation->group_cnt;
assert(cmd->groups==NULL);
- cmd->groups=(struct Maat_group_t*)calloc(sizeof(struct Maat_group_t),cmd->group_num);
- for(i=0;i<compile_inner->group_boundary;i++)
+ cmd->groups=ALLOC(struct Maat_group_t, cmd->group_num);
+ for(i=0;i<relation->group_boundary;i++)
{
- group_inner=(struct Maat_group_inner_t*)dynamic_array_read(compile_inner->groups,i);
+ group_inner=(struct Maat_group_inner*)dynamic_array_read(relation->groups,i);
if(group_inner==NULL)
{
continue;
@@ -872,15 +901,15 @@ int reconstruct_cmd(struct _Maat_feather_t *feather, struct _Maat_cmd_inner_t* _ group_cmd=&(cmd->groups[grp_idx]);
group_cmd->group_id=group_inner->group_id;
- if(group_inner->ref_cnt>1)
+ if(group_inner->ref_by_parent_cnt>1)
{
continue;
}
group_cmd->region_num=group_inner->region_cnt;
- group_cmd->regions=(struct Maat_region_t*)calloc(sizeof(struct Maat_region_t),group_cmd->region_num);
+ group_cmd->regions=ALLOC(struct Maat_region_t, group_cmd->region_num);
for(j=0;j<group_inner->region_boundary;j++)
{
- region_inner=(struct _Maat_region_inner_t*)dynamic_array_read(group_inner->regions,j);
+ region_inner=(struct Maat_region_inner*)dynamic_array_read(group_inner->regions,j);
if(region_inner==NULL)
{
continue;
@@ -893,11 +922,11 @@ int reconstruct_cmd(struct _Maat_feather_t *feather, struct _Maat_cmd_inner_t* _ }
grp_idx++;
}
- pthread_rwlock_unlock(&(compile_inner->rwlock));
+ pthread_rwlock_unlock(&(relation->rwlock));
return 0;
}
-int build_serial_rule(_Maat_feather_t *feather,struct _Maat_cmd_inner_t* _cmd,struct serial_rule_t* list, int size)
+int build_serial_rule(_Maat_feather_t *feather,struct _Maat_cmd_inner_t* _cmd, struct serial_rule_t* list, int size)
{
struct Maat_group_t* p_group=NULL;
struct Maat_region_t* p_region=NULL;
@@ -915,19 +944,12 @@ int build_serial_rule(_Maat_feather_t *feather,struct _Maat_cmd_inner_t* _cmd,st }
if(op==MAAT_OP_ADD)
{
- 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
- ,(_cmd->huge_service_defined!=NULL)?(_cmd->huge_service_defined):(p_m_rule->service_defined)
- ,cmd->group_num);
- set_serial_rule(list+rule_num,MAAT_OP_ADD,cmd->compile.config_id,cmd->label_id,feather->compile_tn,line,timeout);
-
+ serialize_compile(p_m_rule, _cmd->huge_service_defined, cmd->group_num, MAAT_OP_ADD, line, sizeof(line));
+ set_serial_rule(list+rule_num, MAAT_OP_ADD, cmd->compile.config_id, cmd->label_id, feather->compile_tn, line, timeout);
}
else
{
- set_serial_rule(list+rule_num,op,cmd->compile.config_id,cmd->label_id,feather->compile_tn,NULL,timeout);
+ set_serial_rule(list+rule_num, op, cmd->compile.config_id, cmd->label_id, feather->compile_tn, NULL, timeout);
}
rule_num++;
for(i=0;i<cmd->group_num;i++)
@@ -940,9 +962,10 @@ int build_serial_rule(_Maat_feather_t *feather,struct _Maat_cmd_inner_t* _cmd,st p_group->group_id=feather->base_grp_seq;
feather->base_grp_seq++;
}
- snprintf(line,sizeof(line),"%d\t%d\t1",p_group->group_id
- ,p_m_rule->config_id);
- set_serial_rule(list+rule_num,MAAT_OP_ADD,p_group->group_id,0,feather->group_tn,line,timeout);
+ p_group->parent_id=p_m_rule->config_id;
+ p_group->parent_type=PARENT_TYPE_COMPILE;
+ serialize_group(p_group, MAAT_OP_ADD, line, sizeof(line));
+ set_serial_rule(list+rule_num, MAAT_OP_ADD, p_group->group_id, 0, feather->group_tn, line, timeout);
}
else
{
@@ -1358,10 +1381,10 @@ int fix_table_name(_Maat_feather_t* feather,struct Maat_cmd_t* cmd) struct Maat_region_t* p_region=NULL;
enum MAAT_TABLE_TYPE table_type;
- struct Maat_compile_inner_t *compile_rule=NULL;
+ struct Maat_compile_group_relation *compile_rule=NULL;
if(feather->scanner!=NULL)
{
- compile_rule=(struct Maat_compile_inner_t*)HASH_fetch_by_id(feather->scanner->compile_hash, cmd->compile.config_id);
+ compile_rule=(struct Maat_compile_group_relation*)HASH_fetch_by_id(feather->scanner->compile_hash, cmd->compile.config_id);
if(compile_rule!=NULL)
{
MESA_handle_runtime_log(feather->logger,RLOG_LV_FATAL,maat_module
@@ -2056,8 +2079,8 @@ int Maat_cmd_set_group(Maat_feather_t feather,int group_id, const struct Maat_re {
return -1;
}
- //struct Maat_group_inner_t* group_inner=NULL;
- //group_inner=(struct Maat_group_inner_t*)HASH_fetch_by_id(_feather->scanner->group_hash, group_id);
+ //struct Maat_group_inner* group_inner=NULL;
+ //group_inner=(struct Maat_group_inner*)HASH_fetch_by_id(_feather->scanner->group_hash, group_id);
//NOT implemented yet.
assert(0);
return 0;
@@ -2371,7 +2394,7 @@ int Maat_cmd_commit(Maat_feather_t feather) if(_feather->AUTO_NUMBERING_ON==1)
{
- data_reply=_wrap_redisCommand(write_ctx,"INCRBY SEQUENCE_REGION %d",new_region_num);
+ data_reply=_wrap_redisCommand(write_ctx,"INCRBY %s %d", mr_region_id_var, new_region_num);
if(data_reply->type!=REDIS_REPLY_INTEGER)
{
freeReplyObject(data_reply);
@@ -2381,7 +2404,7 @@ int Maat_cmd_commit(Maat_feather_t feather) _feather->base_rgn_seq=data_reply->integer-new_region_num;
freeReplyObject(data_reply);
- data_reply=_wrap_redisCommand(write_ctx,"INCRBY SEQUENCE_GROUP %d",new_group_num);
+ data_reply=_wrap_redisCommand(write_ctx,"INCRBY %s %d", mr_group_id_var, new_group_num);
if(data_reply->type!=REDIS_REPLY_INTEGER)
{
freeReplyObject(data_reply);
@@ -2445,17 +2468,30 @@ long long Maat_cmd_incrby(Maat_feather_t feather,const char* key, int increment) freeReplyObject(data_reply);
return result;
}
+int Maat_cmd_get_new_group_id(Maat_feather_t feather)
+{
+ int group_id=0;
+ group_id=(int) Maat_cmd_incrby(feather, mr_group_id_var, 1);
+ return group_id;
+}
+int Maat_cmd_get_new_region_id(Maat_feather_t feather)
+{
+ int region_id=0;
+ region_id=(int) Maat_cmd_incrby(feather, mr_region_id_var, 1);
+ return region_id;
+}
+
void Maat_cmd_key_free(struct Maat_cmd_key**keys, int size)
{
int i=0;
struct Maat_cmd_key* p=*keys;
- for(i=0; i<size; i++)
+ for(i=0; i<size; i++, p++)
{
free(p->table_name);
p->table_name=NULL;
p->rule_id=0;
}
- free(p);
+ free(*keys);
*keys=NULL;
return;
}
@@ -2547,9 +2583,9 @@ int redis_flush_DB(redisContext* ctx, int db_index, void* logger) append_cmd_cnt++;
redisAppendCommand(ctx,"SET MAAT_PRE_VER %lld",maat_redis_version);
append_cmd_cnt++;
- redisAppendCommand(ctx,"SET SEQUENCE_REGION 1",maat_redis_version);
+ redisAppendCommand(ctx,"SET %s 1", mr_region_id_var);
append_cmd_cnt++;
- redisAppendCommand(ctx,"SET SEQUENCE_GROUP 1",maat_redis_version);
+ redisAppendCommand(ctx,"SET %s 1", mr_group_id_var);
append_cmd_cnt++;
redisAppendCommand(ctx,"EXEC");
append_cmd_cnt++;
@@ -2571,6 +2607,41 @@ int redis_flush_DB(redisContext* ctx, int db_index, void* logger) }
return redis_transaction_success;
}
+static int _Maat_command_set_one_line(struct _Maat_feather_t* _feather, enum MAAT_OPERATION op, int id, const char* table_name, const char* line)
+{
+ redisContext* write_ctx=get_redis_ctx_for_write(_feather);
+ _feather->server_time=redis_server_time(write_ctx);
+ struct serial_rule_t s_rule;
+ set_serial_rule(&s_rule, op, id, 0, table_name, line, 0);
+ int transaction_success=0;
+ transaction_success=exec_serial_rule(write_ctx, &s_rule, 1, _feather->server_time, _feather->logger);
+ empty_serial_rules(&s_rule);
+ return transaction_success;
+}
+int Maat_command_raw_set_compile(Maat_feather_t feather, enum MAAT_OPERATION op, const struct Maat_rule_t* compile, const char* table_name, const char * huge_service_defined, int group_num)
+{
+ struct _Maat_feather_t* _feather=(struct _Maat_feather_t*)feather;
+ char line[MAX_TABLE_LINE_SIZE];
+ serialize_compile(compile, huge_service_defined, group_num, op, line, sizeof(line));
+ int ret=_Maat_command_set_one_line(_feather, op, compile->config_id, table_name, line);
+ return ret;
+}
+int Maat_command_raw_set_region(Maat_feather_t feather, enum MAAT_OPERATION op, const struct Maat_region_t* region, int group_id)
+{
+ struct _Maat_feather_t* _feather=(struct _Maat_feather_t*)feather;
+ char line[MAX_TABLE_LINE_SIZE];
+ serialize_region(region, group_id, line, sizeof(line));
+ int ret=_Maat_command_set_one_line(_feather, op, region->region_id, region->table_name, line);
+ return ret;
+}
+int Maat_command_raw_set_group(Maat_feather_t feather, enum MAAT_OPERATION op, const struct Maat_group_t* group)
+{
+ struct _Maat_feather_t* _feather=(struct _Maat_feather_t*)feather;
+ char line[MAX_TABLE_LINE_SIZE];
+ serialize_group(group, op, line, sizeof(line));
+ int ret=_Maat_command_set_one_line(_feather, op, group->group_id*1024*1204+group->parent_id, group->table_name, line);
+ return ret;
+}
int Maat_cmd_flushDB(Maat_feather_t feather)
{
_Maat_feather_t* _feather=(_Maat_feather_t*)feather;
diff --git a/src/entry/Maat_rule.cpp b/src/entry/Maat_rule.cpp index 5f983d5..0dd5571 100644 --- a/src/entry/Maat_rule.cpp +++ b/src/entry/Maat_rule.cpp @@ -32,7 +32,7 @@ #include "stream_fuzzy_hash.h" #include "gram_index_engine.h" -int MAAT_FRAME_VERSION_2_6_20190222=1; +int MAAT_FRAME_VERSION_2_7_20190629=1; const char* CHARSET_STRING[]={"NONE","gbk","big5","unicode","utf8","bin", "unicode_ascii_esc","unicode_ascii_aligned","unicode_ncr_dec","unicode_ncr_hex","url_encode_gb2312","url_encode_utf8",""}; @@ -65,7 +65,7 @@ int is_valid_match_method(enum MAAT_MATCH_METHOD match_method) } -iconv_t maat_iconv_open(struct Maat_scanner_t* scanner,enum MAAT_CHARSET to,enum MAAT_CHARSET from) +iconv_t maat_iconv_open(struct Maat_scanner* scanner,enum MAAT_CHARSET to,enum MAAT_CHARSET from) { const char *from_s=CHARSET_STRING[from]; const char *to_s=CHARSET_STRING[to]; @@ -87,7 +87,7 @@ iconv_t maat_iconv_open(struct Maat_scanner_t* scanner,enum MAAT_CHARSET to,enum return cd; } -int iconv_convert(struct Maat_scanner_t* scanner,enum MAAT_CHARSET from,enum MAAT_CHARSET to,char *src,int srclen,char *dst,int *dstlen) +int iconv_convert(struct Maat_scanner* scanner,enum MAAT_CHARSET from,enum MAAT_CHARSET to,char *src,int srclen,char *dst,int *dstlen) { size_t ret; int copy_len=0; @@ -206,7 +206,7 @@ int uni2ascii(const char* fmt,const char* src, const int srclen, char* dst, cons } return j; } -int universal_charset_convert(struct Maat_scanner_t* scanner,enum MAAT_CHARSET from,enum MAAT_CHARSET to,char *src,int srclen,char *dst,int *dstlen) +int universal_charset_convert(struct Maat_scanner* scanner,enum MAAT_CHARSET from,enum MAAT_CHARSET to,char *src,int srclen,char *dst,int *dstlen) { int ret=0; char* tmp_buff=NULL; @@ -506,7 +506,7 @@ int HASH_delete_by_id(MESA_htable_handle hash,int id) ret=MESA_htable_del(hash,(unsigned char*)&id, sizeof(id), NULL); return ret; } -MAAT_RULE_EX_DATA rule_ex_data_new(const struct _head_Maat_rule_t * rule_head, const char* srv_def, const struct compile_ex_data_idx* ex_desc) +MAAT_RULE_EX_DATA rule_ex_data_new(const struct Maat_rule_head * rule_head, const char* srv_def, const struct compile_ex_data_idx* ex_desc) { MAAT_RULE_EX_DATA ad=NULL; struct Maat_rule_t rule; @@ -514,7 +514,7 @@ MAAT_RULE_EX_DATA rule_ex_data_new(const struct _head_Maat_rule_t * rule_head, c ex_desc->new_func(ex_desc->idx, &rule, srv_def, &ad, ex_desc->argl,ex_desc->argp); return ad; } -void rule_ex_data_free(const struct _head_Maat_rule_t * rule_head, const char* srv_def, MAAT_RULE_EX_DATA *ad, const struct compile_ex_data_idx* ex_desc) +void rule_ex_data_free(const struct Maat_rule_head * rule_head, const char* srv_def, MAAT_RULE_EX_DATA *ad, const struct compile_ex_data_idx* ex_desc) { struct Maat_rule_t rule; fill_maat_rule(&rule, rule_head, srv_def, strlen(srv_def)+1); @@ -692,12 +692,22 @@ int read_table_description(struct Maat_table_desc** p_table_info,int num,const c char line[MAX_TABLE_LINE_SIZE]; int i=0,ret=0,table_cnt=0; char table_type_str[16]={0},not_care[1024]={0}, tmp_str[32]={0}; - MESA_htable_handle string2int_map=map_create(); + MESA_htable_handle string2int_map=NULL;; struct Maat_table_desc*p=NULL; struct Maat_table_desc*conj_table=NULL; + fp=fopen(table_info_path,"r"); + if(fp==NULL) + { + fprintf(stderr,"Maat read table info %s error.\n",table_info_path); + MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, + "Maat read table info %s failed: %s.\n", table_info_path, strerror(errno)); + return 0; + } + string2int_map=map_create(); map_register(string2int_map,"expr", TABLE_TYPE_EXPR); - map_register(string2int_map,"ip", TABLE_TYPE_IP); + map_register(string2int_map,"ip", TABLE_TYPE_IP); + map_register(string2int_map,"ip_plus", TABLE_TYPE_IP_PLUS); map_register(string2int_map,"compile", TABLE_TYPE_COMPILE); map_register(string2int_map,"plugin", TABLE_TYPE_PLUGIN); map_register(string2int_map,"intval", TABLE_TYPE_INTERVAL); @@ -725,13 +735,7 @@ int read_table_description(struct Maat_table_desc** p_table_info,int num,const c map_register(string2int_map,"yes", 1); map_register(string2int_map,"no", 0); - fp=fopen(table_info_path,"r"); - if(fp==NULL) - { - fprintf(stderr,"Maat read table info %s error.\n",table_info_path); - MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, - "Maat read table info %s error.\n",table_info_path); - } + i=0; while(NULL!=fgets(line,sizeof(line),fp)) { @@ -758,7 +762,7 @@ int read_table_description(struct Maat_table_desc** p_table_info,int num,const c { MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, "Maat read table info %s line %d error:invalid table type.",table_info_path,i); - goto error_jump; + goto invalid_table; } switch(p->table_type) { @@ -770,7 +774,7 @@ int read_table_description(struct Maat_table_desc** p_table_info,int num,const c fprintf(stderr,"Maat read table info %s line %d error:illegal column.\n",table_info_path,i); MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, "Maat read table info %s line %d error:illegal column.",table_info_path,i); - goto error_jump; + goto invalid_table; } break; case TABLE_TYPE_PLUGIN: @@ -780,7 +784,7 @@ int read_table_description(struct Maat_table_desc** p_table_info,int num,const c fprintf(stderr,"Maat read table info %s line %d error:illegal plugin info.\n",table_info_path,i); MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, "Maat read table info %s line %d error:illegal plugin info.",table_info_path,i); - goto error_jump; + goto invalid_table; } break; case TABLE_TYPE_COMPILE: @@ -803,32 +807,32 @@ int read_table_description(struct Maat_table_desc** p_table_info,int num,const c MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, "Maat read table info %s line %d error: table id %uh > %d.\n",table_info_path,i,p->table_id,num); - goto error_jump; + goto invalid_table; } if(p_table_info[p->table_id]!=NULL)//duplicate table_id,means conjunction table; { conj_table=p_table_info[p->table_id]; if(conj_table->conj_cnt==MAX_CONJUNCTION_TABLE_NUM) { - MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module, + MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module, "Maat read table info %s line %d error:reach tableid %d conjunction upper limit." ,table_info_path,i,p->table_id); - goto error_jump; + goto invalid_table; } memcpy(conj_table->table_name[conj_table->conj_cnt],p->table_name[0],MAX_TABLE_NAME_LEN); conj_table->conj_cnt++; - MESA_handle_runtime_log(logger, RLOG_LV_INFO,maat_module, + MESA_handle_runtime_log(logger, RLOG_LV_INFO, maat_module, "Maat read table info %s:%d:conjunction %s with %s (id=%d,total=%d)." ,table_info_path,i,p->table_name[0] ,conj_table->table_name[0],conj_table->table_id,conj_table->conj_cnt); //use goto to free the conjunctioned table_info - goto error_jump; + goto invalid_table; } p_table_info[p->table_id]=p; table_cnt++; continue; -error_jump: +invalid_table: table_info_free(p); p=NULL; } @@ -836,66 +840,116 @@ error_jump: map_destroy(string2int_map); return table_cnt; } -struct Maat_group_inner_t* create_group_rule(int group_id) +struct Maat_group_inner* create_group_rule(int group_id, int table_id, struct Maat_scanner *scanner) { - struct Maat_group_inner_t* group=(struct Maat_group_inner_t*)malloc(sizeof(struct Maat_group_inner_t)); + int ret=0; + struct Maat_group_inner* group=ALLOC(struct Maat_group_inner, 1); group->group_id=group_id; group->region_cnt=0; group->region_boundary=0; - group->ref_cnt=0; + group->ref_by_parent_cnt=0; group->regions=dynamic_array_create(1,8); - group->compile_shortcut=NULL; - group->table_id=0; + group->table_id=table_id; group->group_name=NULL; + group->vertex_id=scanner->grp_vertex_id_generator++; + assert(igraph_vcount(&scanner->group_graph)==group->vertex_id); + igraph_add_vertices(&scanner->group_graph, 1, NULL); //Add 1 vertice. + ret=HASH_add_by_id(scanner->vertex_id2group, group->vertex_id, group); + assert(ret>0); + ret=HASH_add_by_id(scanner->group_hash, group_id, group); + assert(ret>0); pthread_mutex_init(&(group->mutex), NULL); return group; } -void _destroy_group_rule(struct Maat_group_inner_t* group) +void _destroy_group_rule(struct Maat_group_inner* group) { - dynamic_array_destroy(group->regions,free); + if(group->regions) dynamic_array_destroy(group->regions,free); group->region_cnt=0; group->region_boundary=0; group->regions=NULL; - group->ref_cnt=0; + group->ref_by_parent_cnt=0; group->group_id=-1; group->table_id=-1; free(group->group_name); group->group_name=NULL; + free(group->top_groups); + group->top_groups=NULL; pthread_mutex_destroy(&(group->mutex)); free(group); } -void destroy_group_rule(struct Maat_group_inner_t* group) -{ +size_t print_igraph_vector(igraph_vector_t *v, char* buff, size_t sz) { + long int i; + int printed=0; + for (i=0; i<igraph_vector_size(v); i++) { + printed+=snprintf(buff+printed, sz-printed, " %li", (long int) VECTOR(*v)[i]); + } + return printed; +} - if(group->ref_cnt>0||group->region_cnt>0) +#define DESTROY_GROUP_BY_REGION 0 +#define DESTROY_GROUP_BY_PARENT 1 +#define DESTROY_GROUP_BY_CHILD 2 +void destroy_group_rule(struct Maat_group_inner* group_rule, int by_whom, struct Maat_scanner* scanner) +{ + switch(by_whom) { - return; + case DESTROY_GROUP_BY_REGION: + break; + case DESTROY_GROUP_BY_PARENT: + group_rule->ref_by_parent_cnt--; + break; + case DESTROY_GROUP_BY_CHILD: + group_rule->ref_by_children_cnt--; + break; + default: + assert(0); + break; + } + igraph_vector_t v; + char buff[4096]; + if(group_rule->ref_by_parent_cnt==0&&group_rule->ref_by_children_cnt==0&&group_rule->region_cnt==0) + { + HASH_delete_by_id(scanner->group_hash, group_rule->group_id); + HASH_delete_by_id(scanner->vertex_id2group, group_rule->vertex_id); + igraph_vector_init(&v, 8); + igraph_neighbors(&scanner->group_graph, &v, group_rule->vertex_id, IGRAPH_ALL); + if(igraph_vector_size(&v)>0) + { + print_igraph_vector(&v, buff, sizeof(buff)); + MESA_handle_runtime_log(scanner->logger_ref, RLOG_LV_FATAL, maat_module, + "Del group %d exception, still reached by %s.", + group_rule->vertex_id, buff); + assert(0); + } + igraph_vector_destroy(&v); + //Calling _destroy_group_rule on garbage collection to free memory. + garbage_bagging(GARBAGE_GROUP_RULE, group_rule, scanner->tomb_ref); + } - _destroy_group_rule(group); } -void make_group_set(struct Maat_compile_inner_t* compile_rule, struct bool_expr* a_set, unsigned char *has_not) +void make_group_set(struct Maat_compile_group_relation* relation, struct bool_expr* a_set, unsigned char *has_not) { int i=0,j=0; - a_set->user_tag=compile_rule; - struct Maat_group_inner_t*group=NULL; - assert(compile_rule->group_cnt<=MAX_ITEMS_PER_BOOL_EXPR); - for(i=0,j=0;i<compile_rule->group_boundary&&j<MAX_ITEMS_PER_BOOL_EXPR;i++) + a_set->user_tag=relation; + struct Maat_group_inner*group=NULL; + assert(relation->group_cnt<=MAX_ITEMS_PER_BOOL_EXPR); + for(i=0,j=0;i<relation->group_boundary&&j<MAX_ITEMS_PER_BOOL_EXPR;i++) { - group=(struct Maat_group_inner_t*)dynamic_array_read(compile_rule->groups, i); + group=(struct Maat_group_inner*)dynamic_array_read(relation->groups, i); if(group==NULL) { continue; } a_set->items[j].item_id=group->group_id; - a_set->items[j].not_flag=compile_rule->not_flag[j]; + a_set->items[j].not_flag=relation->not_flag[j]; if(a_set->items[j].not_flag) { *has_not=1; } j++; } - assert(j==compile_rule->group_cnt); + assert(j==relation->group_cnt); a_set->item_num=j; } struct compile_walker @@ -906,23 +960,23 @@ struct compile_walker void walk_compile_hash(const uchar * key, uint size, void * data, void * user) { struct bool_expr* one_set=NULL; - struct Maat_compile_inner_t* compile_rule=(struct Maat_compile_inner_t*)data; + struct Maat_compile_group_relation* relation=(struct Maat_compile_group_relation*)data; struct compile_walker* walker=(struct compile_walker*)user; unsigned char has_not_flag=0; MESA_lqueue_head update_q=walker->update_q; - if(compile_rule->db_c_rule==NULL) + if(relation->compile==NULL) { return; } //make sure compile rule's each group has loadded. - if((compile_rule->group_cnt==compile_rule->db_c_rule->declare_grp_num - ||compile_rule->db_c_rule->declare_grp_num==0)//for compatible old version - &&compile_rule->group_cnt>0 - &&compile_rule->group_cnt!=compile_rule->not_group_cnt) + if((relation->group_cnt==relation->compile->declared_grp_num + || relation->compile->declared_grp_num==0)//for compatible old version + && relation->group_cnt>0 + && relation->group_cnt!=relation->not_group_cnt) { one_set=ALLOC(struct bool_expr, 1); //reading compile rule is safe in update thread, mutex lock called when modified - make_group_set(compile_rule, one_set, &has_not_flag); + make_group_set(relation, one_set, &has_not_flag); if(has_not_flag) { walker->compile_has_not_flag++; @@ -994,58 +1048,89 @@ void EMPTY_FREE(void*p) { return; } -struct Maat_compile_inner_t * create_compile_rule(int compile_id) + +struct Maat_compile_rule* create_compile_rule(struct Maat_rule_head* p_head, const char* service_define, int declared_grp_num, const struct Maat_table_desc* table) { - struct Maat_compile_inner_t* p=ALLOC(struct Maat_compile_inner_t,1); - p->compile_id=compile_id; - p->group_cnt=0; - p->group_boundary=1; - p->groups=dynamic_array_create(1, 1); + int i=0; + struct Maat_compile_rule*p=ALLOC(struct Maat_compile_rule, 1); + p->head=*p_head; + p->declared_grp_num=declared_grp_num; p->ads=ALLOC(MAAT_RULE_EX_DATA, MAX_COMPILE_EX_DATA_NUM); - pthread_rwlock_init(&(p->rwlock), NULL); + + //protect by feather->background_update_mutex + p->ref_table=table; + p->head.serv_def_len=strlen(service_define)+1; + p->service_defined=ALLOC(char, p->head.serv_def_len); + memcpy(p->service_defined, service_define, p->head.serv_def_len); + + for(i=0; i<table->compile.ex_data_num; i++) + { + p->ads[i]=rule_ex_data_new(&p->head, p->service_defined, table->compile.ex_desc+i); + } + p->is_valid=1; return p; } -void _destroy_compile_rule(struct Maat_compile_inner_t * compile_rule) + +void destroy_compile_rule(struct Maat_compile_rule* compile_rule) { - const struct Maat_table_desc* table=compile_rule->ref_table; - const struct compile_table_desc* compile_desc=&(table->compile); - struct db_compile_rule_t* db_compile_rule=compile_rule->db_c_rule; int i=0; - compile_rule->compile_id=-1; - dynamic_array_destroy(compile_rule->groups,NULL); + const struct compile_table_desc* compile_desc= &(compile_rule->ref_table->compile); - - pthread_rwlock_wrlock(&(compile_rule->rwlock)); - - if(db_compile_rule!=NULL) + for(i=0; i<compile_desc->ex_data_num; i++) { - for(i=0; i<compile_desc->ex_data_num; i++) - { - rule_ex_data_free(&(db_compile_rule->m_rule_head), db_compile_rule->service_defined, compile_rule->ads+i, compile_desc->ex_desc+i); - compile_rule->ads[i]=NULL; - } - - free(db_compile_rule->service_defined); - free(db_compile_rule); - compile_rule->db_c_rule=NULL; - } + rule_ex_data_free(&(compile_rule->head), compile_rule->service_defined, compile_rule->ads+i, compile_desc->ex_desc+i); + compile_rule->ads[i]=NULL; + } free(compile_rule->ads); - pthread_rwlock_unlock(&(compile_rule->rwlock)); - pthread_rwlock_destroy(&(compile_rule->rwlock)); + compile_rule->is_valid=0; + compile_rule->declared_grp_num=-1; + free(compile_rule->service_defined); + compile_rule->service_defined=NULL; free(compile_rule); + return; } -void destroy_compile_rule(struct Maat_compile_inner_t * p) +struct Maat_compile_group_relation * create_compile_group_relation(int compile_id, struct Maat_scanner *scanner) +{ + int ret=0; + struct Maat_compile_group_relation* p=ALLOC(struct Maat_compile_group_relation, 1); + p->magic_num=COMPILE_RELATION_MAGIC; + p->compile_id=compile_id; + p->group_cnt=0; + p->group_boundary=1; + p->groups=dynamic_array_create(1, 1); + pthread_rwlock_init(&(p->rwlock), NULL); + ret=HASH_add_by_id(scanner->compile_hash, compile_id, p); + assert(ret>0); + return p; +} + +void _destroy_compile_group_relation(struct Maat_compile_group_relation * cg_relation) +{ + assert(cg_relation->magic_num==COMPILE_RELATION_MAGIC); + pthread_rwlock_wrlock(&(cg_relation->rwlock)); + cg_relation->compile_id=-1; + dynamic_array_destroy(cg_relation->groups, NULL); + pthread_rwlock_unlock(&(cg_relation->rwlock)); + + pthread_rwlock_destroy(&(cg_relation->rwlock)); + + free(cg_relation); +} +void destroy_compile_group_relation(struct Maat_compile_group_relation * p, struct Maat_scanner *scanner) { int i=0; - UNUSED struct Maat_compile_inner_t* p_group=NULL; + UNUSED struct Maat_group_inner* p_group=NULL; assert(p->group_cnt==0); + assert(p->compile==NULL); for(i=0;i<p->group_boundary;i++) { - p_group=(struct Maat_compile_inner_t*)dynamic_array_read(p->groups,i); + p_group=(struct Maat_group_inner*)dynamic_array_read(p->groups, i); assert(p_group==NULL); } - _destroy_compile_rule(p); + assert(p->magic_num==COMPILE_RELATION_MAGIC); + HASH_delete_by_id(scanner->compile_hash, p->compile_id); + garbage_bagging(GARBAGE_COMPILE_GOURP_RELATION, p, scanner->tomb_ref); } scan_rule_t* create_rs_str_rule(unsigned int sub_type,enum MAAT_MATCH_METHOD match_method,int is_case_sensitive,const char* string,int len,int l_offset,int r_offset) { @@ -1107,7 +1192,7 @@ void destroy_rs_ip_rule(scan_rule_t* p) { free(p); } -scan_rule_t* create_rs_intval_rule(unsigned int sub_type,struct db_intval_rule_t *intval_rule) +scan_rule_t* create_rs_intval_rule(unsigned int sub_type,struct db_intval_rule *intval_rule) { scan_rule_t *p_rule=(scan_rule_t*)calloc(sizeof(scan_rule_t),1); p_rule->rule_type=RULETYPE_INT; @@ -1173,7 +1258,7 @@ void op_expr_add_rule(struct op_expr_t* op_expr,scan_rule_t* p_rule) return; } GIE_digest_t* create_digest_rule(unsigned int id, enum GIE_operation op,const char* digest, - short cfds_lvl,struct Maat_group_inner_t* tag) + short cfds_lvl,struct Maat_group_inner* tag) { GIE_digest_t* rule=(GIE_digest_t*)calloc(sizeof(GIE_digest_t),1); int digest_len=0; @@ -1221,7 +1306,6 @@ struct Maat_table_runtime* table_runtime_new(const struct Maat_table_desc* table { table_rt->plugin.key2ex_hash=wrap_plugin_EX_hash_new(table_desc->plugin.estimate_size, table_desc->plugin.ex_desc.key2index_func); - pthread_rwlock_init(&(table_rt->plugin.rwlock), NULL); } break; default: @@ -1274,7 +1358,6 @@ void table_runtime_free(struct Maat_table_runtime* p) { MESA_htable_destroy(p->plugin.key2ex_hash, NULL); } - break; default: break; } @@ -1288,7 +1371,7 @@ void table_runtime_free(struct Maat_table_runtime* p) return; } -struct Maat_scanner_t* create_maat_scanner(unsigned int version,_Maat_feather_t *feather) +struct Maat_scanner* create_maat_scanner(unsigned int version,_Maat_feather_t *feather) { int scan_thread_num=feather->scan_thread_num; // int rs_scan_type=feather->rule_scan_type; @@ -1312,22 +1395,34 @@ struct Maat_scanner_t* create_maat_scanner(unsigned int version,_Maat_feather_t hargs.data_expire_with_condition = NULL; - struct Maat_scanner_t* scanner=NULL; - scanner=ALLOC(struct Maat_scanner_t, 1); + struct Maat_scanner* scanner=NULL; + scanner=ALLOC(struct Maat_scanner, 1); //Function Maat_cmd_append will access compile_hash in user thread. - hargs.thread_safe=1; + hargs.thread_safe=8; scanner->compile_hash=MESA_htable_create(&hargs, sizeof(hargs)); MESA_htable_print_crtl(scanner->compile_hash,0); - hargs.thread_safe=1; + hargs.thread_safe=8; scanner->group_hash=MESA_htable_create(&hargs, sizeof(hargs)); MESA_htable_print_crtl(scanner->group_hash,0); + scanner->vertex_id2group=MESA_htable_create(&hargs, sizeof(hargs)); + MESA_htable_print_crtl(scanner->vertex_id2group,0); + + hargs.thread_safe=8; + scanner->exprid_hash=MESA_htable_create(&hargs, sizeof(hargs)); + MESA_htable_print_crtl(scanner->exprid_hash, 0); + + hargs.thread_safe=0; + hargs.data_free = free; scanner->region_hash=MESA_htable_create(&hargs, sizeof(hargs)); MESA_htable_print_crtl(scanner->region_hash,0); + ret=igraph_empty(&scanner->group_graph, 0, IGRAPH_DIRECTED); + assert(ret==IGRAPH_SUCCESS); + scanner->district_map=map_create(); scanner->version=version; @@ -1352,6 +1447,7 @@ struct Maat_scanner_t* create_maat_scanner(unsigned int version,_Maat_feather_t rulescan_set_param(scanner->region,RULESCAN_REGEX_GROUP,NULL,0); } scanner->tomb_ref=feather->garbage_q; + scanner->logger_ref=feather->logger; scanner->region_rslt_buff=ALLOC(scan_result_t, MAX_SCANNER_HIT_NUM*scan_thread_num); for(i=0;i<MAX_TABLE_NUM;i++) @@ -1368,7 +1464,7 @@ struct Maat_scanner_t* create_maat_scanner(unsigned int version,_Maat_feather_t -void destroy_maat_scanner(struct Maat_scanner_t*scanner) +void destroy_maat_scanner(struct Maat_scanner*scanner) { long q_cnt=0,data_size=0; int i=0,j=0; @@ -1379,9 +1475,12 @@ void destroy_maat_scanner(struct Maat_scanner_t*scanner) return; } rulescan_destroy(scanner->region); - MESA_htable_destroy(scanner->compile_hash,(void (*)(void*))_destroy_compile_rule); + MESA_htable_destroy(scanner->compile_hash,(void (*)(void*))_destroy_compile_group_relation); MESA_htable_destroy(scanner->group_hash, (void (*)(void*))_destroy_group_rule); + MESA_htable_destroy(scanner->exprid_hash, NULL); MESA_htable_destroy(scanner->region_hash, NULL); + MESA_htable_destroy(scanner->vertex_id2group, NULL); + map_destroy(scanner->district_map); scanner->district_map=NULL; assert(scanner->tmp_district_map==NULL); @@ -1413,6 +1512,7 @@ void destroy_maat_scanner(struct Maat_scanner_t*scanner) { table_runtime_free(scanner->table_rt[i]); } + igraph_destroy(&scanner->group_graph); free(scanner); return; } @@ -1494,7 +1594,7 @@ void count_rs_region(struct op_expr_t* op_expr,struct _region_stat_t* region_sta return; } -void rulescan_batch_update(rule_scanner_t rs_handle,MESA_lqueue_head expr_queue,void*logger,struct Maat_scanner_t* maat_scanner) +void rulescan_batch_update(rule_scanner_t rs_handle,MESA_lqueue_head expr_queue,void*logger,struct Maat_scanner* maat_scanner) { long i=0,data_size=0; unsigned int j=0; @@ -1580,6 +1680,7 @@ void rulescan_batch_update(rule_scanner_t rs_handle,MESA_lqueue_head expr_queue, assert(table_rt->expr.regex_rule_cnt>=0); break; case TABLE_TYPE_IP: + case TABLE_TYPE_IP_PLUS: table_rt->ip.ipv4_rule_cnt+=region_counter[i].ipv4_rule_cnt; table_rt->ip.ipv6_rule_cnt+=region_counter[i].ipv6_rule_cnt; break; @@ -1602,7 +1703,7 @@ void rulescan_batch_update(rule_scanner_t rs_handle,MESA_lqueue_head expr_queue, free(to_update_expr); } -void digest_batch_update(GIE_handle_t* handle,MESA_lqueue_head update_q,void*logger,struct Maat_scanner_t* maat_scanner,int table_id) +void digest_batch_update(GIE_handle_t* handle,MESA_lqueue_head update_q,void*logger,struct Maat_scanner* maat_scanner,int table_id) { long i=0,data_size=0; int ret=0; @@ -1648,115 +1749,169 @@ void digest_batch_update(GIE_handle_t* handle,MESA_lqueue_head update_q,void*log update_array=NULL; return; } -struct Maat_group_inner_t* add_region_to_group(struct Maat_group_inner_t* group,int table_id,int region_id,int district_id,int expr_id,enum MAAT_TABLE_TYPE region_type) +struct region_group_relation { - int i=0; - struct _Maat_region_inner_t* region_rule=NULL; - for(i=0;i<group->region_boundary;i++) + int region_id; + int group_id; + int array_idx; +}; +int region_group_relation_add(MESA_htable_handle region_hash, int region_id, int group_id, int array_idx) +{ + struct region_group_relation* relation=ALLOC(struct region_group_relation, 1); + relation->region_id=region_id; + relation->group_id=group_id; + relation->array_idx=array_idx; + int ret=HASH_add_by_id(region_hash, region_id, relation); + if(ret<0) { - region_rule=(struct _Maat_region_inner_t*)dynamic_array_read(group->regions, i); - if(region_rule==NULL) - { - continue; - } - if(region_rule->region_id==region_id) - { - break; - } + free(relation); + return -1; + } + else + { + return 0; } - if(i==group->region_boundary)//new region +} +struct region_group_relation* region_group_relation_get(MESA_htable_handle region_hash, int region_id) +{ + struct region_group_relation* relation=NULL; + relation=(struct region_group_relation*)HASH_fetch_by_id(region_hash, region_id); + return relation; +} +int region_group_relation_del(MESA_htable_handle region_hash, int region_id) +{ + int ret=HASH_delete_by_id(region_hash,region_id); + if(ret==-1) + { + return -1; + } + else + { + return 0; + } +} +struct Maat_group_inner* add_region_to_group(struct Maat_group_inner* group,int table_id,int region_id,int district_id,int expr_id,enum MAAT_TABLE_TYPE region_type, struct Maat_scanner* scanner) +{ + struct Maat_region_inner* region_rule=NULL; + struct region_group_relation* relation=NULL; + relation=region_group_relation_get(scanner->region_hash, region_id); + int array_idx; + pthread_mutex_lock(&(group->mutex)); + if(relation==NULL) { - region_rule=(struct _Maat_region_inner_t*)malloc(sizeof(struct _Maat_region_inner_t)); + region_rule=ALLOC(struct Maat_region_inner, 1); region_rule->region_id=region_id; region_rule->expr_id_cnt=1; region_rule->expr_id_ub=region_rule->expr_id_lb=expr_id; region_rule->district_id=district_id; region_rule->table_type=region_type; region_rule->table_id=table_id; - pthread_mutex_lock(&(group->mutex)); - dynamic_array_write(group->regions,group->region_boundary,region_rule); + + dynamic_array_write(group->regions, group->region_boundary, region_rule); + array_idx=group->region_boundary; + region_group_relation_add(scanner->region_hash, region_id, group->group_id, array_idx); group->region_cnt++; group->region_boundary++; - pthread_mutex_unlock(&(group->mutex)); } else { + assert(relation->group_id==group->group_id); + assert(relation->array_idx<group->region_boundary); + array_idx=relation->array_idx; + region_rule=(struct Maat_region_inner*)dynamic_array_read(group->regions, array_idx); assert(expr_id==region_rule->expr_id_ub+1); region_rule->expr_id_ub=expr_id; region_rule->expr_id_cnt++; } + HASH_add_by_id(scanner->exprid_hash, expr_id, (void*)(long long)array_idx); + pthread_mutex_unlock(&(group->mutex)); + return group; } -void cancel_last_region_from_group(struct Maat_group_inner_t* group,int region_id,int expr_id) +void cancel_last_region_from_group(struct Maat_group_inner* group,int region_id,int expr_id, struct Maat_scanner* scanner) { - struct _Maat_region_inner_t* region_rule=NULL; + struct Maat_region_inner* region_rule=NULL; + struct region_group_relation* relation=NULL; + relation=region_group_relation_get(scanner->region_hash, region_id); + assert(relation->group_id==group->group_id); + assert(relation->array_idx==group->region_boundary-1); + int array_idx=relation->array_idx; pthread_mutex_lock(&(group->mutex)); - region_rule=(struct _Maat_region_inner_t*)dynamic_array_read(group->regions,group->region_boundary-1); + region_rule=(struct Maat_region_inner*)dynamic_array_read(group->regions, array_idx); assert(region_rule->expr_id_ub==expr_id&®ion_rule->region_id==region_id); if(region_rule->expr_id_cnt==1) { free(region_rule); - dynamic_array_write(group->regions,group->region_boundary,NULL); + dynamic_array_write(group->regions, group->region_boundary, NULL); group->region_cnt--; group->region_boundary--; + relation=NULL; + region_group_relation_del(scanner->region_hash, region_id); } else { region_rule->expr_id_ub--; region_rule->expr_id_cnt--; } - pthread_mutex_unlock(&(group->mutex)); + HASH_delete_by_id(scanner->exprid_hash, expr_id); + pthread_mutex_unlock(&(group->mutex)); return; } -unsigned int del_region_from_group(struct Maat_group_inner_t* group,int region_id,unsigned int *output_expr_id,int output_size) +unsigned int del_region_from_group(struct Maat_group_inner* group,int region_id,unsigned int *output_expr_id, int output_size, struct Maat_scanner* scanner) { - int i=0,j=0; - struct _Maat_region_inner_t* region_rule=NULL; - pthread_mutex_lock(&(group->mutex)); - for(i=0;i<group->region_boundary;i++) - { - region_rule=(struct _Maat_region_inner_t*)dynamic_array_read(group->regions, i); - if(region_rule==NULL) - { - continue; - } - if(region_rule->region_id==region_id) + int i=0, j=0, ret=0; + struct Maat_region_inner* region_rule=NULL; + struct region_group_relation* relation=NULL; + relation=region_group_relation_get(scanner->region_hash, region_id); + if(relation) + { + pthread_mutex_lock(&(group->mutex)); + assert(relation->group_id==group->group_id); + region_rule=(struct Maat_region_inner*)dynamic_array_read(group->regions, relation->array_idx); + dynamic_array_write(group->regions, relation->array_idx, NULL); + for(i=0;i<region_rule->expr_id_cnt;i++) { - dynamic_array_write(group->regions, i, NULL); - for(j=0;j<region_rule->expr_id_cnt;j++) - { - output_expr_id[j]=region_rule->expr_id_lb+j; - assert(output_expr_id[j]>=0); - } - assert(j<=output_size); - region_rule->region_id=0; - free(region_rule); - region_rule=NULL; - group->region_cnt--; - break; + output_expr_id[i]=region_rule->expr_id_lb+i; + assert(output_expr_id[i]>=0); } + assert(i<=output_size); + region_rule->region_id=0; + free(region_rule); + region_rule=NULL; + group->region_cnt--; + assert(group->region_cnt>=0); + relation=NULL; + ret=region_group_relation_del(scanner->region_hash, region_id); + assert(ret==0); + pthread_mutex_unlock(&(group->mutex)); } - pthread_mutex_unlock(&(group->mutex)); - return j; + for(j=0; j<i; j++) + { + ret=HASH_delete_by_id(scanner->exprid_hash, output_expr_id[j]); + assert(ret==0); + } + + return i; } -int add_group_to_compile(struct Maat_compile_inner_t*a_compile_rule,struct Maat_group_inner_t* a_rule_group, int not_flag) +int add_group_to_compile(struct Maat_compile_group_relation*relation, struct Maat_group_inner* a_rule_group, int not_flag) { int i=0,ret=-1; int write_pos=-1; - struct Maat_group_inner_t* p=NULL; - pthread_rwlock_wrlock(&(a_compile_rule->rwlock)); - if(a_compile_rule->db_c_rule!=NULL - &&a_compile_rule->group_cnt>=a_compile_rule->db_c_rule->declare_grp_num - &&a_compile_rule->db_c_rule->declare_grp_num!=0) + struct Maat_group_inner* p=NULL; + + pthread_rwlock_wrlock(&(relation->rwlock)); + if(relation->compile!=NULL + && relation->group_cnt>=relation->compile->declared_grp_num + && relation->compile->declared_grp_num!=0) { ret=-1; goto error_out; } - for(i=0;i<a_compile_rule->group_boundary;i++) + for(i=0;i<relation->group_boundary;i++) { - p=(struct Maat_group_inner_t*)dynamic_array_read(a_compile_rule->groups,i); + p=(struct Maat_group_inner*)dynamic_array_read(relation->groups,i); if(p==NULL) { write_pos=i; @@ -1770,114 +1925,104 @@ int add_group_to_compile(struct Maat_compile_inner_t*a_compile_rule,struct Maat_ } } } - if(write_pos<0&&a_compile_rule->group_boundary==MAX_EXPR_ITEM_NUM) + if(write_pos<0&&relation->group_boundary==MAX_EXPR_ITEM_NUM) { ret=-1; goto error_out; } if(write_pos<0) { - write_pos=a_compile_rule->group_boundary; - a_compile_rule->group_boundary++; + write_pos=relation->group_boundary; + relation->group_boundary++; } - dynamic_array_write(a_compile_rule->groups, write_pos, a_rule_group); + dynamic_array_write(relation->groups, write_pos, a_rule_group); if(not_flag) { - a_compile_rule->not_flag[write_pos]=1; - a_compile_rule->not_group_cnt++; + relation->not_flag[write_pos]=1; + relation->not_group_cnt++; } else { - a_compile_rule->not_flag[write_pos]=0; - } - a_compile_rule->group_cnt++; - a_rule_group->ref_cnt++; - //member group->compile_shortcut may set to NULL and compile rule pointer repeatly,until rule build finish. - if(a_rule_group->ref_cnt==1&&a_compile_rule->group_cnt==1) - { - a_rule_group->compile_shortcut=a_compile_rule; - } - else - { - a_rule_group->compile_shortcut=NULL; - } - - //update group's shortcut when compile has more than one group. - if(a_compile_rule->group_cnt!=1) - { - for(i=0;i<a_compile_rule->group_boundary;i++) - { - p=(struct Maat_group_inner_t*)dynamic_array_read(a_compile_rule->groups,i); - if(p!=NULL) - { - p->compile_shortcut=NULL; - } - } + relation->not_flag[write_pos]=0; } + relation->group_cnt++; + a_rule_group->ref_by_parent_cnt++; ret=1; error_out: - pthread_rwlock_unlock(&(a_compile_rule->rwlock)); + pthread_rwlock_unlock(&(relation->rwlock)); return ret; } -struct Maat_group_inner_t* del_group_from_compile(struct Maat_compile_inner_t*a_compile_rule,int group_id) +struct Maat_group_inner* del_group_from_compile(struct Maat_compile_group_relation*relation, int group_id) { int i=0; - struct Maat_group_inner_t* group_rule=NULL; - pthread_rwlock_wrlock(&(a_compile_rule->rwlock)); + struct Maat_group_inner* group_rule=NULL; + pthread_rwlock_wrlock(&(relation->rwlock)); for(i=0;i<MAAT_MAX_EXPR_ITEM_NUM;i++) { - group_rule=(struct Maat_group_inner_t*)dynamic_array_read(a_compile_rule->groups,i); + group_rule=(struct Maat_group_inner*)dynamic_array_read(relation->groups,i); if(group_rule==NULL) { continue; } if(group_rule->group_id==group_id) { - group_rule->ref_cnt--; - dynamic_array_write(a_compile_rule->groups,i,NULL); - if(a_compile_rule->not_flag[i]==1) + dynamic_array_write(relation->groups,i,NULL); + if(relation->not_flag[i]==1) { - a_compile_rule->not_group_cnt--; - a_compile_rule->not_flag[i]=0; - } - a_compile_rule->group_cnt--; - pthread_rwlock_unlock(&(a_compile_rule->rwlock)); - return group_rule; + relation->not_group_cnt--; + relation->not_flag[i]=0; + } + relation->group_cnt--; + break; + } + else + { + group_rule=NULL; } } - pthread_rwlock_unlock(&(a_compile_rule->rwlock)); - return NULL; + pthread_rwlock_unlock(&(relation->rwlock)); + return group_rule; } -int MAAT_MAGIC=0xaaaa; -int sync_region(MESA_htable_handle region_hash,int region_id,const char* table_name,int is_valid,void*logger) + +int sync_region(MESA_htable_handle region_hash,int region_id, int group_id, const char* table_name, int is_valid, void*logger) { - int ret=-1; + struct region_group_relation* relation=NULL; + relation=region_group_relation_get(region_hash, region_id); if(is_valid==TRUE) { - ret=HASH_add_by_id(region_hash,region_id,&MAAT_MAGIC); - if(ret<0) + if(relation) { MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , - "region id %d of table %s is not unique.",region_id,table_name); + "region id %d of table %s is already in group %d.", + region_id, table_name, relation->group_id); return -1; } } else { - ret=HASH_delete_by_id(region_hash,region_id); - if(ret==-1) + if(!relation) { MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , - "region delete error,id %d in table %s does not exisit." - ,region_id - ,table_name); + "region delete error, id %d in table %s does not exisit.", + region_id, table_name); return -1; } + else + { + if(group_id!=relation->group_id) + { + MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , + "region delete error, id %d in table %s is already in group %d, but cmd want to delete from group %d.", + region_id, table_name, + relation->group_id, group_id); + return -1; + } + } } return 1; } -int get_district_id(Maat_scanner_t *scanner,const char* district_str) +int get_district_id(Maat_scanner *scanner,const char* district_str) { int map_ret=0,district_id=-1; map_ret=map_str2int(scanner->district_map, district_str,&district_id); @@ -1897,7 +2042,7 @@ int get_district_id(Maat_scanner_t *scanner,const char* district_str) } return district_id; } -int add_expr_rule(struct Maat_table_desc* table,struct db_str_rule_t* db_rule,struct Maat_scanner_t *scanner,void* logger) +int add_expr_rule(struct Maat_table_desc* table,struct db_str_rule_t* db_rule,struct Maat_scanner *scanner,void* logger) { unsigned int i=0,j=0; char* p=NULL,*saveptr=NULL,*region_string=NULL; @@ -1905,7 +2050,7 @@ int add_expr_rule(struct Maat_table_desc* table,struct db_str_rule_t* db_rule,st int expr_id=0,district_id=-1; struct expr_table_desc* expr_desc=&(table->expr); scan_rule_t*p_rule=NULL; - struct Maat_group_inner_t* group_rule=NULL; + struct Maat_group_inner* group_rule=NULL; enum MAAT_CHARSET dst_charset=CHARSET_NONE; char *sub_key_array[MAAT_MAX_EXPR_ITEM_NUM]; int key_left_offset[MAAT_MAX_EXPR_ITEM_NUM]={-1},key_right_offset[MAAT_MAX_EXPR_ITEM_NUM]={-1}; @@ -1916,7 +2061,7 @@ int add_expr_rule(struct Maat_table_desc* table,struct db_str_rule_t* db_rule,st } int sub_expr_cnt=0; struct op_expr_t *op_expr=NULL; - struct Maat_group_inner_t* u_para=NULL; + struct Maat_group_inner* u_para=NULL; if(table->table_type==TABLE_TYPE_EXPR_PLUS) { @@ -1924,11 +2069,10 @@ int add_expr_rule(struct Maat_table_desc* table,struct db_str_rule_t* db_rule,st str_unescape(db_rule->district); district_id=get_district_id(scanner, db_rule->district); } - group_rule=(struct Maat_group_inner_t*)HASH_fetch_by_id(scanner->group_hash, db_rule->group_id); + group_rule=(struct Maat_group_inner*)HASH_fetch_by_id(scanner->group_hash, db_rule->group_id); if(group_rule==NULL) { - group_rule=create_group_rule(db_rule->group_id); - HASH_add_by_id(scanner->group_hash, db_rule->group_id, group_rule); + group_rule=create_group_rule(db_rule->group_id, 0, scanner); } switch(db_rule->expr_type) { @@ -1985,7 +2129,7 @@ int add_expr_rule(struct Maat_table_desc* table,struct db_str_rule_t* db_rule,st break; case EXPR_TYPE_REGEX://it's easy,no need to charset convert expr_id=scanner->exprid_generator++; - u_para=add_region_to_group(group_rule,table->table_id,db_rule->region_id,district_id,expr_id,TABLE_TYPE_EXPR); + u_para=add_region_to_group(group_rule, table->table_id, db_rule->region_id, district_id, expr_id, TABLE_TYPE_EXPR, scanner); if(u_para==NULL) { return -1; @@ -2050,7 +2194,7 @@ int add_expr_rule(struct Maat_table_desc* table,struct db_str_rule_t* db_rule,st break; } expr_id=scanner->exprid_generator++; - u_para=add_region_to_group(group_rule,table->table_id, db_rule->region_id,district_id,expr_id, table->table_type); + u_para=add_region_to_group(group_rule,table->table_id, db_rule->region_id,district_id,expr_id, table->table_type, scanner); if(u_para==NULL)//duplicate { return -1; @@ -2114,7 +2258,7 @@ int add_expr_rule(struct Maat_table_desc* table,struct db_str_rule_t* db_rule,st op_expr->convert_failed>0) { scanner->dedup_expr_num++; - cancel_last_region_from_group(group_rule,db_rule->region_id,op_expr->p_expr->expr_id); + cancel_last_region_from_group(group_rule,db_rule->region_id,op_expr->p_expr->expr_id, scanner); destroy_op_expr(op_expr); //redeem expr_id scanner->exprid_generator--; @@ -2130,7 +2274,7 @@ int add_expr_rule(struct Maat_table_desc* table,struct db_str_rule_t* db_rule,st else { expr_id=scanner->exprid_generator++; - u_para=add_region_to_group(group_rule, table->table_id, db_rule->region_id,district_id,expr_id, table->table_type); + u_para=add_region_to_group(group_rule, table->table_id, db_rule->region_id,district_id,expr_id, table->table_type, scanner); if(u_para==NULL) { return -1; @@ -2161,23 +2305,22 @@ int add_expr_rule(struct Maat_table_desc* table,struct db_str_rule_t* db_rule,st } return 0; } -int add_ip_rule(struct Maat_table_desc* table,struct db_ip_rule_t* db_ip_rule,struct Maat_scanner_t *scanner,void* logger) +int add_ip_rule(struct Maat_table_desc* table,struct db_ip_rule_t* db_ip_rule,struct Maat_scanner *scanner,void* logger) { - struct Maat_group_inner_t* group_rule=NULL; + struct Maat_group_inner* group_rule=NULL; scan_rule_t* p_rule=NULL; struct op_expr_t* op_expr=NULL; - struct Maat_group_inner_t* u_para=NULL; + struct Maat_group_inner* u_para=NULL; int expr_id=0,district_id=-1; - group_rule=(struct Maat_group_inner_t*)HASH_fetch_by_id(scanner->group_hash, db_ip_rule->group_id); + group_rule=(struct Maat_group_inner*)HASH_fetch_by_id(scanner->group_hash, db_ip_rule->group_id); if(group_rule==NULL) { - group_rule=create_group_rule(db_ip_rule->group_id); - HASH_add_by_id(scanner->group_hash, db_ip_rule->group_id, group_rule); + group_rule=create_group_rule(db_ip_rule->group_id, 0, scanner); } expr_id=scanner->exprid_generator++; - u_para=add_region_to_group(group_rule, table->table_id,db_ip_rule->region_id,district_id,expr_id,TABLE_TYPE_IP); + u_para=add_region_to_group(group_rule, table->table_id, db_ip_rule->region_id, district_id, expr_id, TABLE_TYPE_IP, scanner); if(u_para==NULL) { return -1; @@ -2193,22 +2336,21 @@ int add_ip_rule(struct Maat_table_desc* table,struct db_ip_rule_t* db_ip_rule,st MESA_lqueue_join_tail(scanner->region_update_q, &op_expr, sizeof(void*)); return 0; } -int add_intval_rule(struct Maat_table_desc* table,struct db_intval_rule_t* intval_rule,struct Maat_scanner_t *scanner,void* logger) +int add_intval_rule(struct Maat_table_desc* table,struct db_intval_rule* intval_rule,struct Maat_scanner *scanner,void* logger) { - struct Maat_group_inner_t* group_rule=NULL; + struct Maat_group_inner* group_rule=NULL; scan_rule_t* p_rule=NULL; struct op_expr_t* op_expr=NULL; - struct Maat_group_inner_t* u_para=NULL; + struct Maat_group_inner* u_para=NULL; int expr_id=0,district_id=-1; - group_rule=(struct Maat_group_inner_t*)HASH_fetch_by_id(scanner->group_hash, intval_rule->group_id); + group_rule=(struct Maat_group_inner*)HASH_fetch_by_id(scanner->group_hash, intval_rule->group_id); if(group_rule==NULL) { - group_rule=create_group_rule(intval_rule->group_id); - HASH_add_by_id(scanner->group_hash, intval_rule->group_id, group_rule); + group_rule=create_group_rule(intval_rule->group_id, 0, scanner); } expr_id=scanner->exprid_generator++; - u_para=add_region_to_group(group_rule, table->table_id,intval_rule->region_id,district_id,expr_id,TABLE_TYPE_INTERVAL); + u_para=add_region_to_group(group_rule, table->table_id, intval_rule->region_id, district_id, expr_id, TABLE_TYPE_INTERVAL, scanner); if(u_para==NULL) { return -1; @@ -2224,22 +2366,21 @@ int add_intval_rule(struct Maat_table_desc* table,struct db_intval_rule_t* intva MESA_lqueue_join_tail(scanner->region_update_q, &op_expr, sizeof(void*)); return 0; } -int add_digest_rule(struct Maat_table_desc* table,struct db_digest_rule_t* db_digest_rule,struct Maat_scanner_t *scanner,void* logger) +int add_digest_rule(struct Maat_table_desc* table,struct db_digest_rule* db_digest_rule,struct Maat_scanner *scanner,void* logger) { - struct Maat_group_inner_t* group_rule=NULL; + struct Maat_group_inner* group_rule=NULL; GIE_digest_t* digest_rule=NULL; - struct Maat_group_inner_t* u_para=NULL; + struct Maat_group_inner* u_para=NULL; struct Maat_table_runtime * table_rt=scanner->table_rt[table->table_id]; int expr_id=0,district_id=-1; - group_rule=(struct Maat_group_inner_t*)HASH_fetch_by_id(scanner->group_hash, db_digest_rule->group_id); + group_rule=(struct Maat_group_inner*)HASH_fetch_by_id(scanner->group_hash, db_digest_rule->group_id); if(group_rule==NULL) { - group_rule=create_group_rule(db_digest_rule->group_id); - HASH_add_by_id(scanner->group_hash, db_digest_rule->group_id, group_rule); + group_rule=create_group_rule(db_digest_rule->group_id, 0, scanner); } expr_id=scanner->exprid_generator++; - u_para=add_region_to_group(group_rule,table->table_id,db_digest_rule->region_id,district_id,expr_id,TABLE_TYPE_DIGEST); + u_para=add_region_to_group(group_rule, table->table_id, db_digest_rule->region_id, district_id, expr_id, TABLE_TYPE_DIGEST, scanner); if(u_para==NULL) { return -1; @@ -2253,33 +2394,33 @@ int add_digest_rule(struct Maat_table_desc* table,struct db_digest_rule_t* db_di ,db_digest_rule->confidence_degree ,group_rule); MESA_lqueue_join_tail(table_rt->similar.update_q, &digest_rule, sizeof(void*)); - scanner->gie_total_q_size++; + scanner->gie_update_q_size++; return 0; } -int del_region_rule(struct Maat_table_desc* table,int region_id,int group_id,int rule_type,struct Maat_scanner_t *maat_scanner,void* logger) +int del_region_rule(struct Maat_table_desc* table,int region_id,int group_id,int rule_type,struct Maat_scanner *maat_scanner,void* logger) { int i=0; unsigned int expr_id[MAAT_MAX_EXPR_ITEM_NUM*MAX_CHARSET_NUM]={0}; int expr_num=0; - struct Maat_group_inner_t* group_rule=NULL; + struct Maat_group_inner* group_rule=NULL; struct op_expr_t* op_expr=NULL; GIE_digest_t* digest_rule=NULL; - group_rule=(struct Maat_group_inner_t*)HASH_fetch_by_id(maat_scanner->group_hash, group_id); + group_rule=(struct Maat_group_inner*)HASH_fetch_by_id(maat_scanner->group_hash, group_id); if(group_rule==NULL) { MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , - "update error,table %s group id %u not exist,while delete region id %d." + "update error, table %s group id %u not exist, while delete region id %d." ,table->table_name[table->updating_name] ,group_id ,region_id); return -1; } assert(group_id==group_rule->group_id); - expr_num=del_region_from_group(group_rule,region_id, expr_id, sizeof(expr_id)/sizeof(unsigned int)); + expr_num=del_region_from_group(group_rule,region_id, expr_id, sizeof(expr_id)/sizeof(unsigned int), maat_scanner); if(expr_num==0) { MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_module , - "region delete error,id %d table %s region not in group id %d." + "region delete error, id %d table %s region not in group id %d." ,region_id ,table->table_name[table->updating_name] ,group_id); @@ -2288,6 +2429,7 @@ int del_region_rule(struct Maat_table_desc* table,int region_id,int group_id,int switch(table->table_type) { case TABLE_TYPE_IP: + case TABLE_TYPE_IP_PLUS: case TABLE_TYPE_EXPR: case TABLE_TYPE_EXPR_PLUS: case TABLE_TYPE_INTERVAL: @@ -2306,159 +2448,221 @@ int del_region_rule(struct Maat_table_desc* table,int region_id,int group_id,int ,0 ,NULL); MESA_lqueue_join_tail(maat_scanner->table_rt[table->table_id]->similar.update_q,&digest_rule, sizeof(void*)); - maat_scanner->gie_total_q_size++; + maat_scanner->gie_update_q_size++; break; default: assert(0); break; } - if(group_rule->region_cnt==0&&group_rule->region_cnt==0) - { - HASH_delete_by_id(maat_scanner->group_hash,group_id); - garbage_bagging(GARBAGE_GROUP_RULE, group_rule, maat_scanner->tomb_ref); + destroy_group_rule(group_rule, DESTROY_GROUP_BY_REGION, maat_scanner); - } return 0; } -int add_group_rule(struct Maat_table_desc* table,struct db_group_rule_t* db_group_rule,struct Maat_scanner_t *scanner,void* logger) +int add_group_rule(struct Maat_table_desc* table, struct db_group_rule_t* db_group_rule, struct Maat_scanner *scanner, void* logger) { - struct Maat_group_inner_t* group_rule=NULL; - struct Maat_compile_inner_t*compile_rule=NULL; + struct Maat_group_inner* group_rule=NULL, *parent_group=NULL; + struct Maat_compile_group_relation*compile_rule=NULL; int ret=0; - group_rule=(struct Maat_group_inner_t*)HASH_fetch_by_id(scanner->group_hash, db_group_rule->group_id); + igraph_integer_t edge_id; + group_rule=(struct Maat_group_inner*)HASH_fetch_by_id(scanner->group_hash, db_group_rule->group_id); if(group_rule==NULL) { - group_rule=create_group_rule(db_group_rule->group_id); - group_rule->table_id=table->table_id; - - ret=HASH_add_by_id(scanner->group_hash, db_group_rule->group_id, group_rule); - assert(ret>=0); + group_rule=create_group_rule(db_group_rule->group_id, table->table_id, scanner); } - compile_rule=(struct Maat_compile_inner_t*)HASH_fetch_by_id(scanner->compile_hash, db_group_rule->compile_id); - if(compile_rule==NULL) + if(db_group_rule->parent_type==PARENT_TYPE_GROUP) { - compile_rule=create_compile_rule(db_group_rule->compile_id); - ret=HASH_add_by_id(scanner->compile_hash, db_group_rule->compile_id, compile_rule); - assert(ret>=0); + parent_group=(struct Maat_group_inner*)HASH_fetch_by_id(scanner->group_hash, db_group_rule->parent_id); + if(parent_group==NULL) + { + parent_group=create_group_rule(db_group_rule->parent_id, table->table_id, scanner); + } + group_rule->ref_by_parent_cnt++; + parent_group->ref_by_children_cnt++; + ret=igraph_get_eid(&scanner->group_graph, &edge_id, group_rule->vertex_id, parent_group->vertex_id, IGRAPH_DIRECTED, /*error*/ 0); + if(edge_id>0)//if the edge was not found and error is false, then -1 will be assigned to eid. + { + MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module, + "update error, add sub group: %s %d to group %d error, sub group exist.", + table->table_name[table->updating_name], + db_group_rule->group_id, + db_group_rule->parent_id); + return -1; + } + //igraph allow add multiple edges between two vetex, igraph_delete_edges removes one edge per call. + igraph_add_edge(&scanner->group_graph, group_rule->vertex_id, parent_group->vertex_id); } - ret=add_group_to_compile(compile_rule, group_rule, db_group_rule->not_flag); - if(ret<0) + else { - MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module, - "update error,add group: %s %d to compile rule %d error, compile rule is full or duplicate group." - ,table->table_name[table->updating_name] - ,db_group_rule->group_id - ,db_group_rule->compile_id); - return -1; + group_rule->has_compile_neighbors=1; + compile_rule=(struct Maat_compile_group_relation*)HASH_fetch_by_id(scanner->compile_hash, db_group_rule->parent_id); + if(compile_rule==NULL) + { + compile_rule=create_compile_group_relation(db_group_rule->parent_id, scanner); + } + ret=add_group_to_compile(compile_rule, group_rule, db_group_rule->not_flag); + if(ret<0) + { + MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module, + "update error,add group: %s %d to compile rule %d error, compile rule is full or duplicate group.", + table->table_name[table->updating_name], + db_group_rule->group_id, + db_group_rule->parent_id); + return -1; + } } - return 0; - + scanner->to_update_group_cnt++; + return 1; } -void del_group_rule(struct Maat_table_desc* table,struct db_group_rule_t* db_group_rule,struct Maat_scanner_t *scanner,void* logger) +int del_group_rule(struct Maat_table_desc* table, struct db_group_rule_t* db_group_rule, struct Maat_scanner *scanner, void* logger) { - struct Maat_compile_inner_t*compile_rule=NULL; - struct Maat_group_inner_t* group_rule=NULL; - compile_rule=(struct Maat_compile_inner_t*)HASH_fetch_by_id(scanner->compile_hash, db_group_rule->compile_id); - if(compile_rule==NULL) - { - MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , - "update error,delete %s group rule error : compile id %d does not exisit." - ,table->table_name[table->updating_name] - ,db_group_rule->compile_id); - return; - } - group_rule=del_group_from_compile(compile_rule, db_group_rule->group_id); - if(group_rule==NULL) - { - MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , - "update error,delete %s group rule error : group id %d not in compile id %d." - ,table->table_name[table->updating_name] - ,db_group_rule->group_id - ,db_group_rule->compile_id); - return; - } - if(compile_rule->group_cnt==0&&compile_rule->is_valid==0) + struct Maat_compile_group_relation* relation=NULL; + struct Maat_group_inner* group_rule=NULL, *parent_group=NULL; + igraph_es_t es; + int ret=0; + igraph_integer_t edge_num_before=0, edge_num_after=0; + + + if(db_group_rule->parent_type==PARENT_TYPE_GROUP) { - HASH_delete_by_id(scanner->compile_hash, db_group_rule->compile_id); - garbage_bagging(GARBAGE_COMPILE_RULE, compile_rule, scanner->tomb_ref); + group_rule=(struct Maat_group_inner*)HASH_fetch_by_id(scanner->group_hash, db_group_rule->group_id); + parent_group=(struct Maat_group_inner*)HASH_fetch_by_id(scanner->group_hash, db_group_rule->parent_id); + if(group_rule==NULL) + { + MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module , + "update error, delete %s group %d from parent group %d error, target group not exisit.", + table->table_name[table->updating_name], + db_group_rule->group_id, + db_group_rule->parent_id); + return 0; + } + if(parent_group==NULL) + { + MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module , + "update error, delete %s group %d from parent group %d error, parent group not exisit.", + table->table_name[table->updating_name], + db_group_rule->group_id, + db_group_rule->parent_id); + return 0; + } + edge_num_before=igraph_ecount(&scanner->group_graph); + // The edges between the given pairs of vertices will be included in the edge selection. + //The vertex pairs must be given as the arguments of the function call, the third argument + //is the first vertex of the first edge, the fourth argument is the second vertex of the + //first edge, the fifth is the first vertex of the second edge and so on. The last element + //of the argument list must be -1 to denote the end of the argument list. + //https://igraph.org/c/doc/igraph-Iterators.html#igraph_es_pairs_small + ret=igraph_es_pairs_small(&es, IGRAPH_DIRECTED, group_rule->vertex_id, parent_group->vertex_id, -1); + assert(ret==IGRAPH_SUCCESS); + // ignore no such edge to abort(). + igraph_set_error_handler(igraph_error_handler_ignore); + ret=igraph_delete_edges(&scanner->group_graph, es); + edge_num_after=igraph_ecount(&scanner->group_graph); + + if(ret!=IGRAPH_SUCCESS||edge_num_before-edge_num_after!=1) + { + MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module , + "update error, delete %s group %d from parent group %d error, not such relation before.", + table->table_name[table->updating_name], + db_group_rule->group_id, + db_group_rule->parent_id); + } + igraph_es_destroy(&es); + destroy_group_rule(parent_group, DESTROY_GROUP_BY_CHILD, scanner); } - //Directly delete group id will not destroyp group_rule,it 'll be destroyed when delete this group's last region. - if(group_rule->ref_cnt==0&&group_rule->region_cnt==0) + else { - //Directly delete table %s group id %d, do this when delete its last region. + relation=(struct Maat_compile_group_relation*)HASH_fetch_by_id(scanner->compile_hash, db_group_rule->parent_id); + if(relation==NULL) + { + MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module, + "update error, delete %s group %d form compile %d error, compile does not exist.", + table->table_name[table->updating_name], + db_group_rule->group_id, + db_group_rule->parent_id); + return 0; + } + group_rule=del_group_from_compile(relation, db_group_rule->group_id); + if(group_rule==NULL) + { + MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module, + "update error, delete %s group %d from compile %d error, target group does not in compile.", + table->table_name[table->updating_name], + db_group_rule->group_id, + db_group_rule->parent_id); + return 0; + } + if(relation->group_cnt==0 && relation->compile==NULL) + { + destroy_compile_group_relation(relation, scanner); + } } - return; + destroy_group_rule(group_rule, DESTROY_GROUP_BY_PARENT, scanner); + scanner->to_update_group_cnt++; + return 1; } -int add_compile_rule(struct Maat_table_desc* table,struct db_compile_rule_t* db_compile_rule,struct Maat_scanner_t *scanner,void* logger) +int add_compile_rule(struct Maat_table_desc* table, struct Maat_compile_rule* db_compile_rule, struct Maat_scanner *scanner, void* logger) { - struct Maat_compile_inner_t *compile_rule=NULL; - struct _head_Maat_rule_t *p_maat_rule_head=&(db_compile_rule->m_rule_head); - int i=0; - compile_rule=(struct Maat_compile_inner_t*)HASH_fetch_by_id(scanner->compile_hash, p_maat_rule_head->config_id); - if(compile_rule==NULL) + struct Maat_compile_group_relation *cg_relation=NULL; + struct Maat_rule_head *p_maat_rule_head=&(db_compile_rule->head); + + cg_relation=(struct Maat_compile_group_relation*)HASH_fetch_by_id(scanner->compile_hash, p_maat_rule_head->config_id); + if(cg_relation==NULL) { - compile_rule=create_compile_rule(p_maat_rule_head->config_id); - HASH_add_by_id(scanner->compile_hash,p_maat_rule_head->config_id,compile_rule); + cg_relation=create_compile_group_relation(p_maat_rule_head->config_id, scanner); } else { - if(compile_rule->db_c_rule!=NULL)//duplicate config + if(cg_relation->compile!=NULL)//duplicate config { return -1; } } - - pthread_rwlock_wrlock(&(compile_rule->rwlock)); - compile_rule->ref_table=table; - compile_rule->db_c_rule=db_compile_rule; - for(i=0; i<table->compile.ex_data_num; i++) - { - compile_rule->ads[i]=rule_ex_data_new(p_maat_rule_head, db_compile_rule->service_defined, table->compile.ex_desc+i); - } - compile_rule->is_valid=1; - pthread_rwlock_unlock(&(compile_rule->rwlock)); - + cg_relation->compile=db_compile_rule; + scanner->to_update_compile_cnt++; return 0; } -int del_compile_rule(struct Maat_table_desc* table,struct db_compile_rule_t* db_compile_rule,struct Maat_scanner_t *scanner,void* logger) +int del_compile_rule(struct Maat_table_desc* table, int compile_id, struct Maat_scanner *scanner, void* logger) { - struct Maat_compile_inner_t *compile_rule=NULL; - compile_rule=(struct Maat_compile_inner_t*)HASH_fetch_by_id(scanner->compile_hash, db_compile_rule->m_rule_head.config_id); - if(compile_rule==NULL) + struct Maat_compile_group_relation *cg_relation=NULL; + cg_relation=(struct Maat_compile_group_relation*)HASH_fetch_by_id(scanner->compile_hash, compile_id); + if(cg_relation==NULL || cg_relation->compile==NULL) { MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , - "update error,delete %s compile rule error : congfig id %d does not exisit." + "update error, delete %s compile rule error : compile id %d does not exist." ,table->table_name[table->updating_name] - ,db_compile_rule->m_rule_head.config_id); + ,compile_id); return -1; } - pthread_rwlock_wrlock(&(compile_rule->rwlock)); - compile_rule->is_valid=0; - pthread_rwlock_unlock(&(compile_rule->rwlock)); - if(compile_rule->group_cnt==0) + pthread_rwlock_wrlock(&(cg_relation->rwlock)); + garbage_bagging(GARBAGE_COMPILE_RULE, cg_relation->compile, scanner->tomb_ref); + cg_relation->compile=NULL; + pthread_rwlock_unlock(&(cg_relation->rwlock)); + + if(cg_relation->group_cnt==0&&cg_relation->compile==NULL) { - HASH_delete_by_id(scanner->compile_hash, compile_rule->compile_id); - garbage_bagging(GARBAGE_COMPILE_RULE,compile_rule, scanner->tomb_ref); + destroy_compile_group_relation(cg_relation, scanner); } + scanner->to_update_compile_cnt++; return 1; } -void update_group_rule(struct Maat_table_desc* table,const char* table_line,struct Maat_scanner_t *scanner,void* logger) +void update_group_rule(struct Maat_table_desc* table,const char* table_line,struct Maat_scanner *scanner,void* logger) { struct db_group_rule_t db_group_rule; struct Maat_table_runtime* table_rt=scanner->table_rt[table->table_id]; int ret=0; memset(&db_group_rule, 0, sizeof(db_group_rule)); - ret=sscanf(table_line,"%d\t%d\t%d\t%d", &(db_group_rule.group_id), - &(db_group_rule.compile_id), + ret=sscanf(table_line,"%d\t%d\t%d\t%d\t%d", &(db_group_rule.group_id), + &(db_group_rule.parent_id), &(db_group_rule.is_valid), - &(db_group_rule.not_flag)); - if(ret!=3&&ret!=4) + &(db_group_rule.not_flag), + &(db_group_rule.parent_type)); + if(ret!=3&&ret!=4&&ret!=5) { MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_module , - "update error,invalid format of group table %s:%s", + "update error, invalid format of group table %s:%s", table->table_name[table->updating_name], table_line); table->udpate_err_cnt++; return; @@ -2467,13 +2671,22 @@ void update_group_rule(struct Maat_table_desc* table,const char* table_line,stru { db_group_rule.not_flag=0; } + if(db_group_rule.parent_type==PARENT_TYPE_GROUP && db_group_rule.not_flag) + { + MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_module , + "update error, invalid format of group table %s:%s not operation is forbidden for non-compile parent.", + table->table_name[table->updating_name], table_line); + table->udpate_err_cnt++; + return; + } if(db_group_rule.is_valid==FALSE) { - del_group_rule(table, &db_group_rule, scanner, logger); + ret=del_group_rule(table, &db_group_rule, scanner, logger); //leave no trace when compatible_group_update calling - if(table->table_type==TABLE_TYPE_GROUP) + if(table->table_type==TABLE_TYPE_GROUP&&ret==1) { table_rt->origin_rule_num--; + assert(table_rt->origin_rule_num>=0); if(db_group_rule.not_flag) { table_rt->group.not_flag_group--; @@ -2488,7 +2701,7 @@ void update_group_rule(struct Maat_table_desc* table,const char* table_line,stru MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_module , "duplicate config of group table %s group_id %d compile_id %d.", table->table_name[0], db_group_rule.group_id, - db_group_rule.compile_id); + db_group_rule.parent_id); } else @@ -2507,7 +2720,7 @@ void update_group_rule(struct Maat_table_desc* table,const char* table_line,stru return; } -void compatible_group_udpate(struct Maat_table_desc* table,int region_id,int compile_id,int is_valid,struct Maat_scanner_t *scanner,void* logger) +void compatible_group_udpate(struct Maat_table_desc* table,int region_id,int compile_id,int is_valid,struct Maat_scanner *scanner,void* logger) { char virtual_group_line[256]; snprintf(virtual_group_line,sizeof(virtual_group_line), @@ -2515,7 +2728,7 @@ void compatible_group_udpate(struct Maat_table_desc* table,int region_id,int com update_group_rule(table, virtual_group_line,scanner,logger); return; } -void update_expr_rule(struct Maat_table_desc* table,const char* table_line,struct Maat_scanner_t *scanner,void* logger,int group_mode_on) +void update_expr_rule(struct Maat_table_desc* table,const char* table_line,struct Maat_scanner *scanner,void* logger,int group_mode_on) { struct db_str_rule_t* maat_str_rule=ALLOC(struct db_str_rule_t, 1); int ret=0,db_hexbin=0,rule_type=0; @@ -2605,10 +2818,11 @@ void update_expr_rule(struct Maat_table_desc* table,const char* table_line,struc table->udpate_err_cnt++; goto error_out; } - ret=sync_region(scanner->region_hash - ,maat_str_rule->region_id - ,table->table_name[table->updating_name] - ,maat_str_rule->is_valid,logger); + ret=sync_region(scanner->region_hash, + maat_str_rule->region_id, + maat_str_rule->group_id, + table->table_name[table->updating_name], + maat_str_rule->is_valid,logger); if(ret<0) { table->udpate_err_cnt++; @@ -2676,99 +2890,310 @@ error_out: free(maat_str_rule); maat_str_rule=NULL; } -void update_ip_rule(struct Maat_table_desc* table,const char* table_line,struct Maat_scanner_t *scanner,void* logger,int group_mode_on) +enum MAAT_IP_FORMAT +{ + FORMAT_RANGE, + FORMAT_MASK, + FORMAT_CIDR, + FORMAT_UNKNOWN +}; +enum MAAT_IP_FORMAT ip_format_str2int(const char* format) +{ + if(0==strcasecmp(format, "range")) + { + return FORMAT_RANGE; + } + else if(0==strcasecmp(format, "mask")) + { + return FORMAT_MASK; + } + else if(0==strcasecmp(format, "CIDR")) + { + return FORMAT_CIDR; + } + else + { + assert(0); + } + return FORMAT_UNKNOWN; +} +int ip_format2range(int ip_type, enum MAAT_IP_FORMAT format, const char* ip1, const char* ip2, unsigned int range_begin[], unsigned int range_end[]) +{ + unsigned int ipv4_addr=0, ipv4_mask=0, ipv4_range_end=0; + unsigned int ipv6_addr[4]={0}, ipv6_mask[4]={0}, ipv6_range_end[4]={0}; + int cidr=0, bit32=0; + int ret=0, i=0; + if(ip_type!=4 && ip_type!=6) + { + assert(0); + return -1; + } + if(ip_type==4) + { + ret=inet_pton(AF_INET, ip1, &ipv4_addr); + if(ret<=0) + { + return -1; + } + ipv4_addr=ntohl(ipv4_addr); + switch (format) + { + case FORMAT_RANGE: + range_begin[0]=ipv4_addr; + ret=inet_pton(AF_INET, ip2, &ipv4_range_end); + if(ret<=0) + { + return -1; + } + ipv4_range_end=ntohl(ipv4_range_end); + range_end[0]=ipv4_range_end; + break; + case FORMAT_MASK: + ret=inet_pton(AF_INET, ip2, &ipv4_mask); + if(ret<=0) + { + return -1; + } + ipv4_mask=ntohl(ipv4_mask); + range_begin[0]=ipv4_addr&ipv4_mask; + range_end[0]=ipv4_addr|~ipv4_mask; + break; + case FORMAT_CIDR: + cidr=atoi(ip2); + if(cidr>32||cidr<0) + { + return -1; + } + ipv4_mask = (0xFFFFFFFFUL << (32 - cidr)) & 0xFFFFFFFFUL; + range_begin[0]=ipv4_addr&ipv4_mask; + range_end[0]=ipv4_addr|~ipv4_mask; + break; + default: + assert(0); + } + } + else //ipv6 + { + ret=inet_pton(AF_INET6, ip1, ipv6_addr); + if(ret<=0) + { + return -1; + } + ipv6_ntoh(ipv6_addr); + switch(format) + { + case FORMAT_RANGE: + ret=inet_pton(AF_INET6, ip2, ipv6_range_end); + if(ret<=0) + { + return -1; + } + ipv6_ntoh(ipv6_range_end); + memcpy(range_begin, ipv6_addr, sizeof(ipv6_addr)); + memcpy(range_end, ipv6_range_end, sizeof(ipv6_range_end)); + break; + case FORMAT_MASK: + ret=inet_pton(AF_INET6, ip2, ipv6_mask); + if(ret<=0) + { + return -1; + } + ipv6_ntoh(ipv6_mask); + for(i=0; i<4; i++) + { + range_begin[i]=ipv6_addr[i]&ipv6_mask[i]; + range_end[i] = ipv6_addr[i]|~ipv6_mask[i]; + } + break; + case FORMAT_CIDR: + cidr=atoi(ip2); + if(cidr>128||cidr<0) + { + return -1; + } + for(i=0; i<4; i++) + { + bit32=128-cidr-32*(3-i); + if(bit32<0) bit32=0; + ipv6_mask[i]=(0xFFFFFFFFUL << bit32) & 0xFFFFFFFFUL; + range_begin[i]=ipv6_addr[i]&ipv6_mask[i]; + range_end[i] = ipv6_addr[i]|~ipv6_mask[i]; + } + break; + default: + assert(0); + } + } + return 0; +} +void update_ip_rule(struct Maat_table_desc* table, const char* table_line, struct Maat_scanner *scanner, void* logger, int group_mode_on) { struct db_ip_rule_t* ip_rule=(struct db_ip_rule_t*)calloc(sizeof(struct db_ip_rule_t),1); - char src_ip[40],mask_src_ip[40],dst_ip[40],mask_dst_ip[40]; + char src_ip1[40]={0}, src_ip2[40]={0}, dst_ip1[40]={0}, dst_ip2[40]={0}; + char saddr_format[16]={0}, sport_format[16]={0}, daddr_format[16]={0}, dport_format[16]={0}; struct Maat_table_runtime* table_rt=scanner->table_rt[table->table_id]; - unsigned short i_src_port,i_sport_mask,i_dst_port,i_dport_mask; + unsigned short src_port1=0, src_port2=0, dst_port1=0, dst_port2=0; int protocol=0,direction=0; - int ret=0,rule_type=0; + int ret=0; int ret_array[8]={1},i=0; - ret=sscanf(table_line,"%d\t%d\t%d\t%s\t%s\t%hu\t%hu\t%s\t%s\t%hu\t%hu\t%d\t%d\t%d" - ,&(ip_rule->region_id) - ,&(ip_rule->group_id) - ,&(ip_rule->addr_type) - ,src_ip - ,mask_src_ip - ,&i_src_port - ,&i_sport_mask - ,dst_ip - ,mask_dst_ip - ,&i_dst_port - ,&i_dport_mask - ,&protocol - ,&direction - ,&(ip_rule->is_valid)); - if(ret!=14||(ip_rule->addr_type!=4&&ip_rule->addr_type!=6) - ||protocol>65535||protocol<0 - ||(direction!=0&&direction!=1)) + + switch(table->table_type) { - MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , - "update error,invalid format of ip table %s:%s" - ,table->table_name[table->updating_name],table_line); + case TABLE_TYPE_IP: + strncpy(saddr_format, "mask", sizeof(saddr_format)); + strncpy(sport_format, "mask", sizeof(sport_format)); + strncpy(daddr_format, "mask", sizeof(daddr_format)); + strncpy(dport_format, "mask", sizeof(dport_format)); + + ret=sscanf(table_line,"%d\t%d\t%d\t%s\t%s\t%hu\t%hu\t%s\t%s\t%hu\t%hu\t%d\t%d\t%d", + &(ip_rule->region_id), + &(ip_rule->group_id), + &(ip_rule->addr_type), + src_ip1, + src_ip2, + &src_port1, + &src_port2, + dst_ip1, + dst_ip2, + &dst_port1, + &dst_port2, + &protocol, + &direction, + &(ip_rule->is_valid)); + if(ret!=14) + { + MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , + "update error, invalid column number of ip table %s:%s" + ,table->table_name[table->updating_name],table_line); + table->udpate_err_cnt++; + goto error_out; + } + break; + case TABLE_TYPE_IP_PLUS: + ret=sscanf(table_line,"%d\t%d\t%d\t%s\t%s\t%s\t%s\t%hu\t%hu\t%s\t%s\t%s\t%s\t%hu\t%hu\t%d\t%d\t%d", + &(ip_rule->region_id), + &(ip_rule->group_id), + &(ip_rule->addr_type), + saddr_format, + src_ip1, + src_ip2, + sport_format, + &src_port1, + &src_port2, + daddr_format, + dst_ip1, + dst_ip2, + dport_format, + &dst_port1, + &dst_port2, + &protocol, + &direction, + &(ip_rule->is_valid)); + if(ret!=18) + { + MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , + "update error, invalid column number of ip_plus table %s:%s" + ,table->table_name[table->updating_name],table_line); + table->udpate_err_cnt++; + goto error_out; + } + break; + default: + table->udpate_err_cnt++; + goto error_out; + break; + } + if(ip_rule->addr_type!=4&&ip_rule->addr_type!=6) + { + MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module, + "update error, invalid addr type %d of ip/ip_plus table %s:%s", + ip_rule->addr_type, + table->table_name[table->updating_name], table_line); + table->udpate_err_cnt++; + goto error_out; + } + if(protocol>65535 || protocol<0) + { + MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module, + "update error, invalid protocol value %d of ip/ip_plus table %s:%s", + protocol, + table->table_name[table->updating_name],table_line); + table->udpate_err_cnt++; + goto error_out; + } + if(direction!=0 && direction!=1) + { + MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module, + "update error, invalid direction value %d of ip/ip_plus table %s:%s", + direction, + table->table_name[table->updating_name],table_line); table->udpate_err_cnt++; goto error_out; } + if(FORMAT_UNKNOWN==ip_format_str2int(saddr_format)|| + FORMAT_UNKNOWN==ip_format_str2int(sport_format)|| + FORMAT_UNKNOWN==ip_format_str2int(daddr_format)|| + FORMAT_UNKNOWN==ip_format_str2int(dport_format)) + { + MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module, + "update error, invalid addr format of ip/ip_plus table %s:%s, should be range, mask or CIDR", + table->table_name[table->updating_name], table_line); + table->udpate_err_cnt++; + goto error_out; + } + if(ip_rule->addr_type==4) { - ret_array[0]=inet_pton(AF_INET,src_ip,&(ip_rule->ipv4_rule.saddr)); - ip_rule->ipv4_rule.saddr=ntohl(ip_rule->ipv4_rule.saddr); - ret_array[1]=inet_pton(AF_INET,mask_src_ip,&(ip_rule->ipv4_rule.smask)); - ip_rule->ipv4_rule.smask=ntohl(ip_rule->ipv4_rule.smask); - - ret_array[2]=inet_pton(AF_INET,dst_ip,&(ip_rule->ipv4_rule.daddr)); - ip_rule->ipv4_rule.daddr=ntohl(ip_rule->ipv4_rule.daddr); - ret_array[3]=inet_pton(AF_INET,mask_dst_ip,&(ip_rule->ipv4_rule.dmask)); - ip_rule->ipv4_rule.dmask=ntohl(ip_rule->ipv4_rule.dmask); - - ip_rule->ipv4_rule.min_sport=i_src_port&i_sport_mask; - ip_rule->ipv4_rule.max_sport=(i_src_port&i_sport_mask)+(~i_sport_mask); - - ip_rule->ipv4_rule.min_dport=i_dst_port&i_dport_mask; - ip_rule->ipv4_rule.max_dport=(i_dst_port&i_dport_mask)+(~i_dport_mask); + ret_array[0]=ip_format2range(ip_rule->addr_type, ip_format_str2int(saddr_format), src_ip1, src_ip2, &ip_rule->ipv4_rule.min_saddr, &ip_rule->ipv4_rule.max_saddr); + ret_array[1]=ip_format2range(ip_rule->addr_type, ip_format_str2int(daddr_format), dst_ip1, dst_ip2, &ip_rule->ipv4_rule.min_daddr, &ip_rule->ipv4_rule.max_daddr); + if(FORMAT_MASK==ip_format_str2int(dport_format)) + { + ip_rule->ipv4_rule.min_dport=dst_port1&dst_port2; + ip_rule->ipv4_rule.max_dport=dst_port1|~dst_port2; + } + else + { + ip_rule->ipv4_rule.min_dport=dst_port1; + ip_rule->ipv4_rule.max_dport=dst_port2; + } ip_rule->ipv4_rule.proto=protocol; ip_rule->ipv4_rule.direction=direction; - rule_type=RULETYPE_IPv4; } else { - ret_array[0]=inet_pton(AF_INET6,src_ip,&(ip_rule->ipv6_rule.saddr)); - ipv6_ntoh(ip_rule->ipv6_rule.saddr); - ret_array[1]=inet_pton(AF_INET6,mask_src_ip,&(ip_rule->ipv6_rule.smask)); - ipv6_ntoh(ip_rule->ipv6_rule.smask); + ret_array[0]=ip_format2range(ip_rule->addr_type, ip_format_str2int(saddr_format), src_ip1, src_ip2, ip_rule->ipv6_rule.min_saddr, ip_rule->ipv6_rule.max_saddr); + ret_array[1]=ip_format2range(ip_rule->addr_type, ip_format_str2int(daddr_format), dst_ip1, dst_ip2, ip_rule->ipv6_rule.min_daddr, ip_rule->ipv6_rule.max_daddr); - ret_array[2]=inet_pton(AF_INET6,dst_ip,&(ip_rule->ipv6_rule.daddr)); - ipv6_ntoh(ip_rule->ipv6_rule.daddr); - ret_array[3]=inet_pton(AF_INET6,mask_dst_ip,&(ip_rule->ipv6_rule.dmask)); - ipv6_ntoh(ip_rule->ipv6_rule.dmask); - - ip_rule->ipv6_rule.min_sport=i_src_port&i_sport_mask; - ip_rule->ipv6_rule.max_sport=(i_src_port&i_sport_mask)+(~i_sport_mask); - - ip_rule->ipv6_rule.min_dport=i_dst_port&i_dport_mask; - ip_rule->ipv6_rule.max_dport=(i_dst_port&i_dport_mask)+~(i_dport_mask); - + if(FORMAT_MASK==ip_format_str2int(dport_format)) + { + ip_rule->ipv6_rule.min_dport=dst_port1&dst_port2; + ip_rule->ipv6_rule.max_dport=dst_port1|~dst_port2; + } + else + { + ip_rule->ipv6_rule.min_sport=dst_port1; + ip_rule->ipv6_rule.max_sport=dst_port2; + } ip_rule->ipv6_rule.proto=protocol; ip_rule->ipv6_rule.direction=direction; - rule_type=RULETYPE_IPv6; } for(i=0;i<4;i++) { - if(ret_array[i]<=0) + if(ret_array[i]<0) { MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , - "update error,invalid format of ip table %s:%s" + "update error, invalid IP address format of ip table %s:%s" ,table->table_name[table->updating_name],table_line); table->udpate_err_cnt++; goto error_out; } } - ret=sync_region(scanner->region_hash - ,ip_rule->region_id - ,table->table_name[table->updating_name] - ,ip_rule->is_valid,logger); + ret=sync_region(scanner->region_hash, + ip_rule->region_id, + ip_rule->group_id, + table->table_name[table->updating_name], + ip_rule->is_valid,logger); if(ret<0) { table->udpate_err_cnt++; @@ -2776,19 +3201,19 @@ void update_ip_rule(struct Maat_table_desc* table,const char* table_line,struct } if(group_mode_on==FALSE)//for compatible old version { - compatible_group_udpate(table - ,ip_rule->region_id - ,ip_rule->group_id - ,ip_rule->is_valid - ,scanner - ,logger); + compatible_group_udpate(table, + ip_rule->region_id, + ip_rule->group_id, + ip_rule->is_valid, + scanner, + logger); ip_rule->group_id=ip_rule->region_id; } if(ip_rule->is_valid==FALSE) { - ret=del_region_rule(table - ,ip_rule->region_id,ip_rule->group_id,rule_type - ,scanner, logger); + ret=del_region_rule(table, + ip_rule->region_id, ip_rule->group_id, ip_rule->addr_type==6?RULETYPE_IPv6:RULETYPE_IPv4, + scanner, logger); if(ret<0) { table->udpate_err_cnt++; @@ -2801,7 +3226,7 @@ void update_ip_rule(struct Maat_table_desc* table,const char* table_line,struct else { - ret=add_ip_rule(table, ip_rule,scanner, logger); + ret=add_ip_rule(table, ip_rule, scanner, logger); if(ret<0) { MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_module , @@ -2820,9 +3245,9 @@ error_out: ip_rule=NULL; } -void update_intval_rule(struct Maat_table_desc* table,const char* table_line,struct Maat_scanner_t *scanner,void* logger,int group_mode_on) +void update_intval_rule(struct Maat_table_desc* table,const char* table_line,struct Maat_scanner *scanner,void* logger,int group_mode_on) { - struct db_intval_rule_t* intval_rule=ALLOC(struct db_intval_rule_t, 1); + struct db_intval_rule* intval_rule=ALLOC(struct db_intval_rule, 1); struct Maat_table_runtime* table_rt=scanner->table_rt[table->table_id]; int ret=0; ret=sscanf(table_line,"%d\t%d\t%u\t%u\t%d",&(intval_rule->region_id) @@ -2839,10 +3264,11 @@ void update_intval_rule(struct Maat_table_desc* table,const char* table_line,str table->udpate_err_cnt++; goto error_out; } - ret=sync_region(scanner->region_hash - ,intval_rule->region_id - ,table->table_name[table->updating_name] - ,intval_rule->is_valid,logger); + ret=sync_region(scanner->region_hash, + intval_rule->region_id, + intval_rule->group_id, + table->table_name[table->updating_name], + intval_rule->is_valid, logger); if(ret<0) { table->udpate_err_cnt++; @@ -2895,96 +3321,96 @@ error_out: intval_rule=NULL; } -void update_compile_rule(struct Maat_table_desc* table,const char* table_line,struct Maat_scanner_t *scanner, const struct rule_tag* tags, int n_tags,void* logger) +void update_compile_rule(struct Maat_table_desc* table,const char* table_line ,struct Maat_scanner *scanner, const struct rule_tag* tags, int n_tags,void* logger) { struct compile_table_desc* compile_desc=&(table->compile); struct Maat_table_runtime* table_rt=scanner->table_rt[table->table_id]; - struct db_compile_rule_t *p_compile=ALLOC(struct db_compile_rule_t, 1); - struct _head_Maat_rule_t* p_m_rule=&(p_compile->m_rule_head); - char user_region[MAX_TABLE_LINE_SIZE]={0}; + struct Maat_compile_rule *p_compile=NULL; + struct Maat_rule_head m_rule_tmp; + memset(&m_rule_tmp, 0, sizeof(m_rule_tmp)); + + char service_define[MAX_TABLE_LINE_SIZE]={0}; char tag_str[MAX_TABLE_LINE_SIZE]={0}; int ret=0; - p_compile->declare_grp_num=0; - ret=sscanf(table_line,"%d\t%d\t%hhd\t%hhd\t%hhd\t%s\t%s\t%d\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) - ,tag_str - ,user_region - ,&(p_compile->is_valid) - ,&(p_compile->declare_grp_num)); - if((ret!=8&&ret!=9)||p_compile->declare_grp_num>MAAT_MAX_EXPR_ITEM_NUM) - { - MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , - "update error,invalid format of compile table %s:%s" + int is_valid=0, declared_grp_num=0; + ret=sscanf(table_line,"%d\t%d\t%hhd\t%hhd\t%hhd\t%s\t%s\t%d\t%d",&(m_rule_tmp.config_id), + &(m_rule_tmp.service_id), + &(m_rule_tmp.action), + &(m_rule_tmp.do_blacklist), + &(m_rule_tmp.do_log), + tag_str, + service_define, + &is_valid, + &declared_grp_num); + if((ret!=8&&ret!=9)||declared_grp_num>MAAT_MAX_EXPR_ITEM_NUM) + { + MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module , + "update error, invalid format of compile table %s:%s" ,table->table_name[table->updating_name],table_line); - table->udpate_err_cnt++; - goto no_save; + goto error_out; } if(n_tags>0&&strlen(tag_str)>2) { ret=compare_accept_tag(tag_str, tags, n_tags); if(ret<0) { - MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_module , - "update error,invalid tag format of compile table %s:%s" + MESA_handle_runtime_log(logger, RLOG_LV_FATAL,maat_module , + "update error, invalid tag format of compile table %s:%s" ,table->table_name[table->updating_name],table_line); - table->udpate_err_cnt++; - goto no_save; + goto error_out; } if(ret==0) { table->unmatch_tag_cnt++; - goto no_save; + return; } } switch(compile_desc->user_region_encoding) { case USER_REGION_ENCODE_ESCAPE: - str_unescape(user_region); + str_unescape(service_define); break; default: break; } - p_m_rule->serv_def_len=strlen(user_region)+1; - p_compile->service_defined= ALLOC(char, p_m_rule->serv_def_len); - memcpy(p_compile->service_defined,user_region,p_m_rule->serv_def_len); - if(p_compile->is_valid==FALSE) + if(is_valid==FALSE) { - ret=del_compile_rule(table,p_compile,scanner, logger); - table_rt->origin_rule_num--; - goto no_save; + ret=del_compile_rule(table, m_rule_tmp.config_id, scanner, logger); + if(ret>0) + { + table_rt->origin_rule_num--; + } + goto error_out; } else { - ret=add_compile_rule(table, p_compile, scanner,logger); + p_compile=create_compile_rule(&m_rule_tmp, service_define, declared_grp_num, table); + ret=add_compile_rule(table, p_compile, scanner, logger); if(ret<0) { - MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_module , - "duplicate config of compile table %s config_id=%d" - ,table->table_name[table->updating_name],p_m_rule->config_id); - table->udpate_err_cnt++; - goto no_save; + MESA_handle_runtime_log(logger, RLOG_LV_INFO, maat_module, + "duplicate config of compile table %s config_id=%d", + table->table_name[table->updating_name], m_rule_tmp.config_id); + table->udpate_err_cnt++; + destroy_compile_rule(p_compile); + p_compile=NULL; + goto error_out; } table_rt->origin_rule_num++; } return; -no_save: - free(p_compile->service_defined); - p_compile->service_defined=NULL; - free(p_compile); - p_compile=NULL; +error_out: + table->udpate_err_cnt++; return; } -void update_digest_rule(struct Maat_table_desc* table,const char* table_line,struct Maat_scanner_t *scanner,void* logger,int group_mode_on) +void update_digest_rule(struct Maat_table_desc* table,const char* table_line,struct Maat_scanner *scanner,void* logger,int group_mode_on) { struct Maat_table_runtime* table_rt=scanner->table_rt[table->table_id]; - struct db_digest_rule_t* digest_rule=ALLOC(struct db_digest_rule_t, 1); + struct db_digest_rule* digest_rule=ALLOC(struct db_digest_rule, 1); int ret=0; char digest_buff[MAX_TABLE_LINE_SIZE]={'\0'}; if(table->table_type==TABLE_TYPE_DIGEST) @@ -3018,10 +3444,11 @@ void update_digest_rule(struct Maat_table_desc* table,const char* table_line,str table->udpate_err_cnt++; goto error_out; } - ret=sync_region(scanner->region_hash - ,digest_rule->region_id - ,table->table_name[table->updating_name] - ,digest_rule->is_valid,logger); + ret=sync_region(scanner->region_hash, + digest_rule->region_id, + digest_rule->group_id, + table->table_name[table->updating_name], + digest_rule->is_valid, logger); if(ret<0) { table->udpate_err_cnt++; @@ -3127,10 +3554,13 @@ void garbage_bury(MESA_lqueue_head garbage_q,int timeout,void *logger) switch(bag->type) { case GARBAGE_COMPILE_RULE: - destroy_compile_rule(bag->compile_rule); + destroy_compile_rule(bag->compile_rule); + break; + case GARBAGE_COMPILE_GOURP_RELATION: + _destroy_compile_group_relation(bag->compile_group_relation); break; case GARBAGE_GROUP_RULE: - destroy_group_rule(bag->group_rule); + _destroy_group_rule(bag->group_rule); break; case GARBAGE_SCANNER: ref_cnt=alignment_int64_array_sum(bag->scanner->ref_cnt, bag->scanner->max_thread_num); @@ -3185,7 +3615,7 @@ void garbage_bury(MESA_lqueue_head garbage_q,int timeout,void *logger) q_cnt,bury_cnt); } } -void update_plugin_table(struct Maat_table_desc* table,const char* table_line,Maat_scanner_t* scanner, const struct rule_tag* tags, int n_tags, void* logger) +void update_plugin_table(struct Maat_table_desc* table,const char* table_line,Maat_scanner* scanner, const struct rule_tag* tags, int n_tags, void* logger) { int i=0, ret=1, matched_tag=1; unsigned int len=strlen(table_line)+1; @@ -3240,8 +3670,7 @@ void update_plugin_table(struct Maat_table_desc* table,const char* table_line,Ma if(plugin_desc->have_exdata) { ret=Maat_helper_read_column(table_line, plugin_desc->valid_flag_column, &is_valid_offset, &valid_len); - - pthread_rwlock_wrlock(&(table_rt->plugin.rwlock)); + //thread safe is protected by background_update_mutex if(atoi(table_line+is_valid_offset)==1) { plugin_EX_data_new(table, table_line, table_rt->plugin.key2ex_hash, logger); @@ -3250,7 +3679,6 @@ void update_plugin_table(struct Maat_table_desc* table,const char* table_line,Ma { plugin_EX_data_free(table, table_line, table_rt->plugin.key2ex_hash, logger); } - pthread_rwlock_unlock(&(table_rt->plugin.rwlock)); } if(plugin_desc->cb_plug_cnt>0) { @@ -3270,7 +3698,67 @@ void update_plugin_table(struct Maat_table_desc* table,const char* table_line,Ma table_rt->plugin.cache_line_num++; } } -void do_scanner_update(struct Maat_scanner_t* scanner,MESA_lqueue_head garbage_q,int scan_thread_num,void* logger) +void vector_print(igraph_vector_t *v) { + long int i; + for (i=0; i<igraph_vector_size(v); i++) { + printf(" %li", (long int) VECTOR(*v)[i]); + } + printf("\n"); +} + +void walk_group_hash(const uchar * key, uint size, void * data, void * user) +{ + struct Maat_group_inner* group_rule=(struct Maat_group_inner*)data; + struct Maat_group_inner* parent_group=NULL; + struct Maat_scanner* scanner=(struct Maat_scanner*)user; + int tmp_vid=0; + igraph_vector_t vids; + igraph_vector_init(&vids, 0); + + igraph_dfs(&(scanner->group_graph), group_rule->vertex_id, IGRAPH_OUT, + 0, &vids, NULL, NULL, NULL, NULL, NULL, NULL); + + + long int i=0; + long long* temp_group_ids=ALLOC(long long, igraph_vector_size(&vids)); + size_t top_group_cnt=0; + for(i=0; i<igraph_vector_size(&vids); i++) + { + tmp_vid=(int) VECTOR(vids)[i]; + if(tmp_vid<0) + { + break; + } + parent_group=(struct Maat_group_inner*)HASH_fetch_by_id(scanner->vertex_id2group, tmp_vid); + if(parent_group->has_compile_neighbors)//including itself + { + temp_group_ids[top_group_cnt]=parent_group->group_id; + top_group_cnt++; + } + } + pthread_mutex_lock(&(group_rule->mutex)); + free(group_rule->top_groups); + group_rule->top_group_cnt=top_group_cnt; + group_rule->top_groups=ALLOC(long long, group_rule->top_group_cnt); + memcpy(group_rule->top_groups, temp_group_ids, sizeof(long long)*group_rule->top_group_cnt); + if(group_rule->top_group_cnt>scanner->max_presented_top_group_cnt) + { + scanner->max_presented_top_group_cnt=group_rule->top_group_cnt; + scanner->most_popular_sub_group=group_rule->group_id; + } + pthread_mutex_unlock(&(group_rule->mutex)); + igraph_vector_destroy(&vids); + free(temp_group_ids); + temp_group_ids=NULL; + return; +} + +void find_group_paths(struct Maat_scanner* scanner) +{ + MESA_htable_iterate(scanner->group_hash, walk_group_hash, scanner); + return; +} +void do_scanner_update(struct Maat_scanner* scanner, MESA_lqueue_head garbage_q, int scan_thread_num, void* logger) { struct bool_matcher *tmp1=NULL,*tmp2=NULL; MESA_htable_handle tmp_map=NULL; @@ -3280,6 +3768,17 @@ void do_scanner_update(struct Maat_scanner_t* scanner,MESA_lqueue_head garbage_q GIE_create_para_t para; para.gram_value=7; para.position_accuracy=10; + igraph_bool_t is_dag; + igraph_is_dag(&(scanner->group_graph), &is_dag); + if(!is_dag) + { + MESA_handle_runtime_log(logger, RLOG_LV_FATAL, maat_module, + "Sub group cycle detected! Version %d", + scanner->version); + return; + } + find_group_paths(scanner); + tmp1=create_bool_matcher(scanner->compile_hash, scan_thread_num, logger); @@ -3292,7 +3791,11 @@ void do_scanner_update(struct Maat_scanner_t* scanner,MESA_lqueue_head garbage_q garbage_bagging(GARBAGE_BOOL_MATCHER, tmp2, garbage_q); } MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_module , - "Version %d dedup string rule %lu",scanner->version,scanner->dedup_expr_num); + "Version %d: dedup string rule %lu, sub group %d presents %d top groups", + scanner->version, + scanner->dedup_expr_num, + scanner->most_popular_sub_group, + scanner->max_presented_top_group_cnt); scanner->dedup_expr_num=0; rulescan_batch_update(scanner->region, scanner->region_update_q, @@ -3341,7 +3844,6 @@ void do_scanner_update(struct Maat_scanner_t* scanner,MESA_lqueue_head garbage_q } } - scanner->gie_total_q_size=0; if(scanner->tmp_district_map!=NULL) { tmp_map=scanner->district_map; @@ -3350,7 +3852,9 @@ void do_scanner_update(struct Maat_scanner_t* scanner,MESA_lqueue_head garbage_q garbage_bagging(GARBAGE_MAP_STR2INT, tmp_map, garbage_q); } scanner->last_update_time=time(NULL); - + scanner->gie_update_q_size=0; + scanner->to_update_group_cnt=0; + scanner->to_update_compile_cnt=0; return; } @@ -3400,7 +3904,7 @@ void maat_start_cb(long long new_version,int update_type,void*u_para) } return; } -long long scanner_rule_num(struct Maat_scanner_t *scanner) +long long scanner_rule_num(struct Maat_scanner *scanner) { long long total=0; struct Maat_table_runtime* table_rt=NULL; @@ -3471,7 +3975,7 @@ void maat_finish_cb(void* u_para) feather->scanner->cfg_num=scanner_rule_num(feather->scanner); feather->scanner->version=feather->maat_version; expr_wait_q_cnt=MESA_lqueue_get_count(feather->scanner->region_update_q); - feather->postpone_q_size=expr_wait_q_cnt+feather->scanner->gie_total_q_size; + feather->postpone_q_size=expr_wait_q_cnt+feather->scanner->gie_update_q_size; if(time(NULL)-feather->scanner->last_update_time>=feather->effect_interval_ms/1000) { do_scanner_update(feather->scanner @@ -3505,7 +4009,7 @@ int maat_update_cb(const char* table_name,const char* line,void *u_para) struct _Maat_feather_t *feather=(struct _Maat_feather_t *)u_para; int ret=-1,i=0; int table_id=-1; - Maat_scanner_t* scanner=NULL; + Maat_scanner* scanner=NULL; struct Maat_table_desc* p_table=NULL; if(feather->update_tmp_scanner!=NULL) { @@ -3515,10 +4019,11 @@ int maat_update_cb(const char* table_name,const char* line,void *u_para) { scanner=feather->scanner; } +// MESA_handle_runtime_log(feather->logger, RLOG_LV_DEBUG, maat_module, "Maat table %s input: %s", table_name, line); ret=map_str2int(feather->map_tablename2id,table_name,&table_id); if(ret<0) { - MESA_handle_runtime_log(feather->logger,RLOG_LV_INFO,maat_module ,"update warning,unknown table name %s",table_name); + MESA_handle_runtime_log(feather->logger, RLOG_LV_INFO, maat_module ,"update warning, unknown table name %s",table_name); return -1; } p_table=feather->p_table_info[table_id]; @@ -3538,6 +4043,7 @@ int maat_update_cb(const char* table_name,const char* line,void *u_para) update_expr_rule(feather->p_table_info[table_id], line, scanner,feather->logger,feather->GROUP_MODE_ON); break; case TABLE_TYPE_IP: + case TABLE_TYPE_IP_PLUS: update_ip_rule(feather->p_table_info[table_id], line, scanner,feather->logger,feather->GROUP_MODE_ON); break; case TABLE_TYPE_INTERVAL: @@ -3564,13 +4070,14 @@ int maat_update_cb(const char* table_name,const char* line,void *u_para) void *thread_rule_monitor(void *arg) { struct _Maat_feather_t *feather=(struct _Maat_feather_t *)arg; - struct Maat_scanner_t* old_scanner=NULL; + struct Maat_scanner* old_scanner=NULL; long expr_wait_q_cnt=0; int scan_dir_cnt=0; int ret=0; char md5_tmp[MD5_DIGEST_LENGTH*2+1]={0}; char tmp_dir[MAX_TABLE_NAME_LEN]={0}; struct stat attrib; + size_t total_wait_rule_cnt=0; char maat_name[16];//Defined by prctl: The name can be up to 16 bytes long,and should // be null terminated if it contains fewer bytes. @@ -3704,8 +4211,9 @@ void *thread_rule_monitor(void *arg) if(feather->scanner!=NULL) { expr_wait_q_cnt=MESA_lqueue_get_count(feather->scanner->region_update_q); - feather->postpone_q_size=expr_wait_q_cnt+feather->scanner->gie_total_q_size; - if(feather->postpone_q_size>0&&time(NULL)-feather->scanner->last_update_time>=feather->effect_interval_ms/1000) + feather->postpone_q_size=expr_wait_q_cnt+feather->scanner->gie_update_q_size; + total_wait_rule_cnt=feather->postpone_q_size+feather->scanner->to_update_compile_cnt+feather->scanner->to_update_group_cnt; + if(total_wait_rule_cnt>0&&time(NULL)-feather->scanner->last_update_time>=feather->effect_interval_ms/1000) { do_scanner_update(feather->scanner ,feather->garbage_q @@ -3745,7 +4253,6 @@ void *thread_rule_monitor(void *arg) alignment_int64_array_free(feather->inner_mid_cnt); alignment_int64_array_free(feather->outer_mid_cnt); alignment_int64_array_free(feather->hit_cnt); - alignment_int64_array_free(feather->orphan_group_saving); alignment_int64_array_free(feather->not_grp_hit_cnt); if(feather->input_mode==SOURCE_REDIS) { diff --git a/src/entry/Maat_stat.cpp b/src/entry/Maat_stat.cpp index c5e4daf..f0573eb 100644 --- a/src/entry/Maat_stat.cpp +++ b/src/entry/Maat_stat.cpp @@ -21,7 +21,6 @@ enum MAAT_FS_STATUS{ STATUS_ICONV_ERR_CNT, STATUS_SCAN_ERR_CNT, STATUS_ZOMBIE_RS_STREAM, - STATUS_ORPHAN_GROUP_SAVING, STATUS_NOT_GROUP_HIT, STATUS_CMD_NUM, STATUS_CMD_Q_SIZE, @@ -73,7 +72,6 @@ void maat_stat_init(struct _Maat_feather_t* feather) feather->fs_status_id[STATUS_INNER_MID_NUM]=FS_register(feather->stat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT,"inner_mid"); feather->fs_status_id[STATUS_ZOMBIE_RS_STREAM]=FS_register(feather->stat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT,"z_stream"); - feather->fs_status_id[STATUS_ORPHAN_GROUP_SAVING]=FS_register(feather->stat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT,"shortcut_sv"); feather->fs_status_id[STATUS_NOT_GROUP_HIT]=FS_register(feather->stat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT,"nt_grp_hit"); feather->fs_status_id[STATUS_TOTAL_SCAN_LEN]=FS_register(feather->stat_handle, FS_STYLE_STATUS, FS_CALC_CURRENT,"scan_bytes"); @@ -168,7 +166,7 @@ void maat_stat_output(struct _Maat_feather_t* feather) long long total_scan_cnt=0, total_cpu_time=0,total_stream_cnt=0,active_thread_num=0; long long table_stream_num=0,table_scan_cnt=0,table_input_bytes=0,table_scan_cpu_time=0,table_hit_cnt=0; long long outer_mid_cnt=0,inner_mid_cnt=0; - long long orphan_group_saving=0, not_grp_hit_cnt=0; + long long not_grp_hit_cnt=0; long long total_update_error=0,total_iconv_error=0; long long compile_rule_num=0, group_rule_num=0, not_group_rule_num=0, plugin_cache_num=0, plugin_acc_num=0; int i=0; @@ -183,7 +181,6 @@ void maat_stat_output(struct _Maat_feather_t* feather) active_thread_num=alignment_int64_array_cnt(feather->thread_call_cnt, feather->scan_thread_num); outer_mid_cnt=alignment_int64_array_sum(feather->outer_mid_cnt,feather->scan_thread_num); inner_mid_cnt=alignment_int64_array_sum(feather->inner_mid_cnt,feather->scan_thread_num); - orphan_group_saving=alignment_int64_array_sum(feather->orphan_group_saving,feather->scan_thread_num); not_grp_hit_cnt=alignment_int64_array_sum(feather->not_grp_hit_cnt,feather->scan_thread_num); FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_VERSION], 0,FS_OP_SET,feather->maat_version); @@ -191,7 +188,6 @@ void maat_stat_output(struct _Maat_feather_t* feather) FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_TABLE_NUM], 0,FS_OP_SET,feather->table_cnt); FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_OUTER_MID_NUM], 0,FS_OP_SET,outer_mid_cnt); FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_INNER_MID_NUM], 0,FS_OP_SET,inner_mid_cnt); - FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_ORPHAN_GROUP_SAVING], 0,FS_OP_SET,orphan_group_saving); FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_NOT_GROUP_HIT], 0,FS_OP_SET,not_grp_hit_cnt); FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_CMD_NUM], 0,FS_OP_SET,feather->cmd_acc_num); FS_operate(feather->stat_handle, feather->fs_status_id[STATUS_CMD_Q_SIZE], 0,FS_OP_SET,feather->cmd_q_cnt); @@ -234,6 +230,7 @@ void maat_stat_output(struct _Maat_feather_t* feather) total_iconv_error=p_table->expr.iconv_err_cnt; break; case TABLE_TYPE_IP: + case TABLE_TYPE_IP_PLUS: table_regex_ipv6_num=table_rt->ip.ipv6_rule_cnt; break; default: diff --git a/src/entry/json2iris.cpp b/src/entry/json2iris.cpp index 0a5bac8..5d45c85 100644 --- a/src/entry/json2iris.cpp +++ b/src/entry/json2iris.cpp @@ -83,7 +83,7 @@ static int get_group_seq(struct iris_description_t* iris_cfg) } else { - data_reply=_wrap_redisCommand(iris_cfg->redis_write_ctx,"INCRBY SEQUENCE_GROUP 1"); + data_reply=_wrap_redisCommand(iris_cfg->redis_write_ctx,"INCRBY %s 1", mr_group_id_var); sequence=(int)data_reply->integer-1; freeReplyObject(data_reply); } @@ -100,7 +100,7 @@ static int get_region_seq(struct iris_description_t* iris_cfg) } else { - data_reply=_wrap_redisCommand(iris_cfg->redis_write_ctx,"INCRBY SEQUENCE_REGION 1"); + data_reply=_wrap_redisCommand(iris_cfg->redis_write_ctx,"INCRBY %s 1", mr_region_id_var); sequence=(int)data_reply->integer-1; freeReplyObject(data_reply); } @@ -141,6 +141,7 @@ int set_iris_descriptor(const char* json_file,cJSON *json,const char*compile_tn, map_register(iris_cfg->str2int_map, "no",0); map_register(iris_cfg->str2int_map, "ip",TABLE_TYPE_IP); + map_register(iris_cfg->str2int_map, "ip_plus",TABLE_TYPE_IP_PLUS); 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); @@ -321,7 +322,7 @@ error_out: } return -1; } -int write_ip_rule(cJSON *region_json,struct iris_description_t *p_iris,const char* path,void * logger) +int write_ip_line(cJSON *region_json, struct iris_description_t *p_iris, const char* path, void * logger) { struct traslate_command_t json_cmd[MAX_COLUMN_NUM]; int cmd_cnt=0; @@ -407,7 +408,119 @@ int write_ip_rule(cJSON *region_json,struct iris_description_t *p_iris,const cha return direct_write_rule(region_json, p_iris->str2int_map,json_cmd, cmd_cnt,path,logger); } -int write_expr_rule(cJSON *region_json,struct iris_description_t *p_iris,const char* path,enum MAAT_TABLE_TYPE table_type,void * logger) +int write_ip_plus_line(cJSON *region_json, struct iris_description_t *p_iris, const char* path, void * logger) +{ + struct traslate_command_t json_cmd[MAX_COLUMN_NUM]; + int cmd_cnt=0; + memset(json_cmd,0,sizeof(json_cmd)); + + json_cmd[cmd_cnt].json_string="region_id"; + json_cmd[cmd_cnt].json_type=cJSON_Number; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="group_id"; + json_cmd[cmd_cnt].json_type=cJSON_Number; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="addr_type"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].str2int_flag=1; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="saddr_format"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_string="mask"; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="src_ip1"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_string="0.0.0.0"; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="src_ip2"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_string="255.255.255.255"; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="sport_format"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_string="mask"; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="src_port1"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_string="0"; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="src_port2"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_string="65535"; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="daddr_format"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_string="mask"; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="dst_ip1"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_string="0.0.0.0"; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="dst_ip2"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_string="255.255.255.255"; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="dport_format"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_string="mask"; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="dst_port1"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_string="0"; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="dst_port2"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_string="65535"; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="protocol"; + json_cmd[cmd_cnt].json_type=cJSON_Number; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_int=0; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="direction"; + json_cmd[cmd_cnt].json_type=cJSON_String; + json_cmd[cmd_cnt].str2int_flag=1; + json_cmd[cmd_cnt].empty_allowed=1; + json_cmd[cmd_cnt].default_string="double"; + cmd_cnt++; + + json_cmd[cmd_cnt].json_string="is_valid"; + json_cmd[cmd_cnt].json_type=cJSON_Number; + cmd_cnt++; + + return direct_write_rule(region_json, p_iris->str2int_map,json_cmd, cmd_cnt,path,logger); + +} + +int write_expr_line(cJSON *region_json,struct iris_description_t *p_iris,const char* path,enum MAAT_TABLE_TYPE table_type,void * logger) { struct traslate_command_t json_cmd[MAX_COLUMN_NUM]; int cmd_cnt=0; @@ -454,7 +567,7 @@ int write_expr_rule(cJSON *region_json,struct iris_description_t *p_iris,const c return direct_write_rule(region_json, p_iris->str2int_map,json_cmd, cmd_cnt,path,logger); } -int write_intval_rule(cJSON *region_json,struct iris_description_t *p_iris,const char* path,void * logger) +int write_intval_line(cJSON *region_json,struct iris_description_t *p_iris,const char* path,void * logger) { struct traslate_command_t json_cmd[MAX_COLUMN_NUM]; int cmd_cnt=0; @@ -483,7 +596,7 @@ int write_intval_rule(cJSON *region_json,struct iris_description_t *p_iris,const return direct_write_rule(region_json, p_iris->str2int_map,json_cmd, cmd_cnt,path,logger); } -int write_digest_rule(cJSON *region_json,struct iris_description_t *p_iris,const char* path,void * logger) +int write_digest_line(cJSON *region_json, struct iris_description_t *p_iris, const char* path, void * logger) { struct traslate_command_t json_cmd[MAX_COLUMN_NUM]; int cmd_cnt=0; @@ -516,7 +629,7 @@ int write_digest_rule(cJSON *region_json,struct iris_description_t *p_iris,const return direct_write_rule(region_json, p_iris->str2int_map,json_cmd, cmd_cnt,path,logger); } -int write_similar_rule(cJSON *region_json,struct iris_description_t *p_iris,const char* path,void * logger) +int write_similar_line(cJSON *region_json, struct iris_description_t *p_iris, const char* path, void * logger) { struct traslate_command_t json_cmd[MAX_COLUMN_NUM]; int cmd_cnt=0; @@ -546,7 +659,7 @@ int write_similar_rule(cJSON *region_json,struct iris_description_t *p_iris,cons } -int write_plugin_table(cJSON* plug_table_json,int sequence,iris_description_t* p_iris,void* logger) +int write_plugin_line(cJSON* plug_table_json,int sequence,iris_description_t* p_iris,void* logger) { cJSON* item=NULL,*table_content=NULL,*each_line=NULL; struct iris_table_t* table_info=NULL; @@ -665,19 +778,22 @@ int write_region_rule(cJSON* region_json,int compile_id,int group_id,iris_descri { case TABLE_TYPE_EXPR: case TABLE_TYPE_EXPR_PLUS: - ret=write_expr_rule(table_content, p_iris, table_info->table_path,table_type, logger); + ret=write_expr_line(table_content, p_iris, table_info->table_path,table_type, logger); break; case TABLE_TYPE_IP: - ret=write_ip_rule(table_content, p_iris, table_info->table_path, logger); + ret=write_ip_line(table_content, p_iris, table_info->table_path, logger); + break; + case TABLE_TYPE_IP_PLUS: + write_ip_plus_line(table_content, p_iris, table_info->table_path, logger); break; case TABLE_TYPE_INTERVAL: - ret=write_intval_rule(table_content, p_iris, table_info->table_path, logger); + ret=write_intval_line(table_content, p_iris, table_info->table_path, logger); break; case TABLE_TYPE_DIGEST: - ret=write_digest_rule(table_content, p_iris, table_info->table_path, logger); + ret=write_digest_line(table_content, p_iris, table_info->table_path, logger); break; case TABLE_TYPE_SIMILARITY: - write_similar_rule(table_content, p_iris,table_info->table_path, logger); + write_similar_line(table_content, p_iris,table_info->table_path, logger); break; default: assert(0); @@ -691,7 +807,7 @@ int write_region_rule(cJSON* region_json,int compile_id,int group_id,iris_descri return ret; } -int write_compile_rule(cJSON *compile,struct iris_description_t *p_iris,void * logger) +int write_compile_line(cJSON *compile, struct iris_description_t *p_iris, void * logger) { int compile_id=-1,cmd_cnt=0,ret=-1; cJSON* item=NULL; @@ -772,7 +888,7 @@ int write_compile_rule(cJSON *compile,struct iris_description_t *p_iris,void * l set_file_rulenum(table_info->table_path,table_info->line_count,logger); return compile_id; } -int write_group_rule(int compile_id ,int group_id, int group_not_flag, struct iris_description_t *p_iris,void * logger) +int write_group_line(int group_id, int parent_id, int group_not_flag, int parent_type, struct iris_description_t *p_iris, void * logger) { FILE*fp=NULL; int ret=0; @@ -792,7 +908,7 @@ int write_group_rule(int compile_id ,int group_id, int group_not_flag, struct ir "fopen %s error %s.",p_iris->group_table->table_path,strerror(errno)); return -1; } - fprintf(fp,"%d\t%d\t1\t%d\n",group_id, compile_id, group_not_flag); + fprintf(fp,"%d\t%d\t1\t%d\t%d\n",group_id, parent_id, group_not_flag, parent_type); fclose(fp); p_iris->group_table->line_count++; ret=set_file_rulenum(p_iris->group_table->table_path,p_iris->group_table->line_count,logger); @@ -818,17 +934,104 @@ int write_index_file(struct iris_description_t *p_iris,void* logger) fclose(fp); return 0; } -int write_iris(cJSON *json,struct iris_description_t *p_iris,void* logger) +int write_group_rule(cJSON *group_json, int parent_id, int parent_type, int tracking_compile_id, struct iris_description_t *p_iris, void* logger) { - int i=0,j=0,k=0; - int compile_id=-1,compile_cnt=0,group_cnt=0,region_cnt=0,plug_table_cnt=0; + const char* _str_parent_type[2]={"compile", "group"}; + int i=0; + int sub_group_cnt=0, region_cnt=0; int ret=0; int group_not_flag=0; - cJSON *c_rules=NULL,*g_rules=NULL,*r_rules=NULL,*item=NULL,*plug_tables=NULL; - cJSON *compile_rule=NULL,*group_rule=NULL,*region_rule=NULL,*each_plug_table=NULL; + cJSON *region_json=NULL, *item=NULL; + cJSON *sub_groups=NULL, *region_rule=NULL; const char* group_name=NULL; struct group_info_t *group_info=NULL; struct group_info_t untitled_group; + + item=cJSON_GetObjectItem(group_json, "group_name"); + if(item==NULL||item->type!=cJSON_String) + { + group_name=untitled_group_name; + } + else + { + group_name=item->valuestring; + } + item=cJSON_GetObjectItem(group_json,"not_flag"); + if(item==NULL||item->type!=cJSON_Number) + { + group_not_flag=0; + } + else + { + group_not_flag=item->valueint; + } + if(parent_type==PARENT_TYPE_GROUP) + { + group_not_flag=0; + } + + group_info=(struct group_info_t*)MESA_htable_search(p_iris->group_name_map, (const unsigned char*)group_name, strlen(group_name)); + if(group_info==NULL)//exist group name, region already read + { + if(0==strncasecmp(group_name, untitled_group_name, strlen(untitled_group_name))) + { + group_info=&untitled_group; + group_info->group_id=get_group_seq(p_iris); + } + else + { + group_info=ALLOC(struct group_info_t, 1); + group_info->group_id=get_group_seq(p_iris); + MESA_htable_add(p_iris->group_name_map,(const unsigned char*)group_name, strlen(group_name),group_info); + } + } + ret=write_group_line(group_info->group_id, parent_id, group_not_flag, parent_type, p_iris, logger); + if(ret<0) + { + MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json, + "%s rule %d write group error.", _str_parent_type[parent_type], parent_id); + return -1; + } + region_json=cJSON_GetObjectItem(group_json,"regions"); + if(region_json!=NULL) + { + region_cnt=cJSON_GetArraySize(region_json); + for(i=0; i<region_cnt; i++) + { + region_rule=cJSON_GetArrayItem(region_json,i); + ret=write_region_rule(region_rule, tracking_compile_id, group_info->group_id, p_iris, logger); + if(ret<0) + { + MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json, + "compile rule %d write region error.", tracking_compile_id); + return -1; + } + } + } + sub_groups=cJSON_GetObjectItem(group_json,"sub_groups"); + if(sub_groups!=NULL) + { + //recursively + sub_group_cnt=cJSON_GetArraySize(sub_groups); + for(i=0; i<sub_group_cnt; i++) + { + item=cJSON_GetArrayItem(sub_groups, i); + ret=write_group_rule(item, group_info->group_id, PARENT_TYPE_GROUP, tracking_compile_id, p_iris, logger); + if(ret<0) + { + return -1; + } + } + } + return 0; +} +int write_iris(cJSON *json, struct iris_description_t *p_iris, void* logger) +{ + int i=0,j=0; + int compile_id=-1, compile_cnt=0, group_cnt=0, plug_table_cnt=0; + int ret=0; + cJSON *c_rules=NULL, *g_rules=NULL, *plug_tables=NULL; + cJSON *compile_rule=NULL,*group_rule=NULL, *each_plug_table=NULL; plug_tables=cJSON_GetObjectItem(json,"plugin_table"); if(NULL!=plug_tables) { @@ -836,7 +1039,7 @@ int write_iris(cJSON *json,struct iris_description_t *p_iris,void* logger) for(i=0;i<plug_table_cnt;i++) { each_plug_table=cJSON_GetArrayItem(plug_tables,i); - write_plugin_table(each_plug_table, i, p_iris, logger); + write_plugin_line(each_plug_table, i, p_iris, logger); } } c_rules=cJSON_GetObjectItem(json,"rules"); @@ -857,7 +1060,7 @@ int write_iris(cJSON *json,struct iris_description_t *p_iris,void* logger) for(i=0;i<compile_cnt;i++) { compile_rule=cJSON_GetArrayItem(c_rules,i); - compile_id=write_compile_rule(compile_rule,p_iris, logger); + compile_id=write_compile_line(compile_rule,p_iris, logger); if(compile_id<0) { MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json, @@ -881,87 +1084,11 @@ int write_iris(cJSON *json,struct iris_description_t *p_iris,void* logger) for(j=0;j<group_cnt;j++) { group_rule=cJSON_GetArrayItem(g_rules,j); - item=cJSON_GetObjectItem(group_rule,"not_flag"); - if(item==NULL||item->type!=cJSON_Number) - { - group_not_flag=0; - } - else - { - group_not_flag=item->valueint; - } - item=cJSON_GetObjectItem(group_rule,"group_name"); - if(item==NULL||item->type!=cJSON_String) - { - group_name=untitled_group_name; - } - else - { - group_name=item->valuestring; - } - group_info=(struct group_info_t*)MESA_htable_search(p_iris->group_name_map, (const unsigned char*)group_name, strlen(group_name)); - if(group_info!=NULL)//exist group name ,region already read - { - ret=write_group_rule(compile_id, group_info->group_id, group_not_flag, p_iris, logger); - if(ret<0) - { - MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json, - "compile rule %d write group error.",compile_id); - return -1; - } - r_rules=cJSON_GetObjectItem(group_rule,"regions"); - if(r_rules!=NULL) - { - MESA_handle_runtime_log(logger,RLOG_LV_INFO,maat_json, - "compile rule %d's %s declared in previous compile rule, regions NOT take effect." - ,compile_id,group_name); - } - continue; - } - if(0==strncasecmp(group_name,untitled_group_name,strlen(untitled_group_name))) - { - group_info=&untitled_group; - group_info->group_id=get_group_seq(p_iris); - } - else - { - group_info=(struct group_info_t*)malloc(sizeof(struct group_info_t)); - group_info->group_id=get_group_seq(p_iris); - MESA_htable_add(p_iris->group_name_map,(const unsigned char*)group_name, strlen(group_name),group_info); - } - r_rules=cJSON_GetObjectItem(group_rule,"regions"); - if(r_rules==NULL) - { - MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json, - "compile rule %d's %s has no region.",compile_id,group_name); - return -1; - } - region_cnt=cJSON_GetArraySize(r_rules); - if(region_cnt<=0) - { - MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json, - "compile rule %d's %s has no region.",compile_id,group_name); - return -1; - } - for(k=0;k<region_cnt;k++) - { - region_rule=cJSON_GetArrayItem(r_rules,k); - ret=write_region_rule(region_rule, compile_id, group_info->group_id, p_iris, logger); - if(ret<0) - { - MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json, - "compile rule %d write region error.",compile_id); - return -1; - } - } - ret=write_group_rule(compile_id, group_info->group_id, group_not_flag, p_iris, logger); + ret=write_group_rule(group_rule, compile_id, PARENT_TYPE_COMPILE, compile_id, p_iris, logger); if(ret<0) { - MESA_handle_runtime_log(logger,RLOG_LV_FATAL,maat_json, - "compile rule %d write group error.",compile_id); return -1; } - } } ret=write_index_file(p_iris,logger); @@ -971,6 +1098,7 @@ int write_iris(cJSON *json,struct iris_description_t *p_iris,void* logger) } return 0; } +// redis_write_ctx is used by maat_redis_tool to write json to redis. int json2iris(const char* json_file,const char*compile_tn,const char* group_tn,redisContext *redis_write_ctx,char* iris_dir_buf,int buf_len,void* logger) { FILE* json_fp=NULL; diff --git a/src/inc_internal/Maat_rule_internal.h b/src/inc_internal/Maat_rule_internal.h index 22ef3fb..dcb31a0 100644 --- a/src/inc_internal/Maat_rule_internal.h +++ b/src/inc_internal/Maat_rule_internal.h @@ -12,7 +12,7 @@ #include "dynamic_array.h" #include "bool_matcher.h" #include "hiredis.h" - +#include "igraph/igraph.h" #include "stream_fuzzy_hash.h" #include "gram_index_engine.h" #include "alignment_int64.h" @@ -23,6 +23,8 @@ extern const char *maat_module; +#define mr_region_id_var "SEQUENCE_REGION" +#define mr_group_id_var "SEQUENCE_GROUP" #define MAX_TABLE_NUM 256 @@ -69,14 +71,14 @@ struct db_ip_rule_t }; int is_valid; }; -struct db_intval_rule_t +struct db_intval_rule { int region_id; int group_id; interval_rule_t intval; int is_valid; }; -struct db_digest_rule_t +struct db_digest_rule { int region_id; int group_id; @@ -85,7 +87,7 @@ struct db_digest_rule_t short confidence_degree; int is_valid; }; -struct _head_Maat_rule_t +struct Maat_rule_head { int config_id; int service_id; @@ -95,20 +97,23 @@ struct _head_Maat_rule_t char resevered; int serv_def_len; }; -struct db_compile_rule_t +struct Maat_compile_rule { - struct _head_Maat_rule_t m_rule_head;// fix len of Maat_rule_t + struct Maat_rule_head head;// fix len of Maat_rule_t char* service_defined; - long long effective_range; int is_valid; - int declare_grp_num; + int declared_grp_num; + const struct Maat_table_desc* ref_table; + MAAT_RULE_EX_DATA* ads; }; + struct db_group_rule_t { int group_id; - int compile_id; + int parent_id; int is_valid; int not_flag; + int parent_type; //PARENT_TYPE_**, 0:compile, 1: group. }; struct op_expr_t { @@ -120,7 +125,7 @@ struct op_expr_t int rule_type; }; -struct _Maat_region_inner_t +struct Maat_region_inner { int region_id; int district_id; @@ -130,32 +135,38 @@ struct _Maat_region_inner_t int expr_id_ub; enum MAAT_TABLE_TYPE table_type; }; -struct Maat_group_inner_t +#define COMPILE_RELATION_MAGIC 0x1a2b3c4d +struct Maat_compile_group_relation +{ + long long magic_num; + struct Maat_compile_rule *compile; + dynamic_array_t *groups; //element is struct Maat_group_inner* + char not_flag[MAX_ITEMS_PER_BOOL_EXPR]; + int compile_id;//equal to compile->m_rule.config_id + int group_boundary; + int group_cnt; + int not_group_cnt; + pthread_rwlock_t rwlock;//reading compile rule is safe in update thread, rwlock lock called when delete or scan thread read + +}; + +struct Maat_group_inner { int group_id; int table_id; int region_boundary; int region_cnt; - int ref_cnt; + int ref_by_parent_cnt; + int ref_by_children_cnt; char* group_name; + int has_compile_neighbors; + int vertex_id; + int top_group_cnt; + long long* top_groups; dynamic_array_t *regions; - void* compile_shortcut; pthread_mutex_t mutex; }; -struct Maat_compile_inner_t -{ - struct db_compile_rule_t *db_c_rule; - dynamic_array_t *groups; //element is struct Maat_group_inner_t* - char not_flag[MAX_ITEMS_PER_BOOL_EXPR]; - char is_valid; - int compile_id;//equal to db_c_rule->m_rule.config_id - const struct Maat_table_desc* ref_table; - int group_boundary; - int group_cnt; - int not_group_cnt; - MAAT_RULE_EX_DATA* ads; - pthread_rwlock_t rwlock;//reading compile rule is safe in update thread, rwlock lock called when delete or scan thread read -}; + struct _compile_result_t { int compile_id; @@ -163,11 +174,11 @@ struct _compile_result_t }; struct _INNER_scan_status_t { - size_t cur_hit_cnt; - size_t hit_group_cnt; - size_t hit_group_size; - unsigned long long cur_hit_id[MAX_SCANNER_HIT_NUM]; - unsigned long long *hitted_group_id; + size_t cur_hit_group_cnt; + size_t all_hit_group_cnt; + size_t all_hit_group_array_sz; + struct dynamic_array_t* cur_hit_groups; + unsigned long long *all_hit_group_array; char not_grp_compile_hitted_flag; }; struct _OUTER_scan_status_t @@ -184,6 +195,7 @@ enum maat_garbage_type GARBAGE_SCANNER=0, GARBAGE_GROUP_RULE, GARBAGE_COMPILE_RULE, + GARBAGE_COMPILE_GOURP_RELATION, GARBAGE_BOOL_MATCHER, GARBAGE_MAP_STR2INT, GARBAGE_FOREIGN_FILE @@ -218,13 +230,13 @@ struct similar_runtime GIE_handle_t* gie_handle; MESA_lqueue_head update_q; }; + struct plugin_runtime { dynamic_array_t *cache_lines; long long cache_line_num; long long acc_line_num; long long cache_size; - pthread_rwlock_t rwlock; MESA_htable_handle key2ex_hash; }; struct expr_runtime @@ -252,7 +264,7 @@ struct Maat_table_runtime struct plugin_runtime plugin; struct expr_runtime expr; struct ip_runtime ip; - struct group_runtime group; + struct group_runtime group; void * other; }; mcore_long_t scan_cnt; @@ -266,21 +278,33 @@ struct rule_tag char* tag_name; char* tag_val; }; -struct Maat_scanner_t +struct Maat_scanner { long long version; time_t last_update_time; mcore_long_t ref_cnt; rule_scanner_t region; - long gie_total_q_size; + size_t gie_update_q_size; + size_t to_update_group_cnt; + size_t to_update_compile_cnt; struct Maat_table_runtime* table_rt[MAX_TABLE_NUM]; - MESA_htable_handle region_hash; - MESA_htable_handle group_hash; - MESA_htable_handle compile_hash; + MESA_htable_handle region_hash; //key: region_id, value: struct region_group_relation* + MESA_htable_handle exprid_hash; //key: expr_id, value: int array_idx of Maat_group_inner->regions; + MESA_htable_handle group_hash; //key: group_id, value: struct Maat_group_inner* + MESA_htable_handle compile_hash;//key: compile_id, value: struct Maat_compile_group_relation * + + MESA_htable_handle district_map; MESA_htable_handle tmp_district_map; + MESA_htable_handle vertex_id2group; + + igraph_t group_graph; + int grp_vertex_id_generator; + int most_popular_sub_group; + long long max_presented_top_group_cnt; + unsigned int district_num; unsigned int cfg_num; unsigned int exprid_generator; @@ -288,6 +312,7 @@ struct Maat_scanner_t MESA_lqueue_head region_update_q; struct bool_matcher * bool_matcher_expr_compiler; scan_result_t *region_rslt_buff; + void* logger_ref; MESA_lqueue_head tomb_ref;//reference of g_feather->garbage_q int max_thread_num; @@ -323,8 +348,8 @@ struct source_redis_ctx }; struct _Maat_feather_t { - struct Maat_scanner_t *scanner; - struct Maat_scanner_t *update_tmp_scanner; + struct Maat_scanner *scanner; + struct Maat_scanner *update_tmp_scanner; MESA_lqueue_head garbage_q; int table_cnt; int DEFERRED_LOAD_ON; @@ -390,7 +415,6 @@ struct _Maat_feather_t mcore_long_t inner_mid_cnt; mcore_long_t hit_cnt; mcore_long_t thread_call_cnt;//size indicate by scan_thread_num, - mcore_long_t orphan_group_saving; mcore_long_t not_grp_hit_cnt; long long total_scan_bytes; long long total_scan_cnt; @@ -411,9 +435,10 @@ struct _maat_garbage_t int ok_times; union { - struct Maat_scanner_t* scanner; - struct Maat_group_inner_t* group_rule; - struct Maat_compile_inner_t* compile_rule; + struct Maat_scanner* scanner; + struct Maat_group_inner* group_rule; + struct Maat_compile_rule* compile_rule; + struct Maat_compile_group_relation * compile_group_relation; struct bool_matcher* bool_matcher; void * raw; MESA_htable_handle str2int_map; @@ -443,7 +468,7 @@ int parse_accept_tag(const char* value, struct rule_tag** result, void* logger); void garbage_bagging(enum maat_garbage_type type,void *p,MESA_lqueue_head garbage_q); void garbage_bagging_with_timeout(enum maat_garbage_type type,void *p, int timeout, MESA_lqueue_head garbage_q); void garbage_bury(MESA_lqueue_head garbage_q,void *logger); -void make_group_set(struct Maat_compile_inner_t* compile_rule, struct bool_expr* a_set, unsigned char *has_not); +void make_group_set(struct Maat_compile_group_relation* compile_rule, struct bool_expr* a_set, unsigned char *has_not); int read_table_description(struct Maat_table_desc** p_table_info,int num,const char* table_info_path,int max_thread_num,void* logger); void maat_start_cb(long long new_version,int update_type,void*u_para); int maat_update_cb(const char* table_name,const char* line,void *u_para); @@ -466,9 +491,9 @@ int get_foreign_keys_by_prefix(redisContext *ctx, struct serial_rule_t* rule_lis void get_foreign_conts(redisContext *ctx, struct serial_rule_t* rule_list, int rule_num, int print_fn, void *logger); void rewrite_table_line_with_foreign(struct serial_rule_t*p); -void fill_maat_rule(struct Maat_rule_t *rule, const struct _head_Maat_rule_t* rule_head, const char* srv_def, int srv_def_len); -MAAT_RULE_EX_DATA rule_ex_data_new(const struct _head_Maat_rule_t * rule_head, const char* srv_def, const struct compile_ex_data_idx* ex_desc); -void rule_ex_data_free(const struct _head_Maat_rule_t * rule_head, const char* srv_def, MAAT_RULE_EX_DATA *ad, const struct compile_ex_data_idx* ex_desc); +void fill_maat_rule(struct Maat_rule_t *rule, const struct Maat_rule_head* rule_head, const char* srv_def, int srv_def_len); +MAAT_RULE_EX_DATA rule_ex_data_new(const struct Maat_rule_head * rule_head, const char* srv_def, const struct compile_ex_data_idx* ex_desc); +void rule_ex_data_free(const struct Maat_rule_head * rule_head, const char* srv_def, MAAT_RULE_EX_DATA *ad, const struct compile_ex_data_idx* ex_desc); MESA_htable_handle wrap_plugin_EX_hash_new(long long estimate_size, Maat_plugin_EX_key2index_func_t * key2index); int plugin_EX_data_new(const struct Maat_table_desc* plugin_table, const char* line, MESA_htable_handle key2ex_hash, void *logger); int plugin_EX_data_free(const struct Maat_table_desc* plugin_table, const char* line, MESA_htable_handle key2ex_hash, void *logger); diff --git a/src/inc_internal/Maat_table_description.h b/src/inc_internal/Maat_table_description.h index 4e3fa3a..b924c34 100644 --- a/src/inc_internal/Maat_table_description.h +++ b/src/inc_internal/Maat_table_description.h @@ -18,6 +18,7 @@ enum MAAT_TABLE_TYPE { TABLE_TYPE_EXPR=0, TABLE_TYPE_IP, + TABLE_TYPE_IP_PLUS, TABLE_TYPE_INTERVAL, TABLE_TYPE_DIGEST, TABLE_TYPE_EXPR_PLUS, diff --git a/src/inc_internal/view_only/rulescan.h b/src/inc_internal/view_only/rulescan.h index f7a9a42..4397f18 100644 --- a/src/inc_internal/view_only/rulescan.h +++ b/src/inc_internal/view_only/rulescan.h @@ -28,7 +28,9 @@ extern "C" { RULESCAN_DETAIL_RESULT=1, /* ����־λ��ʾ��������ϸ����λ�õ���Ϣ, optval��ΪNULL��optlen��Ϊ0��Ĭ�ϲ�������ϸ��Ϣ*/ RULESCAN_REGEX_GROUP =2, /* ����־λ��ʾ�������������ʽƥ��ķ�����Ϣ���������ֶΣ���Ҫ������RULESCAN_DETAIL_RESULT��־λ,optval��ΪNULL��optlen��Ϊ0��Ĭ�ϲ����ط�����Ϣ */ - RULESCAN_QUICK_SCAN /* ������Ҫ����ɨ��ģʽ��sub_type, ���û��Լ����壬optval��ֵΪ0-4096��optlen��Ϊ4��Ĭ����������ͨɨ��ģʽ��*/ + RULEACAN_ERRLOG_CLOSE, /* ����־λ��ʾ���ر�Rulescan������־�����optval��ΪNULL��optlen��Ϊ0�������õĻ�Ĭ�ϴ�Rulescan������־��� */ + RULESCAN_ERRLOG_FILE_PATH, /* ����Rulescan������־��·�����������ļ����������û����룬optval��ֵΪ�����ļ�������־·����optlenΪ·�����ȡ����û���趨�� + ����־Ĭ�ϴ洢�ڿ�ִ�г���ǰĿ¼�µ�rulescan_tmp�� */ }; #define MAX_REGEX_GROUP_NUM 5 /* �����������ʽ����֧�ֵ�������ĸ��� */ @@ -45,7 +47,7 @@ extern "C" const unsigned int RULETYPE_IPv6 = 4; /* IPv6���� */ const unsigned int MAX_RULETYPE = 5; /* ������������ */ - const unsigned int MAX_SUB_RULETYPE = 4096; /* �������������� */ + const unsigned int MAX_SUB_RULETYPE = 4096; /* �������������� */ /* �ַ��������ɱ�ʾ�ı��ַ������������ַ������������ʽ�� */ typedef struct _string_rule_t @@ -65,34 +67,34 @@ extern "C" unsigned int ub; /* ����������½磨����ub����������Ĭ��Ϊ0 */ }interval_rule_t; - /* �������IPv4���� */ + /* IPv4���� */ typedef struct _ipv4_rule_t { - unsigned int saddr; /* ԴIP��ַ��0��ʾ���Ա��ֶ� */ - unsigned int smask; /* ԴIP��ַ���룻0��ʾ�̶�IP=saddr */ - unsigned int daddr; /* Ŀ��IP��ַ��0��ʾ���Ա��ֶ� */ - unsigned int dmask; /* Ŀ��IP��ַ���룻0��ʾ�̶�IP=daddr */ - unsigned short int min_sport; /* Դ�˿ڷ�Χ�½磻0��ʾ���Ա��ֶ� */ - unsigned short int max_sport; /* Դ�˿ڷ�Χ�Ͻ磻0��ʾ�̶��˿�=min_sport */ - unsigned short int min_dport; /* Ŀ�Ķ˿ڷ�Χ�½磻0��ʾ���Ա��ֶ� */ - unsigned short int max_dport; /* Ŀ�Ķ˿ڷ�Χ�Ͻ磻0��ʾ�̶��˿�=min_dport */ - unsigned short int proto; /* �����Э�飬6��ʾTCP��17��ʾUDP��0��ʾ���Ա��ֶ� */ - unsigned short int direction; /* ����0��ʾ˫��1��ʾ���� */ + unsigned int min_saddr; /* Դ��ַ�½磻0��ʾ���Ա��ֶ� */ + unsigned int max_saddr; /* Դ��ַ�Ͻ磻0��ʾ�̶�IP=min_saddr */ + unsigned int min_daddr; /* Ŀ�ĵ�ַ�½磻0��ʾ���Ա��ֶ� */ + unsigned int max_daddr; /* Ŀ�ĵ�ַ�Ͻ磻0��ʾ�̶�IP=min_daddr */ + unsigned short min_sport; /* Դ�˿ڷ�Χ�½磻0��ʾ���Ա��ֶ� */ + unsigned short max_sport; /* Դ�˿ڷ�Χ�Ͻ磻0��ʾ�̶��˿�=min_sport */ + unsigned short min_dport; /* Ŀ�Ķ˿ڷ�Χ�½磻0��ʾ���Ա��ֶ� */ + unsigned short max_dport; /* Ŀ�Ķ˿ڷ�Χ�Ͻ磻0��ʾ�̶��˿�=min_dport */ + unsigned short proto; /* �����Э�飬6��ʾTCP��17��ʾUDP��0��ʾ���Ա��ֶ� */ + unsigned short direction; /* ����0��ʾ˫��1��ʾ���� */ }ipv4_rule_t; - /* �������IPv6���� */ + /* IPv6���� */ typedef struct _ipv6_rule_t { - unsigned int saddr[4]; /* ԴIP��ַ��0��ʾ���Ա��ֶ� */ - unsigned int smask[4]; /* ԴIP��ַ���룻0��ʾ�̶�IP=saddr */ - unsigned int daddr[4]; /* Ŀ��IP��ַ��0��ʾ���Ա��ֶ� */ - unsigned int dmask[4]; /* Ŀ��IP��ַ���룻0��ʾ�̶�IP=daddr */ - unsigned short int min_sport; /* Դ�˿ڷ�Χ�½磻0��ʾ���Ա��ֶ� */ - unsigned short int max_sport; /* Դ�˿ڷ�Χ�Ͻ磻0��ʾ�̶��˿�=min_sport */ - unsigned short int min_dport; /* Ŀ�Ķ˿ڷ�Χ�½磻0��ʾ���Ա��ֶ� */ - unsigned short int max_dport; /* Ŀ�Ķ˿ڷ�Χ�Ͻ磻0��ʾ�̶��˿�=min_dport */ - unsigned short int proto; /* �����Э�飬6��ʾTCP��17��ʾUDP��������Ĭ��Ϊ0 */ - unsigned short int direction; /* ����0��ʾ˫��1��ʾ���� */ + unsigned int min_saddr[4]; /* Դ��ַ�½磻ȫ0��ʾ���Ա��ֶ� */ + unsigned int max_saddr[4]; /* Դ��ַ�Ͻ磻ȫ0��ʾ�̶�IP=min_saddr */ + unsigned int min_daddr[4]; /* Ŀ�ĵ�ַ�½磻ȫ0��ʾ���Ա��ֶ� */ + unsigned int max_daddr[4]; /* Ŀ�ĵ�ַ�Ͻ磻ȫ0��ʾ�̶�IP=min_daddr */ + unsigned short min_sport; /* Դ�˿ڷ�Χ�½磻0��ʾ���Ա��ֶ� */ + unsigned short max_sport; /* Դ�˿ڷ�Χ�Ͻ磻0��ʾ�̶��˿�=min_sport */ + unsigned short min_dport; /* Ŀ�Ķ˿ڷ�Χ�½磻0��ʾ���Ա��ֶ� */ + unsigned short max_dport; /* Ŀ�Ķ˿ڷ�Χ�Ͻ磻0��ʾ�̶��˿�=min_dport */ + unsigned short proto; /* �����Э�飬6��ʾTCP��17��ʾUDP��������Ĭ��Ϊ0 */ + unsigned short direction; /* ����0��ʾ˫��1��ʾ���� */ }ipv6_rule_t; /* ͨ�õĹ������� */ @@ -188,7 +190,7 @@ extern "C" unsigned int length[MAX_MATCH_POS_NUM]; /* �ù����������н���ij��ȣ���������н��������ǰ�����ݰ������еģ������ö�Ӧ��length=0, ��������������IP�࣬������Ϊ0*/ }rule_result_t; - /* ��������ʽ��ɨ�������ͣ�quickģʽ��ֻ��expr_id�Լ�tag������Ч */ + /* ��������ʽ��ɨ�������� */ typedef struct _scan_result_t { unsigned int expr_id; /* �����ʽ��ID */ diff --git a/src/version.map b/src/version.map index 7f11e6b..a17b821 100644 --- a/src/version.map +++ b/src/version.map @@ -1,6 +1,7 @@ VERS_2.4{ global: extern "C++" { + *MAAT_FRAME_VERSION_*; *Maat_*; *SFH_*; *GIE_*; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ef8db6a..02e8590 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,6 +1,9 @@ add_executable(maat_demo maat_demo.cpp) target_link_libraries(maat_demo maat_frame_shared) +add_executable(test_igraph test_igraph.cpp) +target_link_libraries(test_igraph igraph-static) + add_executable(test_maatframe test_maatframe.cpp) target_link_libraries(test_maatframe maat_frame_shared gtest) diff --git a/test/maat_json.json b/test/maat_json.json index d9dbbe6..ee03144 100644 --- a/test/maat_json.json +++ b/test/maat_json.json @@ -12,7 +12,7 @@ "is_valid": "yes", "groups": [ { - "group_name": "IP_group", + "group_name": "123_IP_group", "regions": [ { "table_name": "IP_CONFIG", @@ -77,7 +77,7 @@ "is_valid": "yes", "groups": [ { - "group_name": "IP_group" + "group_name": "123_IP_group" }, { "group_name": "Untitled", @@ -144,7 +144,7 @@ ] }, { - "group_name": "Untitled", + "group_name": "126_interval_group", "regions": [ { "table_name": "CONTENT_SIZE", @@ -555,7 +555,7 @@ "action": 1, "do_blacklist": 1, "do_log": 1, - "user_region": "anything", + "user_region": "StringScan.UTF8EncodedURL", "is_valid": "yes", "groups": [ { @@ -580,7 +580,7 @@ "action": 1, "do_blacklist": 1, "do_log": 1, - "user_region": "NOT-logic-test1", + "user_region": "NOTLogic.OneRegion", "is_valid": "yes", "groups": [ { @@ -595,7 +595,7 @@ "match_method": "sub", "format": "uncase plain" } - } + } ] }, { @@ -621,7 +621,7 @@ "action": 1, "do_blacklist": 1, "do_log": 1, - "user_region": "NOT-logic-test2", + "user_region": "NOTLogic.ScanNotAtLast", "is_valid": "yes", "groups": [ { @@ -662,7 +662,7 @@ "action": 1, "do_blacklist": 1, "do_log": 1, - "user_region": "NOT-logic-test3", + "user_region": "NOTLogic.ScanNotIP", "is_valid": "yes", "groups": [ { @@ -682,7 +682,7 @@ }, { "not_flag":1, - "group_name": "IP_group" + "group_name": "123_IP_group" } ] }, @@ -692,7 +692,7 @@ "action": 1, "do_blacklist": 1, "do_log": 1, - "user_region": "anything", + "user_region": "StringScan.Regex", "is_valid": "yes", "groups": [ { @@ -717,7 +717,7 @@ "action": 1, "do_blacklist": 1, "do_log": 1, - "user_region": "anything", + "user_region": "StringScan.UTF8EncodedURL", "is_valid": "yes", "groups": [ { @@ -744,7 +744,7 @@ "compile_id": 148, "service": 0, "do_blacklist": 0, - "user_region": "APP_ID=100001;BEHAV_ID=100002", + "user_region": "StringScan.ExprPlusWithOffset", "groups": [ { "regions": [ @@ -770,7 +770,7 @@ "action": 1, "do_blacklist": 1, "do_log": 1, - "user_region": "anything", + "user_region": "StringScan.Regex", "is_valid": "yes", "groups": [ { @@ -796,7 +796,7 @@ "do_blacklist": 0, "do_log": 0, "effective_rage": 0, - "user_region": "0", + "user_region": "StringScan.BugReport20190325", "is_valid": "yes", "groups": [ { @@ -838,7 +838,7 @@ "do_blacklist": 0, "do_log": 0, "effective_rage": 0, - "user_region": "suffix_hit", + "user_region": "StringScan.PrefixAndSuffix", "is_valid": "yes", "groups": [ { @@ -865,7 +865,7 @@ "do_blacklist": 0, "do_log": 0, "effective_rage": 0, - "user_region": "prefix_hit", + "user_region": "StringScan.PrefixAndSuffix", "is_valid": "yes", "groups": [ { @@ -879,9 +879,267 @@ "format": "uncase plain", "match_method": "prefix" } + }, + { + "table_type": "expr", + "table_name": "MAIL_ADDR", + "table_content": { + "keywords": "[email protected]", + "expr_type": "none", + "format": "uncase plain", + "match_method": "prefix" + } } ], - "group_name": "Untitled" + "group_name": "152_mail_addr" + }, + { + "group_name": "interval_group_refered", + "sub_groups": [ + {"group_name": "126_interval_group"} + ] + } + ] + }, + { + "compile_id": 153, + "service": 0, + "action": 0, + "do_blacklist": 0, + "do_log": 0, + "effective_rage": 0, + "user_region": "Policy.SubGroup", + "is_valid": "yes", + "groups": [ + { + "regions": [ + { + "table_type": "expr", + "table_name": "MAIL_ADDR", + "table_content": { + "keywords": "[email protected]", + "expr_type": "none", + "format": "uncase plain", + "match_method": "prefix" + } + } + ], + "group_name": "Untitled", + "sub_groups": [ + {"group_name": "152_mail_addr"} + ], + "not_flag" : 0 + }, + { + "group_name": "IP_group_refered", + "sub_groups": [ + {"group_name": "123_IP_group"} + ] + } + ] + }, + { + "compile_id": 154, + "service": 0, + "action": 0, + "do_blacklist": 0, + "do_log": 0, + "effective_rage": 0, + "user_region": "ipv4_plus", + "is_valid": "yes", + "groups": [ + { + "regions": [ + { + "table_type": "ip_plus", + "table_name": "IP_PLUS_CONFIG", + "table_content": { + "addr_type": "ipv4", + "saddr_format": "range", + "src_ip1": "10.0.7.100", + "src_ip2": "10.0.7.106", + "sport_format": "range", + "src_port1": "5000", + "src_port2": "5001", + "daddr_format": "mask", + "dst_ip1": "123.56.104.218", + "dst_ip2": "255.255.255.0", + "dport_format": "range", + "dst_port1": "7400", + "dst_port2": "7400", + "protocol": 6, + "direction": "double" + } + } + ], + "not_flag" : 0 + } + ] + }, + { + "compile_id": 155, + "service": 0, + "action": 0, + "do_blacklist": 0, + "do_log": 0, + "effective_rage": 0, + "user_region": "ipv6_plus", + "is_valid": "yes", + "groups": [ + { + "regions": [ + { + "table_type": "ip_plus", + "table_name": "IP_PLUS_CONFIG", + "table_content": { + "addr_type": "ipv6", + "saddr_format": "range", + "src_ip1": "1001:da8:205:1::101", + "src_ip2": "1001:da8:205:1::201", + "sport_format": "mask", + "src_port1": "5210", + "src_port2": "65520", + "daddr_format": "mask", + "dst_ip1": "3001:da8:205:1::401", + "dst_ip2": "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0000", + "dport_format": "mask", + "dst_port1": "0", + "dst_port2": "65535", + "protocol": 6, + "direction": "double" + } + } + ], + "not_flag" : 0 + } + ] + }, + { + "compile_id": 156, + "service": 1, + "action": 1, + "do_blacklist": 1, + "do_log": 1, + "user_region": "ExprPlusWithHex", + "is_valid": "yes", + "groups": [ + { + "group_name": "Untitled", + "regions": [ + { + "table_name": "HTTP_REGION", + "table_type": "expr_plus", + "table_content": { + "district": "Content-Type", + "keywords": "2f68746d6c", + "expr_type": "none", + "match_method": "sub", + "format": "hexbin" + } + } + ] + } + ] + }, + { + "compile_id": 157, + "service": 0, + "action": 0, + "do_blacklist": 0, + "do_log": 0, + "effective_rage": 0, + "user_region": "StringScan.StreamScanUTF8", + "is_valid": "yes", + "groups": [ + { + "regions": [ + { + "table_type": "expr", + "table_name": "TROJAN_PAYLOAD", + "table_content": { + "keywords": "我的订单", + "expr_type": "none", + "format": "none", + "match_method": "sub" + } + } + ] + } + ] + }, + { + "compile_id": 158, + "service": 0, + "action": 0, + "do_blacklist": 0, + "do_log": 0, + "effective_rage": 0, + "user_region": "IPScan.IPv4_CIDR", + "is_valid": "yes", + "groups": [ + { + "regions": [ + { + "table_type": "ip_plus", + "table_name": "IP_PLUS_CONFIG", + "table_content": { + "addr_type": "ipv4", + "saddr_format": "CIDR", + "src_ip1": "192.168.0.1", + "src_ip2": "32", + "sport_format": "range", + "src_port1": "5210", + "src_port2": "65520", + "daddr_format": "CIDR", + "dst_ip1": "10.0.6.1", + "dst_ip2": "24", + "dport_format": "mask", + "dst_port1": "0", + "dst_port2": "65535", + "protocol": 6, + "direction": "double" + } + } + ], + "not_flag" : 0 + } + ] + }, + { + "compile_id": 159, + "service": 0, + "action": 0, + "do_blacklist": 0, + "do_log": 0, + "effective_rage": 0, + "user_region": "IPScan.IPv6_CIDR", + "is_valid": "yes", + "groups": [ + { + "regions": [ + { + "table_type": "ip_plus", + "table_name": "IP_PLUS_CONFIG", + "table_content": { + "addr_type": "ipv6", + "saddr_format": "CIDR", + "src_ip1": "2001:db8::", + "src_ip2": "120", + "sport_format": "mask", + "src_port1": "5210", + "src_port2": "65520", + "daddr_format": "CIDR", + "dst_ip1": "2001:4860:4860::8888", + "dst_ip2": "65", + "dport_format": "mask", + "dst_port1": "0", + "dst_port2": "65535", + "protocol": 6, + "direction": "double" + } + } + ], + "not_flag" : 0 } ] } diff --git a/test/table_info.conf b/test/table_info.conf index 6bace4d..5119ef6 100644 --- a/test/table_info.conf +++ b/test/table_info.conf @@ -1,7 +1,7 @@ #each collumn seperate with '\t' #id (0~65535) #name string -#type one of ip,expr,expr_plus,digest,intval,compile or plugin +#type one of ip, ip_plus, expr, expr_plus, digest, intval, compile or plugin #src_charset one of GBK,BIG5,UNICODE,UTF8 #dst_charset combined by GBK,BIG5,UNICODE,UTF8,seperate with '/' #do_merege [yes/no] @@ -24,7 +24,7 @@ 5 CONTENT_SIZE intval -- 6 QD_ENTRY_INFO plugin 4 -- 7 FILE_DIGEST digest -- -8 HTTP_REGION expr_plus GBK GBK no 0 +8 HTTP_REGION expr_plus GBK GBK yes 0 9 SIM_URL similar -- 10 IMAGE_FP expr UTF8 UTF8 yes 128 quickoff 11 TEST_EFFECTIVE_RANGE_TABLE plugin {"valid":4,"tag":5} -- @@ -34,4 +34,5 @@ 15 IR_INTERCEPT_IP plugin {"valid":14,"tag":18} 16 APP_PAYLOAD expr_plus UTF8 UTF8 yes 0 quickoff 17 TROJAN_PAYLOAD expr UTF8 UTF8 yes 0 quickoff -18 MAIL_ADDR expr UTF8 UTF8 yes 0 quickoff
\ No newline at end of file +18 MAIL_ADDR expr UTF8 UTF8 yes 0 quickoff +19 IP_PLUS_CONFIG ip_plus --
\ No newline at end of file diff --git a/test/test_igraph.cpp b/test/test_igraph.cpp new file mode 100644 index 0000000..a4c4d24 --- /dev/null +++ b/test/test_igraph.cpp @@ -0,0 +1,62 @@ +#include "igraph/igraph.h" +#include <assert.h> + +void print_vector(igraph_vector_t *v, FILE *f) { + long int i; + for (i=0; i<igraph_vector_size(v); i++) { + fprintf(f, " %li", (long int) VECTOR(*v)[i]); + } + fprintf(f, "\n"); +} + +int main() { + + igraph_t g; + int ret; + ret=igraph_empty(&g, 0, IGRAPH_DIRECTED); + + igraph_es_t es; + igraph_integer_t edge_num_before=0, edge_num_after=0; + int v[10]; + int i=0; + for(i=0; i<sizeof(v)/sizeof(int); i++) + { + v[i]=i; + igraph_add_vertices(&g, 1, NULL); //Add 1 vertice. + } + igraph_add_edge(&g, v[0], v[1]); + igraph_add_edge(&g, v[0], v[1]); + + igraph_add_edge(&g, v[2], v[3]); + + int edge_id=0; + ret=igraph_get_eid(&g, &edge_id, v[2], v[3], IGRAPH_DIRECTED, 0); + assert(edge_id>0); + + ret=igraph_es_pairs_small(&es, IGRAPH_DIRECTED, v[0], v[1], -1); + assert(ret==IGRAPH_SUCCESS); + edge_num_before=igraph_ecount(&g); + ret=igraph_delete_edges(&g, es); + edge_num_after=igraph_ecount(&g); + assert(edge_num_before-edge_num_after==1); + assert(ret==IGRAPH_SUCCESS); + igraph_es_destroy(&es); + + ret=igraph_es_pairs_small(&es, IGRAPH_DIRECTED, v[3], v[4], -1); + assert(ret==IGRAPH_SUCCESS); + edge_num_before=igraph_ecount(&g); + /* error test, no such edge to delete */ + igraph_set_error_handler(igraph_error_handler_ignore); + + ret=igraph_delete_edges(&g, es); + edge_num_after=igraph_ecount(&g); + assert(edge_num_before=edge_num_after); + assert(ret!=IGRAPH_SUCCESS); + igraph_es_destroy(&es); + + + igraph_destroy(&g); + + return 0; +} + diff --git a/test/test_maatframe.cpp b/test/test_maatframe.cpp index cdb545e..64f062e 100644 --- a/test/test_maatframe.cpp +++ b/test/test_maatframe.cpp @@ -42,14 +42,16 @@ void wait_for_cmd_effective(Maat_feather_t feather, long long version_before) { long long version_after=version_before; int is_updating=1; + long long wating_us=0, sleep_us=1000*100; while(is_updating||version_before==version_after) { Maat_read_state(feather,MAAT_STATE_IN_UPDATING, &is_updating, sizeof(is_updating)); Maat_read_state(feather,MAAT_STATE_VERSION, &version_after, sizeof(version_after)); - usleep(1000*100);//waiting for commands go into effect + usleep(sleep_us);//waiting for commands go into effect + wating_us+=sleep_us; } - +// printf("wait for %lld ms\n", wating_us/1000); } void scan_with_old_or_new_cfg(Maat_feather_t feather, int hit_old) @@ -305,41 +307,48 @@ TEST(StringScan, BugReport20190325) EXPECT_EQ(result[0].config_id, 150); } +#define PrefixAndSuffixTest TEST(StringScan, PrefixAndSuffix) { int ret=0; - int table_id=0; + int mail_addr_table=0, cont_sz_table=0; struct Maat_rule_t result[4]; int found_pos[4]; - const char* table_name="MAIL_ADDR"; scan_status_t mid=NULL; const char* hit_twice="[email protected]"; const char* hit_suffix="[email protected]"; const char* hit_prefix="[email protected]"; - table_id=Maat_table_register(g_feather,table_name); - ASSERT_GT(table_id, 0); + - ret=Maat_full_scan_string(g_feather, table_id,CHARSET_GBK, hit_twice, strlen(hit_twice), + cont_sz_table=Maat_table_register(g_feather, "CONTENT_SIZE"); + ret=Maat_scan_intval(g_feather, cont_sz_table, 2015, + result, 4, &mid, 0); + mail_addr_table=Maat_table_register(g_feather, "MAIL_ADDR"); + ASSERT_GT(mail_addr_table, 0); + ret=Maat_full_scan_string(g_feather, mail_addr_table,CHARSET_GBK, hit_twice, strlen(hit_twice), result,found_pos, 4, &mid, 0); EXPECT_EQ(ret, 2); - EXPECT_EQ(result[0].config_id, 152); - EXPECT_EQ(result[1].config_id, 151); + EXPECT_EQ(result[0].config_id, 151);//compile has more groups is priority + EXPECT_EQ(result[1].config_id, 152); Maat_clean_status(&mid); - ret=Maat_full_scan_string(g_feather, table_id,CHARSET_GBK, hit_suffix, strlen(hit_suffix), + ret=Maat_full_scan_string(g_feather, mail_addr_table,CHARSET_GBK, hit_suffix, strlen(hit_suffix), result,found_pos, 4, &mid, 0); EXPECT_EQ(ret, 1); EXPECT_EQ(result[0].config_id, 151); Maat_clean_status(&mid); - ret=Maat_full_scan_string(g_feather, table_id,CHARSET_GBK, hit_prefix, strlen(hit_prefix), + ret=Maat_scan_intval(g_feather, cont_sz_table, 2015, + result, 4, &mid, 0); + + ret=Maat_full_scan_string(g_feather, mail_addr_table,CHARSET_GBK, hit_prefix, strlen(hit_prefix), result,found_pos, 4, &mid, 0); EXPECT_EQ(ret, 1); EXPECT_EQ(result[0].config_id, 152); Maat_clean_status(&mid); } - +#define ExprPlusTest 1 TEST(StringScan, ExprPlus) { int ret=0; @@ -363,6 +372,8 @@ TEST(StringScan, ExprPlus) &mid, 0); EXPECT_EQ(ret, 1); EXPECT_EQ(result[0].config_id, 128); + + Maat_clean_status(&mid); return; } @@ -414,9 +425,35 @@ TEST(StringScan, ExprPlusWithOffset) &mid, 0); EXPECT_EQ(ret, 1); EXPECT_EQ(result[0].config_id, 148); + + Maat_clean_status(&mid); + return; +} + +TEST(StringScan, ExprPlusWithHex) +{ + int table_id=0,ret=0; + struct Maat_rule_t result[4]; + const char* scan_data="text/html; charset=UTF-8"; + const char* region_name="Content-Type"; + int found_pos[4]; + table_id=Maat_table_register(g_feather, "HTTP_REGION"); + ASSERT_GT(table_id, 0); + scan_status_t mid=NULL; + ret=Maat_set_scan_status(g_feather, &mid, MAAT_SET_SCAN_DISTRICT, region_name, strlen(region_name)); + ASSERT_EQ(ret, 0); + ret=Maat_full_scan_string(g_feather, table_id,CHARSET_GBK, scan_data, strlen(scan_data), + result, found_pos, 4, + &mid, 0); + EXPECT_EQ(ret, 1); + EXPECT_EQ(result[0].config_id, 156); + Maat_clean_status(&mid); + return; + } -TEST(IPScan, IPv4) +#define TEST_IPSCAN +TEST(IPScan, IPv4_mask) { int table_id=0,ret=0; const char* table_name="IP_CONFIG"; @@ -449,7 +486,7 @@ TEST(IPScan, IPv4) Maat_clean_status(&mid); return; } -TEST(IPScan, IPv6) +TEST(IPScan, IPv6_mask) { int table_id=0,ret=0; struct Maat_rule_t result[4]; @@ -474,6 +511,119 @@ TEST(IPScan, IPv6) Maat_clean_status(&mid); return; } +TEST(IPScan, IPv4_range) +{ + int table_id=0,ret=0; + const char* table_name="IP_PLUS_CONFIG"; + struct Maat_rule_t result[4]; + scan_status_t mid=NULL; + struct ipaddr ipv4_addr; + struct stream_tuple4_v4 v4_addr; + ipv4_addr.addrtype=ADDR_TYPE_IPV4; + inet_pton(AF_INET, "10.0.7.106", &(v4_addr.saddr)); + v4_addr.source=htons(5000); + inet_pton(AF_INET, "123.56.104.254", &(v4_addr.daddr)); + v4_addr.dest=htons(7400); + ipv4_addr.v4=&v4_addr; + + + table_id=Maat_table_register(g_feather, table_name); + + EXPECT_GT(table_id, 0); + + ret=Maat_scan_proto_addr(g_feather, table_id, &ipv4_addr, 6, result, 4, &mid, 0); + + EXPECT_EQ(ret, 1); + EXPECT_EQ(result[0].config_id, 154); + + Maat_clean_status(&mid); + return; +} + +TEST(IPScan, IPv6_range) +{ + int table_id=0,ret=0; + struct Maat_rule_t result[4]; + struct ipaddr ipv6_addr; + struct stream_tuple4_v6 v6_addr; + scan_status_t mid=NULL; + + ipv6_addr.addrtype=ADDR_TYPE_IPV6; + inet_pton(AF_INET6,"1001:da8:205:1::151",&(v6_addr.saddr)); + v6_addr.source=htons(5204);//5200~5299? + inet_pton(AF_INET6,"3001:da8:205:1::901",&(v6_addr.daddr)); + v6_addr.dest=htons(80);//any + ipv6_addr.v6=&v6_addr; + const char* table_name="IP_PLUS_CONFIG"; + table_id=Maat_table_register(g_feather,table_name); + EXPECT_GT(table_id, 0); + + //for improving performance. + Maat_set_scan_status(g_feather, &mid, MAAT_SET_SCAN_LAST_REGION,NULL, 0); + ret=Maat_scan_proto_addr(g_feather, table_id, &ipv6_addr, 6, result,4, &mid, 0); + EXPECT_EQ(ret, 1); + EXPECT_EQ(result[0].config_id, 155); + Maat_clean_status(&mid); + return; + +} +TEST(IPScan, IPv4_CIDR) +{ + int table_id=0,ret=0; + const char* table_name="IP_PLUS_CONFIG"; + struct Maat_rule_t result[4]; + scan_status_t mid=NULL; + struct ipaddr ipv4_addr; + struct stream_tuple4_v4 v4_addr; + ipv4_addr.addrtype=ADDR_TYPE_IPV4; + inet_pton(AF_INET, "192.168.0.1", &(v4_addr.saddr)); + v4_addr.source=htons(5210); + inet_pton(AF_INET, "10.0.6.210", &(v4_addr.daddr)); + v4_addr.dest=htons(7400); + ipv4_addr.v4=&v4_addr; + + + table_id=Maat_table_register(g_feather, table_name); + + EXPECT_GT(table_id, 0); + + ret=Maat_scan_proto_addr(g_feather, table_id, &ipv4_addr, 6, result, 4, &mid, 0); + + EXPECT_EQ(ret, 1); + EXPECT_EQ(result[0].config_id, 158); + + Maat_clean_status(&mid); + return; +} +TEST(IPScan, IPv6_CIDR) +{ + int table_id=0,ret=0; + struct Maat_rule_t result[4]; + struct ipaddr ipv6_addr; + struct stream_tuple4_v6 v6_addr; + scan_status_t mid=NULL; + + ipv6_addr.addrtype=ADDR_TYPE_IPV6; + inet_pton(AF_INET6,"2001:db8::00fe",&(v6_addr.saddr)); + v6_addr.source=htons(5204);//5200~5299? + inet_pton(AF_INET6,"2001:4860:4860::8888",&(v6_addr.daddr)); + v6_addr.dest=htons(80);//any + ipv6_addr.v6=&v6_addr; + const char* table_name="IP_PLUS_CONFIG"; + table_id=Maat_table_register(g_feather,table_name); + EXPECT_GT(table_id, 0); + + //for improving performance. + Maat_set_scan_status(g_feather, &mid, MAAT_SET_SCAN_LAST_REGION,NULL, 0); + ret=Maat_scan_proto_addr(g_feather, table_id, &ipv6_addr, 6, result,4, &mid, 0); + EXPECT_EQ(ret, 1); + EXPECT_EQ(result[0].config_id, 159); + Maat_clean_status(&mid); + return; + +} +#define TEST_NOTLogic 1 + TEST(NOTLogic, OneRegion) { const char* string_should_hit="This string ONLY contains must-contained-string-of-rule-143."; @@ -489,15 +639,15 @@ TEST(NOTLogic, OneRegion) ASSERT_GT(table_id, 0); Maat_set_scan_status(g_feather, &mid, MAAT_SET_SCAN_LAST_REGION, NULL, 0); - ret=Maat_full_scan_string(g_feather, table_id,CHARSET_GBK, string_should_hit, strlen(string_should_hit), - result,found_pos, 4, &mid, 0); + ret=Maat_full_scan_string(g_feather, table_id, CHARSET_GBK, string_should_hit, strlen(string_should_hit), + result, found_pos, 4, &mid, 0); EXPECT_GE(ret, 1); Maat_clean_status(&mid); Maat_set_scan_status(g_feather, &mid, MAAT_SET_SCAN_LAST_REGION, NULL, 0); - ret=Maat_full_scan_string(g_feather, table_id,CHARSET_GBK, string_should_not_hit, strlen(string_should_not_hit), - result,found_pos, 4, &mid, 0); + ret=Maat_full_scan_string(g_feather, table_id, CHARSET_GBK, string_should_not_hit, strlen(string_should_not_hit), + result, found_pos, 4, &mid, 0); EXPECT_EQ(ret, -2); Maat_clean_status(&mid); @@ -713,7 +863,7 @@ TEST(StringScan, UTF8EncodedURL) ret=Maat_full_scan_string(g_feather, table_id,CHARSET_GBK, url_utf8_qs, strlen(url_utf8_qs), result,found_pos, 4, &mid, 0); - EXPECT_GT(ret, 1); + EXPECT_EQ(ret, 1); EXPECT_EQ(result[0].config_id, 142); Maat_clean_status(&mid); @@ -843,6 +993,8 @@ TEST(StringScan, StreamInput) Maat_clean_status(&mid); return; } + + TEST(SimilarScan, Pure) { int ret=0; @@ -946,6 +1098,51 @@ TEST(StringScan, OffsetChunk1460) test_offset_str_scan_with_chunk(1460); return; } +#define StringScan_StreamScanUTF8 1 +TEST(StringScan, StreamScanUTF8) +{ + //Bug report: https://mantis.mesalab.cn/view.php?id=712 + int table_id=0,ret=0; + int read_size=0,pass_flag=0; + struct Maat_rule_t result[4]; + scan_status_t mid=NULL; + const char* table_name="TROJAN_PAYLOAD"; + const char* fn="./testdata/jd.com.html"; + FILE* fp=fopen(fn,"r"); + ASSERT_FALSE(fp==NULL); + + char scan_data[2048]; + table_id=Maat_table_register(g_feather,table_name); + ASSERT_GT(table_id, 0); + + + struct Maat_hit_detail_t *hit_detail=(struct Maat_hit_detail_t *)malloc(sizeof(struct Maat_hit_detail_t)*10); + stream_para_t sp=Maat_stream_scan_string_start(g_feather,table_id,0); + int detail_ret=0; + + ASSERT_FALSE(sp==NULL); + + while(0==feof(fp)) + { + read_size=fread(scan_data,1,sizeof(scan_data),fp); + ret=Maat_stream_scan_string_detail(&sp,CHARSET_NONE,scan_data,read_size + ,result,4,hit_detail,10 + ,&detail_ret,&mid); + if(ret>0) + { + pass_flag=1; + break; + } + } + EXPECT_EQ(pass_flag, 1); + EXPECT_EQ(result[0].config_id, 157); + + Maat_stream_scan_string_end(&sp); + free(hit_detail); + fclose(fp); + Maat_clean_status(&mid); + return; +} void accept_tags_entry_cb(int table_id,const char* table_line,void* u_para) { @@ -959,7 +1156,7 @@ void accept_tags_entry_cb(int table_id,const char* table_line,void* u_para) return; } -TEST(RuleTags, Plugin1) +TEST(Policy, PluginRuleTags1) { #define RuleTags_Plugin int ret=0; @@ -985,7 +1182,7 @@ void accept_tags_entry2_cb(int table_id,const char* table_line,void* u_para) return; } -TEST(RuleTags, Plugin2) +TEST(Policy, PluginRuleTags2) { #define RuleTags_Plugin2 int ret=0; @@ -1005,7 +1202,7 @@ TEST(RuleTags, Plugin2) return; } -TEST(RuleTags, Compile) +TEST(Policy, CompileRuleTags) { #define RuleTags_Compile int ret=0; @@ -1086,7 +1283,7 @@ void compile_ex_param_dup(int idx, MAAT_RULE_EX_DATA *to, MAAT_RULE_EX_DATA *fro -TEST(EX_DATA_INDEX, MaatRuleEXData) +TEST(Policy, CompileEXData) { #define rule_EX_data_index @@ -1120,6 +1317,42 @@ TEST(EX_DATA_INDEX, MaatRuleEXData) Maat_clean_status(&mid); return; } +TEST(Policy, SubGroup) +{ +#define TestSubGroup + int ret=0, table_id=0; + const char* scan_string="[email protected]"; + struct Maat_rule_t result[4]; + memset(result, 0, sizeof(result)); + + scan_status_t mid=NULL; + struct ipaddr ipv4_addr; + struct stream_tuple4_v4 v4_addr; + ipv4_addr.addrtype=ADDR_TYPE_IPV4; + inet_pton(AF_INET,"10.0.6.205",&(v4_addr.saddr)); + v4_addr.source=htons(50001); + inet_pton(AF_INET,"10.0.6.201",&(v4_addr.daddr)); + v4_addr.dest=htons(80); + ipv4_addr.v4=&v4_addr; + + table_id=Maat_table_register(g_feather,"MAIL_ADDR"); + ASSERT_GT(table_id, 0); + + ret=Maat_full_scan_string(g_feather, table_id, CHARSET_GBK, scan_string, strlen(scan_string), + result,NULL, 4, &mid, 0); + EXPECT_EQ(ret, -2); + + table_id=Maat_table_register(g_feather, "IP_CONFIG"); + ASSERT_GT(table_id, 0); + + ret=Maat_scan_proto_addr(g_feather, table_id, &ipv4_addr, 6, result, 4, &mid,0); + + EXPECT_EQ(ret, 1); + EXPECT_EQ(result[0].config_id, 153); + + Maat_clean_status(&mid); + return; +} TEST(StreamFuzzyHash, Pure) @@ -1374,6 +1607,7 @@ protected: static int linger_timeout; }; Maat_feather_t MaatCmdTest::_shared_feather; + void* MaatCmdTest::logger; int MaatCmdTest::linger_timeout; @@ -1475,7 +1709,7 @@ TEST_F(MaatCmdTest, SetIP) EXPECT_GE(ret, 0); Maat_free_cmd(cmd); cmd=NULL; - + wait_for_cmd_effective(feather, version_before); struct ipaddr ipv4_addr; struct stream_tuple4_v4 v4_addr; @@ -1503,10 +1737,11 @@ TEST_F(MaatCmdTest, SetIP) //reset timeout. cmd=Maat_create_cmd(&rule, 0); - cmd->expire_after=10; + cmd->expire_after=timeout+5; ret=Maat_cmd(feather, cmd, MAAT_OP_RENEW_TIMEOUT); EXPECT_EQ(ret ,1); - + +// RENEW_TIMEOUT doesn't change MAAT_VERSION, thus we cannot use wait_for_cmd_effective. // wait_for_cmd_effective(feather, version_before); Maat_free_cmd(cmd); @@ -1608,7 +1843,7 @@ TEST_F(MaatCmdTest, RuleIDRecycle) struct Maat_rule_t result; scan_status_t mid=NULL; - + memset(&result, 0, sizeof(result)); int table_id=0; table_id=Maat_table_register(feather,table_name); ASSERT_GT(table_id, 0); @@ -1658,7 +1893,7 @@ TEST_F(MaatCmdTest, ReturnRuleIDWithDescendingOrder) int table_id=0; - table_id=Maat_table_register(feather,table_name); + table_id=Maat_table_register(feather, table_name); ASSERT_GT(table_id, 0); int i=0, repeat_times=4; @@ -1677,6 +1912,7 @@ TEST_F(MaatCmdTest, ReturnRuleIDWithDescendingOrder) ret=Maat_cmd_commit(feather); EXPECT_TRUE(ret>=0); usleep(WAIT_FOR_EFFECTIVE_US);//waiting for commands go into effect + memset(&result, 0, sizeof(result)); ret=Maat_full_scan_string(feather, table_id,CHARSET_GBK, scan_data, strlen(scan_data), result, NULL, 8, &mid, 0); @@ -1689,7 +1925,256 @@ TEST_F(MaatCmdTest, ReturnRuleIDWithDescendingOrder) } return; } +#define MaatCmdTest_SubGroup 0 +TEST_F(MaatCmdTest, SubGroup) +{ + const char* table_name="HTTP_URL"; + const char* group_table_name="GROUP"; + const char* compile_table_name="COMPILE"; + const char* scan_data1="www.v2ex.com/t/573028#程序员的核心竞争力是什么"; + const char* keyword1="程序员&核心竞争力"; + + const char* scan_data2="https://ask.leju.com/bj/detail/12189672562229248/?bi=tg&type=sina-pc&pos=index-dbtlwzl&wt_campaign=M_5CE750003F393&wt_source=PDPS_514ACACFD9E770"; +// const char* keyword2="ask.leju.com/bj/detail/12189672562229248/?bi=tg&type=sina-pc&pos=index-dbtlwzl&wt_campaign=M_5CE750003F393&wt_source=PDPS_514ACACFD9E770"; + const char* keyword2="ask.leju.com/b&/detail/12189672562229248/?&?bi=tg\\&type=sina-pc\\&&\\&pos=index-dbtlwzl\\&&\\&type=sina-pc\\&pos=index-dbtlwzl\\&"; + Maat_feather_t feather=MaatCmdTest::_shared_feather; + int table_id=0; + table_id=Maat_table_register(feather, table_name); + struct Maat_rule_t compile1, compile2; + struct Maat_group_t group1, group2, group3; + struct Maat_region_t region1,region2; + memset(&compile1, 0, sizeof(compile1)); + compile1.config_id=(int)Maat_cmd_incrby(feather, "TEST_SEQ", 1); + Maat_command_raw_set_compile(feather, MAAT_OP_ADD, &compile1, compile_table_name, NULL, 1); + + memset(&compile2, 0, sizeof(compile2)); + compile2.config_id=(int)Maat_cmd_incrby(feather, "TEST_SEQ", 1); + Maat_command_raw_set_compile(feather, MAAT_OP_ADD, &compile2, compile_table_name, NULL, 1); + + //group1->compile1 + memset(&group1, 0, sizeof(group1)); + group1.group_id=Maat_cmd_get_new_group_id(feather); + group1.table_name=group_table_name; + group1.parent_id=compile1.config_id; + group1.parent_type=PARENT_TYPE_COMPILE; + Maat_command_raw_set_group(feather, MAAT_OP_ADD, &group1); + + //group1->compile2 + group1.parent_id=compile2.config_id; + Maat_command_raw_set_group(feather, MAAT_OP_ADD, &group1); + + /*group2->group1->compile1 + \ + \__compile2 + */ + memset(&group2, 0, sizeof(group2)); + group2.group_id=Maat_cmd_get_new_group_id(feather); + group2.table_name=group_table_name; + group2.parent_id=group1.group_id; + group2.parent_type=PARENT_TYPE_GROUP; + Maat_command_raw_set_group(feather, MAAT_OP_ADD, &group2); + + /*region1->group2->group1->compile1 + \ + \_compile2 + */ + memset(®ion1, 0, sizeof(region1)); + region1.region_id=Maat_cmd_get_new_region_id(feather); + region1.region_type=REGION_EXPR; + region1.table_name=table_name; + region1.expr_rule.keywords=keyword1; + region1.expr_rule.expr_type=EXPR_TYPE_AND; + Maat_command_raw_set_region(feather, MAAT_OP_ADD, ®ion1, group2.group_id); + sleep(1); + struct Maat_rule_t result[4]; + memset(&result, 0, sizeof(result)); + + scan_status_t mid=NULL; + int ret=0; + ret=Maat_full_scan_string(feather, table_id, CHARSET_GBK, scan_data1, strlen(scan_data1), + result, NULL, 4, + &mid, 0); + EXPECT_EQ(ret, 2); + EXPECT_EQ(result[0].config_id, compile2.config_id); + EXPECT_EQ(result[1].config_id, compile1.config_id); + Maat_clean_status(&mid); + + + /*region1->group2->group1->compile1 + \ + \--X--compile2 + */ + Maat_command_raw_set_group(feather, MAAT_OP_DEL, &group1); + sleep(1); + ret=Maat_full_scan_string(feather, table_id, CHARSET_GBK, scan_data1, strlen(scan_data1), + result, NULL, 4, + &mid, 0); + EXPECT_EQ(ret, 1); + EXPECT_EQ(result[0].config_id, compile1.config_id); + Maat_clean_status(&mid); + + + /*region1->group2->group1--X-- + \ + \->compile2 + */ + group1.parent_id=compile1.config_id; + Maat_command_raw_set_group(feather, MAAT_OP_DEL, &group1); + Maat_command_raw_set_compile(feather, MAAT_OP_DEL, &compile1, compile_table_name, NULL, 1); + group2.parent_type=PARENT_TYPE_COMPILE; + group2.parent_id=compile2.config_id; + Maat_command_raw_set_group(feather, MAAT_OP_ADD, &group2); + + sleep(1); + ret=Maat_full_scan_string(feather, table_id, CHARSET_GBK, scan_data1, strlen(scan_data1), + result, NULL, 4, + &mid, 0); + EXPECT_EQ(ret, 1); + EXPECT_EQ(result[0].config_id, compile2.config_id); + Maat_clean_status(&mid); + + + /*region1->group2->group1--X-- + \ + \->compile2 + region2->group3 + */ + + memset(&group3, 0, sizeof(group3)); + group3.group_id=Maat_cmd_get_new_group_id(feather); + group3.parent_id=group1.group_id; + group3.parent_type=PARENT_TYPE_GROUP; + group3.table_name=group_table_name; + Maat_command_raw_set_group(feather, MAAT_OP_ADD, &group3); + + memset(®ion2, 0, sizeof(region2)); + region2.region_id=Maat_cmd_get_new_region_id(feather); + region2.region_type=REGION_EXPR; + region2.table_name=table_name; + region2.expr_rule.keywords=keyword2; + region2.expr_rule.expr_type=EXPR_TYPE_AND; + Maat_command_raw_set_region(feather, MAAT_OP_ADD, ®ion2, group3.group_id); + + sleep(1); + ret=Maat_full_scan_string(feather, table_id, CHARSET_GBK, scan_data2, strlen(scan_data2), + result, NULL, 4, + &mid, 0); + EXPECT_EQ(ret, -2); + Maat_clean_status(&mid); + + /*region1->group2->group1--X-- + \ + \->compile2 + region2->group3 + */ + Maat_command_raw_set_compile(feather, MAAT_OP_ADD, &compile1, compile_table_name, NULL, 1); + group1.parent_id=compile1.config_id; + Maat_command_raw_set_group(feather, MAAT_OP_ADD, &group1); + + Maat_command_raw_set_compile(feather, MAAT_OP_DEL, &compile1, compile_table_name, NULL, 1); + group1.parent_id=compile1.config_id; + Maat_command_raw_set_group(feather, MAAT_OP_DEL, &group1); + + sleep(1); + ret=Maat_full_scan_string(feather, table_id, CHARSET_GBK, scan_data1, strlen(scan_data1), + result, NULL, 4, + &mid, 0); + EXPECT_EQ(ret, 1); + EXPECT_EQ(result[0].config_id, compile2.config_id); + + Maat_clean_status(&mid); + +} +#define MaatCmdTest_RefGroup 0 +TEST_F(MaatCmdTest, RefGroup) +{ + + const char* table_name="HTTP_URL"; + const char* group_table_name="GROUP"; + const char* compile_table_name="COMPILE"; + const char* scan_data1="m.facebook.com/help/2297503110373101?helpref=hc_nav&refid=69"; + const char* keyword1="something-should-not-hit"; + const char* keyword2="facebook.com/help/2297503110373101"; + + Maat_feather_t feather=MaatCmdTest::_shared_feather; + int table_id=0; + table_id=Maat_table_register(feather, table_name); + struct Maat_rule_t compile1; + struct Maat_group_t group1, group2; + struct Maat_region_t region1, region2; + + int value=0; + Maat_set_feather_opt(feather, MAAT_OPT_ENABLE_UPDATE, &value, sizeof(value)); + + memset(&compile1, 0, sizeof(compile1)); + compile1.config_id=(int)Maat_cmd_incrby(feather, "TEST_SEQ", 1); + Maat_command_raw_set_compile(feather, MAAT_OP_ADD, &compile1, compile_table_name, NULL, 1); + + //group1->compile1 + memset(&group1, 0, sizeof(group1)); + group1.group_id=Maat_cmd_get_new_group_id(feather); + group1.table_name=group_table_name; + group1.parent_id=compile1.config_id; + group1.parent_type=PARENT_TYPE_COMPILE; + Maat_command_raw_set_group(feather, MAAT_OP_ADD, &group1); + + + /*region1->group1->compile1 + */ + memset(®ion1, 0, sizeof(region1)); + region1.region_id=Maat_cmd_get_new_region_id(feather); + region1.region_type=REGION_EXPR; + region1.table_name=table_name; + region1.expr_rule.keywords=keyword1; + region1.expr_rule.expr_type=EXPR_TYPE_AND; + Maat_command_raw_set_region(feather, MAAT_OP_ADD, ®ion1, group1.group_id); + value=1; + Maat_set_feather_opt(feather, MAAT_OPT_ENABLE_UPDATE, &value, sizeof(value)); + + sleep(1); + + value=0; + Maat_set_feather_opt(feather, MAAT_OPT_ENABLE_UPDATE, &value, sizeof(value)); + //region1->group1-X-compile1 + //region2->group2->compile1 + memset(&group2, 0, sizeof(group2)); + group2.group_id=Maat_cmd_get_new_group_id(feather); + group2.table_name=group_table_name; + group2.parent_id=compile1.config_id; + group2.parent_type=PARENT_TYPE_COMPILE; + + memset(®ion2, 0, sizeof(region2)); + region2.region_id=Maat_cmd_get_new_region_id(feather); + region2.region_type=REGION_EXPR; + region2.table_name=table_name; + region2.expr_rule.keywords=keyword2; + region2.expr_rule.expr_type=EXPR_TYPE_AND; + Maat_command_raw_set_region(feather, MAAT_OP_ADD, ®ion2, group2.group_id); + + + Maat_command_raw_set_compile(feather, MAAT_OP_DEL, &compile1, compile_table_name, NULL, 1); + Maat_command_raw_set_compile(feather, MAAT_OP_ADD, &compile1, compile_table_name, NULL, 1); + Maat_command_raw_set_group(feather, MAAT_OP_DEL, &group1); + Maat_command_raw_set_group(feather, MAAT_OP_ADD, &group2); + value=1; + Maat_set_feather_opt(feather, MAAT_OPT_ENABLE_UPDATE, &value, sizeof(value)); + + sleep(1); + + struct Maat_rule_t result[4]; + memset(&result, 0, sizeof(result)); + + scan_status_t mid=NULL; + int ret=0; + ret=Maat_full_scan_string(feather, table_id, CHARSET_GBK, scan_data1, strlen(scan_data1), + result, NULL, 4, + &mid, 0); + EXPECT_EQ(ret, 1); + EXPECT_EQ(result[0].config_id, compile1.config_id); + Maat_clean_status(&mid); + +} TEST_F(MaatCmdTest, SetLines) { @@ -2105,7 +2590,7 @@ int main(int argc, char ** argv) const char* decrypt_key="mesa2017wy"; const char* accept_tags="{\"tags\":[{\"tag\":\"location\",\"value\":\"北京/朝阳/华严北里/甲22号\"},{\"tag\":\"isp\",\"value\":\"移动\"},{\"tag\":\"location\",\"value\":\"Astana\"}]}"; // const char* subsitute_acc_tags="{\"tags\":[{\"tag\":\"location\",\"value\":\"Astana\"}]}"; - int scan_detail=0; + int scan_detail=0, ret=0; ::testing::InitGoogleTest(&argc, argv); g_logger=MESA_create_runtime_log_handle(log_file, 0); @@ -2113,8 +2598,8 @@ int main(int argc, char ** argv) g_feather=Maat_feather(g_iThreadNum, table_info_path, g_logger); Maat_set_feather_opt(g_feather, MAAT_OPT_INSTANCE_NAME, "demo", strlen("demo")+1); Maat_set_feather_opt(g_feather, MAAT_OPT_DECRYPT_KEY, decrypt_key, strlen(decrypt_key)+1); - Maat_set_feather_opt(g_feather, MAAT_OPT_JSON_FILE_PATH, json_path, strlen(json_path)+1); - + ret=Maat_set_feather_opt(g_feather, MAAT_OPT_JSON_FILE_PATH, json_path, strlen(json_path)+1); + assert(ret==0); Maat_set_feather_opt(g_feather, MAAT_OPT_SCANDIR_INTERVAL_MS, &scan_interval_ms, sizeof(scan_interval_ms)); //Set a short intevral for testing. Maat_set_feather_opt(g_feather, MAAT_OPT_EFFECT_INVERVAL_MS, &effective_interval_ms, sizeof(effective_interval_ms)); @@ -2127,7 +2612,7 @@ int main(int argc, char ** argv) Maat_initiate_feather(g_feather); printf("Maat initiating, see %s\n",log_file); - int ret=RUN_ALL_TESTS(); + ret=RUN_ALL_TESTS(); Maat_burn_feather(g_feather); MESA_destroy_runtime_log_handle(g_logger); return ret; diff --git a/test/testdata/jd.com.html b/test/testdata/jd.com.html new file mode 100644 index 0000000..1650566 --- /dev/null +++ b/test/testdata/jd.com.html @@ -0,0 +1,968 @@ +<!DOCTYPE HTML> +<html lang="zh-CN"> +<head> + <meta charset="UTF-8"> + <title>京东(JD.COM)-正品低价、品质保障、配送及时、轻松购物!</title> + <meta name="description" content="京东JD.COM-专业的综合网上购物商城,为您提供正品低价的购物选择、优质便捷的服务体验。商品来自全球数十万品牌商家,囊括家电、手机、电脑、服装、居家、母婴、美妆、个护、食品、生鲜等丰富品类,满足各种购物需求。" /> + <meta name="Keywords" content="网上购物,网上商城,家电,手机,电脑,服装,居家,母婴,美妆,个护,食品,生鲜,京东" /> + <script type="text/javascript"> + window.pageConfig = { + compatible: true, + preload: false, + navId: "jdhome2016", + timestamp: 1562166088000, + isEnablePDBP: 0, + surveyTitle : '调查问卷', + surveyLink : '//surveys.jd.com/index.php?r=survey/index/sid/889711/newtest/Y/lang/zh-Hans', + leftCateABtestSwitch : 0, + "" : "" + }; + </script> +<!--[if lte IE 7]> + <script src="//misc.360buyimg.com/mtd/pc/index/home/ie6tip.min.js"></script> + <![endif]--> + <!--[if IE 8]> + <script src="//storage.360buyimg.com/fragments/polyfill.js"></script> + <![endif]--> + <link rel="dns-prefetch" href="//static.360buyimg.com" /> + <link rel="dns-prefetch" href="//misc.360buyimg.com" /> + <link rel="dns-prefetch" href="//img10.360buyimg.com" /> + <link rel="dns-prefetch" href="//img11.360buyimg.com" /> + <link rel="dns-prefetch" href="//img12.360buyimg.com" /> + <link rel="dns-prefetch" href="//img13.360buyimg.com" /> + <link rel="dns-prefetch" href="//img14.360buyimg.com" /> + <link rel="dns-prefetch" href="//img20.360buyimg.com" /> + <link rel="dns-prefetch" href="//img30.360buyimg.com" /> + <link rel="dns-prefetch" href="//d.3.cn" /> + <link rel="dns-prefetch" href="//d.jd.com" /> + <link rel="icon" href="//www.jd.com/favicon.ico" mce_href="//www.jd.com/favicon.ico" type="image/x-icon" /> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> + <meta name="renderer" content="webkit" /> + <meta name="google-site-verification" content="4vmYcfLX0KWi82fvht-HAux15inXSVGVQ0tnUZqsdqE" /> + <script type="text/javascript"> + !function(n){function o(n){for(var o=n+"=",t=document.cookie.split(";"),e=0;e<t.length;e++){for(var i=t[e];" "==i.charAt(0);)i=i.substring(1,i.length);if(0==i.indexOf(o))return i.substring(o.length,i.length)}return null}var t=o("pcm"),e=n.navigator.userAgent.toLocaleLowerCase(),i="//m.jd.com",r=/iphone|android|symbianos|windows\sphone/g,c=/micromessenger|qq\/[\d.]+/i;return c.test(e)?(n.location.href="//wqs.jd.com/?from=jdindex",!1):r.test(e)&&"1"!=t?(n.location.href=i,!1):void 0}(window); + </script> + <script type="text/javascript"> + !function(e){pageConfig.wideVersion=function(){var n=e,i=document,o=i.documentElement,t=i.getElementsByTagName("body")[0],a=n.innerWidth||o.clientWidth||t.clientWidth;return a>=1190&&pageConfig.compatible}();var n=[];pageConfig.wideVersion?(n.push("root61"),n.push("o2_wide")):n.push("o2_mini");var i=document.getElementsByTagName("html")[0];i.className=n.join(" ")}(window,void 0); + </script> + <script type="text/javascript"> + window['_REPORT_'] = {}; + window['_REPORT_']['START'] = new Date(); + </script> + + <script type="text/javascript"> + window.search = function (a){var b,c="//search.jd.com/Search?keyword={keyword}&enc={enc}{additional}";var d=search.additinal||"";var e=document.getElementById(a);var f=e.value;if(f=f.replace(/^\s*(.*?)\s*$/,"$1"),f.length>100&&(f=f.substring(0,100)),""==f)return void(window.location.href=window.location.href);var g=0;"undefined"!=typeof window.pageConfig&&"undefined"!=typeof window.pageConfig.searchType&&(g=window.pageConfig.searchType);var h="&cid{level}={cid}";var i="string"==typeof search.cid?search.cid:"";var j="string"==typeof search.cLevel?search.cLevel:"";var k="string"==typeof search.ev_val?search.ev_val:"";switch(g){case 0:break;case 1:j="-1",d+="&book=y";break;case 2:j="-1",d+="&mvd=music";break;case 3:j="-1",d+="&mvd=movie";break;case 4:j="-1",d+="&mvd=education";break;case 5:var l="&other_filters=%3Bcid1%2CL{cid1}M{cid1}[cid2]";switch(j){case"51":h=l.replace(/\[cid2]/,""),h=h.replace(/\{cid1}/g,"5272");break;case"52":h=l.replace(/\{cid1}/g,"5272"),h=h.replace(/\[cid2]/,"%3Bcid2%2CL{cid}M{cid}");break;case"61":h=l.replace(/\[cid2]/,""),h=h.replace(/\{cid1}/g,"5273");break;case"62":h=l.replace(/\{cid1}/g,"5273"),h=h.replace(/\[cid2]/,"%3Bcid2%2CL{cid}M{cid}");break;case"71":h=l.replace(/\[cid2]/,""),h=h.replace(/\{cid1}/g,"5274");break;case"72":h=l.replace(/\{cid1}/g,"5274"),h=h.replace(/\[cid2]/,"%3Bcid2%2CL{cid}M{cid}");break;case"81":h=l.replace(/\[cid2]/,""),h=h.replace(/\{cid1}/g,"5275");break;case"82":h=l.replace(/\{cid1}/g,"5275"),h=h.replace(/\[cid2]/,"%3Bcid2%2CL{cid}M{cid}")}c="//search-e.jd.com/searchDigitalBook?ajaxSearch=0&enc=utf-8&key={keyword}&page=1{additional}";break;case 6:j="-1",c="//music.jd.com/8_0_desc_0_0_1_15.html?key={keyword}";break;case 7:c="//s-e.jd.com/Search?key={keyword}&enc=utf-8";break;case 8:c="//search.jd.hk/Search?keyword={keyword}&enc=utf-8";break;case 9:d+="&market=1"}if("string"==typeof i&&""!=i&&"string"==typeof j){var m=/^(?:[1-8])?([1-3])$/;j="-1"==j?"":m.test(j)?RegExp.$1:"";var n=h.replace(/\{level}/,j);n=n.replace(/\{cid}/g,i),d+=n}if("string"==typeof k&&""!=k&&(d+="&ev="+k),f=encodeURIComponent(f),b=c.replace(/\{keyword}/,f),b=b.replace(/\{enc}/,"utf-8"),b=b.replace(/\{additional}/,d),"object"==typeof $o&&("string"==typeof $o.lastKeyword&&(b+="&wq="+encodeURIComponent($o.lastKeyword)),"string"==typeof $o.pvid&&(b+="&pvid="+$o.pvid)),b.indexOf("/search.jd.com/")>0)try{JA.tracker.ngloader("search.000009",{key:f,posid:a,target:b})}catch(o){}("undefined"==typeof search.isSubmitted||0==search.isSubmitted)&&(setTimeout(function(){window.location.href=b},50),search.isSubmitted=!0)}; + </script> + +<style> + *{margin:0;padding:0}em,i{font-style:normal}li{list-style:none}img{border:0;vertical-align:middle}button{cursor:pointer}a{color:#666;text-decoration:none}a:hover{color:#e33333}button,input{font-family:Microsoft YaHei,Heiti SC,tahoma,arial,Hiragino Sans GB,\\5B8B\4F53,sans-serif}body{-webkit-font-smoothing:antialiased;background-color:#fff;font:12px/1.5 Microsoft YaHei,Heiti SC,tahoma,arial,Hiragino Sans GB,\\5B8B\4F53,sans-serif;color:#666}.hide,.none{display:none}.clearfix:after{visibility:hidden;clear:both;display:block;content:".";height:0}.clearfix{*zoom:1}@font-face{font-family:iconfont;src:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/iconfont.eot);src:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/iconfont.eot?#iefix) format("embedded-opentype"),url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/iconfont.woff) format("woff"),url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/iconfont.ttf) format("truetype"),url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/iconfont.svg#iconfont) format("svg")}.iconfont{font-family:iconfont,sans-serif;font-style:normal;-webkit-text-stroke-width:.2px;-moz-osx-font-smoothing:grayscale}.mod_price{font-size:14px;color:#e33333}.mod_price i{margin-right:3px;font-family:arial,sans-serif;font-weight:400;font-size:12px}.o2_wide{min-width:1190px}.o2_mini{min-width:990px}.grid_c1{margin:0 auto;width:1190px}.o2_mini .grid_c1{width:990px}.mod_ver{display:inline-block;width:0;height:100%;vertical-align:middle;font-size:0}.mod_lazyload{width:100%;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/lazyload.gif)}.loading,.mod_lazyload,.mod_loading{background-repeat:no-repeat;background-position:50% 50%}.loading,.mod_loading{background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/loading.gif)}.mod_loading_placeholder{background:#eee}@media only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5){.mod_lazyload{background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected]);-moz-background-size:90px 90px;background-size:90px 90px}.loading,.mod_loading{background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected]);-moz-background-size:25px 25px;background-size:25px 25px}}@font-face{font-family:impact;src:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/impact.eot);src:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/impact.eot?#iefix) format("embedded-opentype"),url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/impact.woff) format("woff"),url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/impact.ttf) format("truetype"),url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/impact.svg) format("svg");font-weight:400;font-style:normal}@font-face{font-family:fzzzh;src:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/fzzzh.eot);src:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/fzzzh.eot?#iefix) format("embedded-opentype"),url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/fzzzh.woff) format("woff"),url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/fzzzh.ttf) format("truetype"),url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/fzzzh.svg) format("svg");font-weight:400;font-style:normal}@font-face{font-family:impact;src:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/impact.eot);src:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/impact.eot?#iefix) format("embedded-opentype"),url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/impact.woff) format("woff"),url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/fonts/impact.ttf) format("truetype"),url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/impact.svg) format("svg");font-weight:400;font-style:normal}.index{background-color:#f0f3ef}.slider_indicators{position:absolute;left:50%;font-size:0;text-align:center}.slider_indicators_btn{position:relative;display:inline-block;width:16px;height:16px;margin-right:1px;-moz-border-radius:50%;border-radius:50%;-webkit-transition:background .2s ease;-o-transition:background ease .2s;-moz-transition:background ease .2s;transition:background .2s ease}.slider_indicators_btn:after{content:"";display:block;position:absolute;left:3px;top:3px;width:6px;height:6px;-moz-border-radius:50%;border-radius:50%;border:2px solid #b9beba;-webkit-transition:all .2s ease;-o-transition:all ease .2s;-moz-transition:all ease .2s;transition:all .2s ease}.slider_indicators_btn_active{background:#fdd9dd}.slider_indicators_btn_active:after{border:2px solid transparent;background:#eb3436}.slider_item{height:100%;min-height:1px}.slider_control{position:absolute;top:50%;-moz-border-radius:0;border-radius:0;width:20px;height:40px;line-height:40px;background-color:#d9d9d9;background-color:rgba(0,0,0,.15);margin-top:-20px;font-size:20px;z-index:2;border:none;outline:none;-webkit-transition:background-color .2s ease;-o-transition:background-color ease .2s;-moz-transition:background-color ease .2s;transition:background-color .2s ease}.slider_control i{color:#fff;color:hsla(0,0%,100%,.4);-webkit-transition:color .2s ease;-o-transition:color ease .2s;-moz-transition:color ease .2s;transition:color .2s ease}.slider_control:hover{color:#fff;background-color:#999;background-color:rgba(0,0,0,.4)}.slider_control_prev{left:0}.slider_control_next{right:0}.chn,.corechn1,.corechn2{height:480px}.o2_mini .corechn1,.o2_mini .corechn2{height:375px}.special{height:450px}.live{height:520px}.o2_mini .chn,.o2_mini .corechn1,.o2_mini .corechn2{height:400px}.o2_mini .special{height:375px}.o2_mini .live{height:432px}.fl{float:left}.fr{float:right}.al{text-align:left}.ac{text-align:center}.ar{text-align:right}.clear,.clr{display:block;clear:both;height:0;line-height:0;font-size:0}.cart_bd,.cart_ft,.cart_head,.clear,.clr,.m,.mb,.mc,.mt,.p-img,.p-market,.p-name,.p-price,.sm{overflow:hidden}.w{margin:auto;width:1190px}.o2_mini .w{width:990px}.ci-left,.ci-right,.dd-spacer{display:none!important}.loading{display:block;height:70px}.img-error{background:url(//misc.360buyimg.com/lib/skin/e/i/error-jd.gif) no-repeat 50% 50%}#header .w{position:relative;z-index:11;height:140px}#header .style-red{color:#f10215;width:70px;white-space:nowrap;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis}#logo{z-index:2;left:0;top:-31px;width:190px;height:170px;-webkit-box-shadow:0 -12px 10px rgba(0,0,0,.2);-moz-box-shadow:0 -12px 10px rgba(0,0,0,.2);box-shadow:0 -12px 10px rgba(0,0,0,.2);background-color:#fff;border-bottom:1px solid #ededed}#logo,.logo_tit{position:absolute}.logo_tit{width:100%;height:100%}.logo_tit_lk{background-repeat:no-repeat;background-position:0 0;overflow:hidden;display:block;width:190px;height:170px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.head.png);font-size:0}.logo_subtit{display:none}.logo_extend{display:none;position:absolute;width:100%;height:100%}.search-m{position:relative;z-index:1;height:60px}.search-m .search_logo{display:none}.search-m .form{position:absolute;left:320px;top:25px;width:550px;height:35px}.search-m .search_bg{color:#989898;background-color:#fff}.search-m .button,.search-m .search_bg,.search-m .text{position:absolute;top:0;outline:none}.search-m .text{color:#333}.search-m .search_bg,.search-m .text{left:0;padding:4px 44px 4px 4px;width:450px;height:25px;border:1px solid transparent;line-height:25px;font-size:14px}.search-m .button{-moz-border-radius:0;border-radius:0;right:0;width:50px;height:35px;line-height:35px;border:none;background-color:#f10215;font-size:20px;font-weight:700;color:#fff}.photo-search-btn{position:absolute;right:65px;top:10px;width:19px;height:15px;overflow:hidden}.photo-search-btn .upload-bg{display:block;width:19px;height:15px;background:url(//misc.360buyimg.com/product/search/1.0.4/css/i/sprite-photo-search.png) no-repeat;cursor:pointer}.photo-search-btn .upload-trigger{position:absolute;right:0;top:0;z-index:3;width:500px;height:500px;cursor:pointer;filter:alpha(opacity=0);-moz-opacity:0;opacity:0}.photo-search-btn:hover .upload-bg{background-position:-30px 0}.z-have-photo-search .text{width:339px;padding-right:35px}.z-have-photo-search .photo-search-btn{display:block}#photo-search-dropdown{position:absolute;z-index:1;top:60px;left:270px;width:398px;border:1px solid #ccc;border-top:medium none;background:#fff;-moz-box-shadow:1px 2px 1px rgba(0,0,0,.2);-webkit-box-shadow:1px 2px 1px rgba(0,0,0,.2);box-shadow:1px 2px 1px rgba(0,0,0,.2)}.root61 #photo-search-dropdown{left:320px;width:498px}.photo-search-tip{padding:12px;text-align:center}.photo-search-tip .tip-inner{display:inline-block;*display:inline;*zoom:1}.photo-search-tip .tip-icon{display:inline-block;width:53px;height:60px;margin-right:25px;vertical-align:middle;background:url(//misc.360buyimg.com/product/search/1.0.4/css/i/sprite-photo-search.png) no-repeat 0 -20px}.photo-search-tip .tip-main{display:inline-block;*display:inline;*zoom:1;text-align:left;vertical-align:middle;font-family:Microsoft YaHei,sans-serif}.photo-search-tip .tip-title{font-weight:700}.photo-search-tip .tip-error .tip-icon{width:50px;height:64px;background-position:-60px -10px}.search-fix{position:fixed;z-index:100;left:0;top:0;width:100%;border-bottom:2px solid #f10214;background-color:#fff;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,.2);-moz-box-shadow:2px 2px 2px rgba(0,0,0,.2);box-shadow:2px 2px 2px rgba(0,0,0,.2)}.cssanimations .search-fix{-webkit-animation:searchTop .5s ease-in-out;-moz-animation:searchTop .5s ease-in-out;animation:searchTop .5s ease-in-out}@-webkit-keyframes searchTop{0%{top:-50px}to{top:0}}@-moz-keyframes searchTop{0%{top:-50px}to{top:0}}@keyframes searchTop{0%{top:-50px}to{top:0}}.search-fix .search-m{margin:auto;width:1190px;height:48px}.search-fix .search-m .form{top:6px}.search-fix .search-m .search_bg,.search-fix .search-m .text{border-color:#efefef;background-color:#efefef}.search-fix .search-m .search_logo{display:block;position:absolute;left:0;top:4px;width:125px;height:40px}.search-fix .search-m .search_logo_lk{background-repeat:no-repeat;background-position:-195px 0;overflow:hidden;display:block;width:125px;height:40px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.head.png);text-indent:-999px}.search-fix .search-m #shelper{top:40px}.o2_mini .search-fix .search-m{width:990px}.o2_mini .search-m .form{left:270px;width:400px}.o2_mini .search-m .search_bg,.o2_mini .search-m .text{width:340px}@media only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5){.logo_tit_lk{background-position:0 0;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.logo_tit_lk,.search-fix .search-m .search_logo_lk{background-repeat:no-repeat;-moz-background-size:317.5px 170px;background-size:317.5px 170px}.search-fix .search-m .search_logo_lk{background-position:-192.5px 0;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}}#treasure{position:absolute;right:0;bottom:10px;width:190px;height:40px}#treasure img{display:block;width:100%;height:100%}.o2_mini #treasure{display:none}#hotwords{overflow:hidden;position:absolute;left:320px;top:65px;width:550px;height:20px;line-height:20px}#hotwords a{float:left;margin-right:10px;white-space:nowrap;color:#999}#hotwords a:hover{color:#c81623}#hotwords a.red{color:#f10215}.o2_mini #hotwords{left:270px;width:400px}#navitems{overflow:hidden;position:absolute;left:200px;bottom:0;width:790px;height:40px;padding-top:20px}#navitems .spacer,#navitems li,#navitems ul{float:left}#navitems li{margin-left:25px}#navitems a{position:relative;display:block;height:40px;line-height:40px;font-size:14px;color:#333}#navitems a:hover{color:#c81623}#navitems .spacer{overflow:hidden;margin-top:15px;margin-left:17px;margin-right:-7px;width:1px;height:10px;background-color:#ccc}.o2_ie7 #navitems .spacer,.o2_ie8 #navitems .spacer{margin-top:16px}#navitems .promo,#navitems .symbol{display:none}#navitems img{position:absolute;top:-5px;margin-left:-22px;width:42px;height:15px}#shelper{overflow:hidden;position:absolute;z-index:1;left:270px;top:59px;width:398px;border:1px solid #ccc;background-color:#fff;-webkit-box-shadow:1px 2px 1px rgba(0,0,0,.2);-moz-box-shadow:1px 2px 1px rgba(0,0,0,.2);box-shadow:1px 2px 1px rgba(0,0,0,.2)}#shelper li{overflow:hidden;padding:1px 6px;line-height:24px;cursor:pointer}#shelper li.fore1{width:100%;padding:0;border-bottom:1px solid #ddd}#shelper .dropdown-simg{display:inline-block;margin-right:5px;vertical-align:text-bottom}#shelper li.fore1 .search-item{width:250px}#shelper li.fore1 .item1{float:none;width:auto;padding:1px 5px;overflow:hidden}#shelper li.fore1 div.fore1{padding:0 6px}#shelper li.fore1 strong{color:#c00}#shelper li.fore1 .fore1 strong{color:#333}#shelper li.fore1 .item2{float:none;width:auto;padding:1px 6px 1px 20px}#shelper li.fore1 .item3{float:none;width:auto;color:#9c9a9c}#shelper li.fore1 span{float:left}#shelper li.fore1 div:hover,#shelper li:hover{background:#f5f5f5!important}#shelper .search-item{float:left;width:190px;white-space:nowrap;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden}#shelper .search-count{overflow:hidden;color:#aaa;text-align:right;*zoom:1}#shelper .close{border-top:1px solid #efefef;text-align:right}#shelper .item3{cursor:default}#shelper .item3 a{float:left;margin-right:10px;white-space:nowrap}#shelper li.close:hover,#shelper li.fore1:hover{background:none}.root61 #shelper{left:320px;width:498px}.root61 #shelper li.brand-search .bs-item .name{width:380px}#settleup{position:absolute;right:99px;top:25px;z-index:21}#settleup .cw-icon{width:188px;height:33px;background-color:#fff;text-align:center;line-height:33px}#settleup .cw-icon .iconfont{margin-right:3px;font-size:16px;color:#f10214}#settleup .cw-icon a{color:#f10214}#settleup .ci-count{position:absolute;top:5px;left:140px;right:auto;display:inline-block;padding:1px;font-size:12px;line-height:12px;color:#fff;background-color:#f10215;-moz-border-radius:7px;border-radius:7px;min-width:12px;text-align:center}#settleup .dropdown-layer{top:35px;right:0;width:308px}.cart_empty{height:49px;margin:auto;padding:10px 0;text-align:center;line-height:49px;overflow:hidden;color:#999}.cart_empty_img{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;width:56px;height:49px;background-image:url(//img11.360buyimg.com/uba/jfs/t3571/299/131233948/1117/a1196554/58004d6dN2927f0f7.png)}.cart_pop{position:relative;z-index:2;width:100%;background:#fff}.cart_hd{height:25px;padding:6px 8px;line-height:25px}.cart_bd{background:#fff;height:auto!important;height:344px;max-height:344px;overflow-y:auto}.cart_ft{padding:8px;background:#f5f5f5;text-align:right;_height:45px;_padding-top:15px;_padding-bottom:0}.cart_num{font-weight:700}.cart_ft_info{float:left;line-height:29px}.cart_ft_lk{float:right;height:29px;padding:0 10px;background:#e4393c;color:#fff;text-align:center;font-weight:700;line-height:29px;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px}.cart_ft_lk:hover{color:#fff}.cart_giftlist,.cart_manjianlist,.cart_manzenglist,.cart_singlelist,.cart_suitlist{margin-top:-1px}.cart_item{line-height:17px;vertical-align:bottom;*zoom:1;background:#fff}.cart_item:hover{background:#f5f5f5}.cart_item_mz{color:#999}.cart_item_mz:hover{background:#fff}.cart_item_hd,.cart_item_inner{padding:8px 10px;border-top:1px dotted #ccc;overflow:hidden}.cart_item_hd_info{float:left}.cart_item_hd_price{float:right;margin-left:10px}.cart_item_hd .cart_tag{float:none}.cart_gift{height:17px;clear:both;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap}.cart_gift_lk{color:#999}.cart_gift_jq{color:#999;clear:both}.cart_img{float:left;width:50px;height:50px;border:1px solid #ddd;padding:0;margin-right:10px;font-size:0;overflow:hidden}.cart_img_lk{display:block}.cart_name{float:left;width:120px;height:52px;overflow:hidden}.cart_info{float:right;text-align:right;width:85px}.cart_delete,.cart_price,.cart_tag{float:right;clear:both;max-width:85px;white-space:nowrap;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden}.cart_tag{display:inline-block;margin-bottom:2px;color:#fff;padding:0 2px;line-height:16px;vertical-align:top}.cart_tag_orange{background:#f60}.cart_tag_green{background:#3b0}.cart_price{font-weight:700}.cart_item_hd{overflow:hidden}.cart_suitlist .cart_item_hd{background:#d3ebff}.cart_manjianlist .cart_item_hd,.cart_manjianlist .cart_item_hd:hover,.cart_manzenglist .cart_item_hd,.cart_manzenglist .cart_item_hd:hover{background:#bffab1}.cart_suit_tag{font-weight:700}.cart_suit_virtual,.cart_suit_virtual .cart_item_hd,.cart_suit_virtual .cart_item_hd:hover,.cart_suit_virtual .cart_item_inner,.cart_suit_virtual .cart_item_inner:hover,.cart_suit_virtual:hover{background:#f7f7f7}.cart_suit_virtual .cart_item_bd{padding:0 8px}.cart_suit_virtual .cart_item_inner{padding-left:0;padding-right:0}.cart_suit_virtual .cart_delete{margin-left:12px}.cart_suit .cart_num{font-weight:400}.cart_suit_virtual .cart_num{font-weight:700}.shortcut_num{margin-left:4px}#shortcut{border-bottom:1px solid #ddd;background-color:#e3e4e5}#shortcut .w{height:30px;line-height:30px;color:#999}#shortcut a{color:#999}#shortcut a:hover{color:#e33333}#shortcut li{float:left}#shortcut li.spacer{overflow:hidden;margin:11px 5px 0;width:1px;height:10px;background-color:#ccc}#shortcut .dt{padding-left:7px;padding-right:7px}#shortcut .dd{line-height:24px}#shortcut .style-red{color:#f10215}.dorpdown,.shortcut_btn{position:relative;z-index:21}.shortcut_btn:hover{z-index:22}.cw-icon{overflow:hidden;position:relative;z-index:1;float:left;border:1px solid #e3e4e5}.fr .cw-icon{padding-right:20px!important}.fr .iconfont{position:absolute;right:5px;top:10px;width:12px;height:12px;line-height:12px}.o2_ie7 .fr .iconfont,.o2_ie8 .fr .iconfont{top:9px}.dorpdown-layer,.dropdown-layer{display:none;position:absolute;border:1px solid #ccc;background-color:#fff;-webkit-box-shadow:1px 2px 1px rgba(0,0,0,.1);-moz-box-shadow:1px 2px 1px rgba(0,0,0,.1);box-shadow:1px 2px 1px rgba(0,0,0,.1)}.dorpdown:hover .dorpdown-layer,.dropdown:hover .dropdown-layer,.shortcut_btn:hover .dropdown-layer{display:block}.dorpdown:hover .cw-icon,.dropdown:hover .cw-icon,.shortcut_btn:hover .cw-icon{padding-bottom:2px;border-color:#ccc;border-bottom:none;background-color:#fff}#shortcut .cw-icon{height:28px;line-height:28px}#shortcut .dorpdown-layer,#shortcut .dropdown-layer{top:30px}#ttbar-mycity{margin-left:200px}#ttbar-mycity .iconfont{font-size:14px;color:#f10215;margin-right:4px}#ttbar-mycity .dd{left:0;width:300px;padding:10px}.mobile{position:relative;z-index:21}.mobile_txt{width:60px;text-align:center}.mobile_static{position:absolute;left:3px;width:66px;height:66px;border:1px solid #cfcfcf}.mobile_static_qrcode{margin:4px auto;width:60px;height:60px;background:#f6f6f6 url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/mobile_qrcode.png) 50% no-repeat}@media only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5){.mobile_static_qrcode{background:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected]) 50% no-repeat;-moz-background-size:60px;background-size:60px}}.mobile_pop:before,.mobile_static:before{content:"";position:absolute;display:block;top:-9px;left:50%;margin-left:-5px;width:0;height:0;line-height:0;font-size:0;border-width:5px;border-style:solid;border-color:#e4e4e4 #e4e4e4 #f6f6f6}.mobile_pop:before{border-color:#e4e4e4 #e4e4e4 #fff;left:154px}.mobile .mod_loading{height:200px}.mobile_pop{display:none;position:absolute;left:auto;right:0;top:30px;width:190px;border:1px solid #cfcfcf;background-color:#fff;border-bottom:3px solid #60575a}.mobile_on .mobile_pop{display:block}.mobile_on .mobile_static{display:none}#ttbar-serv .dd{right:0;width:170px;padding:10px 0}#ttbar-serv .item{display:inline-block;*display:inline;*zoom:1;width:70px;padding-left:15px}#ttbar-serv .item-business,#ttbar-serv .item-client{padding-left:15px;font-weight:700;color:#666}#ttbar-serv .item-business{margin-top:5px;padding-top:5px;border-top:1px dotted #eee}#ttbar-navs .dd{right:-84px;width:1188px;padding:15px 0}#ttbar-navs dl{float:left;width:255px;padding-left:20px;border-left:1px solid #eee}#ttbar-navs dl.fore1{border-left:none;width:340px}#ttbar-navs dt{margin-bottom:5px;font-weight:700;color:#666}#ttbar-navs dd{overflow:hidden;*zoom:1}#ttbar-navs .item{overflow:hidden;float:left;width:85px;white-space:nowrap}.o2_mini #ttbar-navs .dd{width:988px}.o2_mini #ttbar-navs dl{width:200px}.o2_mini #ttbar-navs dl.fore1{width:300px}.o2_mini #ttbar-navs .item{width:100px}#ttbar-login{margin-right:8px;z-index:20}#ttbar-login .nickname{display:block;width:70px;padding-right:6px;white-space:nowrap;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;text-align:right;margin-right:40px}#ttbar-login.shortcut_userico_company .nickname{padding-right:10px}.o2_mini #ttbar-login{width:145px;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;margin-right:5px;text-align:right}.shortcut_userico_ico{position:absolute;top:6px;right:20px;display:block;width:38px;height:16px}.shortcut_userico3.hover .cw-icon,.shortcut_userico3:hover .cw-icon{border-color:#dfc676}.shortcut_userico0 .shortcut_userico_ico{background-repeat:no-repeat;background-position:-85px -21px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}.shortcut_userico0 .userinfo_ico_icodropdown{background-repeat:no-repeat;background-position:0 -42px;width:51px;height:16px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}.shortcut_userico1 .shortcut_userico_ico{background-repeat:no-repeat;background-position:-85px -42px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}.shortcut_userico1 .userinfo_ico_icodropdown{background-repeat:no-repeat;background-position:0 0;width:80px;height:16px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}.shortcut_userico2 .shortcut_userico_ico{background-repeat:no-repeat;background-position:-85px -21px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}.shortcut_userico2 .userinfo_ico_icodropdown{background-repeat:no-repeat;background-position:0 -42px;width:51px;height:16px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}.shortcut_userico3 .shortcut_userico_ico{background-repeat:no-repeat;background-position:-85px -42px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}.shortcut_userico3 .userinfo_ico_icodropdown{background-repeat:no-repeat;background-position:0 -63px;width:51px;height:16px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}.shortcut_userico4 .shortcut_userico_ico{background-repeat:no-repeat;background-position:-85px -21px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}.shortcut_userico4 .userinfo_ico_icodropdown{background-repeat:no-repeat;background-position:0 -42px;width:51px;height:16px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}.shortcut_userico5 .shortcut_userico_ico{background-repeat:no-repeat;background-position:-85px -21px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}.shortcut_userico5 .userinfo_ico_icodropdown{background-repeat:no-repeat;background-position:0 -42px;width:51px;height:16px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}.shortcut_userico_company .shortcut_userico_ico{background-repeat:no-repeat;background-position:-85px 0;width:47px;height:16px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}.shortcut_userico_company .userinfo_ico_icodropdown{background-repeat:no-repeat;background-position:0 -21px;width:57px;height:16px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png)}@media only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5){.shortcut_userico0 .shortcut_userico_ico{background-position:-59.5px 0;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.shortcut_userico0 .shortcut_userico_ico,.shortcut_userico0 .userinfo_ico_icodropdown{background-repeat:no-repeat;-moz-background-size:97.5px 53px;background-size:97.5px 53px}.shortcut_userico0 .userinfo_ico_icodropdown{background-position:0 -18.5px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.shortcut_userico2 .shortcut_userico_ico{background-position:-59.5px 0;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.shortcut_userico2 .shortcut_userico_ico,.shortcut_userico2 .userinfo_ico_icodropdown{background-repeat:no-repeat;-moz-background-size:97.5px 53px;background-size:97.5px 53px}.shortcut_userico2 .userinfo_ico_icodropdown{background-position:0 -18.5px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.shortcut_userico4 .shortcut_userico_ico{background-position:-59.5px 0;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.shortcut_userico4 .shortcut_userico_ico,.shortcut_userico4 .userinfo_ico_icodropdown{background-repeat:no-repeat;-moz-background-size:97.5px 53px;background-size:97.5px 53px}.shortcut_userico4 .userinfo_ico_icodropdown{background-position:0 -18.5px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.shortcut_userico5 .shortcut_userico_ico{background-position:-59.5px 0;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.shortcut_userico5 .shortcut_userico_ico,.shortcut_userico5 .userinfo_ico_icodropdown{background-repeat:no-repeat;-moz-background-size:97.5px 53px;background-size:97.5px 53px}.shortcut_userico5 .userinfo_ico_icodropdown{background-position:0 -18.5px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.shortcut_userico_company .shortcut_userico_ico{background-repeat:no-repeat;-moz-background-size:97.5px 53px;background-size:97.5px 53px;background-position:0 -37px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.shortcut_userico_company .userinfo_ico_icodropdown{background-repeat:no-repeat;-moz-background-size:97.5px 53px;background-size:97.5px 53px;background-position:0 0;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}}.fs{z-index:9;margin-bottom:30px}.fs,.fs_inner{position:relative}.fs_inner{z-index:1;height:480px;background-color:#f0f3ef}.fs_col1{width:190px}.fs_col1,.fs_col2{float:left;height:480px;margin-right:10px}.fs_col2{width:590px}.fs_col3{float:left}.fs_col3,.fs_col4{width:190px;height:480px}.fs_col4{float:right}.fs_act{display:block;position:absolute;left:0;top:0;width:100%}.o2_mini .fs_col2{width:580px}.o2_mini .fs_act,.o2_mini .fs_col3{display:none}.cate{position:relative;z-index:2}.cate_menu{overflow:hidden;padding:10px 0;height:460px;background-color:#fefefe;color:#636363}.cate_menu_item{overflow:hidden;padding-left:18px;height:27px;line-height:27px;font-size:0;-webkit-transition:background-color .2s ease;-o-transition:background-color ease .2s;-moz-transition:background-color ease .2s;transition:background-color .2s ease}.cate_menu_item_on{background-color:#d9d9d9}.cate_menu_line{padding:0 2px;font-size:12px}.cate_menu_lk{font-size:14px;color:#626262;-webkit-transition:color .2s ease;-o-transition:color ease .2s;-moz-transition:color ease .2s;transition:color .2s ease}.cate_menu_item_on .cate_menu_lk:hover{color:#e33333}.cate_pop{position:absolute;left:191px;top:0;width:998px;min-height:478px;border:1px solid #f7f7f7;background-color:#fff;-webkit-box-shadow:2px 0 5px rgba(0,0,0,.3);-moz-box-shadow:2px 0 5px rgba(0,0,0,.3);box-shadow:2px 0 5px rgba(0,0,0,.3);-webkit-transition:top .25s ease;-o-transition:top .25s ease;-moz-transition:top .25s ease;transition:top .25s ease}.o2_ie7 .cate_pop,.o2_ie8 .cate_pop{border:1px solid #6e6568}.cate_part{display:none;padding:20px 0 10px}.cate_part_col1{float:left;width:800px}.cate_part_col2{float:left;width:198px}.cate_brand{margin:auto;width:168px;font-size:0}.cate_brand_lk{overflow:hidden;display:inline-block;width:83px;height:35px;margin:0 0 1px 1px;background-color:#e7e7e7}.cate_promotion{margin:10px auto 0;width:168px}.cate_promotion_lk{display:block;margin-bottom:1px;height:134px;background-color:#e7e7e7}.cate_channel{overflow:hidden;padding-left:20px;height:24px}.cate_channel_lk{*cursor:pointer;float:left;margin-right:10px;padding:0 10px;height:24px;background-color:#333;line-height:24px;color:#fff}.cate_channel_lk:hover{background-color:#5c5251;color:#fff}.cate_channel_arrow{margin-left:5px}.cate_detail{overflow:hidden;*zoom:1;padding:10px 0 0 20px}.cate_detail_col1,.cate_detail_col2{float:left;width:369px}.cate_detail_col1{padding-right:20px;border-right:1px solid #eee}.cate_detail_col2{margin-left:20px}.cate_detail_item{position:relative;padding-left:80px}.cate_detail_tit{overflow:hidden;position:absolute;left:0;top:6px;width:70px;text-align:right;font-weight:700;white-space:nowrap;-o-text-overflow:ellipsis;text-overflow:ellipsis}.cate_detail_tit_arrow{margin-left:5px}.cate_detail_con{overflow:hidden;*zoom:1;padding:5px 0}.cate_detail_con_lk{float:left;margin:3px 0;padding:0 10px;height:16px;border-left:1px solid #e0e0e0;line-height:16px;white-space:nowrap}.cate_detail_con_lk_hot{position:relative;font-weight:700;color:#c81623;height:14px;line-height:14px;background:#f6f0f0;border:1px dotted #db7078}.cate_con_hot_l,.cate_con_hot_r{position:absolute;display:block;width:5px;height:16px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAQAgMAAABSEQbTAAAACVBMVEUAAADIFiPbcHjTwk3CAAAAAXRSTlMAQObYZgAAABxJREFUCNdjCA0NYHBgEEDBINDAoIBOo6sD6QUAyaoGVdBI6lkAAAAASUVORK5CYII=);top:-1px}.cate_con_hot_l{background-position:0 0;left:-1px}.cate_con_hot_r{background-position:100% 0;right:-1px}.o2_mini .cate_pop{width:798px}.o2_mini .cate_part_col1{width:600px}.o2_mini .cate_detail_col1,.o2_mini .cate_detail_col2{width:590px}.o2_mini .cate_detail_col1{padding-right:0;border-right:none}.o2_mini .cate_detail_col2{margin-left:0}.focus{position:relative;float:left;width:590px;margin-top:10px;overflow:hidden}.focus,.focus_item,.focus_main{height:470px}.focus_item{width:590px;background-color:#fff}.focus_item_img{display:block;width:100%;height:100%;-webkit-transition:opacity .2s;-o-transition:opacity .2s;-moz-transition:opacity .2s;transition:opacity .2s}.focus_item_img[data-src]{opacity:0;background:#eee}.focus_item_lk,.focus_list{overflow:hidden;width:100%;height:100%}.focus_item_atag{position:absolute;right:0;bottom:0;width:34px;height:20px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACIAAAAUCAYAAADoZO9yAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RDlDNTAzMjg4MTA4MTFFOEI4OEVFNDRDNkRCQTgxRTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RDlDNTAzMjk4MTA4MTFFOEI4OEVFNDRDNkRCQTgxRTYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpEOUM1MDMyNjgxMDgxMUU4Qjg4RUU0NEM2REJBODFFNiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpEOUM1MDMyNzgxMDgxMUU4Qjg4RUU0NEM2REJBODFFNiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PrtVBHkAAADxSURBVHjaYmQgD7ADsQwQSwGxIBDzATEbELOQaR4DI4nqQRZrAbECEDMxUBEQ6xAhILYEYmkGGgFGIuSNgNiQ2iFAikNAce4CTQs0B7h8yQHE3vgccfbsWV9iLEBWh08PCw4xDyAWJWQ5NoONjY03I8sj80mNGlB0KGFzBLGGEhtqyOahh4g6NkeQA7A5HJ9nkNMIJzSLUgWQGnrIIWICzSkM1AoRYsRhDoY5hAcaLQwDHSJatCiwSE2soJyjQquCClfIoDuSCVpe8DAMMGCB1qgUBTE19DLiKsDoDUBRI8AwCADIIVyDxSFsg8EhAAEGAOjbPvI0X9SCAAAAAElFTkSuQmCC)}.focus .slider_wrapper{height:470px}.focus .slider_control{*cursor:pointer;position:absolute;z-index:1;top:50%;margin-top:-20px;width:24px;height:40px;background-color:#aeb5ad;background-color:rgba(0,0,0,.2);color:#fff;color:hsla(0,0%,100%,.4);line-height:40px;text-align:center}.focus .slider_control:hover{color:#fff;background-color:#000;background-color:rgba(0,0,0,.5)}.focus .slider_control_prev{left:0}.focus .slider_control_next{right:0}.focus .slider_control i{font-size:20px}.focus .slider_indicators{z-index:1;margin-left:0!important;left:46px;bottom:20px}.focus .slider_indicators_btn{width:18px;height:18px}.focus .slider_indicators_btn,.focus .slider_indicators_btn:after{-webkit-transition:background .2s ease;-o-transition:background ease .2s;-moz-transition:background ease .2s;transition:background .2s ease}.focus .slider_indicators_btn:after{left:4px;top:4px;border-color:hsla(0,0%,100%,.4)}.focus .slider_indicators_btn_active{background:hsla(0,0%,100%,.2)}.focus .slider_indicators_btn_active:after{background:#fff}.mod_actmark{position:absolute;background:no-repeat 0 0;z-index:1;-moz-background-size:100% 100%;background-size:100% 100%}.mod_actmark_top{width:150px;height:80px;background-image:url("//img12.360buyimg.com/da/jfs/t10669/34/2009082262/3950/711d99a8/59ed63d9N6d310aad.png");top:0;left:0}.mod_actmark_focus{width:75px;height:100px;background-image:url("//img12.360buyimg.com/da/jfs/t9862/355/2008307511/6125/4e26230/59ed6aa9N86e430ae.png");top:0;left:20px;z-index:2}.mod_actmark_portal{display:none;width:40px;height:26px;background-image:url("//img11.360buyimg.com/da/jfs/t5632/218/339127326/16869/4ef9c4da/591ebef0N74ab7369.png");top:110px;left:20px;-webkit-transition:-webkit-transform .2s;-moz-transition:transform .2s,-moz-transform .2s;transition:transform .2s,-webkit-transform .2s,-moz-transform .2s}.csstransitions .pt_cover_lk:hover .mod_actmark_portal{-webkit-transform:translateX(-10px);-moz-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}.o2_mini .mod_actmark_top{display:none}@media only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5){.mod_actmark_top{background-image:url("//img20.360buyimg.com/da/jfs/t9601/25/2008908153/24250/25d54882/59ed6ab1N7b3f167a.png")}.mod_actmark_focus{background-image:url("//img13.360buyimg.com/da/jfs/t11548/260/342215298/32981/f0db531a/59ed6ba8Na6f28ab2.png")}.mod_actmark_portal{background-image:url("//img14.360buyimg.com/da/jfs/t5884/122/341875117/1296/762dac4a/591eb9d6N5526460b.png")}}.rec{float:left;width:190px}.rec_item{margin-top:10px}.rec_item,.rec_lk{width:190px;height:150px}.rec_lk{display:block;background:#fff;-webkit-transition:opacity .2s ease;-o-transition:opacity ease .2s;-moz-transition:opacity ease .2s;transition:opacity .2s ease}.rec_lk:hover{opacity:.8}.rec_img{display:block;width:190px;height:150px}.rec_img img{-webkit-transition:opacity .1s ease;-o-transition:opacity ease .1s;-moz-transition:opacity ease .1s;transition:opacity .1s ease}.user{height:150px;background:#fff;margin-top:10px;text-align:center}.user_inner{position:relative;padding-top:62px;height:78px}.user_avatar{position:absolute;left:50%;top:-10px;margin-left:-34px;width:65px;height:65px}.user_avatar_lk{border:5px solid #e3e1df;-moz-border-radius:50%;border-radius:50%;overflow:hidden;-webkit-box-shadow:3px 6px 25px #c3c3c3;-moz-box-shadow:3px 6px 25px #c3c3c3;box-shadow:3px 6px 25px #c3c3c3}.user_avatar_lk,.user_avatar_lk img{display:block;width:55px;height:55px}.user_show{padding:0 10px}.user_show p{overflow:hidden;line-height:20px;width:100%;white-space:nowrap;-o-text-overflow:ellipsis;text-overflow:ellipsis;color:#888}.user_show .user_sl{line-height:0;font-size:0}.user_company{background-position:-111px 0;width:57px;height:16px;margin:3px 10px 0 0;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.user.png)}.user_company,.user_plus1 .user_plusico,.user_plus3 .user_plusico{background-repeat:no-repeat;-moz-background-size:168px 133px;background-size:168px 133px;position:relative;display:inline-block}.user_plus1 .user_plusico,.user_plus3 .user_plusico{background-position:-25px -113px;width:19px;height:13px;top:2px;margin-right:4px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.user.png)}.user_logout,.user_lv,.user_spoint{display:inline-block;vertical-align:top;height:20px;line-height:20px;font-size:12px}.user_login,.user_reg{padding:0 2px}.user_lvico,.user_spoint_ico{display:inline-block;position:relative;width:20px;height:20px;margin-right:4px;background-repeat:no-repeat}.user_spoint_ico{background-position:-111px -21px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.user.png)}.user_lv_0 .user_lvico,.user_lv_6 .user_lvico,.user_spoint_ico{background-repeat:no-repeat;-moz-background-size:168px 133px;background-size:168px 133px}.user_lv_0 .user_lvico,.user_lv_6 .user_lvico{background-position:-136px -21px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.user.png)}.user_lv_1 .user_lvico{background-position:-111px -46px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.user.png)}.user_lv_1 .user_lvico,.user_lv_2 .user_lvico{background-repeat:no-repeat;-moz-background-size:168px 133px;background-size:168px 133px}.user_lv_2 .user_lvico{background-position:-136px -46px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.user.png)}.user_lv_3 .user_lvico{background-position:-111px -71px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.user.png)}.user_lv_3 .user_lvico,.user_lv_4 .user_lvico{background-repeat:no-repeat;-moz-background-size:168px 133px;background-size:168px 133px}.user_lv_4 .user_lvico{background-position:-136px -71px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.user.png)}.user_lv_5 .user_lvico{background-repeat:no-repeat;-moz-background-size:168px 133px;background-size:168px 133px;background-position:0 -113px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.user.png)}@media only screen and (-o-min-device-pixel-ratio:3/2),only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min--moz-device-pixel-ratio:1.5),only screen and (min-device-pixel-ratio:1.5){.user_company{background-position:0 0;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.user_company,.user_spoint_ico{background-repeat:no-repeat;-moz-background-size:102px 61px;background-size:102px 61px}.user_spoint_ico{background-position:0 -18px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.user_plus0 .user_avatar_lk,.user_plus2 .user_avatar_lk,.user_plus4 .user_avatar_lk{background-repeat:no-repeat;background-position:0 0;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.user.png)}.user_plus1 .user_avatar_lk,.user_plus3 .user_avatar_lk{background-repeat:no-repeat;background-position:0 0;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.user.png)}.user_plus1 .user_plusico,.user_plus3 .user_plusico{background-repeat:no-repeat;-moz-background-size:102px 61px;background-size:102px 61px;background-position:-82px -22px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.user_lv_0 .user_lvico,.user_lv_6 .user_lvico{background-position:-22px -18px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.user_lv_0 .user_lvico,.user_lv_1 .user_lvico,.user_lv_6 .user_lvico{background-repeat:no-repeat;-moz-background-size:102px 61px;background-size:102px 61px}.user_lv_1 .user_lvico{background-position:-59px 0;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.user_lv_2 .user_lvico{background-position:0 -41px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.user_lv_2 .user_lvico,.user_lv_3 .user_lvico{background-repeat:no-repeat;-moz-background-size:102px 61px;background-size:102px 61px}.user_lv_3 .user_lvico{background-position:-22px -41px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.user_lv_4 .user_lvico{background-position:-45px -41px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}.user_lv_4 .user_lvico,.user_lv_5 .user_lvico{background-repeat:no-repeat;-moz-background-size:102px 61px;background-size:102px 61px}.user_lv_5 .user_lvico{background-position:-82px 0;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected])}}.user_logout:hover{color:#c81623}.user_profit{margin-top:10px;height:25px;font-size:0}.user_profit_lk{display:inline-block;margin:0 5px;width:70px;height:25px;line-height:25px;font-size:12px;text-align:center;color:#e43f3b;-moz-border-radius:13px;border-radius:13px;-webkit-box-shadow:6px 8px 20px rgba(45,45,45,.15);-moz-box-shadow:6px 8px 20px rgba(45,45,45,.15);box-shadow:6px 8px 20px rgba(45,45,45,.15);-webkit-transition:background .3s ease,color .3s ease;-o-transition:background .3s ease,color .3s ease;-moz-transition:background .3s ease,color .3s ease;transition:background .3s ease,color .3s ease}.user_profit_lk_plus{background:#363634;color:#e5d790}.user_profit_lk_long{margin-right:0;width:152px;padding:0 5px;white-space:nowrap;overflow:hidden;-o-text-overflow:ellipsis;text-overflow:ellipsis}.user_profit_lk_company{background:#fff;color:#b79c6f;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.user_profit .user_profit_lk_company:hover{color:#e33333;background:#fff}.user_profit a:hover{background-color:#e01222;color:#fff}.news{overflow:hidden;height:130px;background:#fff}.news .mod_tab_head{padding:8px 0 0;position:relative;line-height:13px;font-size:0}.news_more{position:absolute;right:12px;top:8px;font-size:12px}.news .mod_tab_head_item{font-size:12px;color:#333;padding-right:15px;padding-left:15px;border-right:1px solid #dfe0e1}.news .news_last{border-right:none}.news .mod_tab_content{position:relative;padding-top:8px;margin:0 15px;height:88px}.news .mod_tab_content_item{display:none;height:100%;overflow:hidden}.news .mod_tab_content_item_on{display:block}.news_item{line-height:22px;max-width:160px;_width:160px;white-space:nowrap;-o-text-overflow:ellipsis;text-overflow:ellipsis;overflow:hidden;color:#999}.news_tab_active{position:absolute;bottom:-1px;left:0;margin-left:13px;width:27px;height:2px;background:#db192b;-webkit-transform:translateX(0s);-moz-transform:translateX(0s);-ms-transform:translateX(0s);transform:translateX(0s);-webkit-transition:-webkit-transform .3s ease;transition:-webkit-transform .3s ease;-o-transition:transform .3s ease;-moz-transition:transform .3s ease,-moz-transform .3s ease;transition:transform .3s ease;transition:transform .3s ease,-webkit-transform .3s ease,-moz-transform .3s ease}.service{overflow:hidden;position:relative;height:190px;-webkit-transition:all .2s ease;-o-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease}.service:after{content:"";position:absolute;top:0;display:block;width:160px;left:15px;height:1px;background:#ebeaea;z-index:1}.service_entry{overflow:hidden;padding:18px 11px 11px;background:#fff}.service_list{height:165px}.service_item{position:relative;float:left;width:42px;height:55px;background:#fff;text-align:center;overflow:hidden}.service_txt{display:block;height:25px;line-height:25px;border-bottom:2px solid #fff;color:#bea68d;-webkit-transition:color .15s ease;-o-transition:color ease .15s;-moz-transition:color ease .15s;transition:color .15s ease}.service_frame{overflow:visible}.service_expand .service_frame .service_txt{background:none;color:#666;height:14px;line-height:14px;padding-bottom:4px;border-bottom:2px solid #fff}.service_lk{display:block;position:relative;*cursor:pointer;padding-top:6px;-webkit-transition:all .2s linear;-o-transition:all linear .2s;-moz-transition:all linear .2s;transition:all .2s linear}.service_corner{position:absolute;right:0;top:0;width:12px;height:16px;font-size:12px;line-height:12px;text-align:center;background:#e01121;color:#fff;-webkit-transition:all .2s ease;-o-transition:all .2s ease;-moz-transition:all .2s ease;transition:all .2s ease}.service_corner:after{content:"";position:absolute;bottom:0;left:0;width:0;height:0;font-size:0;line-height:0;border:solid;border-width:2px 6.5px;border-color:#e01121 #e01121 #fff}.service_corner_txt{vertical-align:top}.service_pop{position:absolute;width:100%;height:180px;background-color:#fff;-webkit-transition:all .2s ease;-o-transition:all ease .2s;-moz-transition:all ease .2s;transition:all .2s ease;top:200px}.service_pop:before{background-position:0 0;content:"";position:absolute;left:-13px;bottom:-10px;width:216px;height:36px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.service.png)}.service_pop_item{position:relative;z-index:1;width:168px;height:180px;padding:0 15px;background-color:#fff}.service_pop_close{position:absolute;right:15px;top:0;width:12px;height:12px;line-height:12px;text-align:center;z-index:1}.service_pop_close:hover{background-color:#ddd}.service_expand{padding-top:0;height:210px}.service_expand:after{content:none}.service_expand .service_frame .service_lk{margin-top:-48px}.service_expand .service_frame_on .service_txt{color:#e01121;border-bottom-color:#e01121}.service_expand .service_pop{top:20px}.csstransitions .service_expand .service_pop{top:200px;-webkit-transform:translate3d(0,-100%,0);-moz-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}.service_expand .service_frame .service_corner{top:30px;width:4px;height:4px;-moz-border-radius:100%;border-radius:100%}.csstransitions .service_expand .service_frame .service_corner{top:0;-webkit-transform:translate3d(0,30px,0);-moz-transform:translate3d(0,30px,0);transform:translate3d(0,30px,0)}.service_expand .service_frame .service_corner:after,.service_expand .service_frame .service_corner_txt{display:none}.service_item:hover .service_txt{color:#e01121}.service_item svg{-webkit-transition:fill .15s ease;-o-transition:fill ease .15s;-moz-transition:fill ease .15s;transition:fill .15s ease;fill:#d1c5ae}.service_ico{display:block;width:20px;height:20px;margin:4px auto 0}.service_ico svg{display:block;width:100%;height:100%}.service_item:hover svg{fill:#e01121}.o2_ie8 .service_ico svg{display:none}.o2_ie8 .service_ico{width:24px;height:24px;margin-top:0}.o2_ie8 .service_ico_huafei{background-position:-145px -42px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.service.png)}.o2_ie8 .service_ico_jipiao{background-position:-29px -42px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.service.png)}.o2_ie8 .service_ico_dianying{background-position:-58px -42px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.service.png)}.o2_ie8 .service_ico_youxi{background-position:-87px -42px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.service.png)}.o2_ie8 .service_ico_qyg{background-position:-116px -42px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.service.png)}.o2_ie8 .service_ico_jiayou{background-position:-116px -71px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.service.png)}.o2_ie8 .service_ico_jiudian{background-position:-174px -42px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.service.png)}.o2_ie8 .service_ico_huoche{background-position:0 -71px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.service.png)}.o2_ie8 .service_ico_zhongchou{background-position:-29px -71px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.service.png)}.o2_ie8 .service_ico_licai{background-position:-58px -71px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.service.png)}.o2_ie8 .service_ico_lipin{background-position:-87px -71px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.service.png)}.o2_ie8 .service_ico_baitiao{background-position:0 -42px;background-image:url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.service.png)} + + .o2_mini .box_subtit { + width: 135px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } + .cate_brand a:not([href]) { + display: none; + } + .user_company:hover{ + color: #fff; + } +.cate_pop { +left: 191px; +background-color: #fff; +} +.chosen_list { +margin: 0 0 0 15px !important; +} +.daily_img:hover, +.daily_item_img:hover { + opacity: 0.8; +} + +.shortcut_userico5 .shortcut_userico_ico { + background-repeat: no-repeat; + background-position: -85px -21px; + background-image: url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png) +} +.shortcut_userico5 .userinfo_ico_icodropdown { + background-repeat: no-repeat; + background-position: 0 -42px; + width: 51px; + height: 16px; + background-image: url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/sprite.shortcutUsername.png) +} +.shortcut_userico5 .shortcut_userico_ico { + background-position: -59.5px 0; + background-image: url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected]) +} +.shortcut_userico5 .shortcut_userico_ico, +.shortcut_userico5 .userinfo_ico_icodropdown { + background-repeat: no-repeat; + -moz-background-size: 97.5px 53px; + background-size: 97.5px 53px +} +.shortcut_userico5 .userinfo_ico_icodropdown { + background-position: 0 -18.5px; + background-image: url(//misc.360buyimg.com/mtd/pc/index_2017/2.1.0/static/images/[email protected]) +} +.user_profit_lk_long { + width: 152px; +} + +</style> + <script type="text/javascript"> + window['_REPORT_']['CSS'] = new Date(); + </script> +</head> +<!-- E ad1 --><body class="index"> + <script> + pageConfig.focusData = [ { "href":"", "src":"", "srcB":"", "alt":"" } ]; + pageConfig.focusMonetizeData = [[{"ext_columns":{"desc":"1:cpm"},"ad_billing_type":1,"id":"4272","href":"\/\/ccc-x.jd.com\/dsp\/nc?ext=aHR0cHM6Ly9wcm8uamQuY29tL21hbGwvYWN0aXZlLzI4OHA5WnpHZHRSY1dEeGtRR1dCc0xNYk5HU1YvaW5kZXguaHRtbA&log=UrJvTnjBzdty2hUEXlk9FY31GbytoEYrM9M1FJcyWSS23yYr-waqZiMLGwxkvXddeZd-y2x1fThW1J3xePlqY1Mvm7BVh8ukjdvVIm47n0gXaK2dQryI37lMmMTFrByJcQCVjftwCuSFfAHWFoMqzGITQfNemRAxGgN8oFB4GUgTdME8eRrjmw7VLZsACcJ0qgxMMV56uoGKAYueREaryGgkOzJpTM2b2lXB-ensWf3_8ojUsDCNaNr89Ilur1bQAvZ7caZgfulxKVQfTY90zRBrg0WhANJzTgwseCf-N57-SgKwyfT4wNVqKRLHm10_mBSS0gULF4-5rSXIdPb0ueiNAKT7JyYqxcbFdihdrXVFVYCjKVPROu22SWoPZymL6f5ZgWV7TylnlCxpnsJrJu8XbgyyGaVBmol2M_VjZ_GQMrpycnlBnD0Vp2es-Ssop1PD6lsuqFSAdqhl8jVj1vozQsbM_ntFpVHRpgRYyDc&v=404","clog":"\/\/im-x.jd.com\/dsp\/np?log=UrJvTnjBzdty2hUEXlk9FY31GbytoEYrM9M1FJcyWSS23yYr-waqZiMLGwxkvXddeZd-y2x1fThW1J3xePlqY1Mvm7BVh8ukjdvVIm47n0gXaK2dQryI37lMmMTFrByJcQCVjftwCuSFfAHWFoMqzGITQfNemRAxGgN8oFB4GUgvjJe9WghfBlEZDDrebhmrnulv3qWEOY6kJCfz9SOy2T2MQykGYebqPTPJDKcXe2lYkgiH3bmPQHzwUpNfaYGSES_IOiO_rmsl2tGyoMCWHDoOiE-2P6oavW8eTWMvqDAKkUnESLxsESqccxwtlXTR74S8foZWpRMNwmombU78uEuTdWS1sg3-gJZKh4b4J0vmhkqJlFyNJweoYz3jB9URLc_A0lxKXSZ7XiPqv56_TvCBMiLpxjjn-b5HrvXzbqWzLrTHBVkGvfPfCfb00NdDHkoMlNBCG23UvDAMOBHaXg&v=404&seq=1","sourceTag":"0","src":"\/\/img1.360buyimg.com\/pop\/jfs\/t1\/56095\/7\/3867\/70792\/5d19b453E4bb10ad3\/503e0a4de729b67a.jpg"}],[{"ext_columns":{"desc":"1:cpm"},"ad_billing_type":1,"id":"3503","href":"\/\/ccc-x.jd.com\/dsp\/nc?ext=aHR0cHM6Ly9wcm8uamQuY29tL21hbGwvYWN0aXZlLzJ6ekFRejFTeTd5SkF3RVFMWGhtMndCNHhkNlUvaW5kZXguaHRtbA&log=vq67ROzfQWj3tXDfiu6ApfJpZcWFdqAiTf2j9ZzUrDzjMFqPkxIvOuebDZ2PZ5-H5OlYMt2yxmgZUIMHYqMa5RO4b2o2cooZdabLIQKfeu_EyUp_oBy0AcYFBzEISvYz4_UToz8aR9PqmeGbQiTXeE6Ez63bBFlr_dG3N-vd7oBAqfscV6L6omdMeasw8sGfDaOtqNJ6yIbSewoUczyWbhExx32vlYX90-7GNE474zLLczn8DjGerRwA6k2PMcsa1MD0DHtrDx6ufmj-QVTEoN3bzkFNRUg7TcVGmxOjYXBzioE7n-9fgFxU6omIM5ilMi-9PfoM_Z2CnoXCfjEVqZXEEbEbAADwF0vNOAzU3z8vdCDiLOvbRwj5rIuQAmE9WB7TbcbpiJ162rNI2FcPICKY7KrruQd8u45VpZbe5tcyWQxf07bq2fiqk7SB-qkNkN2WL48I_S5HGR53NbZBJfzohqY5LUyjyZIwIBdOWAjEKzkYzSP32OBb5GkIyrE1&v=404","clog":"\/\/im-x.jd.com\/dsp\/np?log=vq67ROzfQWj3tXDfiu6ApfJpZcWFdqAiTf2j9ZzUrDzjMFqPkxIvOuebDZ2PZ5-H5OlYMt2yxmgZUIMHYqMa5RO4b2o2cooZdabLIQKfeu_EyUp_oBy0AcYFBzEISvYz4_UToz8aR9PqmeGbQiTXeE6Ez63bBFlr_dG3N-vd7oDUsBFg9eDy7Io44108Ku464FdRhgSMGrDQaxN08zjUTDET-_xsAwcL8V5laLJnFX-wCt4cNZIn9juWZed0XwIQiSDagnmwKayiotAJx2zK1fZWirsLc8ICtU6eVYOWN4Yn_rWVipok2-uKLk4nbzABueirTaWzGQn2-67cbcXy22fyUdJZHqd5AQ_aigzPeaUeAs7x6WxcsQbg9s-YiM__Nn3Ak5LauFJwm8aT_ReEBGeNkNEqlHIyZFhfUlojFQUnEfXIAj45XoBScU5u9N2-tlFTZqVCJz4XPrVEcJu4fIs9JqXd-ZMJ05vTAVCqnG4&v=404&seq=1","sourceTag":"0","src":"\/\/img1.360buyimg.com\/pop\/jfs\/t1\/47132\/31\/3917\/46002\/5d1acfb6Eae9bbd31\/f9be0049eada21ea.jpg"}],[{"ext_columns":{"desc":"\u590f\u65e5\u7279\u60e0","link":"\/\/pro.jd.com\/mall\/active\/3FB63kXQ8Q8LtJSJXX1oTtdRnNXh\/index.html?innerAnchor=48760752238&focus=4","biclk":"1#13#actfore-B0016083-1-48760752238-acthot#0#42","playImpr":"1#13#300002-4-actfore___","mcinfo":"null","sku":"48760752238","text":"\u5927\u724c\u978b\u9774#48760752238"},"sku":"48760752238","did":42,"type":"delivery","href":"\/\/pro.jd.com\/mall\/active\/3FB63kXQ8Q8LtJSJXX1oTtdRnNXh\/index.html?innerAnchor=48760752238&focus=4","activity_id":"B0016083","src":"\/\/imgcps.jd.com\/ling\/48760752238\/5aSn54mM6Z6L6Z20\/5aSP5pel54m55oOg\/t-5bda9c6ebcf6c7034d254223\/d72e5a3f.jpg"}],[{"ext_columns":{"desc":"\u6ee1199\u51cf100","link":"\/\/pro.jd.com\/mall\/active\/4CDuK9nAV5ksSB1UDHFq4pTTp7VB\/index.html?innerAnchor=100001835882&focus=4","biclk":"1#13#actfore-B0016103-1-100001835882-xc01#1#42","playImpr":"1#13#300002-4-actfore___","mcinfo":"null","sku":"100001835882","text":"\u6d77\u56e4\u5168\u7403\u7f8e\u5986#100001835882"},"sku":"100001835882","did":42,"type":"delivery","href":"\/\/pro.jd.com\/mall\/active\/4CDuK9nAV5ksSB1UDHFq4pTTp7VB\/index.html?innerAnchor=100001835882&focus=4","activity_id":"B0016103","src":"\/\/imgcps.jd.com\/ling\/100001835882\/5rW35Zuk5YWo55CD576O5aaG\/5ruhMTk55YePMTAw\/t-5bd915cfba82b80306af5452\/b017bfb1.jpg"}],[{"ext_columns":{"desc":"1:cpm"},"ad_billing_type":1,"id":"3505","href":"\/\/ccc-x.jd.com\/dsp\/nc?ext=aHR0cHM6Ly9zYWxlLmpkLmNvbS9tYWxsL2hqSVQ2dUNWbTVEWS5odG1s&log=SE7vmhcTf2gB_ju3407I1U2MME2SM4nyXISqhf94WB7c4Y22cJ1gw2Uz_68buXkbBU2pruGSa3oG1C2elxBrYclSXZHiTR52kZDwIfrnGny-GoXgqYPOsDhMe73aaSGDFVpjC9puTSBbcbr1Lc2GhJG6278nu9MgoMJ88hKmnI-AjZ8VIPVMseNJV-ZWN8kOiu8E8yfVuGAkWNNDAxa-2fkTOM_Hiz3MXrFgvPEY6W3ehd3D6xS0ZjzmiAm1IV5WbZ9xFUTKJZDwzDIgKqSgA3CzzwJiIZAT2EIl8FrrS77lS1Qm_JWScVUIq_wfTVhXWiVYFLNL6twb5w1B4yXNfsSBSZhzPF9PH5Q9vCOetEqWXqk6uMNGCU2DVPTzalRKKiu-xttgcZoIDIvnM65ROxJln20N7-fBoir4R74IsW0JdbwAwRyHGJ0tohQoNvkOJ55kZiGH6k6jNyyPdAh2z_8fNpmQtfmzugjqS3HvNuhcpBKIH4Q7IxJwjZs2moeD&v=404","clog":"\/\/im-x.jd.com\/dsp\/np?log=SE7vmhcTf2gB_ju3407I1U2MME2SM4nyXISqhf94WB7c4Y22cJ1gw2Uz_68buXkbBU2pruGSa3oG1C2elxBrYclSXZHiTR52kZDwIfrnGny-GoXgqYPOsDhMe73aaSGDFVpjC9puTSBbcbr1Lc2GhFkzoY9HG7IcVZCFF8grCbAzVSyM5BXOmsvphjpLyU0FWIIXeWXbpHJ9O6Pzomcz1kg3YH5hlXt40Z_BHkAlWTJSmPDY8uNoI0_D4Yr6PVKK-MW5y08jRaI7X6zJESNRhoPsWohyv1Zw6u3d2zVuovZqZItJwo1PtfVIcKfPjLJZGFXPnFY98-oTlTjJu3MtR2grzGOeC84lyONHWXdupG8-D7wR2CbOyOYATsIDzHsG1EuwfFWZDfk6yb6vjuV1D-7NHOZwzz37ngHGBRV69REqit0Ae-I9-3aPIbEBMTO9EiZlunNmH8Yedbiv6jCkRA&v=404&seq=1","sourceTag":"0","src":"\/\/img1.360buyimg.com\/pop\/jfs\/t1\/83196\/18\/3149\/187032\/5d15d865Ee3000b1c\/bf4bc9f43013cbc8.jpg"}],[{"ext_columns":{"desc":"1:cpm"},"ad_billing_type":1,"id":"4273","href":"\/\/ccc-x.jd.com\/dsp\/nc?ext=aHR0cHM6Ly9wcm8uamQuY29tL21hbGwvYWN0aXZlLzQ5SlYyY2lTZVczUXpNc2I2Rm5wcXVFSGFFb0svaW5kZXguaHRtbA&log=EG_at_RqwdWSxE7GsrEtA1VDOTMys8925gnIMb26S4IUc60dMEgJBKNc6yI7sM4njrrJh5RCP1ekmYqiTbb90OLjpU4Wibqf5pQadUOWImR3zWt5lL9ePYv8YAohiZ2p7HHkyv6uLV9V2ZmBCenn3h59H4lmI7_jbeylArgYwMcExPMRRqryJlkCH1CGSwXaz9l-nO4XJFjcPg-vrCLNt5MYc6p6z2h4SKgaEzhT1LCCIkzRuJOK7GF8yTopnyNxEOGowmbBMJt1XYs3SvV2e5y1vTt4U6x4cftN39om2zF56mzyn60WKp_bbs2U_d1sg2dWA39crheBmVOWyKwqRVyuRmDm9ceXLiF43pB6Zaxaxrxi-ftHaa7gOgBqxucHnWVH1dQq9U2GkROYbTLNUYG-fimGvRWXQdO5i6rOmNKDeD0qypw3UOvuqhlCBjONJYZILhYxszI67h3UttIj8sAdKCLYgovZYor77676fvA&v=404","clog":"\/\/im-x.jd.com\/dsp\/np?log=EG_at_RqwdWSxE7GsrEtA1VDOTMys8925gnIMb26S4IUc60dMEgJBKNc6yI7sM4njrrJh5RCP1ekmYqiTbb90OLjpU4Wibqf5pQadUOWImR3zWt5lL9ePYv8YAohiZ2p7HHkyv6uLV9V2ZmBCenn3qsQwXQFW2Yn19K96qqk6FdaHO5w-pr5XUoYiC4Pmp3hPdG3vZcf42WFZAetHFABcn1bCqS0CJ2Yp1mqFkATUJl20BR8uHsbp1kg2nUfyk_VQXkPwJynqJBqHxb6rx8eocpqrGyNB4tApCg9GrELQaQlyjDvZXBqWyN8zeUvADA1WgNjKbv6pG5w62pacRb8n6308ys_bIjl_QaAemsOyQNjm4WGiUjOsnvdzD-icRn-u2o7QFnhyCIyHwnwT-Q8js9dwSaRTxrtdZrZxxMs6IZzVMdF6HdiS7YJlwwud0kZwF5I03lNqvRla7PPQLbMgg&v=404&seq=1","sourceTag":"0","src":"\/\/img1.360buyimg.com\/pop\/jfs\/t1\/55469\/23\/3945\/74522\/5d1b179dE381439d0\/8013a53bcefbc3cc.jpg"}],[{"ext_columns":{"desc":"\u767e\u5927\u54c1\u724c\u949c\u60e0","link":"\/\/pro.jd.com\/mall\/active\/2q9EbwAyLo42opeKXrFBBevsZNe2\/index.html?innerAnchor=804322&focus=4","biclk":"1#13#actfore-B0016073-1-804322-acthot#2#42","playImpr":"1#13#300002-4-actfore___","mcinfo":"null","sku":"804322","text":"\u590f\u65e5\u7537\u5305\u95ea\u8d2d\u5b63#804322"},"sku":"804322","did":42,"type":"delivery","href":"\/\/pro.jd.com\/mall\/active\/2q9EbwAyLo42opeKXrFBBevsZNe2\/index.html?innerAnchor=804322&focus=4","activity_id":"B0016073","src":"\/\/imgcps.jd.com\/ling\/804322\/5aSP5pel55S35YyF6Zeq6LSt5a2j\/55m-5aSn5ZOB54mM6ZKc5oOg\/t-5bd91590a96f8a032f5bd570\/c7e2fadf.jpg"}],[{"ext_columns":{"desc":"\u5b66\u751f\u4e13\u4eab\u4f4e\u81f39.9","link":"\/\/pro.jd.com\/mall\/active\/25zWEV78Tk2Jcq66S9fjPiHbn1HT\/index.html?innerAnchor=1479403843&focus=4","biclk":"1#13#actfore-B0016175-1-1479403843-xc01#3#42","playImpr":"1#13#300002-4-actfore___","mcinfo":"null","sku":"1479403843","text":"\u5bb6\u5c45\u6821\u56ed\u5609\u5e74\u534e#1479403843"},"sku":"1479403843","did":42,"type":"delivery","href":"\/\/pro.jd.com\/mall\/active\/25zWEV78Tk2Jcq66S9fjPiHbn1HT\/index.html?innerAnchor=1479403843&focus=4","activity_id":"B0016175","src":"\/\/imgcps.jd.com\/ling\/1479403843\/5a625bGF5qCh5Zut5ZiJ5bm05Y2O\/5a2m55Sf5LiT5Lqr5L2O6IezOS45\/t-5bfe43a4f8edd2d40597f1eb\/a1e8cafe.jpg"}]]; +</script> + <script> + pageConfig.recData = { "data": [ { "t":"//pro.jd.com/mall/active/QW4JzAQaMgpJP1HyEXXDNQkMgMH/index.html", "img":"//m.360buyimg.com/babel/jfs/t1/76350/15/3367/31880/5d1b16d5Edfa003b9/57a28130d78f2676.jpg" } , { "t":"//fresh.jd.com/", "img":"//m.360buyimg.com/babel/jfs/t1/76566/35/3148/84408/5d15b31cEd8ed01ac/1bce5d496befc809.jpg" } , { "t":"", "img":"" } ] }; +</script> + + <div class="mod_container" id="app"> + +<div id="shortcut"> + <div class="w"> + <ul class="fl" clstag="h|keycount|head|topbar_01"> + <li class="dorpdown" id="ttbar-mycity"></li> + </ul> + + <ul class="fr"> + <li class="fore1 dorpdown" id="ttbar-login" clstag="h|keycount|head|topbar_02"> + <a target="_blank" href="javascript:login();" class="link-login">你好,请登录</a> <a href="javascript:regist();" class="link-regist style-red">免费注册</a> + </li> + <li class="spacer"></li> + <li class="fore2" clstag="h|keycount|head|topbar_03"> + <div class="dt"><a target="_blank" href="//order.jd.com/center/list.action">我的订单</a></div> + </li> + <li class="spacer"></li> + <li class="fore3 dorpdown" id="ttbar-myjd" clstag="h|keycount|head|topbar_04"> + <div class="dt cw-icon"><a target="_blank" href="//home.jd.com/">我的京东</a><i class="iconfont"></i><i class="ci-right"><s>◇</s></i></div> + <div class="dd dorpdown-layer"></div> + </li> + <li class="spacer"></li> + <li class="fore4" clstag="h|keycount|head|topbar_05"> + <div class="dt"><a target="_blank" href="//vip.jd.com/">京东会员</a></div> + </li> + <li class="spacer"></li> + <li class="fore5" clstag="h|keycount|head|topbar_06"> + <div class="dt"><a target="_blank" href="//b.jd.com/">企业采购</a></div> + </li> + <li class="spacer"></li> + <li class="fore8 dorpdown" id="ttbar-serv" clstag="h|keycount|head|topbar_07"> + <div class="dt cw-icon">客户服务<i class="iconfont"></i><i class="ci-right"><s>◇</s></i></div> + <div class="dd dorpdown-layer"></div> + </li> + <li class="spacer"></li> + <li class="fore9 dorpdown" id="ttbar-navs" clstag="h|keycount|head|topbar_08"> + <div class="dt cw-icon">网站导航<i class="iconfont"></i><i class="ci-right"><s>◇</s></i></div> + <div class="dd dorpdown-layer"></div> + </li> + <li class="spacer"></li> + <li class="fore10 mobile" id="J_mobile" clstag="h|keycount|head|topbar_09"> + <div class="dt mobile_txt">手机京东</div> + <div class="mobile_static"> + <div class="mobile_static_qrcode"></div> + </div> + <div id='J_mobile_pop' class='mod_loading mobile_pop'> + </div> + </li> + </ul> + </div> +</div> + + +<div id="header"> + <div class="w"> + <div id="logo" class="logo"> + <h1 class="logo_tit"> + <a href="//www.jd.com" class="logo_tit_lk" clstag="h|keycount|head|logo_01">京东</a> + </h1> + <h2 class="logo_subtit">京东,多快好省</h2> + <div class="logo_extend" clstag="h|keycount|head|logo_02"></div> + </div> + + <div id="search"> + <div class="search-m"> + <div class="search_logo"> + <a href="//www.jd.com" class="search_logo_lk" clstag="h|keycount|head|logo_01">京东,多快好省</a> + </div> + <ul id="shelper" style="display: none"></ul> + + <div class="form"> + <input clstag="h|keycount|head|search_a" type="text" onkeydown="javascript:if(event.keyCode==13) search('key');" autocomplete="off" id="key" accesskey="s" class="text" /> + <button clstag="h|keycount|head|search_c" onclick="search('key');return false;" class="button"><i class="iconfont"></i></button> + </div> + </div> + </div> + + <div id="settleup" class="dorpdown" clstag="h|keycount|head|cart_null"> + <div class="cw-icon"> + <i class="ci-left"></i> + <i class="ci-right"></i> + <i class="iconfont"></i> + <a target="_blank" href="//cart.jd.com/cart.action">我的购物车</a> + </div> + <div class="dorpdown-layer"> + <div class="spacer"></div> + <div id="settleup-content"> + <span class="loading"></span> + </div> + </div> + </div> + + <div id="hotwords" clstag="h|keycount|head|search_d"></div> + + <div id="navitems"> + <ul id="navitems-group1"> + <li clstag="h|keycount|head|navi_01" class="fore1"><a target="_blank" href="//miaosha.jd.com/">秒杀</a></li> + <li clstag="h|keycount|head|navi_02" class="fore2"><a target="_blank" href="//a.jd.com/">优惠券</a></li> + <li clstag="h|keycount|head|navi_03" class="fore3"><a target="_blank" href="//plus.jd.com/index?flow_system=appicon&flow_entrance=appicon11&flow_channel=pc">PLUS会员</a></li> + <li clstag="h|keycount|head|navi_04" class="fore4"><a target="_blank" href="//red.jd.com/">闪购</a></li> + </ul> + <div class="spacer"></div> + <ul id="navitems-group2"> + <li clstag="h|keycount|head|navi_05" class="fore1"><a target="_blank" href="//paimai.jd.com/">拍卖</a></li> + <li clstag="h|keycount|head|navi_06" class="fore2"><a target="_blank" href="//fashion.jd.com">京东时尚</a></li> + <li clstag="h|keycount|head|navi_07" class="fore3"><a target="_blank" href="//chaoshi.jd.com/">京东超市</a></li> + <li clstag="h|keycount|head|navi_08" class="fore4"><a target="_blank" href="//fresh.jd.com/">京东生鲜</a></li> + </ul> + <div class="spacer"></div> + <ul id="navitems-group3"> + <li clstag="h|keycount|head|navi_09" class="fore1"><a target="_blank" href="//www.jd.hk/">海囤全球</a></li> + <li clstag="h|keycount|head|navi_10" class="fore2"><a target="_blank" href="//jr.jd.com/">京东金融</a></li> + </ul> + </div> + + <div id="treasure" clstag="h|keycount|head|adbtn_null"></div> + </div> +</div> +<!-- CLUB_LINK start --> +<div style="display:none"> + <a href="//www.jd.com/zxnews/a172d64e17755263.html">HTC手机哪款好</a> + <a href="//www.jd.com/nrjs/af98b9fb7f178611.html">双卡双待手机哪款好</a> + <a href="//www.jd.com/phb/zhishi/1afe932ec41f8476.html">8GB手机排行榜</a> + <a href="//www.jd.com/jxinfo/d9d0db1eb09fac50.html">联想天逸510s 台式机</a> + <a href="//www.jd.com/zxnews/00e438ca02b0ae2a.html">海尔滚筒式洗衣机</a> + <a href="//union.jd.com">网络赚钱</a> + <a href="//www.jd.com/hprm/12259169922114dc5ef82.html">白酒</a> + <a href="//www.jd.com/cppf/15901c58fb5406380f01f.html">立白洗衣液</a> + <a href="//www.jd.com/hotitem/167501d880f4101f9815e.html">青少年牙刷</a> + <a href="//www.jd.com/sptopic/1316b578fe1de22368e4.html">洗面奶</a> + <a href="//www.jd.com/nrjs/3246ed949ba174ea.html">唐狮拼色 连衣裙</a> + <a href="//www.jd.com/brand/9987019f0bd7d403e3de.html">苹果手机</a> + <a href="//www.jd.com/hprm/62331efefe1affa158ff.html">琵琶</a> + <a href="//www.jd.com/sptopic/117296ca19d46b24dfeb3.html">女士鞋</a> + <a href="//www.jd.com/cppf/9847333cd3d99d6886d9.html">实木沙发</a> + <a href="//www.jd.com/book/737280eea8ac7dfea03.html">索尼电视</a> + <a href="//www.jd.com/hotitem/9855fbd5a67b591890f1.html">卫浴品牌</a> + <a href="//www.jd.com/zuozhe/7378d855fa5f85d59a5.html">奥克斯空调</a> + <a href="//fresh.jd.com/shengxian/12218e48f879c700b44c1.html">百香果</a> + <a href="//www.jd.com/zuozhe/652182fc3f82b3ca368.html">索尼耳机</a> + <a href="//yp.jd.com/737c7b888d1794c56af.html">冰箱镶入墙里</a> + <a href="//yp.jd.com/737cd1e1d26d91d1a21.html">康佳家电下乡冰箱</a> + <a href="//yp.jd.com/7373d5561bd0eac3f64.html">奥克斯(AUX)BCD-116AD</a> + <a href="//yp.jd.com/737b0d127b4e1d7400f.html">三星三门</a> + <a href="//yp.jd.com/737998287fe6a22f1a6.html">120升冰箱</a> + <a href="//yp.jd.com/73700468d8022ca9298.html">容声冰箱销量</a> + <a href="//yp.jd.com/737b1bb72524c551898.html">创维(Skyworth)定频冰箱</a> + <a href="//yp.jd.com/737c9a17f2e8e461c74.html">容升晶弘冰箱</a> + <a href="//yp.jd.com/7370bb14283d4edc7c1.html">奥马(Homa)风冷(无霜)定频冰箱</a> + <a href="//yp.jd.com/7375a5b080d9bbfcfe8.html">KG23N1116W</a> + <a href="//yp.jd.com/737a61a20365734e4d0.html">西门孑小型对开门</a> + <a href="//yp.jd.com/737c7f1769736cffdee.html">迷你冰箱50l</a> + <a href="//yp.jd.com/737f05025b1147ef1da.html">256升冰箱</a> + <a href="//yp.jd.com/737e39d90d3df5992fc.html">HNBX多门风冷冰箱</a> + <a href="//yp.jd.com/7379ae168f2a93fc7aa.html">长城冰箱</a> + <a href="//www.jd.com/phb/key_73712194156e93a18e7.html">松下对开门电冰箱</a> + <a href="//www.jd.com/phb/key_737314398427625bb8a.html">德努希变频冰箱</a> + <a href="//www.jd.com/phb/key_73794cec4ada572ca1f.html">冰箱双开门排名</a> + <a href="//www.jd.com/phb/key_737456fd9bea42a0aa3.html">冰鹭(BINGLU)BCD-78S</a> + <a href="//www.jd.com/phb/key_737aeb9fb744d21cec1.html">三星冰箱285wmq</a> +</div> +<!-- CLUB_LINK end --> + <div class="fs"> + <div class="grid_c1 fs_inner"> + <div class="fs_col1"> +<div id='J_cate' class="cate J_cate"> + <ul class="JS_navCtn cate_menu"> + <li class="cate_menu_item" data-index="1" clstag="h|keycount|head|category_01a"> + + <a target="_blank" class="cate_menu_lk" href="//jiadian.jd.com">家用电器</a> + </li> + <li class="cate_menu_item" data-index="2" clstag="h|keycount|head|category_02a"> + + <a target="_blank" class="cate_menu_lk" href="//shouji.jd.com/">手机</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//wt.jd.com">运营商</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//shuma.jd.com/">数码</a> + </li> + <li class="cate_menu_item" data-index="3" clstag="h|keycount|head|category_03a"> + + <a target="_blank" class="cate_menu_lk" href="//diannao.jd.com/">电脑</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//bg.jd.com">办公</a> + </li> + <li class="cate_menu_item" data-index="4" clstag="h|keycount|head|category_04a"> + + <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/home.html">家居</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/furniture.html">家具</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//jzjc.jd.com/">家装</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/kitchenware.html">厨具</a> + </li> + <li class="cate_menu_item" data-index="5" clstag="h|keycount|head|category_05a"> + + <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/1315-1342.html">男装</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/1315-1343.html">女装</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/children.html">童装</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/1315-1345.html">内衣</a> + </li> + <li class="cate_menu_item" data-index="6" clstag="h|keycount|head|category_06a"> + + <a target="_blank" class="cate_menu_lk" href="//beauty.jd.com/">美妆</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/beauty.html">个护清洁</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/pet.html">宠物</a> + </li> + <li class="cate_menu_item" data-index="7" clstag="h|keycount|head|category_07a"> + + <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/womensshoes.html">女鞋</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/bag.html">箱包</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/watch.html">钟表</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/jewellery.html">珠宝</a> + </li> + <li class="cate_menu_item" data-index="8" clstag="h|keycount|head|category_08a"> + + <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/mensshoes.html">男鞋</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/yundongcheng.html">运动</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/outdoor.html">户外</a> + </li> + <li class="cate_menu_item" data-index="9" clstag="h|keycount|head|category_09a"> + + <a target="_blank" class="cate_menu_lk" href="//xinfang.jd.com/">房产</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//car.jd.com/">汽车</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//che.jd.com/">汽车用品</a> + </li> + <li class="cate_menu_item" data-index="10" clstag="h|keycount|head|category_10a"> + + <a target="_blank" class="cate_menu_lk" href="//baby.jd.com">母婴</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//toy.jd.com/">玩具乐器</a> + </li> + <li class="cate_menu_item" data-index="11" clstag="h|keycount|head|category_11a"> + + <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/food.html">食品</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//jiu.jd.com">酒类</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//fresh.jd.com">生鲜</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//china.jd.com">特产</a> + </li> + <li class="cate_menu_item" data-index="12" clstag="h|keycount|head|category_12a"> + + <a target="_blank" class="cate_menu_lk" href="//art.jd.com">艺术</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/1672-2599.html">礼品鲜花</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//nong.jd.com">农资绿植</a> + </li> + <li class="cate_menu_item" data-index="13" clstag="h|keycount|head|category_13a"> + + <a target="_blank" class="cate_menu_lk" href="//health.jd.com">医药保健</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//channel.jd.com/9192-9196.html">计生情趣</a> + </li> + <li class="cate_menu_item" data-index="14" clstag="h|keycount|head|category_14a"> + + <a target="_blank" class="cate_menu_lk" href="//book.jd.com/">图书</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//mvd.jd.com/">文娱</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//e.jd.com/ebook.html">电子书</a> + </li> + <li class="cate_menu_item" data-index="15" clstag="h|keycount|head|category_15a"> + + <a target="_blank" class="cate_menu_lk" href="//jipiao.jd.com/">机票</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//hotel.jd.com/">酒店</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//trip.jd.com/">旅游</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//ish.jd.com/">生活</a> + </li> + <li class="cate_menu_item" data-index="16" clstag="h|keycount|head|category_16a"> + + <a target="_blank" class="cate_menu_lk" href="//licai.jd.com/">理财</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//z.jd.com/">众筹</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//baitiao.jd.com">白条</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//bao.jd.com/">保险</a> + </li> + <li class="cate_menu_item" data-index="17" clstag="h|keycount|head|category_17a"> + + <a target="_blank" class="cate_menu_lk" href="//anzhuang.jd.com">安装</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//jdwx.jd.com">维修</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//cleanclean.jd.com">清洗</a> + <span class="cate_menu_line">/</span> <a target="_blank" class="cate_menu_lk" href="//2.jd.com/">二手</a> + </li> + <li class="cate_menu_item" data-index="18" clstag="h|keycount|head|category_18a"> + + <a target="_blank" class="cate_menu_lk" href="//imall.jd.com/">工业品</a> + </li> + </ul> + <div id="J_popCtn" class="JS_popCtn cate_pop mod_loading" style="display: none;"></div> +</div> + + </div> + + <div class="fs_col2"> +<div id='J_focus' class="J_focus focus"> + <div class="J_focus_main focus_main mod_lazyload"></div> +</div> + </div> + + <div class="fs_col3"> +<div id='J_rec' class='J_rec rec'></div> + </div> + + <div id="J_fs_col4" class="fs_col4"> + +<div id='J_user' class="J_user user mod_loading"> +</div> +<div id='J_news' class="news J_news"> + <div class="mod_tab news_tab J_news_tab"> + <div class="mod_tab_head J_tab_head clearfix"> + <a href="javascript:;" class="mod_tab_head_item news_first" clstag="h|keycount|head|news_a">促销</a> + <a href="javascript:;" class="mod_tab_head_item news_last mod_tab_head_item_on" clstag="h|keycount|head|news_b">公告</a> + <div class="news_tab_active J_news_tab_active"></div> + <a href="//kuaibao.jd.com/" target="_blank" class="news_more" clstag="h|keycount|head|news_c">更多</a> + </div> + <div class="mod_tab_content J_tab_content"> + <div class="mod_tab_content_item mod_tab_content_item_on"> + <ul class="news_list"> + <li class="news_item"><a href="//diannao.jd.com/" target="_blank" class="news_link" clstag="h|keycount|head|news_d01">2019 囤好礼 过好年</a></li> + <li class="news_item"><a href="//pro.jd.com/mall/active/2YFBSKpsSGnJ4tVF1YA8shA8nMV/index.html?cpdad=1DLSUE" target="_blank" class="news_link" clstag="h|keycount|head|news_d02">笔记本限时秒杀</a></li> + <li class="news_item"><a href="//shuma.jd.com/" target="_blank" class="news_link" clstag="h|keycount|head|news_d03">数码好物0元试用</a></li> + <li class="news_item"><a href="//sale.jd.com/act/PUKsc2vOCfZ0.html" target="_blank" class="news_link" clstag="h|keycount|head|news_d04">天际厨电感恩专场豪礼免费拿</a></li> + </ul> + </div> + <div class="mod_tab_content_item"> + <ul class="news_list"> + <li class="news_item"><a href="//www.jd.com/news.aspx?id=38007" target="_blank" class="news_link" clstag="h|keycount|head|news_e01">京东图书勋章体系改版公告</a></li> + <li class="news_item"><a href="//www.jd.com/news.aspx?id=37090" target="_blank" class="news_link" clstag="h|keycount|head|news_e02">京东PLUS会员权益更新及会费调整</a></li> + <li class="news_item"><a href="//www.jd.com/news.aspx?id=36374" target="_blank" class="news_link" clstag="h|keycount|head|news_e03">京东启用全新客服电话“950618”</a></li> + <li class="news_item"><a href="//www.jd.com/news.aspx?id=36083" target="_blank" class="news_link" clstag="h|keycount|head|news_e04">关于召回普利司通(天津)轮胎有限公司2个规格乘用车轮胎的公告</a></li> + </ul> + </div> + </div> + </div> +</div> + +<div id="J_service" class="service"> + <div class="service_entry"> + <ul class="J_tab_head service_list"> + <li class="service_item service_frame mod_tab_head_item"> + <a href="//chongzhi.jd.com/" class="service_lk" target="_blank" clstag="h|keycount|head|shortcut_01"> + <i class="service_ico service_ico_huafei"></i> + <span class="service_txt">话费</span> + </a> + </li> + <li class="service_item service_frame mod_tab_head_item"> + <a href="//jipiao.jd.com/" class="service_lk" target="_blank" clstag="h|keycount|head|shortcut_02"> + <span class="service_corner"><i class="service_corner_txt">抢</i><i class="service_corner_ico"></i></span> + <i class="service_ico service_ico_jipiao"></i> + <span class="service_txt">机票</span> + </a> + </li> + <li class="service_item service_frame mod_tab_head_item"> + <a href="//hotel.jd.com/" class="service_lk" target="_blank" clstag="h|keycount|head|shortcut_03"> + <span class="service_corner"><i class="service_corner_txt">热</i><i class="service_corner_ico"></i></span> + <i class="service_ico service_ico_jiudian"></i> + <span class="service_txt">酒店</span> + </a> + </li> + <li class="service_item service_frame mod_tab_head_item"> + <a href="//game.jd.com/" class="service_lk" target="_blank" clstag="h|keycount|head|shortcut_04"> + <i class="service_ico service_ico_youxi"></i> + <span class="service_txt">游戏</span> + </a> + </li> + <li class="service_item "> + <a href="//b.jd.com/" class="service_lk" target="_blank" clstag="h|keycount|head|shortcut_05"> + <i class="service_ico service_ico_qyg"></i> + <span class="service_txt">企业购</span> + </a> + </li> + <li class="service_item "> + <a href="//jiayouka.jd.com/" class="service_lk" target="_blank" clstag="h|keycount|head|shortcut_06"> + <i class="service_ico service_ico_jiayou"></i> + <span class="service_txt">加油卡</span> + </a> + </li> + <li class="service_item "> + <a href="//movie.jd.com/index.html" class="service_lk" target="_blank" clstag="h|keycount|head|shortcut_07"> + <i class="service_ico service_ico_dianying"></i> + <span class="service_txt">电影票</span> + </a> + </li> + <li class="service_item "> + <a href="//train.jd.com/" class="service_lk" target="_blank" clstag="h|keycount|head|shortcut_08"> + <i class="service_ico service_ico_huoche"></i> + <span class="service_txt">火车票</span> + </a> + </li> + <li class="service_item "> + <a href="//z.jd.com/sceneIndex.html?from=jrscyn_20162" class="service_lk" target="_blank" clstag="h|keycount|head|shortcut_09"> + <i class="service_ico service_ico_zhongchou"></i> + <span class="service_txt">众筹</span> + </a> + </li> + <li class="service_item "> + <a href="//licai.jd.com/?from=jrscyn_20161" class="service_lk" target="_blank" clstag="h|keycount|head|shortcut_10"> + <i class="service_ico service_ico_licai"></i> + <span class="service_txt">理财</span> + </a> + </li> + <li class="service_item "> + <a href="//o.jd.com/market/index.action" class="service_lk" target="_blank" clstag="h|keycount|head|shortcut_11"> + <i class="service_ico service_ico_lipin"></i> + <span class="service_txt">礼品卡</span> + </a> + </li> + <li class="service_item "> + <a href="//baitiao.jd.com/?from=jrscyn_20160" class="service_lk" target="_blank" clstag="h|keycount|head|shortcut_12"> + <i class="service_ico service_ico_baitiao"></i> + <span class="service_txt">白条</span> + </a> + </li> + </ul> + </div> + <div class="J_tab_content service_pop"> + <div class="mod_tab_content_item service_pop_item mod_loading"></div> + <div class="mod_tab_content_item service_pop_item mod_loading"></div> + <div class="mod_tab_content_item service_pop_item mod_loading"></div> + <div class="mod_tab_content_item service_pop_item mod_loading"></div> + <a class="J_service_pop_close service_pop_close iconfont" href="javascript:;"></a> + </div> +</div> + </div> + </div> + <div id="J_fs_act" class="fs_act"></div> + </div> +<style> + #shortcut .shortcut_btn_company2 .dt a { + color: #f00; + } + #shelper li.fore1 .item1 { + overflow: hidden; + } + #shelper .dropdown-simg { + display: inline-block; + margin-right: 5px; + vertical-align: text-bottom; + } + .o2_mini #ttbar-login.shortcut_userico0:hover, + .o2_mini #ttbar-login.shortcut_userico1:hover, + .o2_mini #ttbar-login.shortcut_userico2:hover, + .o2_mini #ttbar-login.shortcut_userico3:hover, + .o2_mini #ttbar-login.shortcut_userico4:hover { + overflow: visible; + } + .o2_mini #ttbar-login.dropdown { + width: 105px; + white-space: nowrap; + overflow: hidden; + } + .o2_mini #ttbar-login.icon-plus-state0:hover, + .o2_mini #ttbar-login.icon-plus-state1:hover, + .o2_mini #ttbar-login.icon-plus-state2:hover, + .o2_mini #ttbar-login.icon-plus-state3:hover, + .o2_mini #ttbar-login.icon-plus-state4:hover { + width: 105px; + overflow: visible; + white-space: normal; + text-align: left; + } + .o2_mini #ttbar-login .dt .nickname { + width: 30px; + } + .o2_mini .floors { + z-index: auto; + } + .mod_actmark_focus { + height: 75px !important; + background-image: url('//img20.360buyimg.com/uba/jfs/t1/34000/11/12894/7552/5cf6722cEd872e151/a34e658d9e135d70.jpg') !important; + } + .mod_actmark_top { + width: 190px !important; + height: 80px !important; + background-image: url('//img13.360buyimg.com/uba/jfs/t1/61160/27/1150/17467/5cf6722cE91d90419/50177d14b0f0b8a5.jpg') !important; + } + + @media only screen and (-webkit-min-device-pixel-ratio: 1.5), + only screen and (min--moz-device-pixel-ratio: 1.5), + only screen and (-o-min-device-pixel-ratio: 3/2), + only screen and (min-device-pixel-ratio: 1.5) { + .mod_actmark_focus { + background-image: url('//img20.360buyimg.com/uba/jfs/t1/34000/11/12894/7552/5cf6722cEd872e151/a34e658d9e135d70.jpg') !important; + } + .mod_actmark_top { + background-image: url('//img13.360buyimg.com/uba/jfs/t1/61160/27/1150/17467/5cf6722cE91d90419/50177d14b0f0b8a5.jpg') !important; + } + } + + .cate16 .cate_menu { + padding: 15px 0; + height: 450px; + } + + .cate16 .cate_menu_item { + height: 28px; + line-height: 28px; + } + + .cate18 .cate_menu { + padding: 6px 0; + height: 468px; + } + + .cate18 .cate_menu_item { + height: 26px; + line-height: 26px; + } + .o2_9 .focus .slider_list { + position: relative; + z-index: 0; + } + .J_news_tab { + display: none; + } + #J_focus.focus--mark + .slider_list + .slider_wrapper + .slider_item:first-child:before { + content: ' '; + height: 75px !important; + background-image: url('//img20.360buyimg.com/uba/jfs/t1/34000/11/12894/7552/5cf6722cEd872e151/a34e658d9e135d70.jpg') !important; + width: 75px; + top: 0; + left: 20px; + z-index: 2; + position: absolute; + background: no-repeat 0 0; + background-size: 100% 100%; + } + +</style> +<script> + pageConfig.idleTimeLoad = false; + pageConfig.enableEnjoy = true; + pageConfig.enableActMark = false; + pageConfig.enableRetina = true; + pageConfig.clstagPrefix = 'h|keycount|'; + pageConfig.O2_REPORT = 100; + pageConfig.leftCateABtestSection = { start: 0, end: 10000 }; + // pageConfig.gatewaySection = 5000; + pageConfig.more0SectionStart = 9000; + pageConfig.more1SectionStart = 2000; + pageConfig.moreASection = [{ start: 0, end: 10000 }]; + pageConfig.moreBSection = []; + pageConfig.logoSectionStart = -1; + pageConfig.logoSectionEnd = 10000; + pageConfig.goodShopSectionStart = 5000; + pageConfig.newsSectionStart = -1; + pageConfig.focusSectionStart = 0; + pageConfig.jingzaoSection = [{ start: 0, end: 10000 }]; + pageConfig.company2Section = [{ start: 0, end: 10000 }]; + pageConfig.goodrecSection = [{ start: 0, end: 0 }]; + pageConfig.goodShopSection = [{ start: 0, end: 10000 }]; + pageConfig.goodShopOldSection = [{ start: 2000, end: 5000 }]; + pageConfig.logInterval = 10; + pageConfig.blockedPresaleSkus = [6773543, 6773561, 6773559, 6560164, 6560154]; + pageConfig.promoFloor = { + isTop: true + }; + pageConfig.actStart = new Date('2019/05/24 00:00:00').getTime(); + pageConfig.actEnd = new Date('2019/06/21 00:00:00').getTime(); + pageConfig.focusABTest = [{ start: 0, end: 10000 }]; +</script> +<script> + window['_REPORT_']['FS'] = new Date(); +</script> </div> +<script> + /* 读取cookie工具 */ + window.readCookie = function (name) { + var nameEQ = name + '='; + var ca = document.cookie.split(';'); + for (var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) == ' ') { + c = c.substring(1, c.length); + } + if (c.indexOf(nameEQ) == 0) { + return c.substring(nameEQ.length, c.length); + } + } + return null; + }; + window.createCookie = function (name, value, days, _Tdom) { + var Tdom = _Tdom || '/'; + var date, expires; + if (days) { + date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + expires = '; expires=' + date.toGMTString(); + } else { + expires = ''; + } + document.cookie = name + '=' + value + expires + '; path=' + Tdom; + }; + try { document.domain = "jd.com" } catch (e) { } + /* 处理isdebug */ + pageConfig.isdebug = (function () { + var searchStr = location.search; + var switchArr = []; + var len, i; + var switchObj = {}; + var switchArr2 = []; + var value = true; + searchStr.replace(/isdebug=((?:-[^-]+)*)/, function(m, g) { + switchArr = g.split('-'); + len = switchArr.length; + for (i = 0; i < len; i++) { + if (switchArr[i] === '') continue; + switchArr2 = switchArr[i].split('|') + value = switchArr2.slice(1).join('|') + switchObj[switchArr2[0]] = value||true; + } + }) + return switchObj; + })(); + var actMarkStart = pageConfig.actStart || new Date('2018/12/06 00:00:00').getTime() + var actMarkEnd = pageConfig.actEnd || new Date('2018/12/14 00:00:00').getTime() + var now = new Date().getTime() + if ((now > actMarkStart && now < actMarkEnd) || + pageConfig.isdebug[10]) { + pageConfig.enableActMark = true; + pageConfig.enableEnjoy = true; + var fakeLogo = document.createElement('div'); + fakeLogo.id = 'J_logo_extend'; + document.body.appendChild(fakeLogo); + } else { + pageConfig.enableActMark = false; + pageConfig.enableEnjoy = false; + } + + /* o2Control, 处理cookie中的开关 */ + window.o2Control = (function () { + var _O2Control = function () { + var ctlStr; + this.cookieName = 'o2Control'; + this.store = {}; + ctlStr = readCookie(this.cookieName) || ''; + this._init(ctlStr); + }; + _O2Control.prototype._init = function (str) { + + if (str.length == 0) return; + + var arr = str.split('|'), + len = arr.length, + i; + + for (i = 0; i < len; i++) { + var tmp = arr[i].split('='); + if (tmp[1] === undefined) + this.store[tmp[0]] = true; + else { + this.store[tmp[0]] = tmp[1]; + } + } + }; + _O2Control.prototype.set = function (k, v) { + var str = [], + i, tmp, res; + + this.store[k] = v == undefined ? true : v; + for (i in this.store) { + tmp = ''; + res = this.store[i]; + if (res === false) continue; + tmp = i; + if (res !== true) tmp += '=' + res; + str.push(tmp); + } + createCookie(this.cookieName, str.join('|'), 365); + }; + _O2Control.prototype.get = function (k) { + return this.store[k]; + }; + return new _O2Control(); + })(); +</script> +<script src="//misc.360buyimg.com/??jdf/lib/jquery-1.6.4.js,mtd/pc/common/js/o2_ua.js,mtd/pc/base/1.0.0/event.js,mtd/pc/index_2017/2.1.0/lib/base.dll.js,mtd/pc/index_2017/2.1.0/home/index.js?v=1"></script> + +<script src="//wl.jd.com/wl.js"></script> +<script type="text/javascript"> + window['_REPORT_']['JS'] = new Date(); + + $('#J_cate').addClass('cate' + $('.cate_menu_item').length); +</script> +<script> + /* Promos类 大促相关 */ + (function () { + var _useLocal = pageConfig.isdebug[10], + _proto = new _.Events(), + Promos + Promos = function (opts) { + /* ext5 为startDate ext6 为endDate */ + var selectFunc + this.opts = {} + $.extend(this.opts, { + id: '', + adList: [], + selectFunc: 'one', + render: function () { + return '' + } + }, opts) + selectFunc = this.opts.selectFunc + if ($.isFunction(selectFunc)) { + this._selectFunc = selectFunc + } else { + this._selectFunc = this._selectFuncs[selectFunc] || this._selectFuncs['one'] + } + this.deferred = new $.Deferred() + Promos.__instances[this.opts.id] = this + } + Promos.__instances = {} + Promos.prototype = _proto + Promos.prototype._selectFuncs = { + one: function (list) { + return list[0] + }, + rand: function (list) { + return list[~~(Math.random() * list.length)] + } + } + Promos.prototype._useLocalTime = _useLocal + Promos.prototype.activated = {} + Promos.prototype.init = function () { + var that = this + if (that.now) { + that._run() + } else { + this.on('timeAjust', function () { + that._run() + }) + } + return this + } + Promos.prototype._run = function () { + var that = this, + id = this.opts.id, + result + this.eventData = $.grep(this.opts.adList, function (v, k) { + if (!v.startDate || !v.endDate) return true + if (that.now > new Date(v.startDate).getTime() && that.now < new Date(v.endDate).getTime()) { + return true + } + }) + if (this.eventData.length) { + this.activeData = this._selectFunc(this.eventData) + this._render(this.activeData) + this.deferred.resolve(this) + } else { + this.deferred.resolve(this) + } + } + Promos.prototype._render = function (data) { + this.activeData = data + this.trigger('beforeRender:' + this.opts.id, this, this.activeData) + result = this.opts.render.call(this, this.activeData) + this.trigger('afterRender:' + this.opts.id, this, result) + } + Promos.prototype.changeTo = function (data) { + this._render(data) + } + /* if (!_useLocal) { + $.ajax({ + url: '//' + location.hostname, + cache: false + }).then(function (data, status, xhr) { + _proto.now = new Date(xhr.getResponseHeader("Date")).getTime(); + _proto.trigger('timeAjust', _proto.now); + }, function () { + _proto.now = new Date().getTime(); + _proto.trigger('timeAjust', _proto.now); + }); + } */ + if (!_useLocal) _proto.now = new Date(pageConfig.timestamp) + else _proto.now = new Date().getTime() + + pageConfig.promos = {} + window.Promos = Promos + + _.eventCenter.on('render:userinfo', function () { + if (!pageConfig.isNewUser || window.pageConfig.enjoyType) return + seajs.config({ + alias: { + ad_noob: '//nfa.jd.com/loadFa.action?aid=0_0_8857' + // ad_noob: '/index/home/widget/ad_noob/ad_noob.js' + } + }) + // 引入新人素材 + seajs.use('ad_noob', function (noob) { + var deferred = [], + data = [], + floorclog, + fsbgclog + $.each(noob, function (k, v) { + if (v.id == 'floor') { + floorclog = v.clog + return + } + if (v.id == 'fsbgclog') { + fsbgclog = v.clog + return + } + var promo = Promos.__instances[v.id] + if (promo) { + deferred.push(promo.deferred) + data.push(v) + } + }) + $.when.apply($, deferred).then(function () { + var promos = Array.prototype.slice.call(arguments) + $.each(promos, function (k, v) { + if (v.activeData && v.activeData.isTop) return + if (v.opts.id == 'fsbg' && fsbgclog) { + data[k].fclog = fsbgclog + } + v.changeTo(data[k]) + }) + }) + }) + }) + })() +</script> + +<script type="text/javascript"> + window['_REPORT_']['DOM'] = new Date(); + if(pageConfig.enableActMark){ + $('#J_focus').addClass('focus--mark') + } + +$('#settleup .dropdown-layer').bind('mouseenter',function(){return false}); + +$('#J_cate').bind('mouseenter', function () {$('.fs').css('zIndex', 10);}).bind('mouseleave', function () {$('.fs').css('zIndex', 9);}); + +(function () { +var isFirst = true; +$('body').delegate('.J-toolbar', 'click', function () { +if (!isFirst) return; +try{ +isFirst = false; +seajs.use('jdf/event', function (jdEvent) {jdEvent.on('loginSuccessByIframe', function () {location.reload();})}) +} catch(e) {} +}); +})(); + +</script> +<!-- areaheaderad start --> +<script type="text/javascript"> +!function(){new Promos({id:"top",selectFunc:"rand",render:function(e){var t;return t=e.ex_src?'<div id="J_event" style="position: relative; z-index: 30; '+e.bgColor+'"><div class="grid_c1" style="position: relative;"><a id="J_event_lk" class="J_event_ex" href="'+e.href+'" target="_blank" clstag="h|keycount|head|adtop_01" style="display: block; width: 100%; height: 200px; background: url('+e.ex_src+') no-repeat 50% 0;" fclog="'+e.clog+'"></a><i id="J_event_close" class="iconfont" style="cursor:pointer; position: absolute; right: 5px; top: 5px; font-weight: bold; font-size: 14px; color: #FFF; background: rgb(45,45,45); opacity: .3; filter: alpha(opacity=30); width: 20px; text-align: center; line-height: 20px;"></i></div></div>':'<div id="J_event" style="position: relative; z-index: 30; '+e.bgColor+'"><div class="grid_c1" style="position: relative;"><a id="J_event_lk" href="'+e.href+'" target="_blank" clstag="h|keycount|head|adtop_01" style="display: block; width: 100%; height: 80px; background: url('+e.src+') no-repeat 50% 0;" fclog="'+e.clog+'"></a><i id="J_event_close" class="iconfont" style="cursor:pointer; position: absolute; right: 5px; top: 5px; font-weight: bold; font-size: 14px; color: #FFF; background: rgb(45,45,45); opacity: .3; filter: alpha(opacity=30); width: 20px; text-align: center; line-height: 20px;"></i></div></div>'},adList:[{bigImageUrl: '//img30.360buyimg.com/da/jfs/t5659/296/1036699731/3402/f7f02767/5923160cN6aecb1e0.png',imageUrl: '',href: '//ccc-x.jd.com/dsp/cpd?ext=aHR0cHM6Ly9qZC5jb20v&log=JF5rMUAKXlLMuE_-1qw2RKwu9W82n03RnztIpYfC-NVWZuaHLhAWyfY2fGI8hkypSTBCaju3R5qI_E261_7LkxcAStUrJC0UJMF7LCT7Laf-jkp6FkBM1_KtuuDYjiVbUef54oz4i9ggYiqOCYBoU-U5x-n5KVAI0nvhNAYIPJiDsb5VLs32T-goU_NhrEmspOtxbaxxVnyX_wBgFl1VFcjEiIV2g1hru-ceooErmXdzEDYcSXDUEid8wKkxt3b6FIOGTkTnt4nWg2_QqMdAviOE2tbxb6SfoAwMJvoQ-WuQeLVXl7ahIASmCnEQIocXooZkfTfp7QnAlt1p38pcc13194WD7zdwUehMA5KWw8GRdUFtsINUVX8sxoTGUoYwZK56vYaZJj4XqPcNC6l5-LVg8ee8H-JOShQd-blYPDNcQYk45bwMhf1FgmRXtaf6KCDMgmBVOXTXca4UykTsrb1xueiMAWiYDa2zmvdmftIVjrFt-7sqqBex_vcrcHoHm_I6E2cIxbE4S-BcAsI02k4QtdUyT9ZYbctycZ1pJHacxkBUXw2_dUKtCspIOPEpKcWMdzQrYt9YJsYIczRz3L83yhU46EUA3c6J6mack0KGv85INXWfuNokT0_xlNkAqOir-_OJr3W-cbqSCOgVL_3G8Txtv6IfTOLk48a37cnh7mLNKr3sbJHHT8LTBi1z',clog: '0.112329.381764.1.571_1816_8701',bgColor: '',ex_bigImageUrl: '',ex_imageUrl: '',startDate: '2016/01/01 00:00:00',endDate: '2016/01/02 00:00:00',isTop: '', alt: ''},{bigImageUrl: '//img13.360buyimg.com/da/jfs/t1/74200/18/3426/51197/5d19eaabEa6997979/faa5b1d3fbb140d3.jpg',imageUrl: '//img30.360buyimg.com/da/jfs/t1/56255/9/3982/50110/5d19eaafE90d42a3f/1f689b8c6119d794.jpg',href: '//ccc-x.jd.com/dsp/cpd?ext=aHR0cHM6Ly9wcm8uamQuY29tL21hbGwvYWN0aXZlLzI4OHA5WnpHZHRSY1dEeGtRR1dCc0xNYk5HU1YvaW5kZXguaHRtbA&log=JF5rMUAKXlLMuE_-1qw2RKwu9W82n03RnztIpYfC-NVWZuaHLhAWyfY2fGI8hkyp4WvapDPzLorXYPGG1gpZ2wtmMHPEAdeupw7Xh038IDt7QsDwEAWro06YXKgQJ_Q_4C5ANsZKZsWczE5R48YEmcyUtD7eDF8wAR1agGBzREwQRz48-EeQ9Y2CDLZaBQ445BBEy-1qcsCzcCj4WzVV7bN6qNTh7ZfMA2bXwnBKz4qaveJfn3mKXkqpuFgmC1eXc6i9LtShxUX-XX9RWfsoKxD9lQO58qHZ-c_FBJEa8qwUo7UwgQu7NH5h8-x-gbPOQhP3niZa34peo6znptbBYptD9ZTo6V0dpr7WYw3G9peEjOeRlOOXxMYlyqOKckstjfvGDEF34i9HeAicCFZYmPFIArxGoQSERE_HK7T_sPNIYdJMDD-EEZQKWcbGY_hpvqADx1K9EyzdqOAUwqNuW62BKMd96bl_nQy9e0BqRAGiDD1EPIGRsGXuC1xb1LFH2PNDiCtmH8AK5wXtMNajy8XGQ7_CuTSLoZmlqW8lEzhkL4Cvl_bliPAHtixOWfQE_Ta9q5szh5uy11wbKl2S9b-K5un-w7U8-2lQKGsr7hEMH96swkX9J2OnjjOzoZTDvOi4_wSe4-VCwW92frQ4jO9LEhvNoTWnJyjdp-cnONB2OYgCM1yybBMkgr1kKWKmPB_avvqQhMj5eSMiq9W8rpII_FgROCEzLKqTjEgBODJpCYsjQdi70SNwti2kDtkc',clog: '15297.111725.575400302.1.571_1816_8701',bgColor: '#dbdce1',ex_bigImageUrl: '',ex_imageUrl: '',startDate: '',endDate: '',isTop: '#dbdce1', alt: ''}]}).on("beforeRender:top",function(e,t){var o,i;t.isNew&&(t.bgColor=t.ext1,t.ex_bigImageUrl=t.ext2,t.ex_imageUrl=t.ext3),t.bgColor=t.bgColor?"background-color:#"+t.bgColor.replace(/#/g,"")+";":"",pageConfig.wideVersion?(o=t.bigImageUrl,i=t.ex_bigImageUrl):(o=t.imageUrl,i=t.ex_imageUrl),t.src=o,t.ex_imageUrl&&t.ex_bigImageUrl&&o2Control.get("lastvisit")!=(new Date).getDate()&&(e.isEx=!0,t.ex_src=i,o2Control.set("lastvisit",(new Date).getDate()))}).on("afterRender:top",function(e,t){var o,i,n=$(t);$("#J_event").remove(),$("#shortcut").before(n);if (pageConfig.enableActMark && pageConfig.wideVersion) {$('#J_event_lk').append('<i class="mod_actmark mod_actmark_top"></i>');}o=$("#J_event"),$("#J_event_close").click(function(){o.fadeOut(function(){_.eventCenter.trigger("render:floorChange")})}),e.isEx&&(i=$("#J_event_lk",n),setTimeout(function(){i.removeClass('J_event_ex').animate({height:80},function(){i.css({backgroundImage:"url("+e.activeData.src+")"}),_.eventCenter.trigger("render:floorChange")})},3e3)),_.eventCenter.trigger("render:floorChange"),_.eventCenter.on("home:load",function(){pageConfig.sendClog($("#J_event_lk"))})}).init()}(); +</script><!-- areaheaderad end --> +</body> +</html> diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index bbfd508..e235b8b 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -8,4 +8,9 @@ target_link_libraries(maat_redis_tool maat_frame_static ${MAAT_DEPEND_DYN_LIB}) target_include_directories(maat_redis_tool PRIVATE ${PROJECT_SOURCE_DIR}/src/inc_internal/) target_include_directories(maat_redis_tool PRIVATE hiredis-vip-static) +add_executable(maat_debug_tool maat_debug_tool.cpp) +add_dependencies(maat_debug_tool maat_frame_shared) +target_link_libraries(maat_debug_tool maat_frame_static ${MAAT_DEPEND_DYN_LIB}) +target_include_directories(maat_debug_tool PRIVATE ${PROJECT_SOURCE_DIR}/src/inc_internal/) + install(TARGETS maat_redis_tool DESTINATION /usr/local/bin/) diff --git a/tools/maat_debug_tool.cpp b/tools/maat_debug_tool.cpp new file mode 100644 index 0000000..5b8d3be --- /dev/null +++ b/tools/maat_debug_tool.cpp @@ -0,0 +1,174 @@ +#include "Maat_rule.h" +#include "Maat_command.h" +#include <MESA/MESA_handle_logger.h> + +#include <stdio.h> /* for printf */ +#include <stdlib.h> /* for exit */ +#include <getopt.h> +#include <sys/stat.h> + + +int debug_maat_str_scan(Maat_feather_t feather, const char* table_name, const char* district, char* data, size_t sz) +{ + int table_id=0,ret=0; + int i=0; + int scan_result_max=64; + struct Maat_rule_t result[scan_result_max]; + scan_status_t mid=NULL; + + + table_id=Maat_table_register(feather, table_name); + if(table_id<0) + { + printf("Unkown table %s\n", table_name); + } + + struct Maat_hit_detail_t *hit_detail=(struct Maat_hit_detail_t *)malloc(sizeof(struct Maat_hit_detail_t)*10); + + enum MAAT_CHARSET maat_charset=CHARSET_UTF8; + + if(strlen(district)>0) + { + ret=Maat_set_scan_status(feather, &mid, MAAT_SET_SCAN_DISTRICT, district, strlen(district)); + } + + ret=Maat_full_scan_string(feather, table_id, maat_charset, data, sz, + result, NULL, scan_result_max, + &mid, 0); + printf("Scan table %s ", table_name); + if(ret==-1) + { + printf("error.\n"); + } + else if(ret==-2) + { + printf("hits group, but not compile.\n"); + } + else if(ret==0) + { + printf("not hit."); + } + else + { + printf("hits "); + for(i=0; i<ret; i++) + { + printf("%d, ", result[i].config_id); + } + } + printf("\n"); + + free(hit_detail); + Maat_clean_status(&mid); + return 0; +} +enum tool_arg_type{ + ARG_TABLE_INFO=0, + ARG_TABLE_NAME, + ARG_SCAN_FILE, + ARG_SCAN_STRING, + ARG_SCAN_DISTRICT, + ARG_SCAN_CHARSET, + ARG_INPUT_JSON, + ARG_DECRYPT_KEY, + ARG_ACCEPT_TAGS, + __ARG_MAX +}; + +int main(int argc, char ** argv) +{ + FILE* fp=NULL; + char* file_buff=NULL; + size_t file_size=0; + struct stat file_info; + char arg_value[__ARG_MAX][1024]; + memset(arg_value, 0, sizeof(arg_value)); + if(argc<2) + { + return 0; + } + int c=0; + while (1) { + int option_index = 0; + static struct option long_options[]={ + {"table-info", required_argument, 0, 0}, + {"table-name", required_argument, 0, 0}, + {"scan-file", optional_argument, 0, 0}, + {"scan-string", optional_argument, 0, 0}, + {"scan-district", optional_argument, 0, 0}, + {"scan-charset", optional_argument, 0, 0}, + {"maat-json", required_argument, 0, 0}, + {"decrypt-key", optional_argument, 0, 0}, + {"accept-tags", optional_argument, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "ab", long_options, &option_index); + if (c == -1) + break; + if(c!=0) + { + printf("Invalid parameter, long options only.\n"); + } + else + { + strcpy(arg_value[option_index], optarg); + } + } + + const char* log_file="./test.log"; + int scan_detail=0, ret=0; + Maat_feather_t feather=NULL; + void *g_logger=NULL; + + g_logger=MESA_create_runtime_log_handle(log_file, 0); + + feather=Maat_feather(4, arg_value[ARG_TABLE_INFO], g_logger); + Maat_set_feather_opt(feather, MAAT_OPT_INSTANCE_NAME, "debugtool", strlen("debugtool")+1); + if(strlen(arg_value[ARG_DECRYPT_KEY])>0) + { + Maat_set_feather_opt(feather, MAAT_OPT_DECRYPT_KEY, arg_value[ARG_DECRYPT_KEY], strlen(arg_value[ARG_DECRYPT_KEY])+1); + } + if(strlen(arg_value[ARG_ACCEPT_TAGS])>0) + { + Maat_set_feather_opt(feather, MAAT_OPT_ACCEPT_TAGS, arg_value[ARG_ACCEPT_TAGS], strlen(arg_value[ARG_ACCEPT_TAGS])+1); + } + ret=Maat_set_feather_opt(feather, MAAT_OPT_JSON_FILE_PATH, arg_value[ARG_INPUT_JSON], strlen(arg_value[ARG_INPUT_JSON])+1); + if(ret!=0) + { + printf("Read %s failed, invalid maat json.\n", arg_value[ARG_INPUT_JSON]); + ret=-1; + goto clean_up; + } + Maat_set_feather_opt(feather, MAAT_OPT_SCAN_DETAIL, &scan_detail, sizeof(scan_detail)); + Maat_initiate_feather(feather); + + if(strlen(arg_value[ARG_SCAN_FILE])>0) + { + + if(stat(arg_value[ARG_SCAN_FILE], &file_info)<0) + { + printf("Stat %s failed.\n", arg_value[ARG_SCAN_FILE]); + goto clean_up; + } + file_size=file_info.st_size; + fp=fopen(arg_value[ARG_SCAN_FILE], "r"); + if(fp==NULL) + { + printf("Open %s failed.\n", arg_value[ARG_SCAN_FILE]); + goto clean_up; + } + file_buff=(char*)malloc(file_size); + fread(file_buff,1,file_size,fp); + fclose(fp); + + debug_maat_str_scan(feather, arg_value[ARG_TABLE_NAME], arg_value[ARG_SCAN_DISTRICT], file_buff, file_size); + free(file_buff); + } +clean_up: + Maat_burn_feather(feather); + MESA_destroy_runtime_log_handle(g_logger); + return ret; +} + + diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt index 9f5a378..d57f53e 100644 --- a/vendor/CMakeLists.txt +++ b/vendor/CMakeLists.txt @@ -30,3 +30,19 @@ file(MAKE_DIRECTORY ${HIREDIS_INCLUDE_DIRECTORIES}) add_library(hiredis-vip-static STATIC IMPORTED GLOBAL) set_property(TARGET hiredis-vip-static PROPERTY IMPORTED_LOCATION ${SOURCE_DIR}/libhiredis_vip.a) set_property(TARGET hiredis-vip-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${SOURCE_DIR}) + +ExternalProject_Add(igraph PREFIX igraph + URL ${CMAKE_CURRENT_SOURCE_DIR}/igraph-0.7.1.tar.gz + URL_MD5 4f6e7c16b45fce8ed423516a9786e4e8 + CONFIGURE_COMMAND ./configure --prefix=<INSTALL_DIR> --disable-shared --with-pic + BUILD_COMMAND make + INSTALL_COMMAND make install + BUILD_IN_SOURCE 1) + +ExternalProject_Get_Property(igraph INSTALL_DIR) +file(MAKE_DIRECTORY ${INSTALL_DIR}/include) + +add_library(igraph-static STATIC IMPORTED GLOBAL) +add_dependencies(igraph-static igraph) +set_property(TARGET igraph-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libigraph.a) +set_property(TARGET igraph-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) diff --git a/vendor/igraph-0.7.1.tar.gz b/vendor/igraph-0.7.1.tar.gz Binary files differnew file mode 100644 index 0000000..9340f6b --- /dev/null +++ b/vendor/igraph-0.7.1.tar.gz |
