unfinished work
This commit is contained in:
@@ -8,9 +8,11 @@ set(MAAT_FRAME_VERSION ${MAAT_FRAME_MAJOR_VERSION}.${MAAT_FRAME_MINOR_VERSION}.$
|
||||
message(STATUS "Maat Frame, Version: ${MAAT_FRAME_VERSION}")
|
||||
|
||||
add_definitions(-fPIC)
|
||||
set(MAAT_SRC maat_api.cpp)
|
||||
set(MAAT_SRC maat_api.cpp bool_matcher.cpp adapter_hs.cpp rcu_hash.cpp maat_garbage_collection.cpp)
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include/)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/deps/)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/src/inc_internal)
|
||||
|
||||
# Static Library Output
|
||||
add_library(maat_frame_static STATIC ${MAAT_SRC})
|
||||
|
||||
534
src/adapter_hs.cpp
Normal file
534
src/adapter_hs.cpp
Normal file
@@ -0,0 +1,534 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: adapter_hs.cpp
|
||||
* Description:
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <hs/hs.h>
|
||||
|
||||
#include "sds/sds.h"
|
||||
#include "adapter_hs.h"
|
||||
#include "uthash/utarray.h"
|
||||
#include "uthash/uthash.h"
|
||||
#include "maat_utils.h"
|
||||
#include "bool_matcher.h"
|
||||
|
||||
struct adpt_hs_compile_data {
|
||||
unsigned int *ids;
|
||||
unsigned int *flags;
|
||||
char **patterns;
|
||||
size_t *pattern_lens;
|
||||
unsigned int n_patterns;
|
||||
};
|
||||
|
||||
/* adapter_hs runtime */
|
||||
struct adapter_hs_runtime {
|
||||
hs_database_t *literal_db;
|
||||
hs_database_t *regex_db;
|
||||
|
||||
hs_scratch_t **scratchs;
|
||||
size_t scratch_size;
|
||||
|
||||
struct bool_matcher *bm;
|
||||
};
|
||||
|
||||
/* adapter_hs instance */
|
||||
struct adapter_hs {
|
||||
size_t nr_worker_threads;
|
||||
size_t n_expr;
|
||||
size_t n_patterns;
|
||||
struct adapter_hs_runtime *hs_rt;
|
||||
};
|
||||
|
||||
struct adapter_hs_stream {
|
||||
int thread_id;
|
||||
size_t n_expr;
|
||||
size_t n_patterns;
|
||||
hs_stream_t *literal_stream;
|
||||
hs_stream_t *regex_stream;
|
||||
struct adapter_hs_runtime *hs_rt;
|
||||
UT_array *pattern_id_set;
|
||||
};
|
||||
|
||||
int adpt_hs_alloc_scratch(struct adapter_hs_runtime *hs_rt, size_t nr_worker_threads, int max_pattern_type)
|
||||
{
|
||||
hs_database_t *database = NULL;
|
||||
hs_rt->scratchs = ALLOC(hs_scratch_t *, nr_worker_threads);
|
||||
|
||||
if (max_pattern_type == PATTERN_TYPE_STR) {
|
||||
database = hs_rt->literal_db;
|
||||
} else {
|
||||
database = hs_rt->regex_db;
|
||||
}
|
||||
|
||||
if (hs_alloc_scratch(database, &hs_rt->scratchs[0]) != HS_SUCCESS) {
|
||||
// log_error("ERROR: Unable to allocate scratch space. Exiting.\n");
|
||||
hs_free_database(database);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < nr_worker_threads; i++) {
|
||||
hs_error_t err = hs_clone_scratch(hs_rt->scratchs[0], &hs_rt->scratchs[i]);
|
||||
if (err != HS_SUCCESS) {
|
||||
// log_error("Unable to clone scratch prototype");
|
||||
hs_free_database(database);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = hs_scratch_size(hs_rt->scratchs[i], &hs_rt->scratch_size);
|
||||
if (err != HS_SUCCESS) {
|
||||
// log_error("Unable to query scratch size");
|
||||
hs_free_database(database);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief build hs block database for literal string and regex expression respectively
|
||||
*
|
||||
* @retval 0(success) -1(failed)
|
||||
*/
|
||||
int adpt_hs_build_database(struct adapter_hs_runtime *hs_rt,
|
||||
struct adpt_hs_compile_data *literal_cd,
|
||||
struct adpt_hs_compile_data *regex_cd,
|
||||
int scan_mode)
|
||||
{
|
||||
hs_error_t err;
|
||||
hs_compile_error_t *compile_err = NULL;
|
||||
|
||||
if (NULL == hs_rt) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (literal_cd != NULL) {
|
||||
err = hs_compile_lit_multi((const char *const *)literal_cd->patterns, literal_cd->flags,
|
||||
literal_cd->ids, literal_cd->pattern_lens, literal_cd->n_patterns,
|
||||
scan_mode, NULL, &hs_rt->literal_db, &compile_err);
|
||||
if (err != HS_SUCCESS) {
|
||||
// log_error
|
||||
if (compile_err) {
|
||||
printf("compile error: %s", compile_err->message);
|
||||
}
|
||||
|
||||
hs_free_compile_error(compile_err);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (regex_cd != NULL) {
|
||||
err = hs_compile_ext_multi((const char *const *)regex_cd->patterns, regex_cd->flags,
|
||||
regex_cd->ids, NULL, regex_cd->n_patterns,
|
||||
scan_mode, NULL, &hs_rt->regex_db, &compile_err);
|
||||
if (err != HS_SUCCESS) {
|
||||
// log_error
|
||||
if (compile_err) {
|
||||
printf("compile error: %s", compile_err->message);
|
||||
}
|
||||
hs_free_compile_error(compile_err);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
if (hs_rt->literal_db != NULL) {
|
||||
hs_free_database(hs_rt->literal_db);
|
||||
hs_rt->literal_db = NULL;
|
||||
}
|
||||
|
||||
if (hs_rt->regex_db != NULL) {
|
||||
hs_free_database(hs_rt->regex_db);
|
||||
hs_rt->regex_db = NULL;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct adpt_hs_compile_data *adpt_hs_compile_data_new(size_t n_patterns)
|
||||
{
|
||||
struct adpt_hs_compile_data *hs_cd = ALLOC(struct adpt_hs_compile_data, 1);
|
||||
hs_cd->patterns = ALLOC(char *, n_patterns);
|
||||
hs_cd->pattern_lens = ALLOC(size_t, n_patterns);
|
||||
hs_cd->ids = ALLOC(unsigned int, n_patterns);
|
||||
hs_cd->flags = ALLOC(unsigned int, n_patterns);
|
||||
|
||||
return hs_cd;
|
||||
}
|
||||
|
||||
void adpt_hs_compile_data_free(struct adpt_hs_compile_data *hs_cd, size_t n_patterns)
|
||||
{
|
||||
if (NULL == hs_cd) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hs_cd->patterns != NULL) {
|
||||
for (size_t i = 0; i < n_patterns; i++) {
|
||||
free(hs_cd->patterns[i]);
|
||||
}
|
||||
|
||||
free(hs_cd->patterns);
|
||||
free(hs_cd->pattern_lens);
|
||||
free(hs_cd->ids);
|
||||
free(hs_cd->flags);
|
||||
}
|
||||
|
||||
free(hs_cd);
|
||||
}
|
||||
|
||||
struct adapter_hs *adapter_hs_initialize(int scan_mode, size_t nr_worker_threads, and_expr_t *expr_array, size_t n_expr_array)
|
||||
{
|
||||
if ((scan_mode != SCAN_MODE_BLOCK && scan_mode != SCAN_MODE_STREAM) ||
|
||||
0 == nr_worker_threads || NULL == expr_array || 0 == n_expr_array) {
|
||||
/* log_error("input parameters illegal!"); */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get the sum of pattern */
|
||||
size_t literal_pattern_num = 0;
|
||||
size_t regex_pattern_num = 0;
|
||||
|
||||
for (size_t i = 0; i < n_expr_array; i++) {
|
||||
if (expr_array[i].n_patterns > MAX_EXPR_PATTERN_NUM) {
|
||||
//log_error("the number of patterns in one expression should less than %d\n", MAX_EXPR_PATTERN_NUM);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < expr_array[i].n_patterns; j++) {
|
||||
if (expr_array[i].patterns[j].type == PATTERN_TYPE_STR) {
|
||||
literal_pattern_num++;
|
||||
} else if (expr_array[i].patterns[j].type == PATTERN_TYPE_REG) {
|
||||
regex_pattern_num++;
|
||||
} else {
|
||||
/* log_error("unknown pattern type: %d\n", expr_array[i].patterns[j].type); */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct adpt_hs_compile_data *literal_cd = NULL;
|
||||
struct adpt_hs_compile_data *regex_cd = NULL;
|
||||
if (literal_pattern_num > 0) {
|
||||
literal_cd = adpt_hs_compile_data_new(literal_pattern_num);
|
||||
}
|
||||
|
||||
if (regex_pattern_num > 0) {
|
||||
regex_cd = adpt_hs_compile_data_new(regex_pattern_num);
|
||||
}
|
||||
|
||||
uint32_t literal_index = 0;
|
||||
uint32_t regex_index = 0;
|
||||
uint32_t pattern_id = 0;
|
||||
|
||||
/* alloc exprs for bool matcher*/
|
||||
struct bool_expr *exprs = ALLOC(struct bool_expr, n_expr_array);
|
||||
|
||||
/* populate adpt_hs_compile_data and bool_expr */
|
||||
for (size_t i = 0; i < n_expr_array; i++) {
|
||||
for (size_t j = 0; j < expr_array[i].n_patterns; j++) {
|
||||
size_t pat_len = 0;
|
||||
|
||||
if (expr_array[i].patterns[j].type == PATTERN_TYPE_STR) {
|
||||
literal_cd->ids[literal_index] = pattern_id;
|
||||
literal_cd->flags[literal_index] = HS_FLAG_CASELESS;
|
||||
|
||||
pat_len = expr_array[i].patterns[j].pat_len;
|
||||
literal_cd->pattern_lens[literal_index] = pat_len;
|
||||
literal_cd->patterns[literal_index] = ALLOC(char, pat_len);
|
||||
memcpy(literal_cd->patterns[literal_index],
|
||||
expr_array[i].patterns[j].pat,
|
||||
expr_array[i].patterns[j].pat_len);
|
||||
literal_index++;
|
||||
} else {
|
||||
regex_cd->ids[regex_index] = pattern_id;
|
||||
regex_cd->flags[regex_index] = HS_FLAG_CASELESS;
|
||||
|
||||
pat_len = expr_array[i].patterns[j].pat_len;
|
||||
regex_cd->pattern_lens[regex_index] = pat_len;
|
||||
regex_cd->patterns[regex_index] = ALLOC(char, pat_len);
|
||||
memcpy(regex_cd->patterns[regex_index],
|
||||
expr_array[i].patterns[j].pat,
|
||||
expr_array[i].patterns[j].pat_len);
|
||||
regex_index++;
|
||||
}
|
||||
exprs[i].items[j].item_id = pattern_id;
|
||||
pattern_id++;
|
||||
}
|
||||
exprs[i].expr_id = expr_array[i].expr_id;
|
||||
exprs[i].item_num = expr_array[i].n_patterns;
|
||||
}
|
||||
|
||||
if (literal_cd != NULL) {
|
||||
literal_cd->n_patterns = literal_index;
|
||||
}
|
||||
|
||||
if (regex_cd != NULL) {
|
||||
regex_cd->n_patterns = regex_index;
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
int max_patterns_type = 0;
|
||||
size_t mem_size = 0;
|
||||
struct adapter_hs *hs_instance = ALLOC(struct adapter_hs, 1);
|
||||
|
||||
hs_instance->nr_worker_threads = nr_worker_threads;
|
||||
hs_instance->n_patterns = pattern_id;
|
||||
hs_instance->n_expr = n_expr_array;
|
||||
hs_instance->hs_rt = ALLOC(struct adapter_hs_runtime, 1);
|
||||
|
||||
/* create bool matcher */
|
||||
hs_instance->hs_rt->bm = bool_matcher_new(exprs, n_expr_array, &mem_size);
|
||||
if (hs_instance->hs_rt->bm != NULL) {
|
||||
/* log_info("Adapter_hs module: build bool matcher of %u expressions with %u bytes memory.",
|
||||
n_expr_array, mem_size); */
|
||||
} else {
|
||||
/* log_error("Adapter_hs module: build bool matcher failed."); */
|
||||
goto error;
|
||||
}
|
||||
free(exprs);
|
||||
|
||||
/* build hs database */
|
||||
ret = adpt_hs_build_database(hs_instance->hs_rt, literal_cd, regex_cd, scan_mode);
|
||||
if (ret < 0) {
|
||||
//log_error()
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (literal_cd != NULL) {
|
||||
adpt_hs_compile_data_free(literal_cd, literal_index);
|
||||
}
|
||||
|
||||
if (regex_cd != NULL) {
|
||||
adpt_hs_compile_data_free(regex_cd, regex_index);
|
||||
}
|
||||
|
||||
/* which pattern type has more patterns, use it as hs_alloc_scratch's input parameter */
|
||||
if (literal_pattern_num > regex_pattern_num) {
|
||||
max_patterns_type = PATTERN_TYPE_STR;
|
||||
} else {
|
||||
max_patterns_type = PATTERN_TYPE_REG;
|
||||
}
|
||||
|
||||
ret = adpt_hs_alloc_scratch(hs_instance->hs_rt, nr_worker_threads, max_patterns_type);
|
||||
if (ret < 0) {
|
||||
// log_error
|
||||
goto error;
|
||||
}
|
||||
|
||||
return hs_instance;
|
||||
error:
|
||||
adapter_hs_destroy(hs_instance);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void adapter_hs_destroy(struct adapter_hs *hs_instance)
|
||||
{
|
||||
if (NULL == hs_instance) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hs_instance->hs_rt != NULL) {
|
||||
if (hs_instance->hs_rt->literal_db != NULL) {
|
||||
hs_free_database(hs_instance->hs_rt->literal_db);
|
||||
}
|
||||
|
||||
if (hs_instance->hs_rt->regex_db != NULL) {
|
||||
hs_free_database(hs_instance->hs_rt->regex_db);
|
||||
}
|
||||
|
||||
if (hs_instance->hs_rt->scratchs != NULL) {
|
||||
for (size_t i = 0; i < hs_instance->nr_worker_threads; i++) {
|
||||
if (hs_instance->hs_rt->scratchs[i] != NULL) {
|
||||
hs_free_scratch(hs_instance->hs_rt->scratchs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(hs_instance->hs_rt->scratchs);
|
||||
|
||||
if (hs_instance->hs_rt->bm != NULL) {
|
||||
bool_matcher_free(hs_instance->hs_rt->bm);
|
||||
}
|
||||
|
||||
free(hs_instance->hs_rt);
|
||||
}
|
||||
|
||||
free(hs_instance);
|
||||
}
|
||||
|
||||
static inline int compare_pattern_id(const void* a, const void* b)
|
||||
{
|
||||
long long ret= *(unsigned long long *)a - *(unsigned long long *)b;
|
||||
|
||||
if (0 == ret) {
|
||||
return 0;
|
||||
} else if (ret < 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
UT_icd ut_pattern_id_icd = {sizeof(unsigned long long), NULL, NULL, NULL};
|
||||
|
||||
/**
|
||||
* @param id: pattern id
|
||||
*/
|
||||
int matched_event_cb(unsigned int id, unsigned long long from,
|
||||
unsigned long long to, unsigned int flags, void *ctx) {
|
||||
// put id in set
|
||||
UT_array *pattern_id_set = (UT_array *)ctx;
|
||||
unsigned long long pattern_id = (unsigned long long)id;
|
||||
if (utarray_find(pattern_id_set, &pattern_id, compare_pattern_id)) {
|
||||
return -1;
|
||||
}
|
||||
utarray_push_back(pattern_id_set, &pattern_id);
|
||||
utarray_sort(pattern_id_set, compare_pattern_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int adapter_hs_scan(struct adapter_hs *hs_instance, int thread_id, const char *data, size_t data_len,
|
||||
int results[], size_t *n_results)
|
||||
{
|
||||
struct adapter_hs_runtime *hs_rt = hs_instance->hs_rt;
|
||||
hs_scratch_t *scratch = hs_rt->scratchs[thread_id];
|
||||
UT_array *pattern_id_set;
|
||||
hs_error_t err;
|
||||
|
||||
utarray_new(pattern_id_set, &ut_pattern_id_icd);
|
||||
utarray_reserve(pattern_id_set, hs_instance->n_patterns);
|
||||
|
||||
if (hs_rt->literal_db != NULL) {
|
||||
err = hs_scan(hs_rt->literal_db, data, data_len, 0, scratch, matched_event_cb, pattern_id_set);
|
||||
if (err != HS_SUCCESS) {
|
||||
//log_error()
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (hs_rt->regex_db != NULL) {
|
||||
err = hs_scan(hs_rt->regex_db, data, data_len, 0, scratch, matched_event_cb, pattern_id_set);
|
||||
if (err != HS_SUCCESS) {
|
||||
//log_error()
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t pattern_set_size = utarray_len(pattern_id_set);
|
||||
unsigned long long items[pattern_set_size];
|
||||
memset(items, 0, sizeof(unsigned long long) * pattern_set_size);
|
||||
for (size_t i = 0; i < pattern_set_size; i++) {
|
||||
items[i] = *(unsigned long long *)utarray_eltptr(pattern_id_set, i);
|
||||
}
|
||||
|
||||
size_t matched_index = 0;
|
||||
struct bool_expr_match *bool_matcher_results = ALLOC(struct bool_expr_match, hs_instance->n_expr);
|
||||
size_t bool_matcher_ret = bool_matcher_match(hs_rt->bm, items, pattern_set_size, bool_matcher_results, hs_instance->n_expr);
|
||||
for (matched_index = 0; matched_index < bool_matcher_ret; matched_index++) {
|
||||
results[matched_index] = bool_matcher_results[matched_index].expr_id;
|
||||
}
|
||||
*n_results = bool_matcher_ret;
|
||||
|
||||
free(bool_matcher_results);
|
||||
utarray_free(pattern_id_set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct adapter_hs_stream *adapter_hs_stream_open(struct adapter_hs *hs_instance, int thread_id)
|
||||
{
|
||||
struct adapter_hs_stream *hs_stream = ALLOC(struct adapter_hs_stream, 1);
|
||||
hs_error_t err;
|
||||
|
||||
hs_stream->thread_id = thread_id;
|
||||
hs_stream->n_expr = hs_instance->n_expr;
|
||||
hs_stream->n_patterns = hs_instance->n_patterns;
|
||||
hs_stream->hs_rt = hs_instance->hs_rt;
|
||||
utarray_new(hs_stream->pattern_id_set, &ut_pattern_id_icd);
|
||||
utarray_reserve(hs_stream->pattern_id_set, hs_stream->n_patterns);
|
||||
|
||||
if (hs_instance->hs_rt->literal_db != NULL) {
|
||||
err = hs_open_stream(hs_instance->hs_rt->literal_db, 0, &hs_stream->literal_stream);
|
||||
if (err != HS_SUCCESS) {
|
||||
// log_error
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (hs_instance->hs_rt->regex_db != NULL) {
|
||||
err = hs_open_stream(hs_instance->hs_rt->regex_db, 0, &hs_stream->regex_stream);
|
||||
if (err != HS_SUCCESS) {
|
||||
// log_error
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return hs_stream;
|
||||
}
|
||||
|
||||
int adapter_hs_scan_stream(struct adapter_hs_stream *hs_stream, const char *data, size_t data_len,
|
||||
int results[], size_t *n_results)
|
||||
{
|
||||
hs_error_t err;
|
||||
|
||||
int thread_id = hs_stream->thread_id;
|
||||
if (hs_stream->literal_stream != NULL) {
|
||||
err = hs_scan_stream(hs_stream->literal_stream, data, data_len, 0, hs_stream->hs_rt->scratchs[thread_id],
|
||||
matched_event_cb, hs_stream->pattern_id_set);
|
||||
if (err != HS_SUCCESS) {
|
||||
//log_error()
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (hs_stream->regex_stream != NULL) {
|
||||
err = hs_scan_stream(hs_stream->regex_stream, data, data_len, 0, hs_stream->hs_rt->scratchs[thread_id],
|
||||
matched_event_cb, hs_stream->pattern_id_set);
|
||||
if (err != HS_SUCCESS) {
|
||||
//log_error()
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t pattern_set_size = utarray_len(hs_stream->pattern_id_set);
|
||||
unsigned long long items[pattern_set_size];
|
||||
memset(items, 0, sizeof(unsigned long long) * pattern_set_size);
|
||||
for (size_t i = 0; i < pattern_set_size; i++) {
|
||||
items[i] = *(unsigned long long *)utarray_eltptr(hs_stream->pattern_id_set, i);
|
||||
}
|
||||
|
||||
size_t matched_index = 0;
|
||||
struct bool_expr_match *bool_matcher_results = ALLOC(struct bool_expr_match, hs_stream->n_expr);
|
||||
size_t bool_matcher_ret = bool_matcher_match(hs_stream->hs_rt->bm, items, pattern_set_size, bool_matcher_results, hs_stream->n_expr);
|
||||
for (matched_index = 0; matched_index < bool_matcher_ret; matched_index++) {
|
||||
results[matched_index] = bool_matcher_results[matched_index].expr_id;
|
||||
}
|
||||
*n_results = bool_matcher_ret;
|
||||
|
||||
free(bool_matcher_results);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void adapter_hs_stream_close(struct adapter_hs_stream *hs_stream)
|
||||
{
|
||||
int thread_id = hs_stream->thread_id;
|
||||
|
||||
hs_close_stream(hs_stream->literal_stream, hs_stream->hs_rt->scratchs[thread_id], NULL, NULL);
|
||||
hs_close_stream(hs_stream->regex_stream, hs_stream->hs_rt->scratchs[thread_id], NULL, NULL);
|
||||
utarray_free(hs_stream->pattern_id_set);
|
||||
|
||||
/* hs_stream->hs_rt point to hs_instance->hs_rt which will call free */
|
||||
hs_stream->hs_rt = NULL;
|
||||
free(hs_stream);
|
||||
}
|
||||
216
src/bool_matcher.cpp
Normal file
216
src/bool_matcher.cpp
Normal file
@@ -0,0 +1,216 @@
|
||||
#include "bool_matcher.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
struct bool_expr_item
|
||||
{
|
||||
size_t item_num;
|
||||
struct bool_item * items;
|
||||
};
|
||||
|
||||
struct bool_matcher
|
||||
{
|
||||
unsigned int bool_expr_num;
|
||||
struct bool_expr_match * bool_expr_ids;
|
||||
struct bool_expr_item * bool_expr_items;
|
||||
unsigned int bool_item_num;
|
||||
unsigned long long * bool_items;
|
||||
unsigned int * mapped_ptr;
|
||||
unsigned int * mapped_ids;
|
||||
unsigned int bitmap_size;
|
||||
unsigned char * bitmap;
|
||||
};
|
||||
|
||||
bool operator<(const struct bool_item & lhs, const struct bool_item & rhs)
|
||||
{
|
||||
return lhs.item_id<rhs.item_id;
|
||||
}
|
||||
|
||||
struct bool_matcher * bool_matcher_new(struct bool_expr * exprs, size_t expr_num, size_t * mem_size)
|
||||
{
|
||||
if(exprs==NULL || expr_num==0) return NULL;
|
||||
|
||||
unsigned int mem_bytes=0;
|
||||
|
||||
struct bool_matcher * matcher=new struct bool_matcher;
|
||||
mem_bytes+=sizeof(bool_matcher);
|
||||
|
||||
matcher->bool_expr_num=(unsigned int)expr_num;
|
||||
matcher->bool_expr_ids =new struct bool_expr_match[expr_num];
|
||||
matcher->bool_expr_items=new struct bool_expr_item[expr_num];
|
||||
mem_bytes+=(unsigned int)expr_num*(sizeof(struct bool_expr_match)+sizeof(struct bool_expr_item));
|
||||
for(unsigned int i=0; i<expr_num; i++)
|
||||
{
|
||||
matcher->bool_expr_ids[i].expr_id =exprs[i].expr_id;
|
||||
matcher->bool_expr_ids[i].user_tag =exprs[i].user_tag;
|
||||
matcher->bool_expr_items[i].item_num=exprs[i].item_num;
|
||||
matcher->bool_expr_items[i].items=new struct bool_item[exprs[i].item_num];
|
||||
mem_bytes+=(unsigned int)exprs[i].item_num*sizeof(struct bool_item);
|
||||
copy(exprs[i].items, exprs[i].items+exprs[i].item_num, matcher->bool_expr_items[i].items);
|
||||
sort(matcher->bool_expr_items[i].items, matcher->bool_expr_items[i].items+exprs[i].item_num);
|
||||
}
|
||||
|
||||
map<unsigned long long, unsigned int> M1;
|
||||
for(unsigned int i=0; i<expr_num; i++)
|
||||
{
|
||||
for(unsigned int j=0; j<exprs[i].item_num; j++)
|
||||
{
|
||||
if(exprs[i].items[j].not_flag==0) M1[exprs[i].items[j].item_id]++;
|
||||
}
|
||||
}
|
||||
|
||||
map< unsigned long long, vector<unsigned int> > M2;
|
||||
for(unsigned int i=0; i<expr_num; i++)
|
||||
{
|
||||
unsigned int min_count=-1;
|
||||
unsigned long long item_id;
|
||||
for(unsigned int j=0; j<exprs[i].item_num; j++)
|
||||
{
|
||||
if(exprs[i].items[j].not_flag==0)
|
||||
{
|
||||
unsigned int c=M1[exprs[i].items[j].item_id];
|
||||
if(c<min_count)
|
||||
{
|
||||
min_count=c;
|
||||
item_id=exprs[i].items[j].item_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
M2[item_id].push_back(i);
|
||||
}
|
||||
|
||||
matcher->bool_item_num=(unsigned int)M2.size();
|
||||
matcher->bool_items =new unsigned long long[M2.size()];
|
||||
matcher->mapped_ptr =new unsigned int[M2.size()+1];
|
||||
matcher->mapped_ids =new unsigned int[matcher->bool_expr_num];
|
||||
mem_bytes+=((unsigned int)M2.size()+1+matcher->bool_expr_num)*sizeof(unsigned int)+(unsigned int)M2.size()*sizeof(unsigned long long);
|
||||
|
||||
matcher->mapped_ptr[0]=0;
|
||||
map< unsigned long long, vector<unsigned int> >::const_iterator it=M2.begin();
|
||||
for(unsigned int k=0; k<M2.size(); ++k, ++it)
|
||||
{
|
||||
matcher->bool_items[k]=it->first;
|
||||
copy(it->second.begin(), it->second.end(), matcher->mapped_ids+matcher->mapped_ptr[k]);
|
||||
matcher->mapped_ptr[k+1]=matcher->mapped_ptr[k]+(unsigned int)it->second.size();
|
||||
}
|
||||
|
||||
M1.clear();
|
||||
M2.clear();
|
||||
|
||||
matcher->bitmap_size=(1U<<27);
|
||||
matcher->bitmap=new unsigned char[(matcher->bitmap_size)>>3];
|
||||
mem_bytes+=(matcher->bitmap_size)>>3;
|
||||
memset(matcher->bitmap, 0, (matcher->bitmap_size)>>3);
|
||||
|
||||
for(unsigned int i=0; i<matcher->bool_item_num; i++)
|
||||
{
|
||||
unsigned int j=matcher->bool_items[i]&(matcher->bitmap_size-1);
|
||||
matcher->bitmap[j>>3]|=(1U<<(j&7));
|
||||
}
|
||||
|
||||
if(mem_size!=NULL) *mem_size=mem_bytes;
|
||||
return matcher;
|
||||
}
|
||||
|
||||
int res_comp(const void * lhs, const void * rhs)
|
||||
{
|
||||
bool_expr_match * _lhs=(bool_expr_match *)lhs;
|
||||
bool_expr_match * _rhs=(bool_expr_match *)rhs;
|
||||
return (_lhs->expr_id<_rhs->expr_id) ? 1 : -1;
|
||||
}
|
||||
|
||||
int do_match(struct bool_expr_item * expr, unsigned long long * item_ids, size_t item_num)
|
||||
{
|
||||
unsigned int i=0;
|
||||
for(unsigned int j=0; j<expr->item_num; ++j)
|
||||
{
|
||||
if(expr->items[j].not_flag==0)
|
||||
{
|
||||
while(i<item_num && item_ids[i]<expr->items[j].item_id) ++i;
|
||||
if(i==item_num || item_ids[i]>expr->items[j].item_id) return 0;
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(i<item_num && item_ids[i]<expr->items[j].item_id) ++i;
|
||||
if(i<item_num && item_ids[i]==expr->items[j].item_id) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bool_matcher_match(struct bool_matcher * matcher, unsigned long long * item_ids, size_t item_num, struct bool_expr_match * results, size_t n_result)
|
||||
{
|
||||
if(matcher==NULL) return -1;
|
||||
if(item_num==0) return 0;
|
||||
|
||||
// sort(item_ids, item_ids+item_num);
|
||||
// size_t J=0;
|
||||
// for(unsigned int i=1; i<item_num; i++)
|
||||
// {
|
||||
// if(item_ids[i]!=item_ids[J]) item_ids[++J]=item_ids[i];
|
||||
// }
|
||||
// item_num=J+1;
|
||||
|
||||
unsigned int r=0;
|
||||
|
||||
for(unsigned int i=0; i<item_num; i++)
|
||||
{
|
||||
unsigned int t=item_ids[i]&(matcher->bitmap_size-1);
|
||||
if((matcher->bitmap[t>>3]&(1U<<(t&7)))==0) continue;
|
||||
|
||||
int l=0, h=(int)matcher->bool_item_num-1;
|
||||
while(l<=h)
|
||||
{
|
||||
int m=(l+h)/2;
|
||||
if(item_ids[i]==matcher->bool_items[m])
|
||||
{
|
||||
for(unsigned int j=matcher->mapped_ptr[m]; j<matcher->mapped_ptr[m+1]; j++)
|
||||
{
|
||||
unsigned int idx=matcher->mapped_ids[j];
|
||||
int ret=do_match(matcher->bool_expr_items+idx, item_ids, item_num);
|
||||
if(ret==1)
|
||||
{
|
||||
if(r==n_result) goto END;
|
||||
results[r++]=matcher->bool_expr_ids[idx];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if(item_ids[i]<matcher->bool_items[m])
|
||||
{
|
||||
h=m-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
l=m+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
END:
|
||||
qsort(results, r, sizeof(bool_expr_match), res_comp);
|
||||
return r;
|
||||
}
|
||||
|
||||
void bool_matcher_free(struct bool_matcher * matcher)
|
||||
{
|
||||
if(matcher==NULL) return;
|
||||
|
||||
delete [] matcher->bool_expr_ids;
|
||||
for(unsigned int i=0; i<matcher->bool_expr_num; i++) delete [] matcher->bool_expr_items[i].items;
|
||||
delete [] matcher->bool_expr_items;
|
||||
|
||||
delete [] matcher->bool_items;
|
||||
delete [] matcher->mapped_ptr;
|
||||
delete [] matcher->mapped_ids;
|
||||
delete [] matcher->bitmap;
|
||||
delete matcher;
|
||||
return;
|
||||
}
|
||||
2932
src/cJSON.c
Normal file
2932
src/cJSON.c
Normal file
File diff suppressed because it is too large
Load Diff
103
src/inc_internal/adapter_hs.h
Normal file
103
src/inc_internal/adapter_hs.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: adapter_hs.h
|
||||
* Description: wrapper for raw hyperscan
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _ADAPTER_HS_H_
|
||||
#define _ADAPTER_HS_H_
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_EXPR_PATTERN_NUM 8
|
||||
|
||||
struct adapter_hs;
|
||||
|
||||
/* scan mode */
|
||||
enum {
|
||||
SCAN_MODE_BLOCK = 1,
|
||||
SCAN_MODE_STREAM,
|
||||
};
|
||||
|
||||
/* pattern type: PATTERN_TYPE_STR(pure literal string) or PATTERN_TYPE_REG(regex expression) */
|
||||
enum {
|
||||
PATTERN_TYPE_STR = 1,
|
||||
PATTERN_TYPE_REG,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/* pattern type */
|
||||
int type;
|
||||
|
||||
/* start pointer of pattern */
|
||||
char *pat;
|
||||
/* pattern length */
|
||||
size_t pat_len;
|
||||
} scan_pattern_t;
|
||||
|
||||
/* logic AND expression, such as (pattern1 & pattern2) */
|
||||
typedef struct {
|
||||
uint32_t expr_id;
|
||||
size_t n_patterns;
|
||||
scan_pattern_t patterns[MAX_EXPR_PATTERN_NUM];
|
||||
} and_expr_t;
|
||||
|
||||
/**
|
||||
* @brief initialize adapter_hs instance
|
||||
*
|
||||
* @param scan_mode: the following scan as block or stream mode
|
||||
* @param nr_worker_threads: the number of scan threads which will call adapter_hs_scan()
|
||||
* @param expr_array: logic AND expression's array
|
||||
* @param n_expr_arrays: the number of logic AND expression's array
|
||||
*
|
||||
* @retval the pointer to adapter_hs instance
|
||||
*/
|
||||
struct adapter_hs *adapter_hs_initialize(int scan_mode, size_t nr_worker_threads, and_expr_t *expr_array, size_t n_expr_array);
|
||||
|
||||
/**
|
||||
* @brief scan input data to match logic AND expression, return all matched expr_id
|
||||
*
|
||||
* @param instance: adapter_hs instance obtained by adapter_hs_initialize()
|
||||
* @param thread_id: the thread_id of caller
|
||||
* @param data: data to be scanned
|
||||
* @param data_len: the length of data to be scanned
|
||||
* @param results: the array of expr_id
|
||||
* @param n_results: number of elements in array of expr_id
|
||||
*/
|
||||
int adapter_hs_scan(struct adapter_hs *instance, int thread_id, const char *data, size_t data_len,
|
||||
int results[], size_t *n_results);
|
||||
|
||||
/**
|
||||
* @brief destroy adapter_hs instance
|
||||
*
|
||||
* @param instance: adapter_hs instance obtained by adapter_hs_initialize()
|
||||
*/
|
||||
void adapter_hs_destroy(struct adapter_hs *instance);
|
||||
|
||||
struct adapter_hs_stream;
|
||||
/**
|
||||
* @brief open adapter_hs stream after adapter_hs instance initialized for stream scan
|
||||
*
|
||||
*/
|
||||
struct adapter_hs_stream *adapter_hs_stream_open(struct adapter_hs *hs_instance, int thread_id);
|
||||
|
||||
int adapter_hs_scan_stream(struct adapter_hs_stream *stream, const char *data, size_t data_len,
|
||||
int results[], size_t *n_results);
|
||||
|
||||
void adapter_hs_stream_close(struct adapter_hs_stream *stream);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
66
src/inc_internal/bool_matcher.h
Normal file
66
src/inc_internal/bool_matcher.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2018
|
||||
* String Algorithms Research Group
|
||||
* Institute of Information Engineering, Chinese Academy of Sciences (IIE-CAS)
|
||||
* National Engineering Laboratory for Information Security Technologies (NELIST)
|
||||
* All rights reserved
|
||||
*
|
||||
* Written by: LIU YANBING (liuyanbing@iie.ac.cn)
|
||||
* Last modification: 2021-06-12
|
||||
*
|
||||
* This code is the exclusive and proprietary property of IIE-CAS and NELIST.
|
||||
* Usage for direct or indirect commercial advantage is not allowed without
|
||||
* written permission from the authors.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_BOOL_MATCHER_H
|
||||
#define INCLUDE_BOOL_MATCHER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#define MAX_ITEMS_PER_BOOL_EXPR 8
|
||||
|
||||
/* not_flag=0表示布尔项item_id必须出现;not_flag=1表示布尔项item_id不能出现 */
|
||||
struct bool_item
|
||||
{
|
||||
unsigned long long item_id;
|
||||
unsigned char not_flag;
|
||||
};
|
||||
|
||||
/* At least one item's not_flag should be 0. */
|
||||
struct bool_expr
|
||||
{
|
||||
unsigned long long expr_id;
|
||||
void *user_tag;
|
||||
size_t item_num;
|
||||
struct bool_item items[MAX_ITEMS_PER_BOOL_EXPR];
|
||||
};
|
||||
|
||||
struct bool_expr_match
|
||||
{
|
||||
unsigned long long expr_id;
|
||||
void *user_tag;
|
||||
};
|
||||
|
||||
struct bool_matcher;
|
||||
|
||||
struct bool_matcher *bool_matcher_new(struct bool_expr *exprs, size_t expr_num, size_t *mem_size);
|
||||
|
||||
/* Returned results are sorted by expr_id in descending order. */
|
||||
// Input item_ids MUST be ASCENDING order and NO duplication.
|
||||
int bool_matcher_match(struct bool_matcher *matcher, unsigned long long *item_ids, size_t item_num, struct bool_expr_match *results, size_t n_result);
|
||||
|
||||
void bool_matcher_free(struct bool_matcher *matcher);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
277
src/inc_internal/cJSON.h
Normal file
277
src/inc_internal/cJSON.h
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 7
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
#define cJSON_True (1 << 1)
|
||||
#define cJSON_NULL (1 << 2)
|
||||
#define cJSON_Number (1 << 3)
|
||||
#define cJSON_String (1 << 4)
|
||||
#define cJSON_Array (1 << 5)
|
||||
#define cJSON_Object (1 << 6)
|
||||
#define cJSON_Raw (1 << 7) /* raw json */
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON
|
||||
{
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *next;
|
||||
struct cJSON *prev;
|
||||
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
struct cJSON *child;
|
||||
|
||||
/* The type of the item, as above. */
|
||||
int type;
|
||||
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int valueint;
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
|
||||
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
|
||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options:
|
||||
|
||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||
|
||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||
|
||||
setting default visibility to hidden by adding
|
||||
-fvisibility=hidden (for gcc)
|
||||
or
|
||||
-xldscope=hidden (for sun cc)
|
||||
to CFLAGS
|
||||
|
||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||
|
||||
*/
|
||||
|
||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_EXPORT_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if defined(CJSON_HIDE_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) type __stdcall
|
||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall
|
||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall
|
||||
#endif
|
||||
#else /* !WIN32 */
|
||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||
#else
|
||||
#define CJSON_PUBLIC(type) type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_NESTING_LIMIT
|
||||
#define CJSON_NESTING_LIMIT 1000
|
||||
#endif
|
||||
|
||||
/* returns the version of cJSON as a string */
|
||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage. */
|
||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* Check if the item is a string and return its valuestring */
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(cJSON *item);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
|
||||
/* Create a string where valuestring references a string so
|
||||
* it will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||
/* Create an object/arrray that only references it's elements so
|
||||
* they will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||
* writing to `item->string` */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||
|
||||
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Helper functions for creating and adding items to an object at the same time.
|
||||
* They return the added item or NULL on failure. */
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||
/* helper for the cJSON_SetNumberValue macro */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||
|
||||
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
29
src/inc_internal/maat_common.h
Normal file
29
src/inc_internal/maat_common.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_common.h
|
||||
* Description: maat common entry
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _MAAT_COMMON_H_
|
||||
#define _MAAT_COMMON_H_
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct maat_options {
|
||||
size_t nr_worker_threads;
|
||||
};
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
36
src/inc_internal/maat_config_monitor.h
Normal file
36
src/inc_internal/maat_config_monitor.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_config_monitor.h
|
||||
* Description: maat config monitor api
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _MAAT_CONFIG_MONITOR_H_
|
||||
#define _MAAT_CONFIG_MONITOR_H_
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define CONFIG_UPDATE_TYPE_NONE 0
|
||||
#define CONFIG_UPDATE_TYPE_FULL 1
|
||||
#define CONFIG_UPDATE_TYPE_INC 2
|
||||
|
||||
|
||||
void config_monitor_traverse(uint64_t version, const char *idx_dir,
|
||||
void (*pre_fn)(uint64_t, int, void *),
|
||||
int (*update_fn)(const char *, const char *, void *),
|
||||
void (*post_fn)(void *),
|
||||
void *u_param);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
29
src/inc_internal/maat_ex_data.h
Normal file
29
src/inc_internal/maat_ex_data.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_ex_data.h
|
||||
* Description: ex data
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _MAAT_EX_DATA_H_
|
||||
#define _MAAT_EX_DATA_H_
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct ex_data_runtime;
|
||||
|
||||
struct ex_data_runtime *ex_data_runtime_new(void (* data_free)(void *data));
|
||||
|
||||
void ex_data_runtime_free(struct ex_data_runtime *ex_data_rt);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
39
src/inc_internal/maat_garbage_collection.h
Normal file
39
src/inc_internal/maat_garbage_collection.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_garbage_collection.h
|
||||
* Description: maat gc
|
||||
* Authors: Zhengchao <zhengchao@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _MAAT_GARBAGE_COLLECTION_H_
|
||||
#define _MAAT_GARBAGE_COLLECTION_H_
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct maat_garbage_bin;
|
||||
|
||||
struct maat_garbage_bin* maat_garbage_bin_new(int default_timeout);
|
||||
|
||||
void maat_garbage_bin_free(struct maat_garbage_bin* bin);
|
||||
|
||||
void maat_garbage_bagging(struct maat_garbage_bin* bin, void* garbage, void (* func)(void *));
|
||||
|
||||
void maat_garbage_collect_routine(struct maat_garbage_bin* bin);
|
||||
|
||||
size_t maat_garbage_bin_get_size(struct maat_garbage_bin* bin);
|
||||
|
||||
void maat_garbage_collect_by_force(struct maat_garbage_bin* bin);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
33
src/inc_internal/maat_kv.h
Normal file
33
src/inc_internal/maat_kv.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_kv_map.h
|
||||
* Description: str2int map api
|
||||
* Authors: Zheng chao <zhengchao@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _MAAT_KV_MAP_H_
|
||||
#define _MAAT_KV_MAP_H_
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct maat_kv_store;
|
||||
|
||||
struct maat_kv_store* maat_kv_store_new(void);
|
||||
|
||||
void maat_kv_store_free(struct maat_kv_store* store);
|
||||
|
||||
int maat_kv_register(struct maat_kv_store* store, const char* key, int value);
|
||||
|
||||
int maat_kv_read(struct maat_kv_store* store, const char* key, int* value);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
74
src/inc_internal/maat_rule.h
Normal file
74
src/inc_internal/maat_rule.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_rule.h
|
||||
* Description: maat rule entry
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _MAAT_RULE_H_
|
||||
#define _MAAT_RULE_H_
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
struct maat_runtime {
|
||||
/* maat_runtime can be created and destroy dynamic, so need version info */
|
||||
uint64_t version;
|
||||
|
||||
time_t last_update_time;
|
||||
|
||||
struct maat_table_runtime_manager *table_rt_mgr;
|
||||
size_t max_table_num;
|
||||
|
||||
int max_thread_num;
|
||||
uint32_t rule_num;
|
||||
};
|
||||
|
||||
enum rule_import_type {
|
||||
RULE_IMPORT_TYPE_IRIS = 1,
|
||||
RULE_IMPORT_TYPE_MAX
|
||||
};
|
||||
|
||||
struct rule_import_iris_ctx {
|
||||
char inc_dir[NAME_MAX];
|
||||
char full_dir[NAME_MAX];
|
||||
};
|
||||
|
||||
struct maat {
|
||||
struct maat_runtime *maat_rt;
|
||||
struct maat_runtime *rebuilding_maat_rt; //TODO: creating
|
||||
//struct maat_garbage_collector *gc;
|
||||
struct maat_table_manager *table_mgr;
|
||||
|
||||
enum rule_import_type rule_import_type;
|
||||
union {
|
||||
struct rule_import_iris_ctx iris_ctx;
|
||||
};
|
||||
|
||||
int is_running;
|
||||
pthread_mutex_t background_update_mutex;
|
||||
int nr_worker_thread;
|
||||
|
||||
uint64_t maat_version;
|
||||
uint64_t last_full_version;
|
||||
pthread_t cfg_mon_thread;
|
||||
};
|
||||
|
||||
void *rule_monitor_loop(void *arg);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
40
src/inc_internal/maat_table_runtime.h
Normal file
40
src/inc_internal/maat_table_runtime.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_table_runtime.h
|
||||
* Description: maat table runtime entry
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _MAAT_TABLE_RUNTIME_H_
|
||||
#define _MAAT_TABLE_RUNTIME_H_
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "maat_table_schema.h"
|
||||
#include "maat_garbage_collection.h"
|
||||
|
||||
struct maat_table_item;
|
||||
struct maat_table_runtime;
|
||||
struct maat_table_runtime_manager;
|
||||
|
||||
struct maat_table_runtime_manager *maat_table_runtime_manager_create(struct maat_table_manager *table_mgr, int max_thread_num, struct maat_garbage_bin* bin);
|
||||
|
||||
void maat_table_runtime_manager_destroy(struct maat_table_runtime_manager *table_rt_mgr);
|
||||
|
||||
struct maat_table_runtime *maat_table_runtime_get(struct maat_table_runtime_manager *table_rt_mgr, int table_id);
|
||||
|
||||
enum maat_table_type maat_table_runtime_get_type(struct maat_table_runtime* table_rt);
|
||||
|
||||
void maat_table_runtime_item_add(struct maat_table_runtime *table_rt, struct maat_table_item *table_item);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
47
src/inc_internal/maat_table_schema.h
Normal file
47
src/inc_internal/maat_table_schema.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_table_schema.h
|
||||
* Description: maat table schema entry
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _MAAT_TABLE_SCHEMA_H_
|
||||
#define _MAAT_TABLE_SCHEMA_H_
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "sds/sds.h"
|
||||
|
||||
enum maat_table_type {
|
||||
TABLE_TYPE_EXPR = 0,
|
||||
TABLE_TYPE_IP_PLUGIN,
|
||||
TABLE_TYPE_MAX
|
||||
};
|
||||
|
||||
struct maat_table_schema;
|
||||
struct maat_table_manager;
|
||||
struct maat_table_item;
|
||||
|
||||
struct maat_table_manager *maat_table_manager_create(sds table_info_path);
|
||||
void maat_table_manager_destroy(struct maat_table_manager *table_mgr);
|
||||
|
||||
int maat_table_manager_get_table_id(struct maat_table_manager* table_mgr, sds table_name);
|
||||
enum maat_table_type maat_table_manager_get_table_type(struct maat_table_manager *table_mgr, int id);
|
||||
|
||||
size_t maat_table_manager_get_size(struct maat_table_manager* table_mgr);
|
||||
|
||||
struct maat_table_item *maat_table_line_to_item(sds line, struct maat_table_schema *table_schema);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
32
src/inc_internal/maat_utils.h
Normal file
32
src/inc_internal/maat_utils.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_utils.h
|
||||
* Description: maat utils entry
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _MAAT_UTILS_H_
|
||||
#define _MAAT_UTILS_H_
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "sds/sds.h"
|
||||
|
||||
#define ALLOC(type, number) ((type *)calloc(sizeof(type), number))
|
||||
|
||||
int get_column_pos(sds line, int column_seq, size_t *offset, size_t *len);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
59
src/inc_internal/rcu_hash.h
Normal file
59
src/inc_internal/rcu_hash.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_rhash.h
|
||||
* Description: maat rcu hashtable
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _RCU_HASH_H_
|
||||
#define _RCU_HASH_H_
|
||||
|
||||
#ifdef __cpluscplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "uthash/uthash.h"
|
||||
|
||||
/* rcu hash table */
|
||||
struct rcu_hash_table;
|
||||
|
||||
struct rcu_hash_table *rcu_hash_new(void (* data_free)(void *data));
|
||||
|
||||
void rcu_hash_free(struct rcu_hash_table *htable);
|
||||
|
||||
/**
|
||||
* @brief the data added just in updating stage
|
||||
* after call rcu_hash_commit, it in effective stage
|
||||
*/
|
||||
void rcu_hash_add(struct rcu_hash_table *htable, const char *key, size_t key_len, void *data);
|
||||
|
||||
void rcu_hash_del(struct rcu_hash_table *htable, const char *key, size_t key_len);
|
||||
|
||||
/**
|
||||
* @brief find in effective nodes
|
||||
*
|
||||
* @param htable: the rcu_hash_table
|
||||
* @param key: the key used for searching in the hash table
|
||||
* @param key_len: the key's length
|
||||
*
|
||||
* @retval NULL or
|
||||
*/
|
||||
void *rcu_hash_find(struct rcu_hash_table *htable, const char *key, size_t key_len);
|
||||
|
||||
size_t rcu_hash_counts(struct rcu_hash_table *htable);
|
||||
|
||||
|
||||
/**
|
||||
* @brief make add/del effective
|
||||
*/
|
||||
void rcu_hash_commit(struct rcu_hash_table *htable);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
128
src/maat_api.cpp
128
src/maat_api.cpp
@@ -1,31 +1,121 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_api.cpp
|
||||
* Description: maat api entry
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <hs/hs.h>
|
||||
|
||||
#include "../include/maat/maat.h"
|
||||
#include "maat_utils.h"
|
||||
#include "maat_rule.h"
|
||||
#include "maat_common.h"
|
||||
#include "maat_table_schema.h"
|
||||
#include "maat_table_runtime.h"
|
||||
#include "sds/sds.h"
|
||||
|
||||
int maat_scan_ipv4(struct maat_feather *feather, struct maat_scan_state *state,
|
||||
const struct ipv4_tuple4 *tuple4, unsigned int *matched_ids, size_t n_match_id)
|
||||
struct maat_options* maat_options_new(void)
|
||||
{
|
||||
struct maat_options *options = ALLOC(struct maat_options, 1);
|
||||
|
||||
options->nr_worker_threads = 1;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
int maat_options_set_worker_thread_number(struct maat_options *opts, size_t n_worker_threads)
|
||||
{
|
||||
opts->nr_worker_threads = n_worker_threads;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int maat_scan_string(struct maat_feather *feather, int table_id, struct maat_scan_state *state,
|
||||
const char *data, size_t length)
|
||||
struct maat *maat_new(struct maat_options opts, const char *table_info_path)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int maat_hyperscan_compile(char *pattern)
|
||||
{
|
||||
hs_database_t *database;
|
||||
hs_compile_error_t *compile_err;
|
||||
if (hs_compile(pattern, HS_FLAG_DOTALL, HS_MODE_BLOCK, NULL, &database,
|
||||
&compile_err) != HS_SUCCESS) {
|
||||
fprintf(stderr, "ERROR: Unable to compile pattern \"%s\": %s\n",
|
||||
pattern, compile_err->message);
|
||||
hs_free_compile_error(compile_err);
|
||||
return -1;
|
||||
#if 0
|
||||
if (NULL == table_info_path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct maat *maat_instance = ALLOC(struct maat, 1);
|
||||
|
||||
maat_instance->table_mgr = maat_table_manager_create(table_info_path);
|
||||
maat_instance->is_running = 0;
|
||||
maat_instance->maat_version = 0;
|
||||
maat_instance->last_full_version = 0;
|
||||
maat_instance->nr_worker_thread = opts.nr_worker_threads;
|
||||
|
||||
pthread_create(&(maat_instance->cfg_mon_thread), NULL, rule_monitor_loop, (void*)maat_instance);
|
||||
|
||||
return maat_instance;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void maat_free(struct maat *maat_instance)
|
||||
{
|
||||
|
||||
void* ret = NULL;
|
||||
pthread_join(maat_instance->cfg_mon_thread, &ret);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int maat_table_get_id(struct maat *instance, const char *table_name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int maat_scan_integer(struct maat *instance, int table_id, int thread_id,
|
||||
unsigned int intval, int results[], size_t n_result,
|
||||
struct maat_state *state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int maat_scan_ip(struct maat *instance, int table_id, int thread_id,
|
||||
const struct ip_data *ip, int results[], size_t n_result,
|
||||
struct maat_state *state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int maat_scan_string(struct maat *maat_instance, int table_id, int thread_id,
|
||||
const char *data, size_t data_len, int results[], size_t *n_results,
|
||||
struct maat_state *state)
|
||||
{
|
||||
#if 0
|
||||
if (NULL == maat_instance || NULL == data ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct maat_runtime *maat_rt = maat_instance->maat_rt;
|
||||
|
||||
struct maat_table_runtime *table_rt = maat_table_runtime_get(maat_rt->table_rt_mgr, table_id);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct maat_stream *maat_scan_stream_open(struct maat *instance, int table_id, int thread_id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int maat_scan_stream(struct maat_stream **stream, int thread_id, const char* data, int data_len,
|
||||
int results[], size_t n_result, struct maat_state *state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void maat_scan_stream_close(struct maat_stream **stream)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void maat_state_reset(struct maat_state *state)
|
||||
{
|
||||
|
||||
}
|
||||
217
src/maat_config_monitor.cpp
Normal file
217
src/maat_config_monitor.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_config_monitor.h
|
||||
* Description: maat config monitor api
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "maat_config_monitor.h"
|
||||
#include "maat_utils.h"
|
||||
|
||||
#define CM_MAX_TABLE_NUM 256
|
||||
#define MAX_CONFIG_LINE (1024 * 16)
|
||||
|
||||
struct cm_table_info_t
|
||||
{
|
||||
char table_name[NAME_MAX];
|
||||
char cfg_path[NAME_MAX];
|
||||
int cfg_num;
|
||||
char encryp_algorithm[NAME_MAX];
|
||||
};
|
||||
|
||||
/*
|
||||
@brief check if rule file updated
|
||||
@retval 0 -> CONFIG_UPDATE_TYPE_NONE
|
||||
1 -> CONFIG_UPDATE_TYPE_FULL
|
||||
2 -> CONFIG_UPDATE_TYPE_INC
|
||||
*/
|
||||
int validate_update_happened(uint64_t current_version, const char *idx_dir, char **idx_paths[], size_t *n_idx_paths)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int cm_read_cfg_index_file(const char* path, struct cm_table_info_t* idx, int size)
|
||||
{
|
||||
int ret = 0;
|
||||
int i = 0;
|
||||
char line[MAX_CONFIG_LINE];
|
||||
struct stat file_info;
|
||||
|
||||
FILE* fp = fopen(path,"r");
|
||||
while (!feof(fp)) {
|
||||
memset(line, 0, sizeof(line));
|
||||
fgets(line, sizeof(line), fp);
|
||||
ret=sscanf(line,"%s\t%d\t%s\t%s",idx[i].table_name
|
||||
,&(idx[i].cfg_num)
|
||||
,idx[i].cfg_path
|
||||
,idx[i].encryp_algorithm);
|
||||
//jump over empty line
|
||||
if (!(ret==3||ret==4)||idx[i].cfg_num==0){
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = stat(idx[i].cfg_path, &file_info);
|
||||
if (ret != 0) {
|
||||
//log_error
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
i++;
|
||||
if (i == size) {
|
||||
//log_error
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
const char* path2filename(const char*path)
|
||||
{
|
||||
int i=0;
|
||||
for(i=strlen(path);i>0;i--)
|
||||
{
|
||||
if(path[i]=='/')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return path+i+1;
|
||||
}
|
||||
|
||||
char *read_nxt_line_from_buff(const char *buff, size_t buff_size, size_t *offset, char *line, int line_size)
|
||||
{
|
||||
int this_offset=0;
|
||||
const char* p;
|
||||
|
||||
//search for CRLF, aka CR '\r'(old Mac), LF '\n'(UNIX) or CRLF"\r\n" (Windows)
|
||||
p = (const char*)memchr(buff+*offset, '\n', buff_size-*offset);
|
||||
if (p == NULL) { // NOT "\n" or "\r\n"
|
||||
p = (const char*)memchr(buff+*offset, '\r', buff_size-*offset);
|
||||
}
|
||||
|
||||
if (p != NULL) { //point to next character
|
||||
p++;
|
||||
} else { //Treat rest buff has no CRLF as a line.
|
||||
p = buff + buff_size;
|
||||
}
|
||||
|
||||
this_offset = p - (buff + *offset);
|
||||
memcpy(line, buff + *offset, MIN(this_offset, line_size-1));
|
||||
|
||||
*offset += this_offset;
|
||||
line[MIN(this_offset, line_size - 1)] = '\0';
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
int cm_read_table_file(struct cm_table_info_t* index,
|
||||
int (*update_fn)(const char *, const char *, void *),
|
||||
void* u_param)
|
||||
{
|
||||
int cfg_num = 0,i =0;
|
||||
int ret = 0;
|
||||
char error_string[NAME_MAX];
|
||||
char line[MAX_CONFIG_LINE]={0};
|
||||
char *ret_str=NULL;
|
||||
char *table_file_buff=NULL;
|
||||
size_t file_sz = 0;
|
||||
size_t file_offset = 0;
|
||||
|
||||
ret = load_file_to_memory(index->cfg_path, (unsigned char **)&table_file_buff, &file_sz);
|
||||
if (ret < 0) {
|
||||
// log_error
|
||||
return -1;
|
||||
}
|
||||
|
||||
read_nxt_line_from_buff(table_file_buff, file_sz, &file_offset, line, sizeof(line));
|
||||
sscanf(line, "%d\n", &cfg_num);
|
||||
|
||||
if(cfg_num != index->cfg_num) {
|
||||
//log_error
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < cfg_num; i++) {
|
||||
line[sizeof(line)-1]='\0';
|
||||
|
||||
ret_str=read_nxt_line_from_buff(table_file_buff, file_sz, &file_offset, line, sizeof(line));
|
||||
|
||||
if(ret_str==NULL) {
|
||||
//log_error
|
||||
break;
|
||||
}
|
||||
|
||||
if(line[sizeof(line)-1]!='\0') {
|
||||
//log_error
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = update_fn(index->table_name, line, u_param);
|
||||
if (ret<0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(table_file_buff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void config_monitor_traverse(uint64_t current_version, const char *idx_dir,
|
||||
void (*start_fn)(uint64_t, int, void *),
|
||||
int (*update_fn)(const char *, const char *, void *),
|
||||
void (*finish_fn)(void *),
|
||||
void *u_param)
|
||||
{
|
||||
size_t i = 0;
|
||||
uint64_t new_version = 0;
|
||||
char **idx_path_array = NULL;
|
||||
size_t idx_path_num = 0;
|
||||
struct cm_table_info_t table_array[CM_MAX_TABLE_NUM];
|
||||
|
||||
memset(table_array, 0, sizeof(table_array));
|
||||
|
||||
int update_type = validate_update_happened(current_version, idx_dir, &idx_path_array, &idx_path_num);
|
||||
if (update_type != CONFIG_UPDATE_TYPE_NONE) {
|
||||
for (i = 0; i < idx_path_num; i++) {
|
||||
int table_num = cm_read_cfg_index_file(idx_path_array[i], table_array, CM_MAX_TABLE_NUM);
|
||||
if (table_num < 0) {
|
||||
//log_error
|
||||
break;
|
||||
}
|
||||
|
||||
char str_not_care[256] = {0};
|
||||
const char* table_filename = path2filename(idx_path_array[i]);
|
||||
sscanf(table_filename,"%[a-zA-Z]_config_index.%lld", str_not_care, &new_version);
|
||||
if (start_fn != NULL) {
|
||||
start_fn(new_version, update_type, u_param);
|
||||
}
|
||||
|
||||
for (int j = 0; j < table_num; j++) {
|
||||
cm_read_table_file(table_array + j, update_fn, u_param);
|
||||
}
|
||||
|
||||
if (finish_fn != NULL) {
|
||||
finish_fn(u_param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < idx_path_num; i++) {
|
||||
free(idx_path_array[i]);
|
||||
}
|
||||
|
||||
free(idx_path_array);
|
||||
}
|
||||
70
src/maat_ex_data.cpp
Normal file
70
src/maat_ex_data.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_ex_data.cpp
|
||||
* Description: ex data
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "uthash/uthash.h"
|
||||
#include "uthash/utarray.h"
|
||||
#include "maat_rhash.h"
|
||||
#include "maat_utils.h"
|
||||
|
||||
typedef void ex_data_schema_new_func_t(int table_id, const char *key, const char *table_line, void* ad, long argl, void *argp);
|
||||
typedef void ex_data_schema_free_func_t(int table_id, void* ad, long argl, void *argp);
|
||||
typedef void ex_data_schema_dup_func_t(int table_id, void *to, void *from, long argl, void *argp);
|
||||
/*
|
||||
struct ex_data_schema
|
||||
{
|
||||
ex_data_schema_new_func_t* new_func;
|
||||
ex_data_schema_free_func_t* free_func;
|
||||
ex_data_schema_dup_func_t* dup_func;
|
||||
//Maat_plugin_EX_key2index_func_t* key2index_func;
|
||||
long argl;
|
||||
void *argp;
|
||||
}; */
|
||||
|
||||
struct ex_data_runtime {
|
||||
UT_array *cache_rows;
|
||||
size_t cache_row_num;
|
||||
size_t cache_size;
|
||||
|
||||
struct rhash_table *htable;
|
||||
//const struct ex_data_schema* ex_schema;
|
||||
int table_id;
|
||||
};
|
||||
|
||||
void cache_row_free(void*p)
|
||||
{
|
||||
free(*(char**)p);
|
||||
}
|
||||
|
||||
UT_icd ut_cache_row_icd = {sizeof(char*), NULL, NULL, cache_row_free};
|
||||
|
||||
struct ex_data_runtime *ex_data_runtime_new(void (* data_free)(void *data))
|
||||
{
|
||||
struct ex_data_runtime *ex_data_rt = ALLOC(struct ex_data_runtime, 1);
|
||||
|
||||
utarray_new(ex_data_rt->cache_rows, &ut_cache_row_icd);
|
||||
ex_data_rt->htable = rhash_table_create(data_free);
|
||||
}
|
||||
|
||||
void ex_data_runtime_free(struct ex_data_runtime *ex_data_rt)
|
||||
{
|
||||
if (ex_data_rt->cache_rows != NULL) {
|
||||
utarray_free(ex_data_rt->cache_rows);
|
||||
ex_data_rt->cache_rows=NULL;
|
||||
ex_data_rt->cache_row_num=0;
|
||||
}
|
||||
|
||||
if (ex_data_rt->htable != NULL) {
|
||||
rhash_table_destroy(ex_data_rt->htable);
|
||||
}
|
||||
|
||||
free(ex_data_rt);
|
||||
}
|
||||
104
src/maat_garbage_collection.cpp
Normal file
104
src/maat_garbage_collection.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_garbage_collection.h
|
||||
* Description:
|
||||
* Authors: Zhengchao <zhengchao@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#include "maat_utils.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/queue.h>
|
||||
#include <assert.h>
|
||||
|
||||
struct maat_garbage_bag {
|
||||
time_t create_time;
|
||||
int timeout;
|
||||
int ok_times;
|
||||
void *garbage;
|
||||
void (* garbage_free)(void *garbage);
|
||||
TAILQ_ENTRY(maat_garbage_bag) entries;
|
||||
};
|
||||
TAILQ_HEAD(maat_garbage_q, maat_garbage_bag);
|
||||
|
||||
struct maat_garbage_bin {
|
||||
struct maat_garbage_q garbage_q;
|
||||
size_t bag_cnt;
|
||||
int timeout_seconds;
|
||||
};
|
||||
|
||||
struct maat_garbage_bin* maat_garbage_bin_new(int default_timeout)
|
||||
{
|
||||
struct maat_garbage_bin* bin = ALLOC(struct maat_garbage_bin, 1);
|
||||
|
||||
TAILQ_INIT(&bin->garbage_q);
|
||||
bin->timeout_seconds = default_timeout;
|
||||
|
||||
return bin;
|
||||
}
|
||||
|
||||
void maat_garbage_bin_free(struct maat_garbage_bin* bin)
|
||||
{
|
||||
struct maat_garbage_bag *p = NULL;
|
||||
|
||||
while (p = TAILQ_FIRST(&bin->garbage_q)) {
|
||||
p->garbage_free(p->garbage);
|
||||
TAILQ_REMOVE(&bin->garbage_q, p, entries);
|
||||
free(p);
|
||||
bin->bag_cnt--;
|
||||
}
|
||||
|
||||
free(bin);
|
||||
}
|
||||
|
||||
size_t maat_garbage_bin_get_size(struct maat_garbage_bin* bin)
|
||||
{
|
||||
return bin->bag_cnt;
|
||||
}
|
||||
|
||||
void maat_garbage_bagging(struct maat_garbage_bin* bin, void* garbage, void (* func)(void *))
|
||||
{
|
||||
struct maat_garbage_bag *bag = ALLOC(struct maat_garbage_bag, 1);
|
||||
|
||||
bag->create_time = time(NULL);
|
||||
bag->timeout = bin->timeout_seconds;
|
||||
bag->garbage = garbage;
|
||||
bag->garbage_free = func;
|
||||
TAILQ_INSERT_TAIL(&bin->garbage_q, bag, entries);
|
||||
bin->bag_cnt++;
|
||||
}
|
||||
void maat_garbage_collect_routine(struct maat_garbage_bin* bin)
|
||||
{
|
||||
struct maat_garbage_bag *p = NULL, *tmp = NULL;
|
||||
size_t n_clollected = 0, n_bag = 0;
|
||||
time_t now = time(NULL);
|
||||
|
||||
for (p = TAILQ_FIRST(&bin->garbage_q); p != NULL; p = tmp) {
|
||||
tmp = TAILQ_NEXT(p, entries);
|
||||
if ((now - p->create_time) > p->timeout || p->timeout == 0) {
|
||||
p->garbage_free(p->garbage);
|
||||
TAILQ_REMOVE(&bin->garbage_q, p, entries);
|
||||
free(p);
|
||||
n_clollected++;
|
||||
}
|
||||
n_bag++;
|
||||
}
|
||||
|
||||
assert(bin->bag_cnt == n_bag);
|
||||
bin->bag_cnt -= n_clollected;
|
||||
}
|
||||
|
||||
void maat_garbage_collect_by_force(struct maat_garbage_bin* bin)
|
||||
{
|
||||
struct maat_garbage_bag *p = NULL;
|
||||
while (p = TAILQ_FIRST(&bin->garbage_q)) {
|
||||
p->garbage_free(p->garbage);
|
||||
TAILQ_REMOVE(&bin->garbage_q, p, entries);
|
||||
free(p);
|
||||
bin->bag_cnt--;
|
||||
}
|
||||
}
|
||||
133
src/maat_kv.cpp
Normal file
133
src/maat_kv.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_kv_map.cpp
|
||||
* Description:
|
||||
* Authors: Zheng chao <zhengchao@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "uthash/uthash.h"
|
||||
#include "maat_utils.h"
|
||||
|
||||
#define MAAT_KV_MAX_KEY_LEN 512
|
||||
|
||||
struct maat_kv_pair
|
||||
{
|
||||
char* key; //must be lower case.
|
||||
size_t keylen;
|
||||
int val;
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
|
||||
struct maat_kv_store
|
||||
{
|
||||
struct maat_kv_pair* hash;
|
||||
};
|
||||
|
||||
void strlowercase(const char* src, size_t src_len, char* dst, size_t dst_sz)
|
||||
{
|
||||
for (size_t i = 0; i < src_len && i < dst_sz; i++) {
|
||||
dst[i] = tolower(src[i]);
|
||||
}
|
||||
}
|
||||
|
||||
struct maat_kv_pair* maat_kv_pair_new(const char* key, size_t keylen, int value)
|
||||
{
|
||||
struct maat_kv_pair *kv = ALLOC(struct maat_kv_pair, 1);
|
||||
|
||||
kv->key = ALLOC(char, keylen);
|
||||
kv->keylen = keylen;
|
||||
kv->val = value;
|
||||
|
||||
strlowercase(key, keylen, kv->key, kv->keylen);
|
||||
|
||||
return kv;
|
||||
}
|
||||
|
||||
void maat_kv_pair_free(struct maat_kv_pair* kv)
|
||||
{
|
||||
free(kv->key);
|
||||
kv->key = NULL;
|
||||
|
||||
free(kv);
|
||||
}
|
||||
|
||||
struct maat_kv_store* maat_kv_store_new(void)
|
||||
{
|
||||
struct maat_kv_store* store = ALLOC(struct maat_kv_store, 1);
|
||||
return store;
|
||||
}
|
||||
|
||||
void maat_kv_store_free(struct maat_kv_store* store)
|
||||
{
|
||||
if (NULL == store) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct maat_kv_pair *kv = NULL;
|
||||
struct maat_kv_pair *tmp_kv = NULL;
|
||||
|
||||
HASH_ITER(hh, store->hash, kv, tmp_kv) {
|
||||
HASH_DEL(store->hash, kv);
|
||||
maat_kv_pair_free(kv);
|
||||
}
|
||||
|
||||
free(store);
|
||||
}
|
||||
|
||||
int maat_kv_register_unNull(struct maat_kv_store* store, const char* key, size_t keylen, int value)
|
||||
{
|
||||
if (keylen > MAAT_KV_MAX_KEY_LEN) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct maat_kv_pair *kv = NULL;
|
||||
struct maat_kv_pair *tmp_kv = NULL;
|
||||
|
||||
kv = maat_kv_pair_new(key, keylen, value);
|
||||
HASH_FIND(hh, store->hash, kv->key, keylen, tmp_kv);
|
||||
if (tmp_kv) {
|
||||
maat_kv_pair_free(kv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
HASH_ADD_KEYPTR(hh, store->hash, kv->key, keylen, kv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int maat_kv_register(struct maat_kv_store* store, const char* key, int value)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = maat_kv_register_unNull(store, key, strlen(key), value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int maat_kv_read_unNull(struct maat_kv_store* store, const char* key, size_t keylen, int* value)
|
||||
{
|
||||
struct maat_kv_pair *kv = NULL;
|
||||
char key_lowercase[MAAT_KV_MAX_KEY_LEN] = {0};
|
||||
|
||||
if (keylen > MAAT_KV_MAX_KEY_LEN) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
strlowercase(key, keylen, key_lowercase, sizeof(key_lowercase));
|
||||
HASH_FIND(hh, store->hash, key_lowercase, keylen, kv);
|
||||
if (kv) {
|
||||
*value=kv->val;
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int maat_kv_read(struct maat_kv_store * store, const char * key, int * value)
|
||||
{
|
||||
return maat_kv_read_unNull(store, key, strlen(key), value);
|
||||
}
|
||||
130
src/maat_rule.cpp
Normal file
130
src/maat_rule.cpp
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* 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>
|
||||
#include <pthread.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "maat_rule.h"
|
||||
#include "maat_config_monitor.h"
|
||||
#include "maat_utils.h"
|
||||
#include "maat_table_runtime.h"
|
||||
#include "maat_table_schema.h"
|
||||
|
||||
struct maat_runtime* create_maat_runtime(uint64_t version, struct maat *maat_instance)
|
||||
{
|
||||
struct maat_runtime *maat_rt = ALLOC(struct maat_runtime, 1);
|
||||
|
||||
maat_rt->version = version;
|
||||
maat_rt->table_rt_mgr = maat_table_runtime_manager_create(maat_instance->table_mgr);
|
||||
maat_rt->max_table_num = maat_table_manager_get_size(maat_instance->table_mgr);
|
||||
}
|
||||
|
||||
void update_maat_runtime(struct maat_runtime *maat_rt)
|
||||
{
|
||||
for (size_t i = 0; i < maat_rt->max_table_num; i++) {
|
||||
struct maat_table_runtime *table_rt = maat_table_runtime_get(maat_rt->table_rt_mgr, i);
|
||||
if (NULL == table_rt) {
|
||||
continue;
|
||||
}
|
||||
|
||||
enum maat_table_type table_type = maat_table_runtime_get_type(table_rt);
|
||||
}
|
||||
}
|
||||
|
||||
void destroy_maat_runtime(struct maat_runtime *maat_rt)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void maat_start_cb(uint64_t new_version, int update_type, void *u_param)
|
||||
{
|
||||
struct maat *maat_instance = (struct maat *)u_param;
|
||||
|
||||
if (update_type == CONFIG_UPDATE_TYPE_FULL) {
|
||||
maat_instance->rebuilding_maat_rt = create_maat_runtime(new_version, maat_instance);
|
||||
} else {
|
||||
maat_instance->maat_version = new_version;
|
||||
}
|
||||
}
|
||||
|
||||
int maat_update_cb(const char* table_name, const char* line, void *u_param)
|
||||
{
|
||||
struct maat *maat_instance =(struct maat *)u_param;
|
||||
struct maat_runtime* maat_rt = NULL;
|
||||
int table_id = maat_table_manager_get_table_id(maat_instance->table_mgr, table_name);
|
||||
struct maat_table_schema* ptable = maat_table_manager_get_table_desc(maat_instance->table_mgr, table_id);
|
||||
|
||||
if (maat_instance->rebuilding_maat_rt != NULL) {
|
||||
maat_rt = maat_instance->rebuilding_maat_rt;
|
||||
} else {
|
||||
maat_rt = maat_instance->maat_rt;
|
||||
}
|
||||
|
||||
//TODO: update rule for table_schema
|
||||
update_maat_runtime();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void maat_finish_cb(void *u_param)
|
||||
{
|
||||
struct maat *maat_instance = (struct maat *)u_param;
|
||||
|
||||
if (maat_instance->latest_maat_rt != NULL) {
|
||||
update_maat_runtime(maat_instance->latest_maat_rt);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
void *rule_monitor_loop(void *arg)
|
||||
{
|
||||
char err_str[NAME_MAX] = {0};
|
||||
struct maat *maat_instance = (struct maat *)arg;
|
||||
|
||||
while (maat_instance->is_running) {
|
||||
usleep(1000 * 1000);
|
||||
if( 0 == pthread_mutex_trylock(&(maat_instance->background_update_mutex))) {
|
||||
switch (maat_instance->rule_import_type) {
|
||||
case RULE_IMPORT_TYPE_IRIS:
|
||||
config_monitor_traverse(maat_instance->maat_version,
|
||||
maat_instance->iris_ctx.inc_dir,
|
||||
maat_start_cb,
|
||||
maat_update_cb,
|
||||
maat_finish_cb,
|
||||
maat_instance);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (maat_instance->latest_maat_rt != NULL) {
|
||||
struct maat_runtime *old_maat_rt = maat_instance->maat_rt;
|
||||
maat_instance->maat_rt = maat_instance->latest_maat_rt;
|
||||
|
||||
if (old_maat_rt != NULL) {
|
||||
|
||||
}
|
||||
|
||||
maat_instance->latest_maat_rt = NULL;
|
||||
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) {
|
||||
update_maat_runtime(maat_instance->maat_rt);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(maat_instance->background_update_mutex));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
126
src/maat_table_runtime.cpp
Normal file
126
src/maat_table_runtime.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_table_runtime.cpp
|
||||
* Description:
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <hs/hs.h>
|
||||
|
||||
#include "maat_utils.h"
|
||||
#include "maat_table_runtime.h"
|
||||
#include "uthash/uthash.h"
|
||||
#include "maat_ex_data.h"
|
||||
#include "adapter_hs.h"
|
||||
|
||||
struct maat_expr_runtime {
|
||||
struct adapter_hs *hs;
|
||||
//rcu_hash *htable;
|
||||
};
|
||||
|
||||
struct maat_ip_plugin_runtime {
|
||||
//struct ip_matcher* ip_matcher;
|
||||
struct ex_data_runtime* ex_data_rt;
|
||||
};
|
||||
|
||||
struct maat_table_runtime {
|
||||
enum maat_table_type table_type; // table schema已有type??
|
||||
uint32_t rule_num;
|
||||
|
||||
union {
|
||||
struct maat_expr_runtime *expr_rt;
|
||||
struct maat_ip_plugin_runtime *ip_plugin_rt;
|
||||
};
|
||||
|
||||
//ex_data_rt
|
||||
//table相关指针
|
||||
};
|
||||
|
||||
struct maat_table_runtime_manager {
|
||||
struct maat_table_runtime **table_rt;
|
||||
size_t n_table_rt;
|
||||
};
|
||||
|
||||
struct maat_table_runtime *table_runtime_new(enum maat_table_type table_type, int max_thread_num, struct maat_garbage_bin* bin)
|
||||
{
|
||||
struct maat_table_runtime *table_rt = ALLOC(struct maat_table_runtime, 1);
|
||||
table_rt->table_type = table_type;
|
||||
switch (table_type) {
|
||||
case TABLE_TYPE_EXPR:
|
||||
table_rt->expr_rt->ex_data_rt = ex_data_runtime_new(NULL);
|
||||
break;
|
||||
case TABLE_TYPE_IP_PLUGIN:
|
||||
table_rt->ip_plugin_rt->ex_data_rt = ex_data_runtime_new(NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return table_rt;
|
||||
}
|
||||
|
||||
void table_runtime_free(struct maat_table_runtime * table_rt)
|
||||
{
|
||||
switch (table_rt->table_type)
|
||||
{
|
||||
case TABLE_TYPE_EXPR:
|
||||
ex_data_runtime_free(table_rt->expr_rt->ex_data_rt);
|
||||
break;
|
||||
case TABLE_TYPE_IP_PLUGIN:
|
||||
ex_data_runtime_free(table_rt->ip_plugin_rt->ex_data_rt);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
free(table_rt);
|
||||
}
|
||||
|
||||
struct maat_table_runtime_manager *maat_table_runtime_manager_create(struct maat_table_manager *table_mgr, int max_thread_num, struct maat_garbage_bin* garbage_bin)
|
||||
{
|
||||
if (NULL == table_mgr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct maat_table_runtime_manager *table_rt_mgr = ALLOC(struct maat_table_runtime_manager, 1);
|
||||
table_rt_mgr->n_table_rt = maat_table_manager_get_size(table_mgr);
|
||||
table_rt_mgr->table_rt = ALLOC(struct maat_table_runtime *, table_rt_mgr->n_table_rt);
|
||||
|
||||
for (size_t i = 0; i < table_rt_mgr->n_table_rt; i++) {
|
||||
enum maat_table_type table_type = maat_table_manager_get_table_type(table_mgr, i);
|
||||
if (table_type == TABLE_TYPE_MAX) {
|
||||
continue;
|
||||
}
|
||||
table_rt_mgr->table_rt[i] = table_runtime_new(table_type, max_thread_num, garbage_bin);
|
||||
}
|
||||
|
||||
return table_rt_mgr;
|
||||
}
|
||||
|
||||
void maat_table_runtime_manager_destroy(struct maat_table_runtime_manager *table_rt_mgr)
|
||||
{
|
||||
for(size_t i = 0; i < table_rt_mgr->n_table_rt; i++) {
|
||||
table_runtime_free(table_rt_mgr->table_rt[i]);
|
||||
table_rt_mgr->table_rt[i] = NULL;
|
||||
}
|
||||
|
||||
free(table_rt_mgr->table_rt);
|
||||
table_rt_mgr->table_rt = NULL;
|
||||
free(table_rt_mgr);
|
||||
}
|
||||
|
||||
struct maat_table_runtime *maat_table_runtime_get(struct maat_table_runtime_manager *table_rt_mgr, int table_id)
|
||||
{
|
||||
assert(table_id < (int)table_rt_mgr->n_table_rt);
|
||||
return table_rt_mgr->table_rt[table_id];
|
||||
}
|
||||
|
||||
enum maat_table_type maat_table_runtime_get_type(struct maat_table_runtime* table_rt)
|
||||
{
|
||||
return table_rt->table_type;
|
||||
}
|
||||
456
src/maat_table_schema.cpp
Normal file
456
src/maat_table_schema.cpp
Normal file
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_table_schema.cpp
|
||||
* Description:
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "maat_utils.h"
|
||||
#include "maat_table_schema.h"
|
||||
#include "maat_kv.h"
|
||||
#include "cJSON.h"
|
||||
#include "adapter_hs.h"
|
||||
#include "maat_ex_data.h"
|
||||
|
||||
|
||||
#define MAX_TABLE_NUM 256
|
||||
#define MAX_TABLE_LINE_SIZE (1024 * 16)
|
||||
#define MAX_ITEM_STR 64
|
||||
|
||||
struct expr_item {
|
||||
int item_id;
|
||||
int group_id;
|
||||
char district[MAX_ITEM_STR]; //128
|
||||
char keywords[MAX_ITEM_STR]; //1k
|
||||
char expr_type[MAX_ITEM_STR];//enum
|
||||
char match_method[MAX_ITEM_STR]; //enum
|
||||
int is_hexbin;
|
||||
int case_sensitive;
|
||||
int is_valid;
|
||||
|
||||
//rule_tag; 只存在schema里
|
||||
//int have_exdata;
|
||||
//struct ex_data *ex_data; //hash表
|
||||
};
|
||||
|
||||
struct ip_plugin_item {
|
||||
int row_id;
|
||||
int ip_type;
|
||||
int start_ip;
|
||||
int end_ip;
|
||||
int valid_flag;
|
||||
int rule_tag;
|
||||
int have_exdata;
|
||||
struct ex_data *ex_data;
|
||||
};
|
||||
|
||||
struct maat_table_item {
|
||||
enum maat_table_type table_type;
|
||||
union {
|
||||
struct expr_item expr_item;
|
||||
struct ip_plugin_item ip_plugin_item;
|
||||
};
|
||||
};
|
||||
|
||||
struct expr_table_schema {
|
||||
int item_id_column;
|
||||
int group_id_column;
|
||||
int district_column;
|
||||
int keywords_column;
|
||||
int expr_type_column;
|
||||
int match_method_column;
|
||||
int is_hexbin_column;
|
||||
int case_sensitive_column;
|
||||
/* valid means add, invalid means delete */
|
||||
int is_valid_column;
|
||||
int have_exdata;
|
||||
struct ex_data_schema *ex_schema;
|
||||
};
|
||||
|
||||
struct ip_plugin_table_schema {
|
||||
int row_id_column;
|
||||
int ip_type_column;
|
||||
int start_ip_column;
|
||||
int end_ip_column;
|
||||
int valid_flag_column;
|
||||
int rule_tag_column;
|
||||
int have_exdata;
|
||||
struct ex_data_schema *ex_schema;
|
||||
};
|
||||
|
||||
struct maat_table_schema {
|
||||
int table_id;
|
||||
sds table_name;
|
||||
enum maat_table_type table_type;
|
||||
union {
|
||||
struct expr_table_schema expr;
|
||||
struct ip_plugin_table_schema ip_plugin;
|
||||
};
|
||||
};
|
||||
|
||||
struct maat_table_manager {
|
||||
struct maat_table_schema *schema_table[MAX_TABLE_NUM];
|
||||
size_t n_schema_table;
|
||||
|
||||
struct maat_kv_store *tablename2id_map;
|
||||
};
|
||||
|
||||
struct maat_table_schema *table_schema_new(void)
|
||||
{
|
||||
struct maat_table_schema *ptable = ALLOC(struct maat_table_schema, 1);
|
||||
|
||||
return ptable;
|
||||
}
|
||||
|
||||
void table_schema_free(struct maat_table_schema *ptable)
|
||||
{
|
||||
free(ptable);
|
||||
}
|
||||
|
||||
int read_expr_table_schema(cJSON *root, struct maat_table_schema *ptable)
|
||||
{
|
||||
int read_cnt = 0;
|
||||
cJSON *item = NULL;
|
||||
|
||||
item = cJSON_GetObjectItem(root, "table_id");
|
||||
if (item != NULL && item->type == cJSON_String) {
|
||||
ptable->table_id = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "table_name");
|
||||
if (item != NULL && item->type == cJSON_String) {
|
||||
memcpy(ptable->table_name, item->valuestring, strlen(item->valuestring));
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "item_id");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->expr.item_id_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "group_id");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->expr.group_id_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "district");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->expr.district_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "keywords");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->expr.keywords_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "expr_type");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->expr.expr_type_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "match_method");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->expr.match_method_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "is_hexbin");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->expr.is_hexbin_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "case_sensitive");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->expr.case_sensitive_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "is_valid");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->expr.is_valid_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
if (read_cnt < 10) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int read_ip_plugin_table_schema(cJSON *root, struct maat_table_schema *ptable)
|
||||
{
|
||||
int read_cnt = 0;
|
||||
cJSON *item = NULL;
|
||||
|
||||
item = cJSON_GetObjectItem(root, "table_id");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->table_id = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "table_name");
|
||||
if (item != NULL && item->type == cJSON_String) {
|
||||
memcpy(ptable->table_name, item->valuestring, strlen(item->valuestring));
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "row_id");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->ip_plugin.row_id_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "ip_type");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->ip_plugin.ip_type_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "start_ip");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->ip_plugin.start_ip_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "end_ip");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->ip_plugin.end_ip_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "valid");
|
||||
if (item != NULL && item->type == cJSON_Number) {
|
||||
ptable->ip_plugin.valid_flag_column = item->valueint;
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
if (read_cnt < 7) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int table_schema_populate(const char *line, struct maat_table_schema *ptable,
|
||||
struct maat_kv_store* reserved_word_map)
|
||||
{
|
||||
int ret = -1;
|
||||
int read_cnt = 0;
|
||||
cJSON *root = NULL;
|
||||
cJSON *item = NULL;
|
||||
sds copy_line = sdsnew(line);
|
||||
sds table_type_str = NULL;
|
||||
|
||||
root = cJSON_Parse(copy_line);
|
||||
if (NULL == root) {
|
||||
goto next;
|
||||
}
|
||||
|
||||
item = cJSON_GetObjectItem(root, "table_type");
|
||||
if (item != NULL && item->type == cJSON_String) {
|
||||
table_type_str = sdsnew(item->valuestring);
|
||||
read_cnt++;
|
||||
}
|
||||
|
||||
ret = maat_kv_read(reserved_word_map, table_type_str, (int*)&(ptable->table_type));
|
||||
if (ret < 0) {
|
||||
goto next;
|
||||
}
|
||||
|
||||
switch (ptable->table_type) {
|
||||
case TABLE_TYPE_EXPR:
|
||||
ret = read_expr_table_schema(root, ptable);
|
||||
if (ret < 0) {
|
||||
goto next;
|
||||
}
|
||||
break;
|
||||
case TABLE_TYPE_IP_PLUGIN:
|
||||
ret = read_ip_plugin_table_schema(root, ptable);
|
||||
if (ret < 0) {
|
||||
goto next;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
next:
|
||||
cJSON_Delete(root);
|
||||
sdsfree(copy_line);
|
||||
if (table_type_str != NULL) {
|
||||
sdsfree(table_type_str);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct maat_table_manager *maat_table_manager_create(sds table_info_path)
|
||||
{
|
||||
FILE *fp = fopen(table_info_path, "r");
|
||||
if (NULL == fp) {
|
||||
fprintf(stderr,"Maat read table info %s error.\n",table_info_path);
|
||||
//log_error()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct maat_kv_store* reserved_word_map = maat_kv_store_new();
|
||||
/* register table type reserved word */
|
||||
maat_kv_register(reserved_word_map, "expr", TABLE_TYPE_EXPR);
|
||||
maat_kv_register(reserved_word_map, "ip_plugin", TABLE_TYPE_IP_PLUGIN);
|
||||
|
||||
int i = 0;
|
||||
char line[MAX_TABLE_LINE_SIZE] = {0};
|
||||
struct maat_table_manager *table_mgr = ALLOC(struct maat_table_manager, 1);
|
||||
struct maat_table_schema **pptable = table_mgr->schema_table;
|
||||
table_mgr->tablename2id_map = maat_kv_store_new();
|
||||
|
||||
while (NULL != fgets(line, sizeof(line), fp)) {
|
||||
i++;
|
||||
|
||||
if (line[0] == '#' || line[0] == ' ' || line[0] == '\t') {
|
||||
continue;
|
||||
}
|
||||
|
||||
struct maat_table_schema *table_schema = table_schema_new();
|
||||
int ret = table_schema_populate(line, table_schema, reserved_word_map);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Maat read table info %s line %d error: illegal table schema.\n",
|
||||
table_info_path, i);
|
||||
//log_error()
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (table_schema->table_id >= MAX_TABLE_NUM) {
|
||||
fprintf(stderr,"Maat read table info %s:%d error: table id %uh > %zu.\n",
|
||||
table_info_path, i, table_schema->table_id, MAX_TABLE_NUM);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = maat_kv_register(table_mgr->tablename2id_map, table_schema->table_name, table_schema->table_id);
|
||||
if (ret < 0) {
|
||||
//log_error("Duplicate table %s of table id %d", table_schema->table_name, table_schema->table_id);
|
||||
goto error;
|
||||
}
|
||||
|
||||
pptable[table_schema->table_id] = table_schema;
|
||||
table_mgr->n_schema_table++;
|
||||
continue;
|
||||
error:
|
||||
table_schema_free(table_schema);
|
||||
}
|
||||
maat_kv_store_free(reserved_word_map);
|
||||
|
||||
return table_mgr;
|
||||
}
|
||||
|
||||
void maat_table_manager_destroy(struct maat_table_manager *table_mgr)
|
||||
{
|
||||
for (size_t i = 0; i < MAX_TABLE_NUM; i++) {
|
||||
if (NULL == table_mgr->schema_table[i]) {
|
||||
continue;
|
||||
}
|
||||
table_schema_free(table_mgr->schema_table[i]);
|
||||
table_mgr->schema_table[i] = NULL;
|
||||
}
|
||||
|
||||
maat_kv_store_free(table_mgr->tablename2id_map);
|
||||
free(table_mgr);
|
||||
}
|
||||
|
||||
int maat_table_manager_get_table_id(struct maat_table_manager* table_mgr, sds table_name)
|
||||
{
|
||||
int table_id = -1;
|
||||
|
||||
int ret=maat_kv_read(table_mgr->tablename2id_map, table_name, &table_id);
|
||||
if (ret > 0) {
|
||||
return table_id;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
enum maat_table_type maat_table_manager_get_table_type(struct maat_table_manager *table_mgr, int id)
|
||||
{
|
||||
if (table_mgr->schema_table[id] == NULL) {
|
||||
return TABLE_TYPE_MAX;
|
||||
}
|
||||
|
||||
return table_mgr->schema_table[id]->table_type;
|
||||
}
|
||||
|
||||
size_t maat_table_manager_get_size(struct maat_table_manager* table_mgr)
|
||||
{
|
||||
return table_mgr->n_schema_table;
|
||||
}
|
||||
|
||||
int populate_expr_table_item(sds line, struct expr_table_schema *expr_schema, struct expr_item *expr_item)
|
||||
{
|
||||
size_t column_offset = 0;
|
||||
size_t column_len = 0;
|
||||
|
||||
int ret = get_column_pos(line, expr_schema->item_id_column, &column_offset, &column_len);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
expr_item->item_id = atoi(line + column_offset);
|
||||
|
||||
ret = get_column_pos(line, expr_schema->group_id_column, &column_offset, &column_len);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
expr_item->group_id = atoi(line + column_offset);
|
||||
|
||||
}
|
||||
|
||||
int populate_ip_plugin_table_item(sds line, struct ip_plugin_table_schema *ip_plugin_schema, struct ip_plugin_item *ip_plugin_item)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct maat_table_item *
|
||||
maat_table_line_to_item(sds line, struct maat_table_schema *table_schema)
|
||||
{
|
||||
int ret = -1;
|
||||
struct maat_table_item *table_item = ALLOC(struct maat_table_item, 1);
|
||||
|
||||
switch (table_schema->table_type)
|
||||
{
|
||||
case TABLE_TYPE_EXPR:
|
||||
table_item->table_type = TABLE_TYPE_EXPR;
|
||||
ret = populate_expr_table_item(line, &table_schema->expr, &table_item->expr_item);
|
||||
if (ret < 0) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
case TABLE_TYPE_IP_PLUGIN:
|
||||
table_item->table_type = TABLE_TYPE_IP_PLUGIN;
|
||||
ret = populate_ip_plugin_table_item(line, &table_schema->ip_plugin, &table_item->ip_plugin_item);
|
||||
if (ret < 0) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return table_item;
|
||||
error:
|
||||
free(table_item);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
35
src/maat_utils.cpp
Normal file
35
src/maat_utils.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_utils.cpp
|
||||
* Description:
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#include "maat_utils.h"
|
||||
|
||||
int get_column_pos(sds line, int column_seq, size_t *offset, size_t *len)
|
||||
{
|
||||
const char* seps=" \t";
|
||||
char* saveptr=NULL, *subtoken=NULL, *str=NULL;
|
||||
sds dup_line = sdsdup(line);
|
||||
int i=0, ret=-1;
|
||||
for (str = dup_line; ; str = NULL)
|
||||
{
|
||||
subtoken = strtok_r(str, seps, &saveptr);
|
||||
if (subtoken == NULL)
|
||||
break;
|
||||
if(i==column_seq-1)
|
||||
{
|
||||
*offset=subtoken-dup_line;
|
||||
*len=strlen(subtoken);
|
||||
ret=0;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
free(dup_line);
|
||||
return ret;
|
||||
}
|
||||
227
src/rcu_hash.cpp
Normal file
227
src/rcu_hash.cpp
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
**********************************************************************************************
|
||||
* File: maat_rhash.cpp
|
||||
* Description:
|
||||
* Authors: Liu WenTan <liuwentan@geedgenetworks.com>
|
||||
* Date: 2022-10-31
|
||||
* Copyright: (c) 2018-2022 Geedge Networks, Inc. All rights reserved.
|
||||
***********************************************************************************************
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "rcu_hash.h"
|
||||
#include "maat_utils.h"
|
||||
#include "maat_garbage_collection.h"
|
||||
|
||||
#define GARBAGE_DEFAULT_TIMEOUT 60
|
||||
|
||||
struct rcu_hash_table {
|
||||
int is_updating;
|
||||
char effective_hash; // 'a' or 'b'
|
||||
|
||||
/* two hash map for rcu */
|
||||
struct rcu_hash_node *hashmap_a;
|
||||
struct rcu_hash_node *hashmap_b;
|
||||
|
||||
void (* data_free)(void *data);
|
||||
struct maat_garbage_bin *garbage_bin;
|
||||
|
||||
pthread_mutex_t update_mutex;
|
||||
};
|
||||
|
||||
struct rcu_hash_node {
|
||||
char *key;
|
||||
size_t key_len;
|
||||
void *data; //table_runtime解析成两个成员
|
||||
|
||||
UT_hash_handle hh_a;
|
||||
UT_hash_handle hh_b;
|
||||
};
|
||||
|
||||
void rcu_hash_node_free(struct rcu_hash_node *node, void (* data_free)(void *data))
|
||||
{
|
||||
if (node->key != NULL) {
|
||||
free(node->key);
|
||||
}
|
||||
|
||||
if (node->data != NULL) {
|
||||
data_free(node->data);
|
||||
}
|
||||
|
||||
free(node);
|
||||
}
|
||||
|
||||
struct rcu_hash_table *rcu_hash_new(void (* data_free)(void *data))
|
||||
{
|
||||
if (NULL == data_free) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct rcu_hash_table *htable = ALLOC(struct rcu_hash_table, 1);
|
||||
|
||||
htable->is_updating = 0;
|
||||
htable->effective_hash = 'a';
|
||||
htable->garbage_bin = maat_garbage_bin_new(GARBAGE_DEFAULT_TIMEOUT);
|
||||
htable->data_free = data_free;
|
||||
pthread_mutex_init(&htable->update_mutex, NULL);
|
||||
|
||||
return htable;
|
||||
}
|
||||
|
||||
void rcu_hash_free(struct rcu_hash_table *htable)
|
||||
{
|
||||
struct rcu_hash_node *tmp = NULL;
|
||||
struct rcu_hash_node *item = NULL;
|
||||
|
||||
if (htable != NULL) {
|
||||
HASH_ITER(hh_a, htable->hashmap_a, item, tmp) {
|
||||
HASH_DELETE(hh_a, htable->hashmap_a, item);
|
||||
rcu_hash_node_free(item, htable->data_free);
|
||||
}
|
||||
|
||||
HASH_ITER(hh_b, htable->hashmap_b, item, tmp) {
|
||||
HASH_DELETE(hh_b, htable->hashmap_b, item);
|
||||
rcu_hash_node_free(item, htable->data_free);
|
||||
}
|
||||
}
|
||||
|
||||
maat_garbage_bin_free(htable->garbage_bin);
|
||||
pthread_mutex_destroy(&htable->update_mutex);
|
||||
|
||||
free(htable);
|
||||
}
|
||||
|
||||
void rcu_hash_update_prepare(struct rcu_hash_table *htable)
|
||||
{
|
||||
struct rcu_hash_node *node = NULL;
|
||||
struct rcu_hash_node *tmp = NULL;
|
||||
|
||||
if (htable->effective_hash == 'a') {
|
||||
assert(htable->hashmap_b == NULL);
|
||||
HASH_ITER(hh_a, htable->hashmap_a, node, tmp) {
|
||||
HASH_ADD_KEYPTR(hh_b, htable->hashmap_b, node->key, node->key_len, node);
|
||||
}
|
||||
} else {
|
||||
assert(htable->hashmap_a == NULL);
|
||||
HASH_ITER(hh_b, htable->hashmap_b, node, tmp) {
|
||||
HASH_ADD_KEYPTR(hh_a, htable->hashmap_a, node->key, node->key_len, node);
|
||||
}
|
||||
}
|
||||
|
||||
htable->is_updating = 1;
|
||||
}
|
||||
|
||||
void rcu_hash_add(struct rcu_hash_table *htable, const char *key, size_t key_len, void *data)
|
||||
{
|
||||
struct rcu_hash_node *node = ALLOC(struct rcu_hash_node, 1);
|
||||
memcpy(node->key, key, key_len);
|
||||
node->key_len = key_len;
|
||||
node->data = data;
|
||||
|
||||
if (!htable->is_updating) {
|
||||
rcu_hash_update_prepare(htable);
|
||||
}
|
||||
|
||||
if (htable->effective_hash == 'a') {
|
||||
HASH_FIND(hh_b, htable->hashmap_b, key, key_len, node);
|
||||
if (NULL == node) {
|
||||
HASH_ADD_KEYPTR(hh_b, htable->hashmap_b, key, key_len, node);
|
||||
}
|
||||
} else {
|
||||
HASH_FIND(hh_a, htable->hashmap_a, key, key_len, node);
|
||||
if (NULL == node) {
|
||||
HASH_ADD_KEYPTR(hh_a, htable->hashmap_a, key, key_len, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rcu_hash_del(struct rcu_hash_table *htable, const char *key, size_t key_len)
|
||||
{
|
||||
struct rcu_hash_node *node = NULL;
|
||||
|
||||
if (!htable->is_updating) {
|
||||
rcu_hash_update_prepare(htable);
|
||||
}
|
||||
|
||||
if (htable->effective_hash == 'a') {
|
||||
HASH_FIND(hh_b, htable->hashmap_b, key, key_len, node);
|
||||
if (node != NULL) {
|
||||
HASH_DELETE(hh_b, htable->hashmap_b, node);
|
||||
}
|
||||
} else {
|
||||
HASH_FIND(hh_a, htable->hashmap_a, key, key_len, node);
|
||||
if (node != NULL) {
|
||||
HASH_DELETE(hh_a, htable->hashmap_a, node);
|
||||
}
|
||||
}
|
||||
|
||||
if (node != NULL) {
|
||||
maat_garbage_bagging(htable->garbage_bin, node, (void (*)(void*))rcu_hash_node_free);
|
||||
}
|
||||
}
|
||||
|
||||
void *rcu_hash_find(struct rcu_hash_table *htable, const char *key, size_t key_len)
|
||||
{
|
||||
struct rcu_hash_node *node = NULL;
|
||||
|
||||
if (htable->effective_hash == 'a') {
|
||||
HASH_FIND(hh_a, htable->hashmap_a, key, key_len, node);
|
||||
if (node != NULL) {
|
||||
return node->data;
|
||||
}
|
||||
} else {
|
||||
HASH_FIND(hh_b, htable->hashmap_b, key, key_len, node);
|
||||
if (node != NULL) {
|
||||
return node->data;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t rcu_hash_counts(struct rcu_hash_table *htable)
|
||||
{
|
||||
if (htable->effective_hash == 'a') {
|
||||
return HASH_CNT(hh_a, htable->hashmap_a);
|
||||
} else {
|
||||
return HASH_CNT(hh_b, htable->hashmap_b);
|
||||
}
|
||||
}
|
||||
|
||||
void rcu_hash_commit(struct rcu_hash_table *htable)
|
||||
{
|
||||
if (!htable->is_updating) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct rcu_hash_node *node = NULL;
|
||||
struct rcu_hash_node *tmp = NULL;
|
||||
|
||||
pthread_mutex_lock(&htable->update_mutex);
|
||||
if (!htable->is_updating) {
|
||||
pthread_mutex_unlock(&htable->update_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
/* updating hash_map is ready, so change effective hash_map */
|
||||
if (htable->effective_hash == 'a') {
|
||||
htable->effective_hash = 'b';
|
||||
usleep(100);
|
||||
HASH_ITER(hh_a, htable->hashmap_a, node, tmp) {
|
||||
HASH_DELETE(hh_a, htable->hashmap_a, node);
|
||||
}
|
||||
} else {
|
||||
htable->effective_hash = 'a';
|
||||
usleep(100);
|
||||
HASH_ITER(hh_b, htable->hashmap_b, node, tmp) {
|
||||
HASH_DELETE(hh_b, htable->hashmap_b, node);
|
||||
}
|
||||
}
|
||||
htable->is_updating = 0;
|
||||
//maat_garbage_collect_by_force(htable->garbage_bin);
|
||||
//rcu_garbage
|
||||
pthread_mutex_unlock(&htable->update_mutex);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../deps/uthash/uthash.h"
|
||||
|
||||
struct sub_string_pattern
|
||||
{
|
||||
int is_regex;
|
||||
size_t len;
|
||||
char *pattern;
|
||||
};
|
||||
struct string_pattern
|
||||
{
|
||||
unsigned int item_id;
|
||||
unsigned int group_id;
|
||||
char district[128];
|
||||
size_t n_sub_pattern;
|
||||
struct sub_string_pattern *sub_pattern;
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
struct string_schema
|
||||
{
|
||||
int item_id_column;
|
||||
int district_column;
|
||||
int pattern_column;
|
||||
int is_regex_column;
|
||||
int valid_flag_column;
|
||||
int rule_tag_column;
|
||||
int have_exdata;
|
||||
struct EX_data_schema ex_schema;
|
||||
};
|
||||
struct string_runtime
|
||||
{
|
||||
struct hs_db_t *pure_literal_db;
|
||||
struct hs_db_t *regex_db;
|
||||
struct bool_matcher *bool_matcher;
|
||||
struct string_pattern *hash_effect_item;
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
struct ip_runtime
|
||||
{
|
||||
EX_data_rt *effect_items;
|
||||
struct ip_matcher *matcher;
|
||||
};
|
||||
struct table_runtime
|
||||
{
|
||||
struct hash_table item_hash;
|
||||
enum table_type type;
|
||||
union
|
||||
{
|
||||
struct ip_runtime *ip_rt;
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user