[patch]change verify expression retval semantics:1(legal) 0(illegal)

This commit is contained in:
liuwentan
2023-05-11 11:21:46 +08:00
parent 7ce971902d
commit 929d6ac139
18 changed files with 450 additions and 463 deletions

View File

@@ -16,7 +16,14 @@ extern "C"
{
#endif
#include <limits.h>
#include <sys/queue.h>
#include "maat.h"
#include "maat_table.h"
#include "log/log.h"
#include "uthash/uthash.h"
#include "hiredis/hiredis.h"
enum maat_operation {
MAAT_OP_DEL = 0,
@@ -31,6 +38,27 @@ struct maat_cmd_line {
int expire_after; //expired after $timeout$ seconds, set to 0 for never timeout.
};
struct foreign_key {
int column;
char *key;
size_t key_len;
char *filename;
};
//rm= Redis Maat
struct serial_rule {
enum maat_operation op;//0: delete, 1: add.
long long rule_id;
long long timeout; // absolute unix time.
char table_name[NAME_MAX];
char *table_line;
int n_foreign;
struct foreign_key *f_keys;
redisContext *ref_ctx;
TAILQ_ENTRY(serial_rule) entries;
UT_hash_handle hh;
};
/**
* @brief write one line to redis
*
@@ -54,6 +82,48 @@ char *maat_cmd_str_escape(char *dst, int size, const char *src);
int maat_cmd_flushDB(struct maat *maat_instance);
/* maat command API for internal */
redisContext *maat_cmd_connect_redis(const char *redis_ip, int redis_port,
int redis_db, struct log_handle *logger);
redisReply *maat_cmd_wrap_redis_command(redisContext *c, const char *format, ...);
int maat_cmd_wrap_redis_get_reply(redisContext *c, redisReply **reply);
long long maat_cmd_redis_server_time_s(redisContext *c);
long long maat_cmd_read_redis_integer(const redisReply *reply);
int maat_cmd_get_valid_flag_offset(const char *line, int column_seq);
const char *maat_cmd_find_Nth_column(const char *line, int Nth, int *column_len);
int maat_cmd_write_rule(redisContext *c, struct serial_rule *s_rule,
size_t serial_rule_num, long long server_time,
struct log_handle *logger);
void maat_cmd_clear_rule_cache(struct serial_rule *s_rule);
int maat_cmd_get_redis_value(redisContext *c, struct serial_rule *rule_list,
int rule_num, int print_process, struct log_handle *logger);
int maat_cmd_get_foreign_keys_by_prefix(redisContext *ctx, struct serial_rule *rule_list,
int rule_num, const char* dir, struct log_handle *logger);
void maat_cmd_get_foreign_conts(redisContext *c, struct serial_rule *rule_list,
int rule_num, int print_fn, struct log_handle *logger);
void maat_cmd_rewrite_table_line_with_foreign(struct serial_rule *s_rule);
void maat_cmd_set_serial_rule(struct serial_rule *rule, enum maat_operation op,
long long rule_id, const char *table_name,
const char *line, long long timeout);
int maat_cmd_get_rm_key_list(redisContext *c, long long instance_version,
long long desired_version, long long *new_version,
struct table_manager *tbl_mgr, struct serial_rule **list,
int *update_type, int cumulative_off, struct log_handle *logger);
#ifdef __cplusplus
}
#endif

View File

@@ -16,8 +16,6 @@ extern "C"
{
#endif
#include "maat_rule.h"
#include <stdint.h>
void redis_monitor_traverse(long long version, struct source_redis_ctx *mr_ctx,

View File

@@ -21,12 +21,9 @@ extern "C"
#include <linux/limits.h>
#include <sys/time.h>
#include <pthread.h>
#include <sys/queue.h>
#include <dirent.h>
#include <openssl/md5.h>
#include "hiredis/hiredis.h"
#include "uthash/uthash.h"
#include "log/log.h"
#include "fieldstat.h"
#include "maat_command.h"
@@ -36,6 +33,7 @@ extern "C"
#include "maat_table.h"
#include "maat_virtual.h"
#include "maat_stat.h"
#include "hiredis/hiredis.h"
#define MAX_TABLE_NUM 1024
#define MAX_COMPILE_TABLE_NUM 16
@@ -55,15 +53,11 @@ enum tag_match {
TAG_MATCH_MATCHED
};
#define ITEM_RULE_MAGIC 0x4d3c2b1a
struct maat_item_inner {
long long magic_num;
long long item_id;
long long group_id;
long long district_id;
int expr_id_cnt;
int expr_id_lb; //low boundary
int expr_id_ub; //up boundary
};
struct maat_item {
@@ -71,23 +65,6 @@ struct maat_item {
long long group_id;
};
#define COMPILE_RULE_MAGIC 0x1a2b3c4d
struct compile_rule {
long long magic_num;
long long compile_id;
char *table_line;
size_t table_line_len;
struct compile_schema *ref_schema;
void **ex_data;
int declared_clause_num;
char table_name[NAME_MAX];
};
struct group2group_rule {
long long group_id;
long long super_group_id;
};
struct maat_runtime {
/* maat_runtime can be created and destroy dynamic, so need version info */
long long version;
@@ -105,6 +82,11 @@ struct maat_runtime {
struct log_handle *logger;
};
struct rule_tag {
char *tag_name;
char *tag_val;
};
enum data_source {
DATA_SOURCE_NONE = 0,
DATA_SOURCE_REDIS,
@@ -117,16 +99,14 @@ struct source_iris_ctx {
char full_idx_dir[NAME_MAX];
};
struct source_json_ctx
{
struct source_json_ctx {
char json_file[NAME_MAX];
char iris_file[NAME_MAX];
char effective_json_md5[MD5_DIGEST_LENGTH*2+1];
struct timespec last_md5_time;
};
struct source_redis_ctx
{
struct source_redis_ctx {
redisContext *read_ctx;
redisContext *write_ctx;
char redis_ip[64];
@@ -135,39 +115,6 @@ struct source_redis_ctx
time_t last_reconnect_time;
};
struct foreign_key {
int column;
char *key;
size_t key_len;
char *filename;
};
//rm= Redis Maat
struct serial_rule {
enum maat_operation op;//0: delete, 1: add.
long long rule_id;
long long timeout; // absolute unix time.
char table_name[NAME_MAX];
char *table_line;
int n_foreign;
struct foreign_key *f_keys;
redisContext *ref_ctx;
TAILQ_ENTRY(serial_rule) entries;
UT_hash_handle hh;
};
#define POSSIBLE_REDIS_REPLY_SIZE 2
struct expected_reply {
int s_rule_seq;
int possible_reply_num;
redisReply possible_replies[POSSIBLE_REDIS_REPLY_SIZE];
};
struct rule_tag {
char *tag_name;
char *tag_val;
};
struct maat_options {
char instance_name[NAME_MAX];
char foreign_cont_dir[NAME_MAX];
@@ -275,72 +222,23 @@ int my_scandir(const char *dir, struct dirent ***namelist,
int(*filter)(const struct dirent *),
int(*compar)(const void *, const void *));
size_t parse_accept_tag(const char *value, struct rule_tag **result, struct log_handle *logger);
int compare_accept_tag(const char *value, const struct rule_tag *accept_tags, size_t n_accept_tag);
struct maat_item_inner *maat_item_inner_new(long long item_id, long long group_id,
long long district_id);
void maat_item_inner_free(void *item_inner);
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);
void maat_finish_cb(void *u_para);
void *rule_monitor_loop(void *arg);
long long maat_runtime_get_sequence(struct maat_runtime *maat_rt, const char *key);
void maat_read_full_config(struct maat *maat_instance);
/* maat command API for internal */
redisContext *maat_cmd_connect_redis(const char *redis_ip, int redis_port,
int redis_db, struct log_handle *logger);
redisReply *maat_cmd_wrap_redis_command(redisContext *c, const char *format, ...);
int maat_cmd_wrap_redis_get_reply(redisContext *c, redisReply **reply);
long long maat_cmd_redis_server_time_s(redisContext *c);
long long maat_cmd_read_redis_integer(const redisReply *reply);
int maat_cmd_get_valid_flag_offset(const char *line, int column_seq);
const char *maat_cmd_find_Nth_column(const char *line, int Nth, int *column_len);
int maat_cmd_write_rule(redisContext *c, struct serial_rule *s_rule,
size_t serial_rule_num, long long server_time,
struct log_handle *logger);
void maat_cmd_clear_rule_cache(struct serial_rule *s_rule);
int maat_cmd_get_rm_key_list(redisContext *c, long long instance_version,
long long desired_version, long long *new_version,
struct table_manager *tbl_mgr, struct serial_rule **list,
int *update_type, int cumulative_off, struct log_handle *logger);
int maat_cmd_get_redis_value(redisContext *c, struct serial_rule *rule_list,
int rule_num, int print_process, struct log_handle *logger);
int maat_cmd_get_foreign_keys_by_prefix(redisContext *ctx, struct serial_rule *rule_list,
int rule_num, const char* dir, struct log_handle *logger);
void maat_cmd_get_foreign_conts(redisContext *c, struct serial_rule *rule_list,
int rule_num, int print_fn, struct log_handle *logger);
void maat_cmd_rewrite_table_line_with_foreign(struct serial_rule *s_rule);
void maat_cmd_set_serial_rule(struct serial_rule *rule, enum maat_operation op,
long long rule_id, const char *table_name,
const char *line, long long timeout);
void garbage_ip_matcher_free(void *ip_matcher, void *arg);
void garbage_interval_matcher_free(void *ip_matcher, void *arg);
void garbage_bool_matcher_free(void *bool_matcher, void *arg);
void garbage_maat_kv_store_free(void *kv_store, void *arg);
#ifdef __cplusplus

View File

@@ -623,8 +623,8 @@ int write_region_rule(cJSON *region_json, int compile_id, int group_id,
}
const char *table_type_str = item->valuestring;
enum table_type table_type = TABLE_TYPE_EXPR;
int ret = maat_kv_read(p_iris->str2int_map, table_type_str, (long long *)&(table_type));
long long table_type_int;
int ret = maat_kv_read(p_iris->str2int_map, table_type_str, &(table_type_int));
if (ret != 1) {
log_error(logger, MODULE_JSON2IRIS,
"[%s:%d] compile rule %d table name %s's table_type %s invalid",
@@ -645,9 +645,8 @@ int write_region_rule(cJSON *region_json, int compile_id, int group_id,
cJSON_AddNumberToObject(table_content, "group_id", group_id);
cJSON_AddNumberToObject(table_content, "is_valid", 1);
struct iris_table *table_info = query_table_info(p_iris, table_name, table_type);
switch(table_type)
{
struct iris_table *table_info = query_table_info(p_iris, table_name, table_type_int);
switch (table_type_int) {
case TABLE_TYPE_FLAG:
case TABLE_TYPE_FLAG_PLUS:
ret = write_flag_line(table_content, p_iris, table_info, logger);
@@ -714,7 +713,7 @@ int write_group2group_line(int group_id, int super_group_id, int is_exclude,
return 0;
}
int write_group_rule(cJSON *group_json, const char *parent_name, int parent_id,
int write_group_rule(cJSON *group_json, int parent_id,
int parent_type, int tracking_compile_id,
int Nth_group, struct iris_description *p_iris,
struct log_handle *logger)
@@ -797,9 +796,8 @@ int write_group_rule(cJSON *group_json, const char *parent_name, int parent_id,
int i = 0;
cJSON_ArrayForEach(item, sub_groups) {
i++;
ret = write_group_rule(item, group_name, group_info->group_id,
PARENT_TYPE_GROUP, tracking_compile_id,
i, p_iris, logger);
ret = write_group_rule(item, group_info->group_id, PARENT_TYPE_GROUP,
tracking_compile_id, i, p_iris, logger);
if (ret < 0) {
return -1;
}
@@ -814,13 +812,9 @@ int write_group_rule(cJSON *group_json, const char *parent_name, int parent_id,
}
if (parent_type == PARENT_TYPE_COMPILE) {
// printf("[group2compile] group:[%s:%d] parent:[%s:%d]\n",
// group_info->group_name, group_info->group_id, parent_name, parent_id);
ret = write_group2compile_line(group_info->group_id, parent_id, group_not_flag,
clause_index, virtual_table, p_iris, g2c_table);
} else {
// printf("[group2group] group:[%s:%d] parent:[%s:%d]\n",
// group_info->group_name, group_info->group_id, parent_name, parent_id);
ret = write_group2group_line(group_info->group_id, parent_id, is_exclude, p_iris);
}
@@ -1030,8 +1024,8 @@ int write_iris(cJSON *json, struct iris_description *p_iris,
parent_group = group_info_add_unsafe(p_iris, parent_group_name);
}
ret = write_group_rule(group_obj, parent_group_name, parent_group->group_id,
PARENT_TYPE_GROUP, 0, 0, p_iris, logger);
ret = write_group_rule(group_obj, parent_group->group_id, PARENT_TYPE_GROUP,
0, 0, p_iris, logger);
if (ret < 0) {
return -1;
}
@@ -1073,8 +1067,8 @@ int write_iris(cJSON *json, struct iris_description *p_iris,
i = 0;
cJSON *group_obj = NULL;
cJSON_ArrayForEach(group_obj, group_array) {
ret = write_group_rule(group_obj, "referenced by compile", compile_id,
PARENT_TYPE_COMPILE, compile_id, i, p_iris, logger);
ret = write_group_rule(group_obj, compile_id, PARENT_TYPE_COMPILE,
compile_id, i, p_iris, logger);
if (ret < 0) {
return -1;
}

View File

@@ -259,80 +259,6 @@ int maat_options_set_logger(struct maat_options *opts, const char *log_path, enu
return 0;
}
void maat_read_full_config(struct maat *maat_instance)
{
int ret = -1;
char err_str[NAME_MAX] = {0};
struct source_redis_ctx *redis_ctx = NULL;
switch (maat_instance->opts.input_mode) {
case DATA_SOURCE_REDIS:
redis_ctx = &(maat_instance->opts.redis_ctx);
log_info(maat_instance->logger, MODULE_MAAT_API,
"Maat initiate from Redis %s:%hu db%d",
redis_ctx->redis_ip, redis_ctx->redis_port, redis_ctx->redis_db);
redis_ctx->read_ctx = maat_cmd_connect_redis(redis_ctx->redis_ip,
redis_ctx->redis_port,
redis_ctx->redis_db,
maat_instance->logger);
if (redis_ctx->read_ctx != NULL) {
redis_monitor_traverse(maat_instance->maat_version, redis_ctx,
maat_start_cb, maat_update_cb, maat_finish_cb,
maat_instance);
}
if (NULL == maat_instance->creating_maat_rt) {
log_error(maat_instance->logger, MODULE_MAAT_API,
"[%s:%d] At initiation: NO effective rule in redis %s:%hu db%d",
__FUNCTION__, __LINE__, redis_ctx->redis_ip, redis_ctx->redis_port,
redis_ctx->redis_db);
}
break;
case DATA_SOURCE_IRIS_FILE:
config_monitor_traverse(maat_instance->maat_version,
maat_instance->opts.iris_ctx.full_idx_dir,
maat_start_cb, maat_update_cb, maat_finish_cb,
maat_instance, maat_instance->opts.decrypt_key,
maat_instance->logger);
if (NULL == maat_instance->creating_maat_rt) {
log_error(maat_instance->logger, MODULE_MAAT_API,
"[%s:%d] At initiation: NO effective rule in %s",
__FUNCTION__, __LINE__, maat_instance->opts.iris_ctx.full_idx_dir);
}
break;
case DATA_SOURCE_JSON_FILE:
ret = load_maat_json_file(maat_instance, maat_instance->opts.json_ctx.json_file,
err_str, sizeof(err_str));
if (ret < 0) {
log_error(maat_instance->logger, MODULE_MAAT_API,
"[%s:%d] Maat re-initiate with JSON file %s failed: %s",
__FUNCTION__, __LINE__, maat_instance->opts.json_ctx.json_file, err_str);
}
config_monitor_traverse(maat_instance->maat_version,
maat_instance->opts.json_ctx.iris_file,
maat_start_cb, maat_update_cb, maat_finish_cb,
maat_instance, maat_instance->opts.decrypt_key,
maat_instance->logger);
if (NULL == maat_instance->creating_maat_rt) {
log_error(maat_instance->logger, MODULE_MAAT_API,
"[%s:%d] At initiation: NO effective rule in %s",
__FUNCTION__, __LINE__, maat_instance->opts.json_ctx.iris_file);
}
break;
default:
break;
}
maat_instance->maat_rt = maat_instance->creating_maat_rt;
maat_instance->creating_maat_rt = NULL;
maat_instance->is_running = 1;
if (maat_instance->maat_rt != NULL) {
maat_instance->maat_version = maat_instance->maat_rt->version;
maat_instance->last_full_version = maat_instance->maat_rt->version;
}
}
void _maat_free(struct maat *maat_instance)
{
if (NULL == maat_instance) {
@@ -475,10 +401,15 @@ int maat_helper_read_column(const char *table_line, int Nth_column,
int maat_helper_verify_regex_expression(const char *regex_expr)
{
if (NULL == regex_expr) {
return -1;
return 0;
}
return adapter_hs_verify_regex_expression(regex_expr, NULL);
int ret = adapter_hs_verify_regex_expression(regex_expr, NULL);
if (ret < 0) {
return 0;
} else {
return 1;
}
}
int maat_get_table_id(struct maat *maat_instance, const char *table_name)

View File

@@ -400,7 +400,7 @@ int bool_plugin_runtime_update(void *bool_plugin_runtime, void *bool_plugin_sche
const char *key = line + item_id_offset;
size_t key_len = item_id_len;
ret = bool_plugin_runtime_update_row(bool_plugin_rt, table_name, line, key, key_len,
bool_expr, is_valid);
bool_expr, is_valid);
if (ret < 0) {
if (bool_expr != NULL) {
bool_plugin_expr_free(bool_expr);

View File

@@ -82,6 +82,17 @@ struct literal_clause {
UT_hash_handle hh;
};
struct compile_rule {
long long magic_num;
long long compile_id;
char *table_line;
size_t table_line_len;
struct compile_schema *ref_schema;
void **ex_data;
int declared_clause_num;
char table_name[NAME_MAX];
};
/* compile_runtime and group2compile_runtime share compile_hash_map */
struct compile_runtime {
struct bool_matcher *bm;
@@ -147,7 +158,6 @@ struct maat_compile_state {
time_t compile_rt_version;
size_t this_scan_hit_item_cnt;
int not_clause_hitted_flag;
int is_no_count_scan;
size_t hit_path_cnt;
UT_array *internal_hit_paths;
@@ -159,12 +169,11 @@ UT_icd ut_literal_id_icd = {sizeof(struct maat_literal_id), NULL, NULL, NULL};
UT_icd ut_clause_id_icd = {sizeof(long long), NULL, NULL, NULL};
UT_icd ut_hit_path_icd = {sizeof(struct maat_internal_hit_path), NULL, NULL, NULL};
#define MAAT_HIER_COMPILE_MAGIC 0x4a5b6c7d
struct maat_compile *maat_compile_new(long long compile_id)
{
struct maat_compile *compile = ALLOC(struct maat_compile, 1);
compile->magic = MAAT_HIER_COMPILE_MAGIC;
compile->magic = MAAT_COMPILE_MAGIC;
compile->compile_id = compile_id;
for(int i = 0; i < MAX_ITEMS_PER_BOOL_EXPR; i++) {
@@ -275,11 +284,6 @@ void rule_ex_data_new_cb(void *user_data, void *param, const char *table_name, i
{
struct ex_data_schema *ex_schema = (struct ex_data_schema *)param;
struct compile_rule *compile = (struct compile_rule *)user_data;
// if(compile->ref_table->table_id!=ex_desc->table_id)
// {
// return;
// }
void *ad = rule_ex_data_new(table_name, table_id, compile->table_line, ex_schema);
*compile->ex_data = ad;
@@ -299,6 +303,7 @@ void compile_runtime_user_data_iterate(struct compile_runtime *compile_rt,
callback(compile->user_data, param, compile->table_name, table_id);
}
}
FREE(data_array);
}
@@ -1123,6 +1128,7 @@ size_t maat_compile_bool_matcher_match(struct compile_runtime *compile_rt, int i
return ud_result_cnt;
}
#define COMPILE_RULE_MAGIC 0x1a2b3c4d
struct compile_rule *compile_rule_new(struct compile_item *compile_item,
struct compile_schema *schema,
const char *table_name,
@@ -1404,7 +1410,6 @@ void maat_compile_state_reset(struct maat_compile_state *compile_state)
compile_state->compile_rt_version = 0;
compile_state->this_scan_hit_item_cnt = 0;
compile_state->not_clause_hitted_flag = 0;
compile_state->is_no_count_scan = 0;
compile_state->hit_path_cnt = 0;
utarray_clear(compile_state->internal_hit_paths);

View File

@@ -222,7 +222,14 @@ int my_scandir(const char *dir, struct dirent ***namelist,
n++;
if (n >= DIR_ENT_SIZE) {
DIR_ENT_SIZE += ENLARGE_STEP;
list = (struct dirent **)realloc((void*)list, DIR_ENT_SIZE * sizeof(struct dirent *));
struct dirent **tmp_list = (struct dirent **)realloc((void*)list, DIR_ENT_SIZE * sizeof(struct dirent *));
if (tmp_list != NULL) {
list = tmp_list;
} else {
FREE(list);
closedir(od);
return -1;
}
}
}

View File

@@ -14,8 +14,11 @@
#include <stdio.h>
#include "maat.h"
#include "log/log.h"
#include "maat_utils.h"
#include "maat_rule.h"
#include "maat_command.h"
#include "hiredis/hiredis.h"
#include "maat_config_monitor.h"
#include "maat_redis_monitor.h"
#include "maat_plugin.h"
@@ -40,6 +43,13 @@ const char *foreign_key_prefix = "__FILE_";
const char *mr_op_str[] = {"DEL", "ADD", "RENEW_TIMEOUT"};
#define POSSIBLE_REDIS_REPLY_SIZE 2
struct expected_reply {
int s_rule_seq;
int possible_reply_num;
redisReply possible_replies[POSSIBLE_REDIS_REPLY_SIZE];
};
char *get_foreign_cont_filename(const char *table_name, long long rule_id,
const char *foreign_key, const char *dir)
{

View File

@@ -32,160 +32,7 @@
#define MODULE_MAAT_RULE module_name_str("maat.rule")
static int compare_each_tag(cJSON *tag_obj, const struct rule_tag *accept_tags, size_t n_accept_tag)
{
if (NULL == tag_obj || NULL == accept_tags) {
return TAG_MATCH_ERR;
}
cJSON *tab_name_obj = cJSON_GetObjectItem(tag_obj, "tag");
if (NULL == tab_name_obj || tab_name_obj->type != cJSON_String) {
return TAG_MATCH_ERR;
}
const char *tag_name = tab_name_obj->valuestring;
cJSON *tag_vals_array = cJSON_GetObjectItem(tag_obj, "value");
if (NULL == tag_vals_array || tag_vals_array->type != cJSON_Array) {
return TAG_MATCH_ERR;
}
int name_matched = 0;
int n_val = cJSON_GetArraySize(tag_vals_array);
for (size_t i = 0; i < n_accept_tag; i++) {
if (0 != strcmp(accept_tags[i].tag_name, tag_name)) {
continue;
}
name_matched++;
for (int j = 0; j < n_val; j++) {
cJSON *tag_val_obj = cJSON_GetArrayItem(tag_vals_array, j);
if (NULL == tag_val_obj || tag_val_obj->type != cJSON_String) {
return TAG_MATCH_ERR;
}
const char *tag_val = tag_val_obj->valuestring;
// compare a/b/c with a/b/c/d is a miss.
if (strlen(accept_tags[i].tag_val) < strlen(tag_val)) {
continue;
}
// compare a1a2/b1/c1 with a1a2/b/ is a miss.
//make sure the overlap is ended with a '/'
if (0 == strncmp(accept_tags[i].tag_val, tag_val, strlen(tag_val)) &&
(strlen(accept_tags[i].tag_val) == strlen(tag_val) || accept_tags[i].tag_val[strlen(tag_val)] == '/')) {
return TAG_MATCH_MATCHED;
}
}
}
//no matched name is considered as a
if (name_matched > 0) {
return TAG_MATCH_UNMATCHED;
} else {
return TAG_MATCH_MATCHED;
}
}
//@param tag_set likes [{"tag":"location","value":["北京/朝阳/华严北里","上海/浦东/陆家嘴"]},{"tag":"isp","value":["电信","移动"]}]
static int compare_each_tag_set(cJSON *tag_set, const struct rule_tag *accept_tags, size_t n_accept_tag)
{
int matched = 0;
int n_tag = cJSON_GetArraySize(tag_set);
for (int i = 0; i < n_tag; i++) {
cJSON *tag_obj = cJSON_GetArrayItem(tag_set, i);
if (NULL == tag_obj || tag_obj->type != cJSON_Object) {
return TAG_MATCH_ERR;
}
int ret = compare_each_tag(tag_obj, accept_tags, n_accept_tag);
if (ret < 0) {
return TAG_MATCH_ERR;
}
if(1 == ret) {
matched++;
}
}
if (matched == n_tag) {
return TAG_MATCH_MATCHED;
} else {
return TAG_MATCH_UNMATCHED;
}
}
//@param value is a JSON, like {"tags":[{"tag":"location","value":"北京/朝阳/华严北里/甲22号},{"tag":"isp","value":"电信"}]}
size_t parse_accept_tag(const char *value, struct rule_tag **result, struct log_handle *logger)
{
if (NULL == value || NULL == result || NULL == logger) {
return 0;
}
cJSON *json = cJSON_Parse(value);
if (!json) {
log_error(logger, MODULE_MAAT_RULE,
"[%s:%d] parse accept tag Error before: %-200.200s",
__FUNCTION__, __LINE__, cJSON_GetErrorPtr());
return 0;
}
cJSON *tag = NULL, *tmp = NULL;
cJSON *array = cJSON_GetObjectItem(json, "tags");
int n_tag = cJSON_GetArraySize(array);
struct rule_tag *p = ALLOC(struct rule_tag, n_tag);
for (int i = 0; i < n_tag; i++) {
tag = cJSON_GetArrayItem(array, i);
tmp = cJSON_GetObjectItem(tag, "tag");
p[i].tag_name = maat_strdup(tmp->valuestring);
tmp = cJSON_GetObjectItem(tag, "value");
p[i].tag_val = maat_strdup(tmp->valuestring);
}
cJSON_Delete(json);
*result = p;
return n_tag;
}
//@param value {"tag_sets":[[{"tag":"location","value":["北京/朝阳/华严北里","上海/浦东/陆家嘴"]},{"tag":"isp","value":["电信","移动"]}],[{"tag":"location","value":["北京"]},{"tag":"isp","value":["联通"]}]]}
//@return 1 on match, 0 on not match, -1 on error.
int compare_accept_tag(const char *value, const struct rule_tag *accept_tags, size_t n_accept_tag)
{
int ret = TAG_MATCH_ERR;
int n_set = 0;
cJSON *tag_set = NULL;
cJSON *tag_set_array = NULL;
cJSON *root = cJSON_Parse(value);
if (NULL == root) {
goto error;
}
tag_set_array = cJSON_GetObjectItem(root, "tag_sets");
if (NULL == tag_set_array || tag_set_array->type != cJSON_Array) {
goto error;
}
n_set = cJSON_GetArraySize(tag_set_array);
for (int i = 0; i < n_set; i++) {
tag_set = cJSON_GetArrayItem(tag_set_array, i);
if (NULL == tag_set || tag_set->type != cJSON_Array) {
goto error;
}
ret = compare_each_tag_set(tag_set, accept_tags, n_accept_tag);
//match or error occurs.
if (ret != TAG_MATCH_UNMATCHED) {
break;
}
}
error:
cJSON_Delete(root);
return ret;
}
#define ITEM_RULE_MAGIC 0x4d3c2b1a
struct maat_item_inner *maat_item_inner_new(long long item_id, long long group_id,
long long district_id)
{
@@ -206,7 +53,6 @@ void maat_item_inner_free(void *item_inner)
struct maat_item_inner *item = (struct maat_item_inner *)item_inner;
assert(item->magic_num == ITEM_RULE_MAGIC);
assert(item->expr_id_cnt == 0 || item->expr_id_cnt == item->expr_id_ub - item->expr_id_lb + 1);
item->magic_num = 0;
free(item);
@@ -244,58 +90,6 @@ void maat_runtime_commit(struct maat_runtime *maat_rt, int update_type,
maat_rt->last_update_time = time(NULL);
}
long long maat_runtime_get_sequence(struct maat_runtime *maat_rt, const char *key)
{
if (NULL == maat_rt || NULL == key) {
return -1;
}
long long sequence = 0;
int map_ret = maat_kv_read(maat_rt->sequence_map, key, &sequence);
if (map_ret < 0) {
maat_kv_register(maat_rt->sequence_map, key, sequence);
} else {
sequence++;
int ret = maat_kv_write(maat_rt->sequence_map, key, sequence);
if (ret < 0) {
return -1;
}
}
return sequence;
}
void maat_runtime_destroy(struct maat_runtime *maat_rt)
{
if (NULL == maat_rt) {
return;
}
if (maat_rt->sequence_map != NULL) {
maat_kv_store_free(maat_rt->sequence_map);
maat_rt->sequence_map = NULL;
}
if (maat_rt->ref_cnt != NULL) {
alignment_int64_array_free(maat_rt->ref_cnt);
maat_rt->ref_cnt = NULL;
}
FREE(maat_rt);
}
void garbage_maat_kv_store_free(void *kv_store, void *arg)
{
struct maat_kv_store *store = (struct maat_kv_store *)kv_store;
maat_kv_store_free(store);
}
void garbage_maat_runtime_destroy(void *maat_runtime, void *arg)
{
struct maat_runtime *maat_rt = (struct maat_runtime *)maat_runtime;
maat_runtime_destroy(maat_rt);
}
void maat_start_cb(long long new_version, int update_type, void *u_param)
{
struct maat *maat_instance = (struct maat *)u_param;
@@ -427,6 +221,132 @@ void maat_finish_cb(void *u_param)
maat_instance->new_version = INVALID_VERSION;
}
void maat_read_full_config(struct maat *maat_instance)
{
int ret = -1;
char err_str[NAME_MAX] = {0};
struct source_redis_ctx *redis_ctx = NULL;
switch (maat_instance->opts.input_mode) {
case DATA_SOURCE_REDIS:
redis_ctx = &(maat_instance->opts.redis_ctx);
log_info(maat_instance->logger, MODULE_MAAT_RULE,
"Maat initiate from Redis %s:%hu db%d",
redis_ctx->redis_ip, redis_ctx->redis_port, redis_ctx->redis_db);
redis_ctx->read_ctx = maat_cmd_connect_redis(redis_ctx->redis_ip,
redis_ctx->redis_port,
redis_ctx->redis_db,
maat_instance->logger);
if (redis_ctx->read_ctx != NULL) {
redis_monitor_traverse(maat_instance->maat_version, redis_ctx,
maat_start_cb, maat_update_cb, maat_finish_cb,
maat_instance);
}
if (NULL == maat_instance->creating_maat_rt) {
log_error(maat_instance->logger, MODULE_MAAT_RULE,
"[%s:%d] At initiation: NO effective rule in redis %s:%hu db%d",
__FUNCTION__, __LINE__, redis_ctx->redis_ip, redis_ctx->redis_port,
redis_ctx->redis_db);
}
break;
case DATA_SOURCE_IRIS_FILE:
config_monitor_traverse(maat_instance->maat_version,
maat_instance->opts.iris_ctx.full_idx_dir,
maat_start_cb, maat_update_cb, maat_finish_cb,
maat_instance, maat_instance->opts.decrypt_key,
maat_instance->logger);
if (NULL == maat_instance->creating_maat_rt) {
log_error(maat_instance->logger, MODULE_MAAT_RULE,
"[%s:%d] At initiation: NO effective rule in %s",
__FUNCTION__, __LINE__, maat_instance->opts.iris_ctx.full_idx_dir);
}
break;
case DATA_SOURCE_JSON_FILE:
ret = load_maat_json_file(maat_instance, maat_instance->opts.json_ctx.json_file,
err_str, sizeof(err_str));
if (ret < 0) {
log_error(maat_instance->logger, MODULE_MAAT_RULE,
"[%s:%d] Maat re-initiate with JSON file %s failed: %s",
__FUNCTION__, __LINE__, maat_instance->opts.json_ctx.json_file, err_str);
}
config_monitor_traverse(maat_instance->maat_version,
maat_instance->opts.json_ctx.iris_file,
maat_start_cb, maat_update_cb, maat_finish_cb,
maat_instance, maat_instance->opts.decrypt_key,
maat_instance->logger);
if (NULL == maat_instance->creating_maat_rt) {
log_error(maat_instance->logger, MODULE_MAAT_RULE,
"[%s:%d] At initiation: NO effective rule in %s",
__FUNCTION__, __LINE__, maat_instance->opts.json_ctx.iris_file);
}
break;
default:
break;
}
maat_instance->maat_rt = maat_instance->creating_maat_rt;
maat_instance->creating_maat_rt = NULL;
maat_instance->is_running = 1;
if (maat_instance->maat_rt != NULL) {
maat_instance->maat_version = maat_instance->maat_rt->version;
maat_instance->last_full_version = maat_instance->maat_rt->version;
}
}
long long maat_runtime_get_sequence(struct maat_runtime *maat_rt, const char *key)
{
if (NULL == maat_rt || NULL == key) {
return -1;
}
long long sequence = 0;
int map_ret = maat_kv_read(maat_rt->sequence_map, key, &sequence);
if (map_ret < 0) {
maat_kv_register(maat_rt->sequence_map, key, sequence);
} else {
sequence++;
int ret = maat_kv_write(maat_rt->sequence_map, key, sequence);
if (ret < 0) {
return -1;
}
}
return sequence;
}
void maat_runtime_destroy(struct maat_runtime *maat_rt)
{
if (NULL == maat_rt) {
return;
}
if (maat_rt->sequence_map != NULL) {
maat_kv_store_free(maat_rt->sequence_map);
maat_rt->sequence_map = NULL;
}
if (maat_rt->ref_cnt != NULL) {
alignment_int64_array_free(maat_rt->ref_cnt);
maat_rt->ref_cnt = NULL;
}
FREE(maat_rt);
}
void garbage_maat_kv_store_free(void *kv_store, void *arg)
{
struct maat_kv_store *store = (struct maat_kv_store *)kv_store;
maat_kv_store_free(store);
}
void garbage_maat_runtime_destroy(void *maat_runtime, void *arg)
{
struct maat_runtime *maat_rt = (struct maat_runtime *)maat_runtime;
maat_runtime_destroy(maat_rt);
}
void *rule_monitor_loop(void *arg)
{
/* Defined by prctl: The name can be up to 16 bytes long, and should

View File

@@ -283,6 +283,161 @@ struct table_operations table_ops[TABLE_TYPE_MAX] = {
}
};
//@param value is a JSON, like {"tags":[{"tag":"location","value":"北京/朝阳/华严北里/甲22号},{"tag":"isp","value":"电信"}]}
size_t parse_accept_tag(const char *value, struct rule_tag **result, struct log_handle *logger)
{
if (NULL == value || NULL == result || NULL == logger) {
return 0;
}
cJSON *json = cJSON_Parse(value);
if (!json) {
log_error(logger, MODULE_TABLE,
"[%s:%d] parse accept tag Error before: %-200.200s",
__FUNCTION__, __LINE__, cJSON_GetErrorPtr());
return 0;
}
cJSON *tag = NULL, *tmp = NULL;
cJSON *array = cJSON_GetObjectItem(json, "tags");
int n_tag = cJSON_GetArraySize(array);
struct rule_tag *p = ALLOC(struct rule_tag, n_tag);
for (int i = 0; i < n_tag; i++) {
tag = cJSON_GetArrayItem(array, i);
tmp = cJSON_GetObjectItem(tag, "tag");
p[i].tag_name = maat_strdup(tmp->valuestring);
tmp = cJSON_GetObjectItem(tag, "value");
p[i].tag_val = maat_strdup(tmp->valuestring);
}
cJSON_Delete(json);
*result = p;
return n_tag;
}
static int compare_each_tag(cJSON *tag_obj, const struct rule_tag *accept_tags, size_t n_accept_tag)
{
if (NULL == tag_obj || NULL == accept_tags) {
return TAG_MATCH_ERR;
}
cJSON *tab_name_obj = cJSON_GetObjectItem(tag_obj, "tag");
if (NULL == tab_name_obj || tab_name_obj->type != cJSON_String) {
return TAG_MATCH_ERR;
}
const char *tag_name = tab_name_obj->valuestring;
cJSON *tag_vals_array = cJSON_GetObjectItem(tag_obj, "value");
if (NULL == tag_vals_array || tag_vals_array->type != cJSON_Array) {
return TAG_MATCH_ERR;
}
int name_matched = 0;
int n_val = cJSON_GetArraySize(tag_vals_array);
for (size_t i = 0; i < n_accept_tag; i++) {
if (0 != strcmp(accept_tags[i].tag_name, tag_name)) {
continue;
}
name_matched++;
for (int j = 0; j < n_val; j++) {
cJSON *tag_val_obj = cJSON_GetArrayItem(tag_vals_array, j);
if (NULL == tag_val_obj || tag_val_obj->type != cJSON_String) {
return TAG_MATCH_ERR;
}
const char *tag_val = tag_val_obj->valuestring;
// compare a/b/c with a/b/c/d is a miss.
if (strlen(accept_tags[i].tag_val) < strlen(tag_val)) {
continue;
}
// compare a1a2/b1/c1 with a1a2/b/ is a miss.
//make sure the overlap is ended with a '/'
if (0 == strncmp(accept_tags[i].tag_val, tag_val, strlen(tag_val)) &&
(strlen(accept_tags[i].tag_val) == strlen(tag_val) ||
accept_tags[i].tag_val[strlen(tag_val)] == '/')) {
return TAG_MATCH_MATCHED;
}
}
}
//no matched name is considered as a
if (name_matched > 0) {
return TAG_MATCH_UNMATCHED;
} else {
return TAG_MATCH_MATCHED;
}
}
//@param tag_set likes [{"tag":"location","value":["北京/朝阳/华严北里","上海/浦东/陆家嘴"]},{"tag":"isp","value":["电信","移动"]}]
static int compare_each_tag_set(cJSON *tag_set, const struct rule_tag *accept_tags, size_t n_accept_tag)
{
int matched = 0;
int n_tag = cJSON_GetArraySize(tag_set);
for (int i = 0; i < n_tag; i++) {
cJSON *tag_obj = cJSON_GetArrayItem(tag_set, i);
if (NULL == tag_obj || tag_obj->type != cJSON_Object) {
return TAG_MATCH_ERR;
}
int ret = compare_each_tag(tag_obj, accept_tags, n_accept_tag);
if (ret < 0) {
return TAG_MATCH_ERR;
}
if(1 == ret) {
matched++;
}
}
if (matched == n_tag) {
return TAG_MATCH_MATCHED;
} else {
return TAG_MATCH_UNMATCHED;
}
}
//@param value {"tag_sets":[[{"tag":"location","value":["北京/朝阳/华严北里","上海/浦东/陆家嘴"]},{"tag":"isp","value":["电信","移动"]}],[{"tag":"location","value":["北京"]},{"tag":"isp","value":["联通"]}]]}
//@return 1 on match, 0 on not match, -1 on error.
int compare_accept_tag(const char *value, const struct rule_tag *accept_tags, size_t n_accept_tag)
{
int ret = TAG_MATCH_ERR;
int n_set = 0;
cJSON *tag_set = NULL;
cJSON *tag_set_array = NULL;
cJSON *root = cJSON_Parse(value);
if (NULL == root) {
goto error;
}
tag_set_array = cJSON_GetObjectItem(root, "tag_sets");
if (NULL == tag_set_array || tag_set_array->type != cJSON_Array) {
goto error;
}
n_set = cJSON_GetArraySize(tag_set_array);
for (int i = 0; i < n_set; i++) {
tag_set = cJSON_GetArrayItem(tag_set_array, i);
if (NULL == tag_set || tag_set->type != cJSON_Array) {
goto error;
}
ret = compare_each_tag_set(tag_set, accept_tags, n_accept_tag);
//match or error occurs.
if (ret != TAG_MATCH_UNMATCHED) {
break;
}
}
error:
cJSON_Delete(root);
return ret;
}
void *maat_table_schema_new(cJSON *json, const char *table_name,
enum table_type table_type,
struct table_manager *tbl_mgr,

View File

@@ -113,7 +113,6 @@ int load_file_to_memory(const char *file_name, unsigned char **pp_out, size_t *o
read_size = fread(*pp_out, 1, *out_sz, fp);
if (read_size != *out_sz) {
FREE(*pp_out);
return -1;
}
fclose(fp);