From c994077c3bea80197c214dcf9f972678a8f08bbb Mon Sep 17 00:00:00 2001 From: luqiuwen Date: Sat, 8 Jun 2019 19:41:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=8B=AC=E7=AB=8B=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96maat=E5=8F=A5=E6=9F=84=E7=9A=84=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- platform/CMakeLists.txt | 7 +- plugin/business/traffic-mirror/src/entry.cpp | 173 +++++++++++++++++-- 2 files changed, 160 insertions(+), 20 deletions(-) diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt index 5f0648f..5af17f9 100644 --- a/platform/CMakeLists.txt +++ b/platform/CMakeLists.txt @@ -30,10 +30,6 @@ if(ENABLE_PLUGIN_HTTP2) target_link_libraries(tfe -Wl,--whole-archive http2 -Wl,--no-whole-archive) endif() -if(ENABLE_PLUGIN_TRAFFIC_MIRROR) - target_link_libraries(tfe -Wl,--whole-archive traffic-mirror -Wl,--no-whole-archive) -endif() - if(ENABLE_PLUGIN_PANGU_HTTP) target_link_libraries(tfe -Wl,--whole-archive pangu-http -Wl,--no-whole-archive) endif() @@ -42,6 +38,9 @@ if(ENABLE_PLUGIN_SSL_POLICY) target_link_libraries(tfe -Wl,--whole-archive ssl-policy -Wl,--no-whole-archive) endif() +if(ENABLE_PLUGIN_TRAFFIC_MIRROR) + target_link_libraries(tfe -Wl,--whole-archive traffic-mirror -Wl,--no-whole-archive) +endif() install(TARGETS tfe RUNTIME DESTINATION bin COMPONENT Program) diff --git a/plugin/business/traffic-mirror/src/entry.cpp b/plugin/business/traffic-mirror/src/entry.cpp index dd29638..23a2f61 100644 --- a/plugin/business/traffic-mirror/src/entry.cpp +++ b/plugin/business/traffic-mirror/src/entry.cpp @@ -3,9 +3,9 @@ #include #include #include -#include "../include/traffic_mirror.h" -extern Maat_feather_t g_business_maat; +#include +#include struct traffic_mirror_me { @@ -81,7 +81,7 @@ void policy_table_ex_data_new_cb(int table_id, const char * key, const char * ta ex_data->profile_id = 0; json_item = cJSON_GetObjectItem(json_subroot, "enable"); - if (unlikely(!json_item || cJSON_IsNumber(json_item))) + if (unlikely(!json_item || !cJSON_IsNumber(json_item))) { TFE_LOG_ERROR(instance->logger, "invalid JSON, decrypt_mirror->enable not existed or invalid type."); goto ignore; @@ -94,7 +94,7 @@ void policy_table_ex_data_new_cb(int table_id, const char * key, const char * ta } json_item = cJSON_GetObjectItem(json_subroot, "mirror_profile"); - if (unlikely(!json_item || cJSON_IsNumber(json_item))) + if (unlikely(!json_item || !cJSON_IsNumber(json_item))) { TFE_LOG_ERROR(instance->logger, "invalid JSON, decrypt_mirror->mirror_profile not existed or invalid type."); goto ignore; @@ -103,11 +103,16 @@ void policy_table_ex_data_new_cb(int table_id, const char * key, const char * ta success: TFE_LOG_DEBUG(instance->logger, "table line in PXY_INTERCEPT_COMPILE added: %s", table_line); *ad = ex_data; + + fprintf(stderr, "---- ex_data = %p, atomic_refcnt = %d, enable = %d, profile_id = %d\n", + ex_data, ex_data->atomic_refcnt, ex_data->profile_id); + ex_data = nullptr; goto out; ignore: TFE_LOG_ERROR(instance->logger, "table line in PXY_INTERCEPT_COMPILE ignored: %s", table_line); + *ad = nullptr; goto out; out: @@ -187,19 +192,29 @@ void profile_table_ex_data_new_cb(int table_id, const char * key, const char * t unsigned int iter = 0; cJSON_ArrayForEach(element, json_item) { - if (unlikely(!cJSON_IsNumber(element))) + if (unlikely(!cJSON_IsString(element))) { TFE_LOG_ERROR(instance->logger, "invalid JSON, " - "elements in mirror_profile->vlan is not a number"); + "elements in mirror_profile->vlan is not a string"); goto ignore; } - ex_data->vlans[iter] = element->valueint; + unsigned int vlan_in_number = 0; + sscanf(element->valuestring, "%u", &vlan_in_number); + + if (unlikely(vlan_in_number <= 0 || vlan_in_number > 4094)) + { + TFE_LOG_ERROR(instance->logger, "invalid JSON, " + "vlan id must between 1 and 4094."); + goto ignore; + } + + ex_data->vlans[iter] = vlan_in_number; ex_data->ether_addrs[iter] = ether_addr_broadcast; iter++; } - assert(iter + 1 == ex_data->nr_targets); + assert(iter == ex_data->nr_targets); goto success; } @@ -240,7 +255,8 @@ void profile_table_ex_data_new_cb(int table_id, const char * key, const char * t iter++; } - assert(iter + 1 == ex_data->nr_targets); + assert(iter == ex_data->nr_targets); + goto success; } success: @@ -252,6 +268,7 @@ success: ignore: TFE_LOG_ERROR(instance->logger, "table line in PXY_PROFILE_TRAFFIC_MIRROR ignored: %s", table_line); + *ad = nullptr; goto out; out: @@ -271,15 +288,136 @@ out: } } +#define MAAT_INPUT_JSON 0 +#define MAAT_INPUT_REDIS 1 +#define MAAT_INPUT_FILE 2 + +static Maat_feather_t maat_feather_create(const char * instance_name, + const char * profile, const char * section, unsigned int max_thread, void * logger) +{ + Maat_feather_t target; + int input_mode = 0, maat_stat_on = 0, maat_perf_on = 0; + int ret = 0, scan_detail = 0, effect_interval = 60; + + char table_info[TFE_STRING_MAX] = {0}, inc_cfg_dir[TFE_STRING_MAX] = {0}, ful_cfg_dir[TFE_STRING_MAX] = {0}; + char redis_server[TFE_STRING_MAX] = {0}; + char redis_port_range[TFE_STRING_MAX] = {0}; + char accept_tags[TFE_STRING_MAX] = {0}; + int redis_port_begin = 0, redis_port_end = 0; + int redis_port_select = 0; + int redis_db_idx = 0; + + char json_cfg_file[TFE_STRING_MAX] = {0}; + char maat_stat_file[TFE_STRING_MAX] = {0}; + + MESA_load_profile_int_def(profile, section, "maat_input_mode", &(input_mode), 0); + MESA_load_profile_int_def(profile, section, "stat_switch", &(maat_stat_on), 1); + MESA_load_profile_int_def(profile, section, "perf_switch", &(maat_perf_on), 1); + MESA_load_profile_string_def(profile, section, "table_info", table_info, sizeof(table_info), ""); + MESA_load_profile_string_def(profile, section, "accept_tags", accept_tags, sizeof(accept_tags), ""); + MESA_load_profile_string_def(profile, section, "json_cfg_file", json_cfg_file, sizeof(json_cfg_file), ""); + MESA_load_profile_string_def(profile, section, "maat_redis_server", redis_server, sizeof(redis_server), ""); + MESA_load_profile_string_def(profile, section, "maat_redis_port_range", redis_port_range, sizeof(redis_server), + "6379"); + + ret = sscanf(redis_port_range, "%d-%d", &redis_port_begin, &redis_port_end); + if (ret == 1) + { + redis_port_select = redis_port_begin; + } + else if (ret == 2) + { + srand(time(NULL)); + redis_port_select = redis_port_begin + rand() % (redis_port_end - redis_port_begin); + } + else + { + TFE_LOG_ERROR(logger, "Invalid redis port range %s, MAAT init failed.", redis_port_range); + } + + MESA_load_profile_int_def(profile, section, "maat_redis_db_index", &(redis_db_idx), 0); + MESA_load_profile_string_def(profile, section, "inc_cfg_dir", inc_cfg_dir, sizeof(inc_cfg_dir), ""); + MESA_load_profile_string_def(profile, section, "full_cfg_dir", ful_cfg_dir, sizeof(ful_cfg_dir), ""); + + MESA_load_profile_string_def(profile, section, "stat_file", maat_stat_file, sizeof(maat_stat_file), ""); + MESA_load_profile_int_def(profile, section, "effect_interval_s", &(effect_interval), 60); + + effect_interval *= 1000;//convert s to ms + assert(strlen(inc_cfg_dir) != 0 || strlen(ful_cfg_dir) != 0 || strlen(redis_server) != 0 + || strlen(json_cfg_file) != 0); + + target = Maat_feather(max_thread, table_info, logger); + Maat_set_feather_opt(target, MAAT_OPT_INSTANCE_NAME, instance_name, strlen(instance_name) + 1); + switch (input_mode) + { + case MAAT_INPUT_JSON: + Maat_set_feather_opt(target, MAAT_OPT_JSON_FILE_PATH, json_cfg_file, strlen(json_cfg_file) + 1); + break; + case MAAT_INPUT_REDIS:Maat_set_feather_opt(target, MAAT_OPT_REDIS_IP, redis_server, strlen(redis_server) + 1); + Maat_set_feather_opt(target, MAAT_OPT_REDIS_PORT, &redis_port_select, sizeof(redis_port_select)); + Maat_set_feather_opt(target, MAAT_OPT_REDIS_INDEX, &redis_db_idx, sizeof(redis_db_idx)); + break; + case MAAT_INPUT_FILE: Maat_set_feather_opt(target, MAAT_OPT_FULL_CFG_DIR, ful_cfg_dir, strlen(ful_cfg_dir) + 1); + Maat_set_feather_opt(target, MAAT_OPT_INC_CFG_DIR, inc_cfg_dir, strlen(inc_cfg_dir) + 1); + break; + default: TFE_LOG_ERROR(logger, "Invalid MAAT Input Mode: %d.", input_mode); + goto error_out; + break; + } + + Maat_set_feather_opt(target, MAAT_OPT_FOREIGN_CONT_DIR, "./pangu_files", strlen("./pangu_files") + 1); + if (maat_stat_on) + { + Maat_set_feather_opt(target, MAAT_OPT_STAT_FILE_PATH, maat_stat_file, strlen(maat_stat_file) + 1); + Maat_set_feather_opt(target, MAAT_OPT_STAT_ON, NULL, 0); + if (maat_perf_on) + { + Maat_set_feather_opt(target, MAAT_OPT_PERF_ON, NULL, 0); + } + } + + Maat_set_feather_opt(target, MAAT_OPT_EFFECT_INVERVAL_MS, &effect_interval, sizeof(effect_interval)); + Maat_set_feather_opt(target, MAAT_OPT_SCAN_DETAIL, &scan_detail, sizeof(scan_detail)); + if (strlen(accept_tags) > 0) + { + Maat_set_feather_opt(target, MAAT_OPT_ACCEPT_TAGS, &accept_tags, sizeof(accept_tags)); + } + + ret = Maat_initiate_feather(target); + if (ret < 0) + { + TFE_LOG_ERROR(logger, "%s MAAT init failed.", __FUNCTION__); + goto error_out; + } + + return target; +error_out: + Maat_burn_feather(target); + return NULL; +} + int traffic_mirror_init(struct tfe_proxy * proxy) { int result = 0; struct traffic_mirror_instance * instance = g_traffic_mirror_instance; + /* Using PANGU-HTTP's profile */ + const char * profile = "./conf/pangu/pangu_pxy.conf"; + const char * section = "maat"; + /* INIT DECRYPT MIRROR INSTANCE */ - instance->maat_feather = g_business_maat; - instance->logger = tfe_proxy_get_error_logger(); - instance->nr_threads = tfe_proxy_get_work_thread_count(); + instance->logger = tfe_proxy_get_error_logger(); + instance->nr_threads = tfe_proxy_get_work_thread_count(); + + /* MAAT Feather, the configuration is same with pangu-http */ + instance->maat_feather = maat_feather_create("traffic-mirror", profile, section, + instance->nr_threads, instance->logger); + + if (unlikely(!instance->maat_feather)) + { + TFE_LOG_ERROR(instance->logger, "failed at creating maat feather."); + goto errout; + } /* REGISTER MAAT FEATHER */ instance->policy_table_id = Maat_table_register(instance->maat_feather, "PXY_INTERCEPT_COMPILE"); @@ -307,8 +445,8 @@ int traffic_mirror_init(struct tfe_proxy * proxy) goto errout; } - result = Maat_plugin_EX_register(instance->maat_feather, instance->policy_table_id, - profile_table_ex_data_new_cb, profile_table_ex_data_free_cb, policy_table_ex_data_dup_cb, + result = Maat_plugin_EX_register(instance->maat_feather, instance->profile_table_id, + profile_table_ex_data_new_cb, profile_table_ex_data_free_cb, profile_table_ex_data_dup_cb, nullptr, 0, instance); if (unlikely(result < 0)) @@ -332,8 +470,8 @@ int traffic_mirror_on_open_cb(const struct tfe_stream * stream, unsigned int thr assert(instance != NULL); assert(cmsg != NULL); - char str_policy_id[TFE_SYMBOL_MAX]; - char str_profile_id[TFE_SYMBOL_MAX]; + char str_policy_id[TFE_SYMBOL_MAX] = {0}; + char str_profile_id[TFE_SYMBOL_MAX] = {0}; unsigned int opt_val; uint16_t opt_out_size; @@ -352,6 +490,8 @@ int traffic_mirror_on_open_cb(const struct tfe_stream * stream, unsigned int thr policy_ex_data = (struct policy_table_ex_data *)Maat_plugin_get_EX_data(instance->maat_feather, instance->policy_table_id, str_policy_id); + fprintf(stderr, "--- policy lookup, str_policy_id = %s, opt_val = %u\n", str_policy_id, opt_val); + if (!policy_ex_data) { TFE_LOG_ERROR(instance->logger, "failed at getting policy %s's EXDATA, detach the stream", str_policy_id); @@ -411,6 +551,7 @@ enum tfe_stream_action traffic_mirror_on_data_cb(const struct tfe_stream * strea { struct traffic_mirror_me * me = (struct traffic_mirror_me *)(*pme); traffic_mirror_rebuild_data(me->rebuild_ctx, (const char *)data, (size_t)len, dir); + return ACTION_FORWARD_DATA; } void traffic_mirror_on_close_cb(const struct tfe_stream * stream, unsigned int thread_id,