2023-02-22 15:22:41 +08:00
/**********************************************************************************************
2022-11-17 05:05:35 +08:00
* File : maat_rule . cpp
* Description :
* Authors : Liu WenTan < liuwentan @ geedgenetworks . com >
* Date : 2022 - 10 - 31
* Copyright : ( c ) 2018 - 2022 Geedge Networks , Inc . All rights reserved .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
# include <unistd.h>
2022-11-25 16:32:29 +08:00
# include <stdio.h>
2022-11-17 05:05:35 +08:00
# include <pthread.h>
2023-02-21 11:27:18 +08:00
# include <linux/limits.h>
2022-11-25 16:32:29 +08:00
# include <string.h>
# include <sys/prctl.h>
2022-12-03 22:23:41 +08:00
# include <sys/stat.h>
2022-11-25 16:32:29 +08:00
# include <assert.h>
2022-11-17 05:05:35 +08:00
2022-12-03 22:23:41 +08:00
# include "json2iris.h"
2023-01-31 20:39:53 +08:00
# include "log/log.h"
2022-11-17 05:05:35 +08:00
# include "maat_utils.h"
2022-12-03 22:23:41 +08:00
# include "maat_rule.h"
# include "maat_config_monitor.h"
# include "maat_redis_monitor.h"
2023-01-30 21:59:35 +08:00
# include "maat_table.h"
# include "maat_compile.h"
# include "maat_plugin.h"
2023-04-20 15:34:56 +08:00
# include "maat_stat.h"
2023-03-01 09:32:36 +08:00
# include "ip_matcher.h"
2022-12-14 15:28:21 +08:00
# include "alignment.h"
2023-01-31 20:39:53 +08:00
# include "maat_garbage_collection.h"
2022-11-17 05:05:35 +08:00
2022-12-09 17:12:18 +08:00
# define MODULE_MAAT_RULE module_name_str("maat.rule")
2023-03-15 11:36:54 +08:00
struct maat_item * maat_item_new ( long long item_id , long long group_id , void * user_data ,
void ( * user_data_free ) ( void * ) )
2023-01-30 21:59:35 +08:00
{
struct maat_item * item = NULL ;
item = ALLOC ( struct maat_item , 1 ) ;
item - > group_id = group_id ;
item - > item_id = item_id ;
item - > user_data = user_data ;
2023-03-15 11:36:54 +08:00
item - > user_data_free = user_data_free ;
2023-01-30 21:59:35 +08:00
return item ;
}
2023-03-15 13:30:39 +08:00
void maat_item_free ( void * maat_item )
2023-01-30 21:59:35 +08:00
{
2023-03-15 11:36:54 +08:00
struct maat_item * item = ( struct maat_item * ) maat_item ;
if ( item - > user_data_free & & item - > user_data ) {
item - > user_data_free ( item - > user_data ) ;
2023-01-30 21:59:35 +08:00
item - > user_data = NULL ;
}
free ( item ) ;
}
2023-01-31 20:39:53 +08:00
static int compare_each_tag ( cJSON * tag_obj , const struct rule_tag * accept_tags , size_t n_accept_tag )
2023-01-30 21:59:35 +08:00
{
if ( NULL = = tag_obj | | NULL = = accept_tags ) {
2023-02-03 17:28:14 +08:00
return TAG_MATCH_ERR ;
2023-01-30 21:59:35 +08:00
}
cJSON * tab_name_obj = cJSON_GetObjectItem ( tag_obj , " tag " ) ;
if ( NULL = = tab_name_obj | | tab_name_obj - > type ! = cJSON_String ) {
2023-02-03 17:28:14 +08:00
return TAG_MATCH_ERR ;
2023-01-30 21:59:35 +08:00
}
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 ) {
2023-02-03 17:28:14 +08:00
return TAG_MATCH_ERR ;
2023-01-30 21:59:35 +08:00
}
int name_matched = 0 ;
int n_val = cJSON_GetArraySize ( tag_vals_array ) ;
2023-01-31 20:39:53 +08:00
for ( size_t i = 0 ; i < n_accept_tag ; i + + ) {
2023-01-30 21:59:35 +08:00
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 ) {
2023-02-03 17:28:14 +08:00
return TAG_MATCH_ERR ;
2023-01-30 21:59:35 +08:00
}
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 ) ] = = ' / ' ) ) {
2023-02-03 17:28:14 +08:00
return TAG_MATCH_MATCHED ;
2023-01-30 21:59:35 +08:00
}
}
}
//no matched name is considered as a
if ( name_matched > 0 ) {
2023-02-03 17:28:14 +08:00
return TAG_MATCH_UNMATCHED ;
2023-01-30 21:59:35 +08:00
} else {
2023-02-03 17:28:14 +08:00
return TAG_MATCH_MATCHED ;
2023-01-30 21:59:35 +08:00
}
}
//@param tag_set likes [{"tag":"location","value":["北京/朝阳/华严北里","上海/浦东/陆家嘴"]},{"tag":"isp","value":["电信","移动"]}]
2023-01-31 20:39:53 +08:00
static int compare_each_tag_set ( cJSON * tag_set , const struct rule_tag * accept_tags , size_t n_accept_tag )
2023-01-30 21:59:35 +08:00
{
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 ) {
2023-02-03 17:28:14 +08:00
return TAG_MATCH_ERR ;
2023-01-30 21:59:35 +08:00
}
int ret = compare_each_tag ( tag_obj , accept_tags , n_accept_tag ) ;
if ( ret < 0 ) {
2023-02-03 17:28:14 +08:00
return TAG_MATCH_ERR ;
2023-01-30 21:59:35 +08:00
}
if ( 1 = = ret ) {
matched + + ;
}
}
if ( matched = = n_tag ) {
2023-02-03 17:28:14 +08:00
return TAG_MATCH_MATCHED ;
2023-01-30 21:59:35 +08:00
} else {
2023-02-03 17:28:14 +08:00
return TAG_MATCH_UNMATCHED ;
2023-01-30 21:59:35 +08:00
}
}
//@param value is a JSON, like {"tags":[{"tag":"location","value":"北京/朝阳/华严北里/甲22号},{"tag":"isp","value":"电信"}]}
2023-01-31 20:39:53 +08:00
size_t parse_accept_tag ( const char * value , struct rule_tag * * result , struct log_handle * logger )
2023-01-30 21:59:35 +08:00
{
2023-01-31 20:39:53 +08:00
if ( NULL = = value | | NULL = = result | | NULL = = logger ) {
return 0 ;
}
cJSON * json = cJSON_Parse ( value ) ;
2023-01-30 21:59:35 +08:00
if ( ! json ) {
log_error ( logger , MODULE_MAAT_RULE ,
2023-03-02 14:52:31 +08:00
" [%s:%d] parse accept tag Error before: %-200.200s " ,
__FUNCTION__ , __LINE__ , cJSON_GetErrorPtr ( ) ) ;
2023-01-30 21:59:35 +08:00
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.
2023-01-31 20:39:53 +08:00
int compare_accept_tag ( const char * value , const struct rule_tag * accept_tags , size_t n_accept_tag )
2023-01-30 21:59:35 +08:00
{
2023-02-03 17:28:14 +08:00
int ret = TAG_MATCH_ERR ;
2023-01-30 21:59:35 +08:00
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 ;
}
2023-01-31 20:39:53 +08:00
ret = compare_each_tag_set ( tag_set , accept_tags , n_accept_tag ) ;
2023-01-30 21:59:35 +08:00
//match or error occurs.
2023-02-03 17:28:14 +08:00
if ( ret ! = TAG_MATCH_UNMATCHED ) {
2023-01-30 21:59:35 +08:00
break ;
}
}
error :
cJSON_Delete ( root ) ;
return ret ;
}
2023-03-15 11:36:54 +08:00
struct maat_item_inner * maat_item_inner_new ( long long group_id , long long item_id , long long district_id )
2023-01-30 21:59:35 +08:00
{
struct maat_item_inner * item = ALLOC ( struct maat_item_inner , 1 ) ;
item - > magic_num = ITEM_RULE_MAGIC ;
item - > item_id = item_id ;
item - > group_id = group_id ;
item - > district_id = district_id ;
return item ;
}
2023-01-31 20:39:53 +08:00
void maat_item_inner_free ( void * item_inner )
2023-01-30 21:59:35 +08:00
{
2023-01-31 20:39:53 +08:00
if ( NULL = = item_inner ) {
return ;
}
struct maat_item_inner * item = ( struct maat_item_inner * ) item_inner ;
2023-01-30 21:59:35 +08:00
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 ) ;
}
2022-11-25 16:32:29 +08:00
struct maat_runtime * maat_runtime_create ( long long version , struct maat * maat_instance )
2022-11-17 05:05:35 +08:00
{
struct maat_runtime * maat_rt = ALLOC ( struct maat_runtime , 1 ) ;
maat_rt - > version = version ;
2023-01-31 20:39:53 +08:00
int ret = table_manager_runtime_create ( maat_instance - > tbl_mgr , maat_instance - > nr_worker_thread ,
maat_instance - > garbage_bin ) ;
2023-01-30 21:59:35 +08:00
if ( ret < 0 ) {
FREE ( maat_rt ) ;
return NULL ;
}
maat_rt - > ref_tbl_mgr = maat_instance - > tbl_mgr ;
2023-01-31 20:39:53 +08:00
maat_rt - > max_table_num = table_manager_table_count ( maat_instance - > tbl_mgr ) ;
2023-03-15 11:36:54 +08:00
maat_rt - > sequence_map = maat_kv_store_new ( ) ;
2022-12-14 15:28:21 +08:00
maat_rt - > logger = maat_instance - > logger ;
maat_rt - > ref_garbage_bin = maat_instance - > garbage_bin ;
maat_rt - > ref_cnt = alignment_int64_array_alloc ( maat_instance - > nr_worker_thread ) ;
2022-11-25 16:32:29 +08:00
return maat_rt ;
2022-11-17 05:05:35 +08:00
}
2023-04-12 20:48:19 +08:00
void maat_runtime_commit ( struct maat_runtime * maat_rt , int update_type ,
2023-04-13 14:56:35 +08:00
long long maat_rt_version , struct log_handle * logger )
2022-11-17 05:05:35 +08:00
{
for ( size_t i = 0 ; i < maat_rt - > max_table_num ; i + + ) {
2023-04-13 14:56:35 +08:00
table_manager_commit_runtime ( maat_rt - > ref_tbl_mgr , i , update_type , maat_rt_version ) ;
2022-11-17 05:05:35 +08:00
}
2022-11-25 16:32:29 +08:00
maat_rt - > last_update_time = time ( NULL ) ;
2022-11-17 05:05:35 +08:00
}
2023-03-15 11:36:54 +08:00
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 ;
}
2022-11-25 16:32:29 +08:00
void maat_runtime_destroy ( struct maat_runtime * maat_rt )
2022-11-17 05:05:35 +08:00
{
2022-11-25 16:32:29 +08:00
if ( NULL = = maat_rt ) {
return ;
}
2023-04-13 18:53:36 +08:00
2023-03-15 11:36:54 +08:00
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 ;
}
2022-12-05 23:21:18 +08:00
FREE ( maat_rt ) ;
2022-11-17 05:05:35 +08:00
}
2023-04-04 15:59:34 +08:00
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 ) ;
}
2023-03-29 22:25:14 +08:00
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 ) ;
}
2022-11-25 16:32:29 +08:00
void maat_start_cb ( long long new_version , int update_type , void * u_param )
2022-11-17 05:05:35 +08:00
{
struct maat * maat_instance = ( struct maat * ) u_param ;
2023-03-15 11:36:54 +08:00
maat_instance - > new_version = new_version ;
2023-04-12 20:48:19 +08:00
size_t i = 0 ;
size_t table_cnt = table_manager_table_count ( maat_instance - > tbl_mgr ) ;
enum table_type table_type = TABLE_TYPE_INVALID ;
2023-03-15 11:36:54 +08:00
2023-02-03 17:28:14 +08:00
if ( update_type = = MAAT_UPDATE_TYPE_FULL ) {
2022-11-25 16:32:29 +08:00
maat_instance - > creating_maat_rt = maat_runtime_create ( new_version , maat_instance ) ;
2023-04-12 20:48:19 +08:00
for ( i = 0 ; i < table_cnt ; i + + ) {
table_type = table_manager_get_table_type ( maat_instance - > tbl_mgr , i ) ;
if ( table_type = = TABLE_TYPE_COMPILE ) {
// compile runtime need a reference to maat runtime
void * compile_rt = table_manager_get_updating_runtime ( maat_instance - > tbl_mgr , i ) ;
compile_runtime_init ( compile_rt , maat_instance - > creating_maat_rt ) ;
}
}
} else {
2022-11-17 05:05:35 +08:00
maat_instance - > maat_version = new_version ;
}
2022-11-25 16:32:29 +08:00
2023-04-12 20:48:19 +08:00
for ( i = 0 ; i < table_cnt ; i + + ) {
table_type = table_manager_get_table_type ( maat_instance - > tbl_mgr , i ) ;
if ( table_type = = TABLE_TYPE_PLUGIN ) {
void * schema = table_manager_get_schema ( maat_instance - > tbl_mgr , i ) ;
plugin_table_all_callback_start ( ( struct plugin_schema * ) schema , update_type ) ;
2023-03-15 11:36:54 +08:00
}
2023-04-12 20:48:19 +08:00
}
2022-11-17 05:05:35 +08:00
}
2022-11-25 16:32:29 +08:00
int maat_update_cb ( const char * table_name , const char * line , void * u_param )
2022-11-17 05:05:35 +08:00
{
2023-01-30 21:59:35 +08:00
if ( NULL = = table_name | | NULL = = line | | NULL = = u_param ) {
return 0 ;
}
2022-11-17 05:05:35 +08:00
struct maat * maat_instance = ( struct maat * ) u_param ;
struct maat_runtime * maat_rt = NULL ;
2023-01-30 21:59:35 +08:00
int table_id = table_manager_get_table_id ( maat_instance - > tbl_mgr , table_name ) ;
2022-12-03 22:23:41 +08:00
if ( table_id < 0 ) {
2023-01-30 21:59:35 +08:00
log_error ( maat_instance - > logger , MODULE_MAAT_RULE ,
2023-03-02 14:52:31 +08:00
" [%s:%d] update warning, unknown table name %s " ,
__FUNCTION__ , __LINE__ , table_name ) ;
2022-12-03 22:23:41 +08:00
return - 1 ;
}
2023-01-30 21:59:35 +08:00
void * schema = table_manager_get_schema ( maat_instance - > tbl_mgr , table_id ) ;
if ( NULL = = schema ) {
2022-12-09 17:12:18 +08:00
log_error ( maat_instance - > logger , MODULE_MAAT_RULE ,
2023-03-02 14:52:31 +08:00
" [%s:%d] update warning, table name %s doesn't have table schema " ,
__FUNCTION__ , __LINE__ , table_name ) ;
2022-12-03 22:23:41 +08:00
return - 1 ;
}
2022-12-06 00:35:36 +08:00
2023-04-12 20:48:19 +08:00
int update_type = MAAT_UPDATE_TYPE_INC ;
if ( maat_instance - > creating_maat_rt ! = NULL ) { //Full update
2022-11-25 16:32:29 +08:00
maat_rt = maat_instance - > creating_maat_rt ;
2023-04-12 20:48:19 +08:00
update_type = MAAT_UPDATE_TYPE_FULL ;
2022-11-17 05:05:35 +08:00
} else {
maat_rt = maat_instance - > maat_rt ;
}
2023-03-15 11:36:54 +08:00
2023-04-12 20:48:19 +08:00
table_manager_update_runtime ( maat_rt - > ref_tbl_mgr , table_name , table_id , line , update_type ) ;
2023-01-30 21:59:35 +08:00
2022-11-17 05:05:35 +08:00
return 0 ;
}
2023-04-12 19:20:05 +08:00
long long maat_runtime_rule_num ( struct maat_runtime * maat_rt )
2022-11-25 16:32:29 +08:00
{
2023-04-12 19:20:05 +08:00
long long total = 0 ;
2022-11-25 16:32:29 +08:00
for ( size_t i = 0 ; i < maat_rt - > max_table_num ; i + + ) {
2023-04-12 19:20:05 +08:00
long long rule_cnt = table_manager_runtime_rule_count ( maat_rt - > ref_tbl_mgr , i ) ;
total + = rule_cnt ;
if ( rule_cnt ! = 0 ) {
log_info ( maat_rt - > logger , MODULE_MAAT_RULE , " table:%d rule count:%lld " , i , rule_cnt ) ;
}
2022-11-25 16:32:29 +08:00
}
return total ;
}
2023-01-31 20:39:53 +08:00
void maat_plugin_table_all_callback_finish ( struct table_manager * tbl_mgr )
{
size_t table_cnt = table_manager_table_count ( tbl_mgr ) ;
2023-02-07 11:25:31 +08:00
enum table_type table_type = TABLE_TYPE_INVALID ;
2023-01-31 20:39:53 +08:00
for ( size_t i = 0 ; i < table_cnt ; i + + ) {
table_type = table_manager_get_table_type ( tbl_mgr , i ) ;
if ( table_type ! = TABLE_TYPE_PLUGIN ) {
continue ;
}
void * plugin_schema = table_manager_get_schema ( tbl_mgr , i ) ;
plugin_table_all_callback_finish ( ( struct plugin_schema * ) plugin_schema ) ;
}
}
2022-11-17 05:05:35 +08:00
void maat_finish_cb ( void * u_param )
{
struct maat * maat_instance = ( struct maat * ) u_param ;
2023-01-31 20:39:53 +08:00
maat_plugin_table_all_callback_finish ( maat_instance - > tbl_mgr ) ;
2022-11-25 16:32:29 +08:00
if ( maat_instance - > creating_maat_rt ! = NULL ) {
2023-04-13 14:56:35 +08:00
maat_runtime_commit ( maat_instance - > creating_maat_rt , MAAT_UPDATE_TYPE_FULL ,
maat_instance - > creating_maat_rt - > version , maat_instance - > logger ) ;
2023-04-12 19:20:05 +08:00
maat_instance - > creating_maat_rt - > rule_num = maat_runtime_rule_num ( maat_instance - > creating_maat_rt ) ;
2023-02-03 17:28:14 +08:00
log_info ( maat_instance - > logger , MODULE_MAAT_RULE ,
" Full config version %llu load %d entries complete " ,
maat_instance - > creating_maat_rt - > version ,
maat_instance - > creating_maat_rt - > rule_num ) ;
2022-11-25 16:32:29 +08:00
} else if ( maat_instance - > maat_rt ! = NULL ) {
maat_instance - > maat_rt - > version = maat_instance - > maat_version ;
2023-04-13 14:56:35 +08:00
maat_runtime_commit ( maat_instance - > maat_rt , MAAT_UPDATE_TYPE_INC ,
maat_instance - > maat_rt - > version , maat_instance - > logger ) ;
2023-04-12 19:20:05 +08:00
maat_instance - > maat_rt - > rule_num = maat_runtime_rule_num ( maat_instance - > maat_rt ) ;
2023-02-03 17:28:14 +08:00
log_info ( maat_instance - > logger , MODULE_MAAT_RULE ,
" Inc config version %llu load %d entries complete " ,
maat_instance - > maat_rt - > version ,
maat_instance - > maat_rt - > rule_num ) ;
2023-03-15 11:36:54 +08:00
} else {
log_info ( maat_instance - > logger , MODULE_MAAT_RULE ,
2023-04-13 14:56:35 +08:00
" Version %d has no valid rules, plugin callback complete. " ,
maat_instance - > maat_version ) ;
2022-11-17 05:05:35 +08:00
}
2023-03-15 11:36:54 +08:00
maat_instance - > new_version = INVALID_VERSION ;
2022-11-17 05:05:35 +08:00
}
void * rule_monitor_loop ( void * arg )
{
2022-11-25 16:32:29 +08:00
/* Defined by prctl: The name can be up to 16 bytes long, and should
be null terminated if it contains fewer bytes . */
char maat_name [ 16 ] = { 0 } ;
2022-11-17 05:05:35 +08:00
struct maat * maat_instance = ( struct maat * ) arg ;
2022-11-25 16:32:29 +08:00
if ( strlen ( maat_instance - > instance_name ) > 0 ) {
snprintf ( maat_name , sizeof ( maat_name ) , " MAAT_%s " , maat_instance - > instance_name ) ;
} else {
snprintf ( maat_name , sizeof ( maat_name ) , " MAAT " ) ;
}
int ret = prctl ( PR_SET_NAME , ( unsigned long long ) maat_name , NULL , NULL , NULL ) ;
assert ( ret > = 0 ) ;
pthread_mutex_lock ( & ( maat_instance - > background_update_mutex ) ) ;
/* if deferred load on */
if ( maat_instance - > deferred_load ! = 0 ) {
2023-02-03 17:28:14 +08:00
log_info ( maat_instance - > logger , MODULE_MAAT_RULE ,
2023-03-02 14:52:31 +08:00
" Deferred Loading ON, updating in %s:%d " , __FUNCTION__ , __LINE__ ) ;
2023-04-14 11:32:59 +08:00
maat_read_full_config ( maat_instance ) ;
2022-11-25 16:32:29 +08:00
}
pthread_mutex_unlock ( & ( maat_instance - > background_update_mutex ) ) ;
2022-12-03 22:23:41 +08:00
char md5_tmp [ MD5_DIGEST_LENGTH * 2 + 1 ] = { 0 } ;
char err_str [ NAME_MAX ] = { 0 } ;
struct stat attrib ;
2022-11-17 05:05:35 +08:00
while ( maat_instance - > is_running ) {
2023-03-02 14:52:31 +08:00
log_info ( maat_instance - > logger , MODULE_MAAT_RULE , " %s:%d............. " , __FUNCTION__ , __LINE__ ) ;
2022-11-25 16:32:29 +08:00
usleep ( maat_instance - > rule_update_checking_interval_ms * 1000 ) ;
2023-02-16 16:45:06 +08:00
if ( 0 = = pthread_mutex_trylock ( & ( maat_instance - > background_update_mutex ) ) ) {
2022-11-25 16:32:29 +08:00
switch ( maat_instance - > input_mode ) {
2022-12-03 22:23:41 +08:00
case DATA_SOURCE_REDIS :
redis_monitor_traverse ( maat_instance - > maat_version ,
& ( maat_instance - > mr_ctx ) ,
2022-12-09 17:12:18 +08:00
maat_start_cb , maat_update_cb , maat_finish_cb ,
2022-12-03 22:23:41 +08:00
maat_instance ) ;
break ;
2022-11-25 16:32:29 +08:00
case DATA_SOURCE_IRIS_FILE :
2022-11-17 05:05:35 +08:00
config_monitor_traverse ( maat_instance - > maat_version ,
2022-12-05 23:21:18 +08:00
maat_instance - > iris_ctx . inc_idx_dir ,
2022-12-09 17:12:18 +08:00
maat_start_cb , maat_update_cb , maat_finish_cb ,
maat_instance , maat_instance - > logger ) ;
2022-11-17 05:05:35 +08:00
break ;
2022-12-03 22:23:41 +08:00
case DATA_SOURCE_JSON_FILE :
memset ( md5_tmp , 0 , sizeof ( md5_tmp ) ) ;
stat ( maat_instance - > json_ctx . json_file , & attrib ) ;
if ( memcmp ( & attrib . st_ctim , & ( maat_instance - > json_ctx . last_md5_time ) , sizeof ( attrib . st_ctim ) ) ) {
maat_instance - > json_ctx . last_md5_time = attrib . st_ctim ;
md5_file ( maat_instance - > json_ctx . json_file , md5_tmp ) ;
if ( 0 ! = strcmp ( md5_tmp , maat_instance - > json_ctx . effective_json_md5 ) ) {
2022-12-09 17:12:18 +08:00
ret = load_maat_json_file ( maat_instance , maat_instance - > json_ctx . json_file ,
err_str , sizeof ( err_str ) ) ;
2022-12-03 22:23:41 +08:00
if ( ret < 0 ) {
2022-12-09 17:12:18 +08:00
log_error ( maat_instance - > logger , MODULE_MAAT_RULE ,
2023-03-02 14:52:31 +08:00
" [%s:%d] Maat re-initiate with JSON file %s (md5=%s)failed: %s \n " ,
__FUNCTION__ , __LINE__ , maat_instance - > json_ctx . json_file ,
md5_tmp , err_str ) ;
2022-12-03 22:23:41 +08:00
} else {
config_monitor_traverse ( 0 , maat_instance - > json_ctx . iris_file ,
2022-12-09 17:12:18 +08:00
maat_start_cb , maat_update_cb , maat_finish_cb ,
maat_instance , maat_instance - > logger ) ;
log_info ( maat_instance - > logger , MODULE_MAAT_RULE ,
" Maat re-initiate with JSON file %s success, md5: %s \n " ,
maat_instance - > json_ctx . json_file , md5_tmp ) ;
2022-12-03 22:23:41 +08:00
}
}
}
break ;
2022-11-17 05:05:35 +08:00
default :
break ;
}
2022-11-25 16:32:29 +08:00
if ( maat_instance - > creating_maat_rt ! = NULL ) {
2022-11-17 05:05:35 +08:00
struct maat_runtime * old_maat_rt = maat_instance - > maat_rt ;
2022-11-25 16:32:29 +08:00
maat_instance - > maat_rt = maat_instance - > creating_maat_rt ;
2022-11-17 05:05:35 +08:00
if ( old_maat_rt ! = NULL ) {
2022-11-29 14:12:40 +08:00
if ( maat_instance - > maat_rt - > version > old_maat_rt - > version ) {
2023-02-03 17:28:14 +08:00
log_info ( maat_instance - > logger , MODULE_MAAT_RULE ,
" Maat version updated %lld -> %lld \n " ,
2022-12-09 17:12:18 +08:00
old_maat_rt - > version , maat_instance - > maat_rt - > version ) ;
2022-11-29 14:12:40 +08:00
} else {
2023-02-03 17:28:14 +08:00
log_info ( maat_instance - > logger , MODULE_MAAT_RULE ,
" Maat version roll back %lld -> %lld \n " ,
2022-12-09 17:12:18 +08:00
old_maat_rt - > version , maat_instance - > maat_rt - > version ) ;
2022-11-29 14:12:40 +08:00
}
2023-03-29 22:25:14 +08:00
maat_garbage_bagging ( maat_instance - > garbage_bin , old_maat_rt , NULL ,
garbage_maat_runtime_destroy ) ;
2022-11-17 05:05:35 +08:00
}
2022-11-25 16:32:29 +08:00
maat_instance - > creating_maat_rt = NULL ;
2022-11-17 05:05:35 +08:00
maat_instance - > maat_version = maat_instance - > maat_rt - > version ;
maat_instance - > last_full_version = maat_instance - > maat_rt - > version ;
}
if ( maat_instance - > maat_rt ! = NULL ) {
2022-11-25 16:32:29 +08:00
time_t time_window = time ( NULL ) - maat_instance - > maat_rt - > last_update_time ;
2023-02-03 17:28:14 +08:00
if ( time_window > = maat_instance - > rule_effect_interval_ms / 1000 ) {
2023-04-13 14:56:35 +08:00
maat_runtime_commit ( maat_instance - > maat_rt , MAAT_UPDATE_TYPE_INC ,
maat_instance - > maat_rt - > version , maat_instance - > logger ) ;
2023-02-03 17:28:14 +08:00
log_info ( maat_instance - > logger , MODULE_MAAT_RULE ,
2023-02-23 14:50:07 +08:00
" Actual update config version %u, %d entries load to maat runtime. " ,
2022-12-12 00:10:30 +08:00
maat_instance - > maat_rt - > version , maat_instance - > maat_rt - > rule_num ) ;
2022-11-25 16:32:29 +08:00
}
2022-11-17 05:05:35 +08:00
}
pthread_mutex_unlock ( & ( maat_instance - > background_update_mutex ) ) ;
}
2022-11-25 16:32:29 +08:00
maat_garbage_collect_routine ( maat_instance - > garbage_bin ) ;
2023-04-20 15:34:56 +08:00
if ( ( 1 = = maat_instance - > stat_on ) & & ( time ( NULL ) % 2 = = 0 ) ) {
maat_stat_output ( maat_instance - > stat , maat_instance - > maat_version , maat_instance - > perf_on ) ;
}
2022-11-17 05:05:35 +08:00
}
2022-11-25 16:32:29 +08:00
maat_runtime_destroy ( maat_instance - > maat_rt ) ;
2023-04-03 19:01:26 +08:00
maat_garbage_bin_free ( maat_instance - > garbage_bin ) ;
2023-04-04 15:59:34 +08:00
table_manager_destroy ( maat_instance - > tbl_mgr ) ; //table manager MUST be freed at last.
2022-12-03 22:23:41 +08:00
2023-04-20 15:34:56 +08:00
if ( maat_instance - > stat ! = NULL ) {
maat_stat_free ( maat_instance - > stat ) ;
maat_instance - > stat = NULL ;
}
2023-02-03 17:28:14 +08:00
2022-12-03 22:23:41 +08:00
if ( maat_instance - > input_mode = = DATA_SOURCE_REDIS ) {
if ( maat_instance - > mr_ctx . read_ctx ! = NULL ) {
redisFree ( maat_instance - > mr_ctx . read_ctx ) ;
maat_instance - > mr_ctx . read_ctx = NULL ;
}
if ( maat_instance - > mr_ctx . write_ctx ! = NULL ) {
redisFree ( maat_instance - > mr_ctx . write_ctx ) ;
maat_instance - > mr_ctx . write_ctx = NULL ;
}
}
2023-03-15 11:36:54 +08:00
log_handle_destroy ( maat_instance - > logger ) ;
2022-12-03 22:23:41 +08:00
FREE ( maat_instance ) ;
2022-11-25 16:32:29 +08:00
return NULL ;
2023-03-15 11:36:54 +08:00
}