[patch]change verify expression retval semantics:1(legal) 0(illegal)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
334
src/maat_rule.c
334
src/maat_rule.c
@@ -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
|
||||
|
||||
155
src/maat_table.c
155
src/maat_table.c
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user