summaryrefslogtreecommitdiff
path: root/decoders/session_flags/session_flags_plugin.cpp
diff options
context:
space:
mode:
authorroot <[email protected]>2024-09-03 07:01:58 +0000
committerroot <[email protected]>2024-09-03 07:01:58 +0000
commit6f1ac6b36b28d082cebf8e4c3eeedd592c1946f9 (patch)
tree5c664bc282e5c01b634430531e43dae44dc50538 /decoders/session_flags/session_flags_plugin.cpp
parenta8206cffc0ba55c6cb2b0b1054860ee28ec4a0b8 (diff)
add socks_decoder, stratum_decoder and session_flags
Diffstat (limited to 'decoders/session_flags/session_flags_plugin.cpp')
-rw-r--r--decoders/session_flags/session_flags_plugin.cpp404
1 files changed, 404 insertions, 0 deletions
diff --git a/decoders/session_flags/session_flags_plugin.cpp b/decoders/session_flags/session_flags_plugin.cpp
new file mode 100644
index 0000000..db9522c
--- /dev/null
+++ b/decoders/session_flags/session_flags_plugin.cpp
@@ -0,0 +1,404 @@
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include "mesa_sts.h"
+#include "cJSON.h"
+#include "stellar/stellar.h"
+#include "stellar/session.h"
+#include "stellar/stellar_mq.h"
+#include "stellar/stellar_exdata.h"
+#include "stellar/log.h"
+
+#include "session_flags_internal.h"
+
+#define _MAX_STR_LEN 64
+
+#define UNUSED(x) (void)(x)
+
+const char *CFG_FILE_PATH="./etc/session_flags/session_flags.toml";
+
+uint32_t sts_random_switch = 0;
+
+struct session_flags_init_conf g_sf_conf;
+
+static const char* random_looking_judge_table[] = {
+ "frequency",
+ "block_frequency",
+ "cumulative_sums",
+ "runs",
+ "longest_run",
+ "rank",
+ "non_overlapping_template_matching",
+ "overlapping_template_matching",
+ "universal",
+ "random_excursions",
+ "random_excursions_variant",
+ "poker_detect",
+ "runs_distribution",
+ "self_correlation",
+ "binary_derivative"
+};
+
+static void session_flags_topic_free_cb(void *msg, void *msg_free_arg)
+{
+ UNUSED(msg_free_arg);
+ struct session_flags_message *flags = (struct session_flags_message *)msg;
+
+ if (flags)
+ {
+ if (flags->packet_sequence_array)
+ {
+ free(flags->packet_sequence_array);
+ }
+ free(flags);
+ }
+
+ return;
+}
+
+static void session_flags_exdata_free_cb(int idx, void *ex_ptr, void *arg)
+{
+ UNUSED(idx);
+ UNUSED(arg);
+
+ if (ex_ptr == NULL)
+ {
+ return;
+ }
+ struct session_flags_ctx *ctx = (struct session_flags_ctx *)ex_ptr;
+ tunneling_hs_stream_free(ctx);
+
+ free(ex_ptr);
+}
+
+void session_flags_entry(struct session *session, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env)
+{
+ UNUSED(per_session_ctx);
+ if (msg == NULL)
+ {
+ return;
+ }
+
+ const struct packet *pkt = (const struct packet *)msg;
+ struct session_flags_plugin_info *sf_plugin_info = (struct session_flags_plugin_info *)plugin_env;
+ struct session_flags_ctx *ctx = (struct session_flags_ctx *)session_exdata_get(session, sf_plugin_info->sess_ctx_exdata_idx);
+
+ if (ctx == NULL)
+ {
+ ctx = (struct session_flags_ctx *)calloc(1, sizeof(struct session_flags_ctx));
+ session_exdata_set(session, sf_plugin_info->sess_ctx_exdata_idx, ctx);
+
+ session_flags_stat_init(&ctx->stat, session_get_direction(session));
+ if (g_sf_conf.tunneling_enabled)
+ {
+ tunneling_hs_stream_init(sf_plugin_info, ctx);
+ }
+ }
+
+ struct session_flags_stat *stat = &ctx->stat;
+ session_flags_result *flags_result = NULL;
+ size_t pktlen = 0;
+
+ pktlen = packet_get_raw_len(pkt);
+
+ uint64_t curr_time_ms = 0;
+ const struct timeval *tv;
+
+ tv = packet_get_timeval(pkt);
+ if (tv != NULL)
+ {
+ curr_time_ms = tv->tv_sec * 1000 + tv->tv_usec / 1000;
+ }
+
+ flags_result = session_flags(sf_plugin_info, ctx, session, topic_id, pktlen, session_get_flow_type(session), curr_time_ms);
+
+ if ((stat->stream_live_time_ms > g_sf_conf.session_max_process_time_ms))
+ {
+ stellar_session_plugin_dettach_current_session(session);
+ }
+
+ uint32_t pkts_num = stat->c2s.pkts + stat->s2c.pkts;
+
+ if (flags_result != NULL)
+ {
+ if (flags_result->flags != ctx->history_flags)
+ {
+ struct session_flags_message *flags_msg = session_flags_generate_firewall_message(flags_result->flags, flags_result->identify);
+ if (session_mq_publish_message(session, sf_plugin_info->session_flags_topic_id, flags_msg) < 0)
+ {
+ session_flags_topic_free_cb(flags_msg, NULL);
+
+ STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "[%s] publish session flags message failed, flags:0x%x, pkts_num:%d", session_get0_readable_addr(session), flags_result->flags, pkts_num);
+ return;
+ }
+
+ ctx->history_flags = flags_result->flags;
+
+ STELLAR_LOG_DEBUG(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE,
+ "[%s] flags:0x%x, pkts_num:%d\n \
+ c2s_iter: bulky: %f, CBR: %f, download: %f, interactive: %f, pseudo_unidirectional: %f, streaming: %f, CBR_CV: %f\n \
+ s2c_iter: bulky: %f, CBR: %f, download: %f, interactive: %f, pseudo_unidirectional: %f, streaming: %f, CBR_CV: %f\n \
+ iter_cnt: %d, bidirectional: %f\n", session_get0_readable_addr(session), ctx->history_flags, pkts_num,
+ stat->iter.c2s.bulky, stat->iter.c2s.CBR, stat->iter.c2s.download, stat->iter.c2s.interactive, stat->iter.c2s.pseudo_unidirectional, stat->iter.c2s.streaming, session_flags_calculate_CV(&stat->iter.c2s.omean),
+ stat->iter.s2c.bulky, stat->iter.s2c.CBR, stat->iter.s2c.download, stat->iter.s2c.interactive, stat->iter.s2c.pseudo_unidirectional, stat->iter.s2c.streaming, session_flags_calculate_CV(&stat->iter.s2c.omean),
+ stat->iter.iter_cnt, stat->iter.bidirectional);
+ }
+ }
+
+ return;
+}
+
+static void session_flags_load_config(struct session_flags_plugin_info *sf_plugin_info, const char *cfg_file, struct session_flags_init_conf *g_sf_conf)
+{
+ char errbuf[256] = {0};
+
+ FILE *fp = fopen(cfg_file, "r");
+ if (NULL == fp)
+ {
+ STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "Can't open config file:%s", cfg_file);
+ return;
+ }
+
+ toml_table_t *toml_root = toml_parse_file(fp, errbuf, sizeof(errbuf));
+ fclose(fp);
+
+ toml_table_t *cfg_tbl = toml_table_in(toml_root, "SESSION_FLAGS");
+ if (NULL == cfg_tbl)
+ {
+ STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "config file:%s has no key: [SESSION_FLAGS]", cfg_file);
+ toml_free(toml_root);
+ return;
+ }
+
+ toml_datum_t toml_val = toml_int_in(cfg_tbl, "INTERACTIVE_STARTTIME_MS");
+ if (toml_val.ok)
+ {
+ g_sf_conf->interactive_starttime_ms = toml_val.u.i;
+ }
+ else
+ {
+ g_sf_conf->interactive_starttime_ms = 15000;
+ }
+
+ toml_val = toml_int_in(cfg_tbl, "INTERACTIVE_PULSE_NUM");
+ if (toml_val.ok)
+ {
+ g_sf_conf->interactive_pulse_num = toml_val.u.i;
+ }
+ else
+ {
+ g_sf_conf->interactive_pulse_num = 4;
+ }
+
+ toml_val = toml_int_in(cfg_tbl, "INTERACTIVE_LATENCY_MS");
+ if (toml_val.ok)
+ {
+ g_sf_conf->interactive_latency_ms = toml_val.u.i;
+ }
+ else
+ {
+ g_sf_conf->interactive_latency_ms = 1000;
+ }
+
+ toml_val = toml_int_in(cfg_tbl, "MAIN_DIR_FRONT_N_PKTS");
+ if (toml_val.ok)
+ {
+ g_sf_conf->main_dir_front_n_pkts = toml_val.u.i;
+ }
+ else
+ {
+ g_sf_conf->main_dir_front_n_pkts = 100;
+ }
+
+ toml_val = toml_int_in(cfg_tbl, "LARGE_PKTS_INIT_SIZE");
+ if (toml_val.ok)
+ {
+ g_sf_conf->large_ptks_init_size = toml_val.u.i;
+ }
+ else
+ {
+ g_sf_conf->large_ptks_init_size = 1000;
+ }
+
+ toml_val = toml_int_in(cfg_tbl, "SESSION_MAX_PROCESS_TIME_MS");
+ if (toml_val.ok)
+ {
+ g_sf_conf->session_max_process_time_ms = toml_val.u.i;
+ }
+ else
+ {
+ g_sf_conf->session_max_process_time_ms = 30000;
+ }
+
+ toml_val = toml_int_in(cfg_tbl, "FET_ENABLED");
+ if (toml_val.ok)
+ {
+ g_sf_conf->fet_enabled = toml_val.u.b;
+ }
+ else
+ {
+ g_sf_conf->fet_enabled = 1;
+ }
+
+ toml_val = toml_int_in(cfg_tbl, "RANDOM_LOOKING_UDP_IGNORE_PKTS");
+ if (toml_val.ok)
+ {
+ g_sf_conf->random_looking_udp_ignore_pkts = toml_val.u.i;
+ }
+ else
+ {
+ g_sf_conf->random_looking_udp_ignore_pkts = 3;
+ }
+
+ toml_val = toml_int_in(cfg_tbl, "TUNNELING_TLS_IGNORE_PKTS");
+ if (toml_val.ok)
+ {
+ g_sf_conf->tunneling_tls_ignore_pkts = toml_val.u.i;
+ }
+ else
+ {
+ g_sf_conf->tunneling_tls_ignore_pkts = 4;
+ }
+
+ toml_val = toml_int_in(cfg_tbl, "TUNNELING_MAX_SCAN_PKTS");
+ if (toml_val.ok)
+ {
+ g_sf_conf->tunneling_max_scan_pkts = toml_val.u.i;
+ }
+ else
+ {
+ g_sf_conf->tunneling_max_scan_pkts = 15;
+ }
+
+ toml_val = toml_string_in(cfg_tbl, "TUNNELING_PCRE_LIST");
+ if (toml_val.ok)
+ {
+ strncpy(g_sf_conf->tunneling_pcre_list, toml_val.u.s, sizeof(g_sf_conf->tunneling_pcre_list) - 1);
+ }
+ else
+ {
+ strncpy(g_sf_conf->tunneling_pcre_list, "{\"tunneling_pcre_list\":[]}", sizeof(g_sf_conf->tunneling_pcre_list) - 1);
+ }
+
+ toml_val = toml_string_in(cfg_tbl, "RANDOM_LOOKING_JUDGE_LIST");
+ if (toml_val.ok)
+ {
+ strncpy(g_sf_conf->random_looking_judge_list, toml_val.u.s, sizeof(g_sf_conf->random_looking_judge_list) - 1);
+ }
+ else
+ {
+ strncpy(g_sf_conf->random_looking_judge_list, "{\"random_looking_judge_list\":[]}", sizeof(g_sf_conf->random_looking_judge_list) - 1);
+ }
+}
+
+extern "C" void *session_flags_plugin_init(struct stellar *st)
+{
+ char random_looking_list_str[2048] = {0};
+ struct session_flags_plugin_info *sf_plugin_info = (struct session_flags_plugin_info *)calloc(1, sizeof(struct session_flags_plugin_info));
+ cJSON *json = NULL, *item = NULL;
+ int array_num;
+
+ sf_plugin_info->st = st;
+ sf_plugin_info->sess_ctx_exdata_idx = stellar_exdata_new_index(st, "SESSION_FLAGS_SESS_CTX", session_flags_exdata_free_cb, NULL);
+
+ sf_plugin_info->log_handle = stellar_get_logger(st);
+ if(sf_plugin_info->log_handle==NULL)
+ {
+ printf("stellar_get_logger object failed ...\n");
+ goto ERROR;
+ }
+
+ memset(&g_sf_conf, 0, sizeof(g_sf_conf));
+ session_flags_load_config(sf_plugin_info, CFG_FILE_PATH, &g_sf_conf);
+ tunneling_hyperscan_engine_init(sf_plugin_info, &g_sf_conf);
+
+ json = cJSON_Parse(g_sf_conf.random_looking_judge_list);
+ if (json == NULL)
+ {
+ STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "cJSON_Parse failed, random_looking_list_str:%s", random_looking_list_str);
+ goto ERROR;
+ }
+ item = cJSON_GetObjectItem(json, "random_looking_judge_list");
+ if (item == NULL)
+ {
+ STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "cJSON_GetObjectItem failed, random_looking_list_str:%s", random_looking_list_str);
+ goto ERROR;
+ }
+ array_num = cJSON_GetArraySize(item);
+ if (array_num > STS_RANDOM_JUDGE_NUM || array_num < 0)
+ {
+ STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "array size error, array_num:%d", array_num);
+ goto ERROR;
+ }
+ for (int i = 0; i < array_num; i++)
+ {
+ for (int j = 0; j < STS_RANDOM_JUDGE_NUM; j++)
+ {
+ if (strcmp(cJSON_GetArrayItem(item, i)->valuestring, random_looking_judge_table[j]) == 0)
+ {
+ STS_SET_FLAG(sts_random_switch, j);
+ g_sf_conf.random_judge_flags_cnt++;
+ break;
+ }
+ }
+ }
+ cJSON_Delete(json);
+
+ sf_plugin_info->plugin_id = stellar_session_plugin_register(st, NULL, NULL, sf_plugin_info);
+ if (sf_plugin_info->plugin_id < 0)
+ {
+ STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "stellar_session_plugin_register failed");
+ goto ERROR;
+
+ }
+
+ sf_plugin_info->session_flags_topic_id = stellar_mq_create_topic(st, SESSION_FLAGS_MESSAGE_TOPIC, session_flags_topic_free_cb, NULL);
+ if (sf_plugin_info->session_flags_topic_id < 0)
+ {
+ STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "stellar_session_mq_create_topic failed");
+ goto ERROR;
+ }
+
+ sf_plugin_info->tcp_topic_id = stellar_mq_get_topic_id(st, TOPIC_TCP_INPUT);
+ sf_plugin_info->udp_topic_id = stellar_mq_get_topic_id(st, TOPIC_UDP_INPUT);
+ if (sf_plugin_info->tcp_topic_id < 0 || sf_plugin_info->udp_topic_id < 0)
+ {
+ STELLAR_LOG_FATAL(sf_plugin_info->log_handle, SESSION_FLAGS_LOG_MODULE, "stellar_session_mq_get_topic_id failed");
+ goto ERROR;
+ }
+
+ stellar_session_mq_subscribe(st, sf_plugin_info->tcp_topic_id, session_flags_entry, sf_plugin_info->plugin_id);
+ stellar_session_mq_subscribe(st, sf_plugin_info->udp_topic_id, session_flags_entry, sf_plugin_info->plugin_id);
+
+ return sf_plugin_info;
+
+ERROR:
+ if (sf_plugin_info != NULL)
+ {
+ free(sf_plugin_info);
+ }
+
+ if (json != NULL)
+ {
+ cJSON_Delete(json);
+ }
+
+ perror("session_flags init failed");
+ exit(-1);
+}
+
+extern "C" void session_flags_plugin_exit(void *plugin_ctx)
+{
+ if (plugin_ctx == NULL)
+ {
+ return;
+ }
+
+ struct session_flags_plugin_info *sf_plugin_info = (struct session_flags_plugin_info *)plugin_ctx;
+
+ tunneling_hyperscan_engine_exit(sf_plugin_info->tunneling_hs_db);
+
+ free(plugin_ctx);
+
+ return;
+} \ No newline at end of file