TSG-14654: 控制报文格式调整, 增加将cmsg字段发送给TFE, 控制报文采用mpack封装格式

This commit is contained in:
刘学利
2023-05-06 02:23:12 +00:00
parent 5bc9831e03
commit 224f503289
28 changed files with 17186 additions and 396 deletions

View File

@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8)
add_definitions(-fPIC)
set(SRC tsg_entry.cpp tsg_rule.cpp tsg_ssl_utils.cpp tsg_send_log.cpp tsg_statistic.cpp tsg_ssh_utils.cpp tsg_gtp_signaling.cpp tsg_action.cpp tsg_leaky_bucket.cpp tsg_dns.cpp tsg_icmp.cpp tsg_tamper.cpp tsg_bridge.cpp tsg_protocol.cpp tsg_sync_state.cpp tsg_variable.cpp)
set(SRC tsg_entry.cpp tsg_rule.cpp tsg_ssl_utils.cpp tsg_send_log.cpp tsg_statistic.cpp tsg_ssh_utils.cpp tsg_gtp_signaling.cpp tsg_action.cpp tsg_leaky_bucket.cpp tsg_dns.cpp tsg_icmp.cpp tsg_tamper.cpp tsg_bridge.cpp tsg_protocol.cpp tsg_sync_state.cpp tsg_variable.cpp tsg_proxy.cpp mpack.c)
include_directories(${CMAKE_SOURCE_DIR}/inc)
include_directories(/opt/MESA/include/MESA/)

7304
src/mpack.c Normal file

File diff suppressed because it is too large Load Diff

8207
src/mpack.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -141,6 +141,12 @@ void session_runtime_attribute_free(const struct streaminfo *a_stream, int bridg
srt_attribute->ja3_fingerprint=NULL;
}
if(srt_attribute->proxy_tcp_attr != NULL)
{
dictator_free(a_stream->threadnum, (void *)srt_attribute->proxy_tcp_attr);
srt_attribute->proxy_tcp_attr = NULL;
}
dictator_free(a_stream->threadnum, data);
data=NULL;
}

View File

@@ -132,6 +132,7 @@ struct session_runtime_attribute
struct tunnel_endpoint *client_endpoint;
struct tunnel_endpoint *server_endpoint;
unsigned long session_flags;
struct tsg_proxy_tcp_attribute *proxy_tcp_attr;
};

View File

@@ -31,6 +31,7 @@
#include "tsg_rule_internal.h"
#include "tsg_protocol_common.h"
#include "tsg_sync_state.h"
#include "tsg_proxy.h"
#ifdef __cplusplus
extern "C"
@@ -787,7 +788,20 @@ int session_state_sync_in_opening_and_closing(const struct streaminfo *a_stream,
return 1;
}
size_t matched_rules_increase_in_avtiving(const struct matched_policy_rules *matched_rules, struct maat_rule *new_rules, size_t n_new_rules, struct maat_rule *inc_rules, size_t n_inc_rules)
int session_state_update_policy(struct update_policy *u_policy, struct maat_rule *matched_rules, size_t n_matched_rules, enum policy_type p_type)
{
u_policy->n_ids=n_matched_rules;
u_policy->type=p_type;
for(size_t i=0; i<n_matched_rules; i++)
{
u_policy->ids[i]=matched_rules[i].rule_id;
}
return 0;
}
size_t matched_rules_increase_in_activing(const struct matched_policy_rules *matched_rules, struct maat_rule *new_rules, size_t n_new_rules, struct maat_rule *inc_rules, size_t n_inc_rules)
{
size_t n_inc_rules_offset=0;
size_t num=MIN(MAX_RESULT_NUM-matched_rules->n_rules, n_new_rules);
@@ -826,6 +840,10 @@ int session_set_segment_id_in_activing(const struct streaminfo *a_stream, TSG_SE
p_type=POLICY_UPDATE_SHAPING;
segment_id=(unsigned short)g_tsg_para.shaping_sid;
break;
case TSG_SERVICE_INTERCEPT:
p_type=POLICY_UPDATE_INTERCEPT;
segment_id=(unsigned short)g_tsg_para.intercept_sid;
break;
default:
return 0;
}
@@ -864,16 +882,23 @@ int session_set_segment_id_in_activing(const struct streaminfo *a_stream, TSG_SE
sid_list.sid_list[0]=segment_id;
MESA_set_stream_opt(a_stream, MSO_STREAM_PREPLEND_SEGMENT_ID_LIST, (void *)&sid_list, sizeof(struct segment_id_list));
struct update_policy policy_array;
policy_array.n_ids=n_inc_rules;
policy_array.type=p_type;
for(size_t i=0; i<n_inc_rules; i++)
int policy_array_offset=1;
struct update_policy policy_array[2];
session_state_update_policy(&(policy_array[0]), inc_rules, n_inc_rules, p_type);
if(service==TSG_SERVICE_INTERCEPT)
{
policy_array.ids[i]=inc_rules[i].rule_id;
memset(&policy_array[0].cmsg, 0, sizeof(struct proxy_cmsg));
tsg_proxy_update_policy_fill(a_stream, &(policy_array[0]));
struct matched_policy_rules *s_chaining = (struct matched_policy_rules *)session_matched_rules_get(a_stream, TSG_SERVICE_CHAINING);
if(s_chaining!=NULL)
{
policy_array_offset++;
session_state_update_policy(&(policy_array[1]), s_chaining->rules, s_chaining->n_rules, POLICY_UPDATE_SERVICE_CHAINING);
}
}
tsg_sync_policy_update(a_stream, &policy_array, 1);
tsg_sync_policy_update(a_stream, policy_array, policy_array_offset);
MESA_set_stream_opt(a_stream, MSO_STREAM_PREPLEND_SEGMENT_ID_LIST, (void *)segment_ids, sizeof(struct segment_id_list));
@@ -896,7 +921,7 @@ int session_state_sync_in_activing(const struct streaminfo *a_stream, TSG_SERVIC
}
struct maat_rule inc_rules[MAX_RESULT_NUM]={0};
size_t n_inc_results=matched_rules_increase_in_avtiving(matched_rules, rules, n_rules, inc_rules, MAX_RESULT_NUM-matched_rules->n_rules);
size_t n_inc_results=matched_rules_increase_in_activing(matched_rules, rules, n_rules, inc_rules, MAX_RESULT_NUM-matched_rules->n_rules);
if(n_inc_results==0)
{
return 0;
@@ -1459,19 +1484,6 @@ static unsigned char matched_security_rules_deal(const struct streaminfo *a_stre
srt_action_context_set_rule_method(a_stream, TSG_METHOD_TYPE_ALLOW, a_stream->threadnum);
break;
case TSG_ACTION_INTERCEPT:
if(tsg_scan_intercept_exclusion(a_stream, g_tsg_maat_feather, p_rule, srt_process_context->domain, a_stream->threadnum))
{
FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_EXCLUSION], 0, FS_OP_ADD, 1);
break;
}
session_matched_rules_notify(a_stream, TSG_SERVICE_INTERCEPT, p_rule, 1, a_stream->threadnum);
FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_INTERCEPT], 0, FS_OP_ADD, 1);
state=APP_STATE_DROPME|APP_STATE_KILL_OTHER;
srt_action_context_set_rule_method(a_stream, TSG_METHOD_TYPE_UNKNOWN, a_stream->threadnum);
break;
default:
break;
}
@@ -1479,9 +1491,9 @@ static unsigned char matched_security_rules_deal(const struct streaminfo *a_stre
return state;
}
int matched_shaping_rules_deal(const struct streaminfo *a_stream, struct maat_rule *shaping_results, size_t n_shaping_results, int thread_seq)
int matched_shaping_rules_deal(const struct streaminfo *a_stream, struct maat_rule *shaping_rules, size_t n_shaping_rules, int thread_seq)
{
session_state_sync_in_activing(a_stream, TSG_SERVICE_SHAPING, shaping_results, n_shaping_results, thread_seq);
session_state_sync_in_activing(a_stream, TSG_SERVICE_SHAPING, shaping_rules, n_shaping_rules, thread_seq);
FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_SHAPING], 0, FS_OP_ADD, 1);
srt_action_context_set_rule_method(a_stream, TSG_METHOD_TYPE_UNKNOWN, thread_seq);
@@ -1489,6 +1501,17 @@ int matched_shaping_rules_deal(const struct streaminfo *a_stream, struct maat_ru
return 0;
}
int matched_intercept_rules_deal(const struct streaminfo *a_stream, struct maat_rule *intercept_rules, size_t n_intercept_rules, int thread_seq)
{
struct maat_rule *p_rule=matched_rules_decision_criteria(intercept_rules, n_intercept_rules);
session_state_sync_in_activing(a_stream, TSG_SERVICE_INTERCEPT, p_rule, 1, thread_seq);
FS_operate(g_tsg_para.fs2_handle, g_tsg_para.fs2_field_id[TSG_FS2_INTERCEPT], 0, FS_OP_ADD, 1);
srt_action_context_set_rule_method(a_stream, TSG_METHOD_TYPE_UNKNOWN, thread_seq);
return 0;
}
int matched_service_chaining_rules_deal(const struct streaminfo *a_stream, struct maat_rule *s_chaining_rules, size_t n_s_chaining_rules, int thread_seq)
{
session_state_sync_in_activing(a_stream, TSG_SERVICE_CHAINING, s_chaining_rules, n_s_chaining_rules, thread_seq);
@@ -1500,25 +1523,33 @@ int matched_service_chaining_rules_deal(const struct streaminfo *a_stream, struc
unsigned char session_matched_rules_deal(const struct streaminfo *a_stream, struct session_runtime_process_context *srt_process_context, struct maat_rule *rules, size_t n_rules, const void *a_packet)
{
unsigned char state=APP_STATE_GIVEME;
struct maat_rule security_rules[MAX_RESULT_NUM]={0};
size_t n_security_rules=tsg_select_matched_security_rules(rules, n_rules, security_rules, MAX_RESULT_NUM);
if(n_security_rules>0)
struct maat_rule s_chaining_rules[MAX_RESULT_NUM]={0};
size_t n_s_chaining_rules=tsg_select_rules_by_service_id(rules, n_rules, s_chaining_rules, MAX_RESULT_NUM, TSG_SERVICE_CHAINING);
if(n_s_chaining_rules>0)
{
state=matched_security_rules_deal(a_stream, srt_process_context, security_rules, n_security_rules, a_packet, a_stream->threadnum);
matched_service_chaining_rules_deal(a_stream, s_chaining_rules, n_s_chaining_rules, a_stream->threadnum);
}
struct maat_rule intercept_rules[MAX_RESULT_NUM]={0};
size_t n_intercept_rules=tsg_select_rules_by_service_id(rules, n_rules, intercept_rules, MAX_RESULT_NUM, TSG_SERVICE_INTERCEPT);
if(n_intercept_rules>0)
{
matched_intercept_rules_deal(a_stream, intercept_rules, n_intercept_rules, a_stream->threadnum);
}
struct maat_rule shaping_rules[MAX_RESULT_NUM]={0};
size_t n_shaping_rules=tsg_select_matched_shaping_rules(rules, n_rules, shaping_rules, MAX_RESULT_NUM);
if(n_shaping_rules>0 && !(state&APP_STATE_KILL_OTHER))
size_t n_shaping_rules=tsg_select_rules_by_service_id(rules, n_rules, shaping_rules, MAX_RESULT_NUM, TSG_SERVICE_SHAPING);
if(n_shaping_rules>0)
{
matched_shaping_rules_deal(a_stream, shaping_rules, n_shaping_rules, a_stream->threadnum);
}
struct maat_rule s_chaining_rules[MAX_RESULT_NUM]={0};
size_t n_s_chaining_rules=tsg_select_matched_service_chaining_rules(rules, n_rules, s_chaining_rules, MAX_RESULT_NUM);
if(n_s_chaining_rules>0 && !(state&APP_STATE_KILL_OTHER))
struct maat_rule security_rules[MAX_RESULT_NUM]={0};
size_t n_security_rules=tsg_select_rules_by_service_id(rules, n_rules, security_rules, MAX_RESULT_NUM, TSG_SERVICE_SECURITY);
if(n_security_rules>0)
{
matched_service_chaining_rules_deal(a_stream, s_chaining_rules, n_s_chaining_rules, a_stream->threadnum);
state=matched_security_rules_deal(a_stream, srt_process_context, security_rules, n_security_rules, a_packet, a_stream->threadnum);
}
return state;
@@ -1734,6 +1765,10 @@ static unsigned char tsg_master_data_entry(const struct streaminfo *a_stream, vo
}
hit_num+=session_pending_state_deal(a_stream, srt_process_context, matched_rules+hit_num, MAX_TSG_ALL_RESULT_NUM-hit_num, a_packet);
if (a_stream->type == STREAM_TYPE_TCP && a_packet != NULL)
{
tsg_proxy_tcp_options_parse(a_stream, a_packet);
}
state=session_matched_rules_deal(a_stream, srt_process_context, matched_rules, hit_num, a_packet);
srt_process_context->deal_pkt_num++;
break;
@@ -1823,6 +1858,11 @@ static unsigned char tsg_master_all_entry(const struct streaminfo *a_stream, uns
struct maat_rule shaping_results[MAX_RESULT_NUM]={0};
struct session_runtime_action_context *srt_action_context=(struct session_runtime_action_context *)(*pme);
if (a_stream->type == STREAM_TYPE_TCP && a_packet != NULL)
{
tsg_proxy_tcp_options_parse(a_stream, a_packet);
}
if(stream_state==OP_STATE_PENDING && srt_action_context->method_type!=TSG_METHOD_TYPE_SHUNT && !(srt_action_context->udp_data_dropme))
{
if(srt_action_context->method_type==TSG_METHOD_TYPE_UNKNOWN)
@@ -1836,7 +1876,7 @@ static unsigned char tsg_master_all_entry(const struct streaminfo *a_stream, uns
int hit_num=tsg_scan_nesting_addr(a_stream, g_tsg_maat_feather, PROTO_UNKONWN, scan_mid, matched_rules, MAX_TSG_ALL_RESULT_NUM);
if(hit_num>0)
{
int security_result_num=tsg_select_matched_security_rules(matched_rules, hit_num, security_results, MAX_RESULT_NUM);
int security_result_num = tsg_select_rules_by_service_id(matched_rules, hit_num, security_results, MAX_RESULT_NUM, TSG_SERVICE_SECURITY);
p_result=matched_rules_decision_criteria(security_results, security_result_num);
if(p_result!=NULL)
{
@@ -1855,18 +1895,18 @@ static unsigned char tsg_master_all_entry(const struct streaminfo *a_stream, uns
}
}
size_t n_shaping_results=tsg_select_matched_shaping_rules(matched_rules, hit_num, shaping_results, MAX_RESULT_NUM);
if(state==APP_STATE_GIVEME && n_shaping_results>0)
{
matched_shaping_rules_deal(a_stream, shaping_results, n_shaping_results, thread_seq);
}
struct maat_rule s_chaining_result[MAX_RESULT_NUM]={0};
size_t n_s_chaining_results=tsg_select_matched_service_chaining_rules(matched_rules, hit_num, s_chaining_result, MAX_RESULT_NUM);
size_t n_s_chaining_results=tsg_select_rules_by_service_id(matched_rules, hit_num, s_chaining_result, MAX_RESULT_NUM, TSG_SERVICE_CHAINING);
if(state==APP_STATE_GIVEME && n_s_chaining_results>0)
{
matched_service_chaining_rules_deal(a_stream, s_chaining_result, n_s_chaining_results, thread_seq);
}
size_t n_shaping_results=tsg_select_rules_by_service_id(matched_rules, hit_num, shaping_results, MAX_RESULT_NUM, TSG_SERVICE_SHAPING);
if(state==APP_STATE_GIVEME && n_shaping_results>0)
{
matched_shaping_rules_deal(a_stream, shaping_results, n_shaping_results, thread_seq);
}
}
maat_state_free(scan_mid);
@@ -2078,6 +2118,7 @@ extern "C" int TSG_MASTER_INIT()
MESA_load_profile_int_def(tsg_conffile, "SYSTEM", "FEATURE_TAMPER", &g_tsg_para.feature_tamper, 0);
MESA_load_profile_int_def(tsg_conffile, "SYSTEM", "SERVICE_CHAINING_SID", &g_tsg_para.service_chaining_sid, 0);
MESA_load_profile_int_def(tsg_conffile, "SYSTEM", "SHAPING_SID", &g_tsg_para.shaping_sid, 0);
MESA_load_profile_int_def(tsg_conffile, "SYSTEM", "intercept_sid", &g_tsg_para.intercept_sid, 0);
ret=MESA_load_profile_int_def(tsg_conffile, "SYSTEM", "DEVICE_SEQ_IN_DATA_CENTER", &g_tsg_para.device_seq_in_dc, 0);
if(ret<0)

561
src/tsg_proxy.cpp Normal file
View File

@@ -0,0 +1,561 @@
#include <MESA/stream.h>
#include <MESA/MESA_handle_logger.h>
#include "tsg_rule.h"
#include "tsg_variable.h"
#include "tsg_send_log.h"
#include "tsg_sync_state.h"
#include "tsg_proxy.h"
#define DEFAULT_WINSCLE 0
#define DEFAULT_MSS 1460
enum tsg_proxy_ipv4hdr_parse_error{
TSG_PROXY_IPV4HDR_NULL_PACKET = -1,
};
enum tsg_proxy_ipv6hdr_parse_error{
TSG_PROXY_IPV6HDR_NULL_PACKET = -1,
TSG_PROXY_IPV6HDR_NO_TCPHDR = -2,
TSG_PROXY_IPV6HDR_INVALID_TYPE = -3,
};
int tsg_proxy_ipv6_header_parse(const void *a_packet, struct pkt_info *pktinfo){
if(a_packet == NULL){
return TSG_PROXY_IPV6HDR_NULL_PACKET;
}
pktinfo->addr_type = ADDR_TYPE_IPV6;
pktinfo->iphdr.v6 = (struct ip6_hdr*)a_packet;
pktinfo->ip_totlen = ntohs(pktinfo->iphdr.v6->ip6_ctlun.ip6_un1.ip6_un1_plen) + sizeof(struct ip6_hdr);
uint8_t next_hdr_type = pktinfo->iphdr.v6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
char *next_hdr_ptr = (char*)pktinfo->iphdr.v6 + sizeof(struct ip6_hdr);
int skip_len = 0;
int ret = 0;
while(true){
switch(next_hdr_type)
{
case IPPROTO_TCP:
//parse tcphdr
pktinfo->iphdr_len = next_hdr_ptr - (char*)a_packet;
pktinfo->tcphdr = (struct tcphdr*)next_hdr_ptr;
pktinfo->tcphdr_len = pktinfo->tcphdr->doff * 4;
pktinfo->data = (char*)pktinfo->tcphdr + pktinfo->tcphdr_len;
pktinfo->data_len = pktinfo->ip_totlen - pktinfo->iphdr_len - pktinfo->tcphdr_len;
return 0;
case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING:
case IPPROTO_AH:
case IPPROTO_DSTOPTS:
skip_len = (*(next_hdr_ptr + 1)) * 8 + 8;
next_hdr_type = *next_hdr_ptr;
next_hdr_ptr += skip_len;
break;
case IPPROTO_NONE:
ret = TSG_PROXY_IPV6HDR_NO_TCPHDR;
goto error_out;
default:
ret = TSG_PROXY_IPV6HDR_INVALID_TYPE;
goto error_out;
}
}
error_out:
return ret;
}
int tsg_proxy_ipv4_header_parse(const void *a_packet, struct pkt_info *pktinfo){
if(a_packet == NULL){
return TSG_PROXY_IPV4HDR_NULL_PACKET;
}
pktinfo->addr_type = ADDR_TYPE_IPV4;
pktinfo->iphdr.v4 = (struct iphdr*)a_packet;
pktinfo->iphdr_len = pktinfo->iphdr.v4->ihl * 4;
pktinfo->ip_totlen = ntohs(pktinfo->iphdr.v4->tot_len);
pktinfo->tcphdr = (struct tcphdr*)((char*)pktinfo->iphdr.v4 + pktinfo->iphdr_len);
pktinfo->tcphdr_len = pktinfo->tcphdr->doff * 4;
pktinfo->data = (char*)pktinfo->tcphdr + pktinfo->tcphdr_len;
pktinfo->data_len = pktinfo->ip_totlen - pktinfo->iphdr_len - pktinfo->tcphdr_len;
return 0;
}
static char* tsg_proxy_ipv4_errmsg_get(enum tsg_proxy_ipv4hdr_parse_error _errno){
switch(_errno){
case TSG_PROXY_IPV4HDR_NULL_PACKET:
return (char*)"null packet";
default:
return (char*)"unknown error";
}
}
static char* tsg_proxy_ipv6_errmsg_get(enum tsg_proxy_ipv6hdr_parse_error _errno){
switch(_errno){
case TSG_PROXY_IPV6HDR_NULL_PACKET:
return (char*)"null packet";
case TSG_PROXY_IPV6HDR_NO_TCPHDR:
return (char*)"no tcp header";
case TSG_PROXY_IPV6HDR_INVALID_TYPE:
return (char*)"invalid header type";
default:
return (char*)"unknown error";
}
}
static void tsg_proxy_ip_header_parse(const void *a_packet, enum addr_type_t addr_type, const struct streaminfo *stream, struct pkt_info *pktinfo){
if(addr_type == ADDR_TYPE_IPV6){
int ret = tsg_proxy_ipv6_header_parse(a_packet, pktinfo);
if(ret < 0){
char *errmsg = tsg_proxy_ipv6_errmsg_get((enum tsg_proxy_ipv6hdr_parse_error)ret);
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_FATAL, "PROXY", "Failed at parse ipv6 header, errmsg = %s, stream treaceid = %llu", errmsg, tsg_get_stream_trace_id(stream));
pktinfo->parse_failed = 1;
}
}
else{
int ret = tsg_proxy_ipv4_header_parse(a_packet, pktinfo);
if(ret < 0){
char *errmsg = tsg_proxy_ipv4_errmsg_get((enum tsg_proxy_ipv4hdr_parse_error)ret);
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_FATAL, "PROXY", "Failed at parse ipv4 header, errmsg = %s, stream treaceid = %llu", errmsg, tsg_get_stream_trace_id(stream));
pktinfo->parse_failed = 1;
}
}
return;
}
static void tsg_proxy_tcpopt_get(struct tsg_proxy_tcp_option *tcp_opt, struct tcphdr* tcphdr,int tcphdr_len)
{
tcp_opt->mss = DEFAULT_MSS;
tcp_opt->wscale = DEFAULT_WINSCLE;
tcp_opt->window = ntohs(tcphdr->window);
const unsigned char *ptr = ((const unsigned char*)tcphdr + 20);
int length = tcphdr_len - 20;
while (length > 0){
int opcode = *ptr++;
int opsize;
switch (opcode){
case TCPOPT_EOL:
return;
case TCPOPT_NOP: /* Ref: RFC 793 section 3.1 */
length--;
continue;
default:
opsize = *ptr++;
if (opsize < 2) /* "silly options" */
return;
if (opsize > length)
return; /* don't parse partial options */
switch (opcode){
case TCPOPT_MAXSEG:
if (opsize == TCPOLEN_MAXSEG){
uint16_t in_mss = *(uint16_t *)ptr;
if(in_mss){
tcp_opt->mss = ntohs(in_mss);
}
}
break;
case TCPOPT_WINDOW:
if (opsize == TCPOLEN_WINDOW){
uint8_t snd_wscale = *(uint8_t *)ptr;
// rfc7323 page9: Thus, the shift count MUST be limited to 14 (which allows windows of 2^30 = 1 GiB).
// If a Window Scale option is received with a shift.cnt value larger than 14,
// the TCP SHOULD log the error but MUST use 14 instead of the specified value. */
tcp_opt->wscale = snd_wscale;
if(tcp_opt->wscale > 14){
tcp_opt->wscale = 14;
}
tcp_opt->wscale_set = 1;
//*wscale_perm=1;
}
break;
case TCPOPT_TIMESTAMP:
if (opsize == TCPOLEN_TIMESTAMP){
tcp_opt->ts_set = 1;
tcp_opt->ts_val = *(uint32_t*)ptr;
tcp_opt->ts_ecr = *(uint32_t*)(ptr + 4);
}
break;
case TCPOPT_SACK_PERMITTED:
if (opsize == TCPOLEN_SACK_PERMITTED){
tcp_opt->sack = 1;
}
break;
}
ptr += opsize-2;
length -= opsize;
}
}
return;
}
static int tsg_proxy_rawpkt_info_get(const void *raw_pkt, struct tsg_proxy_tcp_option *tcp_opt, const struct streaminfo *stream)
{
int ret;
struct segment_id_list *sids = NULL;
ret = get_rawpkt_opt_from_streaminfo(stream, RWA_PKT_GET_SID_LIST, &sids);
if (ret != sizeof(struct segment_id_list)) {
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_FATAL, "PROXY", "Failed to get sid list, stream treaceid = %llu, %s", tsg_get_stream_trace_id(stream), printaddr(&stream->addr, stream->threadnum));
return -1;
}
memcpy(&tcp_opt->sid_list, sids, sizeof(struct segment_id_list));
void *route_ctx = NULL;
ret = get_rawpkt_opt_from_streaminfo(stream, RAW_PKT_GET_ROUTE_CTX, &route_ctx);
if (ret < 0) {
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_FATAL, "PROXY", "Failed to get route ctx, stream treaceid = %llu, %s", tsg_get_stream_trace_id(stream), printaddr(&stream->addr, stream->threadnum));
return -1;
}
tcp_opt->route_ctx_len = ret;
memcpy(tcp_opt->route_ctx, route_ctx, ret);
return 0;
}
void tsg_proxy_tcp_parse(struct tsg_proxy_tcp_attribute *tcp_attr, struct pkt_info *pktinfo, const struct streaminfo *stream)
{
const void *raw_pkt = get_rawpkt_from_streaminfo(stream);
if (!raw_pkt) {
return;
}
if (pktinfo->tcphdr->syn && !pktinfo->tcphdr->ack) {
tsg_proxy_rawpkt_info_get(raw_pkt, &tcp_attr->tcp_opt_client, stream);
tsg_proxy_tcpopt_get(&tcp_attr->tcp_opt_client, pktinfo->tcphdr, pktinfo->tcphdr_len);
}
if (pktinfo->tcphdr->syn && pktinfo->tcphdr->ack) {
tsg_proxy_rawpkt_info_get(raw_pkt, &tcp_attr->tcp_opt_server, stream);
tsg_proxy_tcpopt_get(&tcp_attr->tcp_opt_server, pktinfo->tcphdr, pktinfo->tcphdr_len);
}
}
static struct tsg_proxy_tcp_attribute *tsg_proxy_tcp_attribute_get(const struct streaminfo *stream)
{
struct session_runtime_attribute *srt_attribute = (struct session_runtime_attribute *)session_runtime_attribute_get(stream);
if (srt_attribute == NULL) {
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_FATAL, "PROXY", "Failed to get session runtime attribute, stream treaceid = %llu", tsg_get_stream_trace_id(stream));
return NULL;
}
if (srt_attribute->proxy_tcp_attr == NULL) {
srt_attribute->proxy_tcp_attr = (struct tsg_proxy_tcp_attribute *)dictator_malloc(stream->threadnum, sizeof(struct tsg_proxy_tcp_attribute));
memset(srt_attribute->proxy_tcp_attr, 0, sizeof(struct tsg_proxy_tcp_attribute));
}
return srt_attribute->proxy_tcp_attr;
}
void tsg_proxy_first_data_process(const struct streaminfo *stream, struct tsg_proxy_tcp_attribute *tcp_attr, struct pkt_info *pktinfo)
{
struct tsg_proxy_tcp_option tcp_opt;
enum TSG_PROTOCOL tcp_protocol;
const struct session_runtime_process_context *session_context = session_runtime_process_context_get(stream);
memset(&tcp_opt, 0, sizeof(struct tsg_proxy_tcp_option));
tcp_protocol = srt_process_context_get_protocol(session_context);
switch(tcp_protocol)
{
case PROTO_SSL:
tcp_attr->tcp_protocol = 0x1;
break;
case PROTO_SSH:
tcp_attr->tcp_protocol = 0x2;
break;
default:
tcp_attr->tcp_protocol = 0x0;
}
if(tcp_attr->tcp_opt_client.ts_set && tcp_attr->tcp_opt_server.ts_set) {
tsg_proxy_tcpopt_get(&tcp_opt, pktinfo->tcphdr, pktinfo->tcphdr_len);
if(stream->curdir == DIR_C2S){
tcp_attr->tcp_opt_client.ts_val = tcp_opt.ts_val;
tcp_attr->tcp_opt_server.ts_val = tcp_opt.ts_ecr;
} else {
tcp_attr->tcp_opt_client.ts_val = tcp_opt.ts_ecr;
tcp_attr->tcp_opt_server.ts_val = tcp_opt.ts_val;
}
}
tcp_attr->tcp_info_packet_cur_dir = stream->curdir;
if (stream->curdir == DIR_C2S) {
tcp_attr->tcp_seq = pktinfo->tcphdr->seq;
tcp_attr->tcp_ack = pktinfo->tcphdr->ack_seq;
} else {
tcp_attr->tcp_seq = pktinfo->tcphdr->ack_seq;
tcp_attr->tcp_ack = pktinfo->tcphdr->seq;
}
return;
}
void tsg_proxy_tcp_options_parse(const struct streaminfo *stream, const void *a_packet)
{
struct pkt_info pktinfo;
struct tsg_proxy_tcp_attribute *tcp_attr = tsg_proxy_tcp_attribute_get(stream);
if (tcp_attr == NULL) {
return;
}
if (tcp_attr->ignore) {
return;
}
memset(&pktinfo, 0, sizeof(struct pkt_info));
tsg_proxy_ip_header_parse(a_packet, (enum addr_type_t)stream->addr.addrtype, stream, &pktinfo);
if (pktinfo.parse_failed) {
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_FATAL, "PROXY", "invalid ip header, bypass pkt");
return;
}
if(stream->ptcpdetail->datalen > 0) {
if (tcp_attr->first_data_pkt_processed) {
struct maat_rule maat_rule;
int rule_num;
rule_num = session_matched_rules_copy(stream, TSG_SERVICE_INTERCEPT, &maat_rule, 1);
if (rule_num == 0) {
tcp_attr->ignore = 1;
}
} else {
tsg_proxy_first_data_process(stream, tcp_attr, &pktinfo);
tcp_attr->first_data_pkt_processed = 1;
}
return;
}
tsg_proxy_tcp_parse(tcp_attr, &pktinfo, stream);
return;
}
static void tsg_proxy_cmsg_subscriber_fill(struct session_runtime_attribute *session_attr, struct proxy_cmsg *cmsg)
{
const char *client_subscribe_id = srt_attribute_get_client_subscriber_id(session_attr);
const char *server_subscribe_id = srt_attribute_get_server_subscriber_id(session_attr);
if (client_subscribe_id) {
cmsg->src_sub_id = (char *)client_subscribe_id;
}
if (server_subscribe_id) {
cmsg->dst_sub_id = (char *)server_subscribe_id;
}
return;
}
static void tsg_proxy_cmsg_asn_fill(struct session_runtime_attribute *session_attr, struct proxy_cmsg *cmsg)
{
const struct asn_info *client_asn = srt_attribute_get_client_ip_asn(session_attr);
const struct asn_info *server_asn = srt_attribute_get_server_ip_asn(session_attr);
if (client_asn) {
if (client_asn->asn_id) {
cmsg->src_asn = client_asn->asn_id;
}
if (client_asn->organization) {
cmsg->src_organization = client_asn->organization;
}
}
if (server_asn) {
if (server_asn->asn_id) {
cmsg->dst_asn = server_asn->asn_id;
}
if (server_asn->organization) {
cmsg->dst_organization = server_asn->organization;
}
}
return;
}
static void tsg_proxy_cmsg_ip_location_fill(struct session_runtime_attribute *session_attr, struct proxy_cmsg *cmsg)
{
const struct location_info *client_location = srt_attribute_get_client_ip_location(session_attr);
const struct location_info *server_location = srt_attribute_get_server_ip_location(session_attr);
if (client_location) {
if (client_location->country_full) {
cmsg->src_ip_location_country = client_location->country_full;
}
if (client_location->province_full) {
cmsg->src_ip_location_provine = client_location->province_full;
}
if (client_location->city_full) {
cmsg->src_ip_location_city = client_location->city_full;
}
if (client_location->subdivision_addr) {
cmsg->src_ip_location_subdivision = client_location->subdivision_addr;
}
}
if (server_location) {
if (server_location->country_full) {
cmsg->dst_ip_location_country = server_location->country_full;
}
if (server_location->province_full) {
cmsg->dst_ip_location_provine = server_location->province_full;
}
if (server_location->city_full) {
cmsg->dst_ip_location_city = server_location->city_full;
}
if (server_location->subdivision_addr) {
cmsg->dst_ip_location_subdivision = server_location->subdivision_addr;
}
}
return;
}
static void tsg_proxy_cmsg_ja3_fingerprint_fill(struct session_runtime_attribute *session_attr, struct proxy_cmsg *cmsg)
{
const char *ja3_fingerprint = srt_attribute_get_ja3_fingerprint(session_attr);
if (ja3_fingerprint) {
cmsg->ssl_client_ja3_fingerprint = (char *)ja3_fingerprint;
}
return;
}
static void tsg_proxy_cmsg_fqdn_category_fill(struct session_runtime_attribute *session_attr, struct proxy_cmsg *cmsg)
{
size_t n_category_ids = 0;
uint32_t category_ids[8] = {0};
struct cmsg_int32_array *fqdn_cat_ids = &cmsg->fqdn_cat_id_val;
n_category_ids = srt_attribute_get_category_ids(session_attr, category_ids, sizeof(category_ids)/sizeof(category_ids[0]));
if (n_category_ids > 0 && n_category_ids <= 8) {
fqdn_cat_ids->num = n_category_ids;
for (unsigned int i = 0; i < n_category_ids; i++) {
fqdn_cat_ids->value[i] = category_ids[i];
}
}
return;
}
static void tsg_proxy_tcp_attribute_dump(tsg_proxy_tcp_attribute *tcp_attr, struct proxy_cmsg *cmsg, const struct streaminfo *stream)
{
struct tsg_proxy_tcp_option *client = &tcp_attr->tcp_opt_client;
struct tsg_proxy_tcp_option *server = &tcp_attr->tcp_opt_server;
char client_sids_str[128] = {0};
char server_sids_str[128] = {0};
char temp[10] = {0};
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_DEBUG, "PROXY", "dump tcp attribute for stream %s, session_id %llu",
printaddr(&stream->addr, stream->threadnum), tsg_get_stream_trace_id(stream));
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_DEBUG, "PROXY", "tcp_seq %u, tcp_ack %u, tcp_protocol %u, tcp_info_packet_cur_dir %u\n"\
"client mss %u, client wscale_set %u, client wscale %u, client sack %u, client ts_set %u, client ts_val %u, client window %u"\
"server mss %u, server wscale_set %u, server wscale %u, server sack %u, server ts_set %u, server ts_val %u, server window %u",
tcp_attr->tcp_seq, tcp_attr->tcp_ack, tcp_attr->tcp_protocol, tcp_attr->tcp_info_packet_cur_dir,
client->mss, client->wscale_set, client->wscale, client->sack, client->ts_set, client->ts_val, client->window,
server->mss, server->wscale_set, server->wscale, server->sack, server->ts_set, server->ts_val, server->window);
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_DEBUG, "PROXY", "tcp_seq_route_ctx len %u, tcp_ack_route_ctx len %u\n", client->route_ctx_len, server->route_ctx_len);
for (unsigned int i = 0; i < client->sid_list.sz_sidlist; i++) {
snprintf(temp, sizeof(temp), "%u", client->sid_list.sid_list[i]);
strcat(client_sids_str, temp);
strcat(client_sids_str, ",");
}
for (unsigned int i = 0; i < server->sid_list.sz_sidlist; i++) {
snprintf(temp, sizeof(temp), "%u", server->sid_list.sid_list[i]);
strcat(server_sids_str, temp);
strcat(server_sids_str, ",");
}
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_DEBUG, "PROXY", "tcp_seq_sids num %u, tcp_seq_sids value: %s, tcp_ack_sids num %u, tcp_seq_sids value: %s",
client->sid_list.sz_sidlist, client_sids_str, server->sid_list.sz_sidlist, server_sids_str);
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_DEBUG, "proxy", "client subscribe id: %s\n"\
"server subscribe id: %s\n"\
"client asn: %s\n"\
"server asn: %s\n"\
"client orgnization: %s\n"\
"server orgnization: %s\n"\
"client ip country: %s\n"\
"server ip country: %s\n"\
"client ip province: %s\n"\
"server ip province: %s\n"\
"client ip city: %s\n"\
"server ip city: %s\n"\
"client ip subdevision: %s\n"\
"server ip subdevision: %s\n"\
"ssl ja3 fingerprint:%s\n",
cmsg->src_sub_id,
cmsg->dst_sub_id,
cmsg->src_asn,
cmsg->dst_asn,
cmsg->src_organization,
cmsg->dst_organization,
cmsg->src_ip_location_country,
cmsg->dst_ip_location_country,
cmsg->src_ip_location_provine,
cmsg->dst_ip_location_provine,
cmsg->src_ip_location_city,
cmsg->dst_ip_location_city,
cmsg->src_ip_location_subdivision,
cmsg->dst_ip_location_subdivision,
cmsg->ssl_client_ja3_fingerprint);
return;
}
void tsg_proxy_update_policy_fill(const struct streaminfo *stream, struct update_policy *policy)
{
struct proxy_cmsg *cmsg = &policy->cmsg;
struct tsg_proxy_tcp_attribute *tcp_attr = tsg_proxy_tcp_attribute_get(stream);
struct session_runtime_attribute *session_attr = (struct session_runtime_attribute *)session_runtime_attribute_get(stream);
if (session_attr == NULL || tcp_attr == NULL) {
return;
}
struct tsg_proxy_tcp_option *client = &tcp_attr->tcp_opt_client;
struct tsg_proxy_tcp_option *server = &tcp_attr->tcp_opt_server;
cmsg->tcp_seq = tcp_attr->tcp_seq;
cmsg->tcp_ack = tcp_attr->tcp_ack;
cmsg->tcp_protocol = tcp_attr->tcp_protocol;
cmsg->tcp_info_packet_cur_dir = tcp_attr->tcp_info_packet_cur_dir;
cmsg->tcp_mss_client = client->mss;
cmsg->tcp_sack_client = client->sack;
cmsg->tcp_ts_client = client->ts_set;
cmsg->tcp_window_client = client->window;
cmsg->tcp_ts_client_val = client->ts_val;
cmsg->tcp_seq_route_ctx.num = client->route_ctx_len;
memcpy(cmsg->tcp_seq_route_ctx.value, client->route_ctx, client->route_ctx_len);
cmsg->tcp_seq_sids.num = client->sid_list.sz_sidlist;
for (unsigned int i = 0; i < client->sid_list.sz_sidlist; i++) {
cmsg->tcp_seq_sids.value[i] = client->sid_list.sid_list[i];
}
cmsg->tcp_mss_server = server->mss;
cmsg->tcp_sack_server = server->sack;
cmsg->tcp_ts_server = server->ts_set;
cmsg->tcp_window_server = server->window;
cmsg->tcp_ts_server_val = server->ts_val;
cmsg->tcp_ack_route_ctx.num = server->route_ctx_len;
memcpy(cmsg->tcp_ack_route_ctx.value, server->route_ctx, server->route_ctx_len);
cmsg->tcp_ack_sids.num = server->sid_list.sz_sidlist;
for (unsigned int i = 0; i < server->sid_list.sz_sidlist; i++) {
cmsg->tcp_ack_sids.value[i] = server->sid_list.sid_list[i];
}
if (client->wscale_set && server->wscale_set) {
cmsg->tcp_wsacle_exist = 1;
cmsg->tcp_wsacle_client = client->wscale;
cmsg->tcp_wsacle_server = server->wscale;
}
tsg_proxy_cmsg_subscriber_fill(session_attr, cmsg);
tsg_proxy_cmsg_asn_fill(session_attr, cmsg);
tsg_proxy_cmsg_ip_location_fill(session_attr, cmsg);
tsg_proxy_cmsg_ja3_fingerprint_fill(session_attr, cmsg);
tsg_proxy_cmsg_fqdn_category_fill(session_attr, cmsg);
tsg_proxy_tcp_attribute_dump(tcp_attr, cmsg, stream);
return;
}

53
src/tsg_proxy.h Normal file
View File

@@ -0,0 +1,53 @@
#pragma once
#include <MESA/stream.h>
struct tsg_proxy_tcp_option
{
uint16_t mss;
uint8_t wscale_set;
uint8_t wscale;
uint8_t sack;
uint8_t ts_set;
uint32_t ts_val;
uint32_t ts_ecr;
uint16_t window;
uint8_t route_ctx_len;
uint8_t route_ctx[64];//route_ctx is contiguous memory
struct segment_id_list sid_list;
};
struct tsg_proxy_tcp_attribute
{
uint8_t first_data_pkt_processed;
uint8_t ignore;
uint32_t tcp_seq;
uint32_t tcp_ack;
uint8_t tcp_protocol;
uint8_t tcp_info_packet_cur_dir;
struct tsg_proxy_tcp_option tcp_opt_client;
struct tsg_proxy_tcp_option tcp_opt_server;
};
struct pkt_info{
addr_type_t addr_type;
union{
struct iphdr *v4;
struct ip6_hdr *v6;
}iphdr;
uint16_t iphdr_len;
uint16_t ip_totlen;
struct tcphdr *tcphdr;
uint16_t tcphdr_len;
char *data;
uint16_t data_len;
int parse_failed;
};
int tsg_proxy_ipv4_header_parse(const void *a_packet, struct pkt_info *pktinfo);
int tsg_proxy_ipv6_header_parse(const void *a_packet, struct pkt_info *pktinfo);
void tsg_proxy_tcp_parse(struct tsg_proxy_tcp_attribute *tcp_attr, struct pkt_info *pktinfo, const struct streaminfo *pstream);
void tsg_proxy_first_data_process(const struct streaminfo *stream, struct tsg_proxy_tcp_attribute *tcp_attr, struct pkt_info *pktinfo);
void tsg_proxy_tcp_options_parse(const struct streaminfo *stream, const void *a_packet);
void tsg_proxy_update_policy_fill(const struct streaminfo *stream, struct update_policy *policy);

View File

@@ -3075,7 +3075,7 @@ size_t tsg_matched_rules_select(struct maat *feather, TSG_SERVICE service, long
return offset;
}
size_t tm_select_result_by_service_id(struct maat_rule *matched_rules, size_t n_matched_rules, struct maat_rule *rules, size_t n_rules, enum TSG_SERVICE service_id)
size_t tsg_select_rules_by_service_id(struct maat_rule *matched_rules, size_t n_matched_rules, struct maat_rule *rules, size_t n_rules, enum TSG_SERVICE service_id)
{
size_t offset=0;
for(size_t i=0; i<n_matched_rules; i++)
@@ -3089,21 +3089,6 @@ size_t tm_select_result_by_service_id(struct maat_rule *matched_rules, size_t n_
return offset;
}
size_t tsg_select_matched_security_rules(struct maat_rule *matched_rules, size_t n_matched_rules, struct maat_rule *rules, size_t n_rules)
{
return tm_select_result_by_service_id(matched_rules, n_matched_rules, rules, n_rules, TSG_SERVICE_SECURITY);
}
size_t tsg_select_matched_shaping_rules(struct maat_rule *matched_rules, size_t n_matched_rules, struct maat_rule *rules, size_t n_rules)
{
return tm_select_result_by_service_id(matched_rules, n_matched_rules, rules, n_rules, TSG_SERVICE_SHAPING);
}
size_t tsg_select_matched_service_chaining_rules(struct maat_rule *matched_rules, size_t n_matched_rules, struct maat_rule *rules, size_t n_rules)
{
return tm_select_result_by_service_id(matched_rules, n_matched_rules, rules, n_rules, TSG_SERVICE_CHAINING);
}
int tsg_table_idx_get_by_protocol(TSG_PROTOCOL proto)
{
switch(proto)

View File

@@ -168,8 +168,3 @@ int tsg_scan_intercept_exclusion(const struct streaminfo *a_stream, struct maat
struct maat_rule *tsg_select_deny_rule(struct maat_rule *rules, size_t n_rules);
struct umts_user_info *tsg_get_umts_user_info_form_redis(struct maat *feather, long long teid);
size_t tsg_select_matched_security_rules(struct maat_rule * matched_rules, size_t n_matched_rules, struct maat_rule *rules, size_t n_rules);
size_t tsg_select_matched_shaping_rules(struct maat_rule * matched_rules, size_t n_matched_rules, struct maat_rule *rules, size_t n_rules);
size_t tsg_select_matched_service_chaining_rules(struct maat_rule * matched_rules, size_t n_matched_rules, struct maat_rule *rules, size_t n_rules);

View File

@@ -2111,8 +2111,8 @@ int send_security_event_log(struct tsg_log_instance_t *_instance, struct TLD_han
TLD_append(_handle, _instance->id2field[LOG_COMMON_POLICY_ID].name, (void *)(long)(rules[i].rule_id), TLD_TYPE_LONG);
TLD_append(_handle, _instance->id2field[LOG_COMMON_SERVICE].name, (void *)(long)(rules[i].service_id), TLD_TYPE_LONG);
TLD_append(_handle, _instance->id2field[LOG_COMMON_ACTION].name, (void *)(long)((unsigned char)rules[i].action), TLD_TYPE_LONG);
TLD_append(_handle, _instance->id2field[LOG_COMMON_VSYSTEM_ID].name, (void *)(long)rules[i].vsys_id, TLD_TYPE_LONG);
TLD_append(_handle, _instance->id2field[LOG_COMMON_ACTION].name, (void *)(long)(rules[i].action), TLD_TYPE_LONG);
set_policy_action_para_exec_result(_instance, _handle, a_stream, &(rules[i]));

View File

@@ -2,53 +2,50 @@
#include <stdlib.h>
#include <string.h>
#include <MESA/cJSON.h>
#include <MESA/MESA_handle_logger.h>
#include "tsg_variable.h"
#include "tsg_sync_state.h"
#include "tsg_send_log.h"
#include "mpack.h"
// i don't need this
int set_exec_profile_ids(const struct streaminfo *a_stream, struct parse_handle *p);
const char *policy_key[ POLICY_UPDATE_MAX] =
const char *policy_key[POLICY_UPDATE_MAX] = {"sce", "shaper", "proxy"};
char *mpack_data = NULL;
size_t mpack_size = 0;
static int tsg_mpack_init_map(const struct streaminfo *a_stream, mpack_writer_t *writer, const char *state)
{
"service_chaining",
"shaping",
};
mpack_writer_init_growable(writer, &mpack_data, &mpack_size);
mpack_build_map(writer);
static int tsg_send_ctrl_pkt(const struct streaminfo *a_stream, cJSON *object)
// tsync : 2.0
mpack_write_cstr(writer, "tsync");
mpack_write_cstr(writer, "2.0");
// session_id
mpack_write_cstr(writer, "session_id");
mpack_write_u64(writer, tsg_get_stream_trace_id((struct streaminfo *)a_stream));
// state
mpack_write_cstr(writer, "state");
mpack_write_cstr(writer, state);
return 0;
}
static int tsg_mpack_send_pkt(const struct streaminfo *a_stream, mpack_writer_t *writer)
{
if (object == NULL)
mpack_complete_map(writer); // tsg_mpack_init_map
if (mpack_writer_destroy(writer) != mpack_ok)
{
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_FATAL, "MPACK_WRITER", "An error occurred encoding the data!");
return -1;
}
char *payload = NULL;
uint64_t session_id = tsg_get_stream_trace_id((struct streaminfo *)a_stream);
// tsg_get_stream_trace_id maybe return -1
if (session_id && session_id != (uint64_t)-1)
{
char trace_id[128]={0};
snprintf(trace_id, sizeof(trace_id), "%lu", session_id);
cJSON_AddStringToObject(object, "session_id", trace_id);
}
cJSON_AddStringToObject(object, "tsync", "1.0");
payload = cJSON_PrintUnformatted(object);
if (payload == NULL)
{
cJSON_Delete(object);
return -1;
}
// send//
sapp_inject_ctrl_pkt((struct streaminfo *)a_stream, SIO_DEFAULT, payload, strlen(payload)+1, a_stream->routedir);
cJSON_free(payload);
cJSON_Delete(object);
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_DEBUG, "MSGPACK_PROXY_BUFF", "send buff_len = %lu", mpack_size);
sapp_inject_ctrl_pkt((struct streaminfo *)a_stream, SIO_DEFAULT, mpack_data, mpack_size, a_stream->routedir);
free(mpack_data);
mpack_data = NULL;
mpack_size = 0;
return 0;
}
@@ -59,23 +56,21 @@ int tsg_send_session_state(const struct streaminfo *a_stream, unsigned char stat
return -1;
}
cJSON *object = cJSON_CreateObject();
if (state== OP_STATE_PENDING)
mpack_writer_t writer;
if (state == OP_STATE_PENDING)
{
cJSON_AddStringToObject(object, "state", "opening");
tsg_mpack_init_map(a_stream, &writer, "opening");
}
else if (state == OP_STATE_CLOSE)
else if (state == OP_STATE_CLOSE)
{
cJSON_AddStringToObject(object, "state", "closing");
tsg_mpack_init_map(a_stream, &writer, "closing");
}
else
{
cJSON_Delete(object);
return -1;
}
return tsg_send_ctrl_pkt(a_stream, object);
return tsg_mpack_send_pkt(a_stream, &writer);
}
int tsg_sync_resetall_state(const struct streaminfo *a_stream)
@@ -85,93 +80,211 @@ int tsg_sync_resetall_state(const struct streaminfo *a_stream)
return -1;
}
cJSON *object = cJSON_CreateObject();
cJSON_AddStringToObject(object, "state", "resetall");
mpack_writer_t writer;
tsg_mpack_init_map(a_stream, &writer, "resetall");
return tsg_send_ctrl_pkt(a_stream, object);
return tsg_mpack_send_pkt(a_stream, &writer);
}
int tsg_sync_policy_update(const struct streaminfo *a_stream, struct update_policy *policy_array, int policy_array_num)
static void tsg_mpack_append_str(mpack_writer_t *writer, char *str)
{
if (a_stream == NULL || policy_array == NULL || policy_array_num > (int) POLICY_UPDATE_MAX || policy_array_num <= 0)
if (str)
{
return -1;
mpack_write_cstr(writer, str);
}
else
{
mpack_write_nil(writer);
}
cJSON *params_object = NULL;
cJSON *policy_arr = NULL;
cJSON *object = cJSON_CreateObject();
cJSON_AddStringToObject(object, "state", "active");
cJSON_AddStringToObject(object, "method", "policy_update");
params_object = cJSON_AddObjectToObject(object, "params");
for (int i = 0; i < policy_array_num; i++)
{
int tmp_ids[8]={0};
int n_tmp_ids=MIN(policy_array[i].n_ids, 8);
for(int j=0; j<n_tmp_ids; j++)
{
tmp_ids[j]=(int)(policy_array[i].ids[j]);
}
policy_arr = cJSON_CreateIntArray(tmp_ids, n_tmp_ids);
if (policy_arr == NULL || policy_array[i].type >= POLICY_UPDATE_MAX)
{
cJSON_Delete(object);
return -1;
}
cJSON_AddItemToObject(params_object, policy_key[policy_array[i].type], policy_arr);
policy_arr = NULL;
}
return tsg_send_ctrl_pkt(a_stream, object);
return;
}
int tsg_recv_control_pkt(const struct streaminfo *a_stream, const void *payload, int payload_len)
static void tsg_mpack_append_array_u32(mpack_writer_t *writer, struct cmsg_int32_array *array)
{
if (a_stream == NULL || payload == NULL || payload_len == 0)
if (array->num > 0)
{
mpack_build_array(writer);
for (size_t i = 0; i < array->num; i++)
{
mpack_write_u32(writer, array->value[i]);
}
mpack_complete_array(writer);
}
else
{
mpack_write_nil(writer);
}
return;
}
static void tsg_mpack_append_array_u16(mpack_writer_t *writer, struct cmsg_int16_array *array)
{
if (array->num > 0)
{
mpack_build_array(writer);
for (size_t i = 0; i < array->num; i++)
{
mpack_write_u16(writer, array->value[i]);
}
mpack_complete_array(writer);
}
else
{
mpack_write_nil(writer);
}
return;
}
static void tsg_mpack_append_array_u8(mpack_writer_t *writer, struct cmsg_int8_array *array)
{
if (array->num > 0)
{
mpack_build_array(writer);
for (size_t i = 0; i < array->num; i++)
{
mpack_write_u8(writer, array->value[i]);
}
mpack_complete_array(writer);
}
else
{
mpack_write_nil(writer);
}
return;
}
static void tsg_mpack_append_cmsg_value(mpack_writer_t *writer, struct proxy_cmsg *cmsg)
{
if (cmsg == NULL)
{
mpack_write_nil(writer);
MESA_handle_runtime_log(g_tsg_para.logger, RLOG_LV_DEBUG, "MSGPACK_PROXY", "No cmsg!");
}
else
{
mpack_build_array(writer); // array
mpack_write_u32(writer, cmsg->tcp_seq);
mpack_write_u32(writer, cmsg->tcp_ack);
mpack_write_u16(writer, cmsg->tcp_mss_client);
mpack_write_u16(writer, cmsg->tcp_mss_server);
if (cmsg->tcp_wsacle_exist == 1)
{
mpack_write_u8(writer, cmsg->tcp_wsacle_client);
mpack_write_u8(writer, cmsg->tcp_wsacle_server);
}
else
{
mpack_write_nil(writer);
mpack_write_nil(writer);
}
mpack_write_u8(writer, cmsg->tcp_sack_client);
mpack_write_u8(writer, cmsg->tcp_sack_server);
mpack_write_u8(writer, cmsg->tcp_ts_client);
mpack_write_u8(writer, cmsg->tcp_ts_server);
mpack_write_u8(writer, cmsg->tcp_protocol);
mpack_write_u16(writer, cmsg->tcp_window_client);
mpack_write_u16(writer, cmsg->tcp_window_server);
mpack_write_u32(writer, cmsg->tcp_ts_client_val);
mpack_write_u32(writer, cmsg->tcp_ts_server_val);
mpack_write_u8(writer, cmsg->tcp_info_packet_cur_dir);
tsg_mpack_append_str(writer, cmsg->src_sub_id);
tsg_mpack_append_str(writer, cmsg->dst_sub_id);
tsg_mpack_append_str(writer, cmsg->src_asn);
tsg_mpack_append_str(writer, cmsg->dst_asn);
tsg_mpack_append_str(writer, cmsg->src_organization);
tsg_mpack_append_str(writer, cmsg->dst_organization);
tsg_mpack_append_str(writer, cmsg->src_ip_location_country);
tsg_mpack_append_str(writer, cmsg->dst_ip_location_country);
tsg_mpack_append_str(writer, cmsg->src_ip_location_provine);
tsg_mpack_append_str(writer, cmsg->dst_ip_location_provine);
tsg_mpack_append_str(writer, cmsg->src_ip_location_city);
tsg_mpack_append_str(writer, cmsg->dst_ip_location_city);
tsg_mpack_append_str(writer, cmsg->src_ip_location_subdivision);
tsg_mpack_append_str(writer, cmsg->dst_ip_location_subdivision);
tsg_mpack_append_str(writer, cmsg->ssl_client_ja3_fingerprint);
// fqdn_cat_id_val
tsg_mpack_append_array_u32(writer, &cmsg->fqdn_cat_id_val);
// tcp_seq_sids
tsg_mpack_append_array_u16(writer, &cmsg->tcp_seq_sids);
// tcp_ack_sids
tsg_mpack_append_array_u16(writer, &cmsg->tcp_ack_sids);
// tcp_seq_route_ctx
tsg_mpack_append_array_u8(writer, &cmsg->tcp_seq_route_ctx);
// tcp_ack_route_ctx
tsg_mpack_append_array_u8(writer, &cmsg->tcp_ack_route_ctx);
mpack_complete_array(writer); // array
}
return;
}
static void tsg_mpack_append_update_policy(mpack_writer_t *writer, struct update_policy *policy_update, enum policy_type type)
{
mpack_write_cstr(writer, policy_key[type]);
mpack_build_map(writer); // update_policy_type
mpack_write_cstr(writer, "rule_ids");
if (policy_update->n_ids > 0)
{
mpack_build_array(writer); // rule_ids
for (int i = 0; i < policy_update->n_ids; i++)
{
mpack_write_i64(writer, policy_update->ids[i]);
}
mpack_complete_array(writer); // rule_ids
}
else
{
mpack_write_nil(writer);
}
if (type == POLICY_UPDATE_INTERCEPT)
{
mpack_write_cstr(writer, "tcp_handshake");
tsg_mpack_append_cmsg_value(writer, &policy_update->cmsg);
}
mpack_complete_map(writer); // update_policy_type
return;
}
int tsg_sync_policy_update(const struct streaminfo *a_stream, struct update_policy *policy_update, size_t n_policy_update)
{
if (a_stream == NULL || policy_update == NULL || policy_update->type >= POLICY_UPDATE_MAX || n_policy_update == 0)
{
return -1;
}
char *state = NULL;
char *method = NULL;
char *tsync = NULL;
cJSON *params_object = NULL;
cJSON *sf_ids_array = NULL;
struct parse_handle result = {0};
mpack_writer_t writer;
cJSON *object = cJSON_Parse((char *)payload);
if (object == NULL)
tsg_mpack_init_map((struct streaminfo *)a_stream, &writer, "active");
// method: policy_update
mpack_write_cstr(&writer, "method");
mpack_write_cstr(&writer, "policy_update");
// params
mpack_write_cstr(&writer, "params");
mpack_build_map(&writer);
for (int i = 0; i < (int)n_policy_update; i++)
{
return -1;
}
tsync = cJSON_GetObjectItem(object, "tsync")->valuestring;
memcpy(result.tsync, tsync, strlen(tsync));
//result.session_id = (uint64_t)atoll(cJSON_GetObjectItem(object, "session_id")->string);
state = cJSON_GetObjectItem(object, "state")->valuestring;
memcpy(result.state, state, strlen(state));
method = cJSON_GetObjectItem(object, "method")->valuestring;
memcpy(result.method, method, strlen(method));
params_object = cJSON_GetObjectItem(object, "params");
sf_ids_array = cJSON_GetObjectItem(params_object, "sf_profile_ids");
result.sf_ids.n_ids = cJSON_GetArraySize(sf_ids_array);
for (int i = 0; i < result.sf_ids.n_ids; i ++)
{
result.sf_ids.ids[i] = cJSON_GetArrayItem(sf_ids_array, i)->valueint;
tsg_mpack_append_update_policy(&writer, &policy_update[i], policy_update[i].type);
}
mpack_complete_map(&writer); // params
//set_exec_profile_ids(a_stream, &result);
cJSON_Delete(object);
return 0;
return tsg_mpack_send_pkt(a_stream, &writer);
}
int tsg_sync_closing_state(const struct streaminfo *a_stream, unsigned char state)
@@ -185,4 +298,3 @@ int tsg_sync_opening_state(const struct streaminfo *a_stream, unsigned char stat
return 0;
}

View File

@@ -5,33 +5,83 @@
enum policy_type
{
POLICY_UPDATE_SERVICE_CHAINING = 0,
POLICY_UPDATE_SERVICE_CHAINING = 0,
POLICY_UPDATE_SHAPING,
POLICY_UPDATE_INTERCEPT,
POLICY_UPDATE_MAX
};
struct cmsg_int32_array
{
size_t num;
uint32_t value[8];
};
struct cmsg_int16_array
{
size_t num;
uint16_t value[8];
};
struct cmsg_int8_array
{
size_t num;
uint8_t value[64];
};
struct proxy_cmsg
{
uint32_t tcp_seq;
uint32_t tcp_ack;
uint16_t tcp_mss_client;
uint16_t tcp_mss_server;
uint8_t tcp_wsacle_exist;
uint8_t tcp_wsacle_client;
uint8_t tcp_wsacle_server;
uint8_t tcp_sack_client;
uint8_t tcp_sack_server;
uint8_t tcp_ts_client;
uint8_t tcp_ts_server;
uint8_t tcp_protocol;
uint16_t tcp_window_client;
uint16_t tcp_window_server;
uint32_t tcp_ts_client_val;
uint32_t tcp_ts_server_val;
uint8_t tcp_info_packet_cur_dir;
char *src_sub_id;
char *dst_sub_id;
char *src_asn;
char *dst_asn;
char *src_organization;
char *dst_organization;
char *src_ip_location_country;
char *dst_ip_location_country;
char *src_ip_location_provine;
char *dst_ip_location_provine;
char *src_ip_location_city;
char *dst_ip_location_city;
char *src_ip_location_subdivision;
char *dst_ip_location_subdivision;
char *ssl_client_ja3_fingerprint;
struct cmsg_int32_array fqdn_cat_id_val;
struct cmsg_int16_array tcp_seq_sids;
struct cmsg_int16_array tcp_ack_sids;
struct cmsg_int8_array tcp_seq_route_ctx;
struct cmsg_int8_array tcp_ack_route_ctx;
};
struct update_policy
{
enum policy_type type;
int n_ids;
long long ids[8];
};
// i don't need this
struct parse_handle
{
char tsync[8];
uint64_t session_id;
char state[8];
char method[16];
struct update_policy sf_ids;
enum policy_type type;
int n_ids;
long long ids[8];
struct proxy_cmsg cmsg;
};
int tsg_sync_resetall_state(const struct streaminfo *a_stream);
int tsg_send_session_state(const struct streaminfo *a_stream, unsigned char state);
int tsg_sync_opening_state(const struct streaminfo *a_stream, unsigned char state);
int tsg_sync_closing_state(const struct streaminfo *a_stream, unsigned char state);
int tsg_sync_policy_update(const struct streaminfo *a_stream, struct update_policy *policy_array, int policy_array_num);
int tsg_recv_control_pkt(const struct streaminfo *a_stream, const void *payload, int payload_len);
int tsg_sync_policy_update(const struct streaminfo *a_stream, struct update_policy *policy_update, size_t n_policy_update);
// int tsg_recv_control_pkt(const struct streaminfo *a_stream, const void *payload, int payload_len);

View File

@@ -127,6 +127,7 @@ struct tsg_rt_para
int feature_tamper;
int service_chaining_sid;
int shaping_sid;
int intercept_sid;
int send_resetall;
enum DEPLOY_MODE deploy_mode;
int scan_time_interval;