This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
tango-tfe/common/src/tfe_ctrl_packet.cpp

711 lines
32 KiB
C++
Raw Normal View History

2023-04-18 16:03:57 +08:00
#include <string.h>
#include <stdlib.h>
#include <cjson/cJSON.h>
2023-05-15 16:41:59 +08:00
#include "mpack.h"
2023-04-18 16:03:57 +08:00
#include "tfe_cmsg.h"
#include "tfe_utils.h"
#include "tfe_ctrl_packet.h"
2023-05-15 16:41:59 +08:00
enum ctr_pkt_index
{
INDEX_TSYNC = 0,
INDEX_SESSION_ID,
INDEX_STATE,
INDEX_METHOD,
INDEX_KEY_SCE,
INDEX_VALUE_SCE,
INDEX_KEY_SHAPER,
INDEX_VALUE_SHAPER,
INDEX_KEY_PROXY,
INDEX_VALUE_PROXY,
INDEX_MAX
};
enum {
CMSG_MODE,
ARRAY_MODE,
VARIABLE_MODE,
};
enum {
MPACK_ARRAY_SRC_IP_LOCATION,
MPACK_ARRAY_DST_IP_LOCATION,
MPACK_ARRAY_SRC_IP_LOCATION_OBJ_ID,
MPACK_ARRAY_DST_IP_LOCATION_OBJ_ID,
2023-05-15 16:41:59 +08:00
MPACK_ARRAY_SEQ_SIDS,
MPACK_ARRAY_ACK_SIDS,
MPACK_ARRAY_SEQ_ROUTE_CTX,
MPACK_ARRAY_ACK_ROUTE_CTX,
MPACK_ARRAY_SEQ_PKT_HEADER,
MPACK_ARRAY_ACK_PKT_HEADER,
MPACK_ARRAY_MAX,
};
enum {
MPACK_VAR_FLAG,
2023-11-16 19:34:43 +08:00
MPACK_VAR_WSACLE_CLIENT_FLAG,
MPACK_VAR_WSACLE_SERVER_FLAG,
MPACK_VAR_MAX,
2023-05-15 16:41:59 +08:00
};
enum {
INDEX_SRC_IP_LOCATION,
INDEX_DST_IP_LOCATION,
INDEX_SRC_IP_LOCATION_OBJ_ID,
INDEX_DST_IP_LOCATION_OBJ_ID,
};
int ip_location_cmsg_map[4][4] = {
{TFE_CMSG_SRC_REGION_STR, TFE_CMSG_SRC_PROVINCE_STR, TFE_CMSG_SRC_CITY_STR, TFE_CMSG_SRC_SUBDIVISION_STR},
{TFE_CMSG_DST_REGION_STR, TFE_CMSG_DST_PROVINCE_STR, TFE_CMSG_DST_CITY_STR, TFE_CMSG_DST_SUBDIVISION_STR},
{TFE_CMSG_SRC_REGION_ID, TFE_CMSG_SRC_PROVINCE_ID, TFE_CMSG_SRC_CITY_ID, TFE_CMSG_SRC_SUBDIVISION_ID},
{TFE_CMSG_DST_REGION_ID, TFE_CMSG_DST_PROVINCE_ID, TFE_CMSG_DST_CITY_ID, TFE_CMSG_DST_SUBDIVISION_ID}
};
struct ip_location_string_s {
const char *name[4];
};
struct ip_location_string_s ip_location_string_map[4] = {
{"TFE_CMSG_SRC_REGION_STR", "TFE_CMSG_SRC_PROVINCE_STR", "TFE_CMSG_SRC_CITY_STR", "TFE_CMSG_SRC_SUBDIVISION_STR"},
{"TFE_CMSG_DST_REGION_STR", "TFE_CMSG_DST_PROVINCE_STR", "TFE_CMSG_DST_CITY_STR", "TFE_CMSG_DST_SUBDIVISION_STR"},
{"TFE_CMSG_SRC_REGION_ID", "TFE_CMSG_SRC_PROVINCE_ID", "TFE_CMSG_SRC_CITY_ID", "TFE_CMSG_SRC_SUBDIVISION_ID"},
{"TFE_CMSG_DST_REGION_ID", "TFE_CMSG_DST_PROVINCE_ID", "TFE_CMSG_DST_CITY_ID", "TFE_CMSG_DST_SUBDIVISION_ID"}
};
2023-05-15 16:41:59 +08:00
struct mpack_mmap_id2type
{
int id;
int mode;
int type;
2023-05-15 16:41:59 +08:00
const char *str_name;
int size;
}mpack_table[] = {
{.id = 0, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_SEQ, .str_name = "TFE_CMSG_TCP_RESTORE_SEQ", .size = 4},
{.id = 1, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_ACK, .str_name = "TFE_CMSG_TCP_RESTORE_ACK", .size = 4},
{.id = 2, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_MSS_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_MSS_CLIENT", .size = 2},
{.id = 3, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_MSS_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_MSS_SERVER", .size = 2},
2023-11-16 19:34:43 +08:00
{.id = 4, .mode = VARIABLE_MODE, .type = MPACK_VAR_WSACLE_CLIENT_FLAG, .str_name = "TFE_CMSG_TCP_RESTORE_WSACLE_CLIENT_FLAG", .size = 1},
{.id = 5, .mode = VARIABLE_MODE, .type = MPACK_VAR_WSACLE_SERVER_FLAG, .str_name = "TFE_CMSG_TCP_RESTORE_WSACLE_SERVER_FLAG", .size = 1},
{.id = 6, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_WSACLE_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_WSACLE_CLIENT", .size = 1},
{.id = 7, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_WSACLE_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_WSACLE_SERVER", .size = 1},
{.id = 8, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_SACK_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_SACK_CLIENT", .size = 1},
{.id = 9, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_SACK_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_SACK_SERVER", .size = 1},
{.id = 10, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_TS_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_TS_CLIENT", .size = 1},
{.id = 11, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_TS_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_TS_SERVER", .size = 1},
{.id = 12, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_PROTOCOL, .str_name = "TFE_CMSG_TCP_RESTORE_PROTOCOL", .size = 1},
{.id = 13, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_WINDOW_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_WINDOW_CLIENT", .size = 2},
{.id = 14, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_WINDOW_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_WINDOW_SERVER", .size = 2},
{.id = 15, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_TS_CLIENT_VAL, .str_name = "TFE_CMSG_TCP_RESTORE_TS_CLIENT_VAL", .size = 4},
{.id = 16, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_TS_SERVER_VAL, .str_name = "TFE_CMSG_TCP_RESTORE_TS_SERVER_VAL", .size = 4},
{.id = 17, .mode = CMSG_MODE, .type = TFE_CMSG_TCP_RESTORE_INFO_PACKET_CUR_DIR, .str_name = "TFE_CMSG_TCP_RESTORE_INFO_PACKET_CUR_DIR", .size = 1},
{.id = 18, .mode = CMSG_MODE, .type = TFE_CMSG_SRC_SUB_ID, .str_name = "TFE_CMSG_SRC_SUB_ID", .size = 256},
{.id = 19, .mode = CMSG_MODE, .type = TFE_CMSG_DST_SUB_ID, .str_name = "TFE_CMSG_DST_SUB_ID", .size = 256},
{.id = 20, .mode = CMSG_MODE, .type = TFE_CMSG_SRC_ASN_VAL, .str_name = "TFE_CMSG_SRC_ASN_VAL", .size = 8},
{.id = 21, .mode = CMSG_MODE, .type = TFE_CMSG_DST_ASN_VAL, .str_name = "TFE_CMSG_DST_ASN_VAL", .size = 8},
{.id = 22, .mode = CMSG_MODE, .type = TFE_CMSG_SRC_ASN_ID, .str_name = "TFE_CMSG_SRC_ASN_ID", .size = 8},
{.id = 23, .mode = CMSG_MODE, .type = TFE_CMSG_DST_ASN_ID, .str_name = "TFE_CMSG_DST_ASN_ID", .size = 8},
{.id = 24, .mode = ARRAY_MODE, .type = MPACK_ARRAY_SRC_IP_LOCATION, .str_name = "MPACK_ARRAY_SRC_IP_LOCATION", .size = 256},
{.id = 25, .mode = ARRAY_MODE, .type = MPACK_ARRAY_DST_IP_LOCATION, .str_name = "MPACK_ARRAY_DST_IP_LOCATION", .size = 256},
{.id = 26, .mode = ARRAY_MODE, .type = MPACK_ARRAY_SRC_IP_LOCATION_OBJ_ID, .str_name = "MPACK_ARRAY_SRC_IP_LOCATION_OBJ_ID", .size = 8},
{.id = 27, .mode = ARRAY_MODE, .type = MPACK_ARRAY_DST_IP_LOCATION_OBJ_ID, .str_name = "MPACK_ARRAY_DST_IP_LOCATION_OBJ_ID", .size = 8},
{.id = 28, .mode = CMSG_MODE, .type = TFE_CMSG_SSL_CLIENT_JA3_FINGERPRINT, .str_name = "TFE_CMSG_SSL_CLIENT_JA3_FINGERPRINT", .size = 32},
{.id = 29, .mode = ARRAY_MODE, .type = MPACK_ARRAY_SEQ_SIDS, .str_name = "TFE_SEQ_SIDS", .size = 2},
{.id = 30, .mode = ARRAY_MODE, .type = MPACK_ARRAY_ACK_SIDS, .str_name = "TFE_ACK_SIDS", .size = 2},
{.id = 31, .mode = ARRAY_MODE, .type = MPACK_ARRAY_SEQ_ROUTE_CTX, .str_name = "TFE_SEQ_ROUTE_CTX", .size = 1},
{.id = 32, .mode = ARRAY_MODE, .type = MPACK_ARRAY_ACK_ROUTE_CTX, .str_name = "TFE_ACK_ROUTE_CTX", .size = 1},
{.id = 33, .mode = ARRAY_MODE, .type = MPACK_ARRAY_SEQ_PKT_HEADER, .str_name = "TFE_SEQ_PKT_HEADER", .size = 1},
{.id = 34, .mode = ARRAY_MODE, .type = MPACK_ARRAY_ACK_PKT_HEADER, .str_name = "TFE_ACK_PKT_HEADER", .size = 1},
{.id = 35, .mode = VARIABLE_MODE, .type = MPACK_VAR_FLAG, .str_name = "TFE_FLAG", .size = 1}
2023-05-15 16:41:59 +08:00
};
extern void * g_packet_io_logger;
static int sids_array_parse_mpack(struct ctrl_pkt_parser *handler, mpack_node_t node, int is_seq)
2023-05-15 16:41:59 +08:00
{
struct sids *sid = is_seq ? &handler->seq_sids : &handler->ack_sids;
sid->num = mpack_node_array_length(node);
if (sid->num > MR_SID_LIST_MAXLEN) {
TFE_LOG_ERROR(g_packet_io_logger, "%s: session %lu unexpected control packet: (%s sid num[%d] is invalid, over max num[%d])", LOG_TAG_CTRLPKT, handler->session_id, is_seq ? "seq" : "ack", sid->num, MR_SID_LIST_MAXLEN);
2023-05-15 16:41:59 +08:00
return -1;
}
for (int i = 0; i < sid->num; i++)
{
sid->elems[i] = mpack_node_u16(mpack_node_array_at(node, i));
}
return 0;
}
static int route_ctx_parse_mpack(struct ctrl_pkt_parser *handler, mpack_node_t node, int is_seq)
2023-05-15 16:41:59 +08:00
{
struct route_ctx *ctx = is_seq ? &handler->seq_route_ctx : &handler->ack_route_ctx;
size_t len = mpack_node_bin_size(node);
if (len < 0 || len > 64) {
TFE_LOG_ERROR(g_packet_io_logger, "%s: session %lu unexpected control packet: (%s route len[%ld] is invalid, over max size[64])", LOG_TAG_CTRLPKT, handler->session_id, is_seq ? "seq" : "ack", len);
2023-05-15 16:41:59 +08:00
return -1;
}
ctx->len = len;
memcpy(ctx->data, mpack_node_bin_data(node), len);
return 0;
}
static int pkt_header_parse_mpack(struct ctrl_pkt_parser *handler, mpack_node_t node, int is_seq)
{
char **header = is_seq ? &handler->seq_header : &handler->ack_header;
int *header_len = is_seq ? &handler->seq_len : &handler->ack_len;
size_t len = mpack_node_bin_size(node);
if (len < 0) {
TFE_LOG_ERROR(g_packet_io_logger, "%s: session %lu unexpected control packet: (%s packet header len[%ld] is invalid)", LOG_TAG_CTRLPKT, handler->session_id, is_seq ? "seq" : "ack", len);
return -1;
2023-05-15 16:41:59 +08:00
}
if (len == 0)
return 0;
*header = (char *)calloc(len, sizeof(char));
memcpy(*header, mpack_node_bin_data(node), len);
*header_len = len;
2023-05-15 16:41:59 +08:00
return 0;
}
static int ip_location_array_parse_mpack(struct ctrl_pkt_parser *handler, mpack_node_t node, int map_index)
{
char location_str[1024] = {0};
uint32_t array_cnt = mpack_node_array_length(node);
if (array_cnt != 4) {
TFE_LOG_ERROR(g_packet_io_logger, "%s: session %lu unexpected control packet: (%s ip location array count[%u] != [4])", LOG_TAG_CTRLPKT, handler->session_id, map_index==INDEX_SRC_IP_LOCATION ? "src" : "dst", array_cnt);
return -1;
}
for (uint32_t i = 0; i < array_cnt; i++) {
mpack_node_t ptr = mpack_node_array_at(node, i);
switch (mpack_node_type(ptr)) {
case mpack_type_str:
if (mpack_node_strlen(ptr) == 0)
break;
memset(location_str, 0, sizeof(location_str));
mpack_node_copy_cstr(ptr, location_str, sizeof(location_str));
tfe_cmsg_set(handler->cmsg, (enum tfe_cmsg_tlv_type)ip_location_cmsg_map[map_index][i], (const unsigned char*)location_str, mpack_node_strlen(ptr));
break;
default:
break;
}
}
return 0;
}
static int ip_location_obj_id_array_parse_mpack(struct ctrl_pkt_parser *handler, mpack_node_t node, int map_index)
{
uint64_t object_id = 0;
uint32_t array_cnt = mpack_node_array_length(node);
if (array_cnt != 4) {
TFE_LOG_ERROR(g_packet_io_logger, "%s: session %lu unexpected control packet: (%s ip location array count[%u] != [4])", LOG_TAG_CTRLPKT, handler->session_id, map_index==INDEX_SRC_IP_LOCATION_OBJ_ID ? "src" : "dst", array_cnt);
return -1;
}
for (uint32_t i = 0; i < array_cnt; i++) {
mpack_node_t ptr = mpack_node_array_at(node, i);
switch (mpack_node_type(ptr)) {
case mpack_type_uint:
object_id = mpack_node_u64(ptr);
tfe_cmsg_set(handler->cmsg, (enum tfe_cmsg_tlv_type)ip_location_cmsg_map[map_index][i], (const unsigned char*)&object_id, 8);
break;
default:
break;
}
}
return 0;
}
static int mpack_parse_uint(struct ctrl_pkt_parser *handler, mpack_node_t node, int table_index)
2023-05-15 16:41:59 +08:00
{
uint64_t value = 0;
int mode = mpack_table[table_index].mode;
switch(mode) {
case CMSG_MODE:
2023-11-16 19:34:43 +08:00
if (mpack_table[table_index].type == TFE_CMSG_TCP_RESTORE_WSACLE_CLIENT && handler->wsacle_client_flag == 0)
break;
if (mpack_table[table_index].type == TFE_CMSG_TCP_RESTORE_WSACLE_SERVER && handler->wsacle_server_flag == 0)
break;
value = mpack_node_u64(node);
tfe_cmsg_set(handler->cmsg, (enum tfe_cmsg_tlv_type)mpack_table[table_index].type, (const unsigned char *)&value, mpack_table[table_index].size);
break;
case VARIABLE_MODE:
if (mpack_table[table_index].type == MPACK_VAR_FLAG) {
handler->intercpet_data = mpack_node_u8(node);
if (handler->intercpet_data == 0) {
if (handler->seq_sids.num == 0) {
TFE_LOG_ERROR(g_packet_io_logger, "%s: session %lu unexpected control packet: (seq sid num is 0)", LOG_TAG_CTRLPKT, handler->session_id);
return -1;
}
if (handler->ack_sids.num == 0) {
TFE_LOG_ERROR(g_packet_io_logger, "%s: session %lu unexpected control packet: (ack sid num is 0)", LOG_TAG_CTRLPKT, handler->session_id);
return -1;
}
if (handler->seq_route_ctx.len == 0) {
TFE_LOG_ERROR(g_packet_io_logger, "%s: session %lu unexpected control packet: (seq route ctx len is 0)", LOG_TAG_CTRLPKT, handler->session_id);
return -1;
}
if (handler->ack_route_ctx.len == 0) {
TFE_LOG_ERROR(g_packet_io_logger, "%s: session %lu unexpected control packet: (ack route ctx len is 0)", LOG_TAG_CTRLPKT, handler->session_id);
return -1;
}
if (handler->seq_len == 0) {
TFE_LOG_ERROR(g_packet_io_logger, "%s: session %lu unexpected control packet: (seq packet header len is 0)", LOG_TAG_CTRLPKT, handler->session_id);
return -1;
}
if (handler->ack_len == 0) {
TFE_LOG_ERROR(g_packet_io_logger, "%s: session %lu unexpected control packet: (ack packet header len is 0)", LOG_TAG_CTRLPKT, handler->session_id);
return -1;
}
}
}
2023-11-16 19:34:43 +08:00
else if (mpack_table[table_index].type == MPACK_VAR_WSACLE_CLIENT_FLAG) {
handler->wsacle_client_flag = mpack_node_u8(node);
}
else if (mpack_table[table_index].type == MPACK_VAR_WSACLE_SERVER_FLAG) {
handler->wsacle_server_flag = mpack_node_u8(node);
}
break;
}
return 0;
}
static void mpack_parse_str(struct ctrl_pkt_parser *handler, mpack_node_t node, int table_index)
{
char cmsg_str[1024] = {0};
int mode = mpack_table[table_index].mode;
switch(mode) {
case CMSG_MODE:
mpack_node_copy_cstr(node, cmsg_str, sizeof(cmsg_str));
tfe_cmsg_set(handler->cmsg, (enum tfe_cmsg_tlv_type)mpack_table[table_index].type, (const unsigned char *)cmsg_str, mpack_node_strlen(node));
break;
}
return;
}
static void mpack_parse_nil(struct ctrl_pkt_parser *handler, mpack_node_t node, int table_index)
{
char empty_str[4] = {0};
int mode = mpack_table[table_index].mode;
switch(mode) {
case CMSG_MODE:
tfe_cmsg_set(handler->cmsg, (enum tfe_cmsg_tlv_type)mpack_table[table_index].type, (const unsigned char *)empty_str, 0);
break;
}
return;
}
static int mpack_parse_array(struct ctrl_pkt_parser *handler, mpack_node_t node, int table_index)
{
int ret = 0;
int mode = mpack_table[table_index].mode;
if (mode != ARRAY_MODE)
return -1;
switch(mpack_table[table_index].type) {
case MPACK_ARRAY_SEQ_ROUTE_CTX:
ret = route_ctx_parse_mpack(handler, node, 1);
if (ret != 0)
return -1;
break;
case MPACK_ARRAY_ACK_ROUTE_CTX:
ret = route_ctx_parse_mpack(handler, node, 0);
if (ret != 0)
return -1;
break;
case MPACK_ARRAY_SEQ_PKT_HEADER:
ret = pkt_header_parse_mpack(handler, node, 1);
if (ret != 0)
return -1;
break;
case MPACK_ARRAY_ACK_PKT_HEADER:
ret = pkt_header_parse_mpack(handler, node, 0);
if (ret != 0)
return -1;
break;
case MPACK_ARRAY_SEQ_SIDS:
ret = sids_array_parse_mpack(handler, node, 1);
if (ret != 0)
return -1;
break;
case MPACK_ARRAY_ACK_SIDS:
ret = sids_array_parse_mpack(handler, node, 0);
if (ret != 0)
return -1;
break;
case MPACK_ARRAY_SRC_IP_LOCATION:
ret = ip_location_array_parse_mpack(handler, node, INDEX_SRC_IP_LOCATION);
if (ret != 0)
return -1;
break;
case MPACK_ARRAY_DST_IP_LOCATION:
ret = ip_location_array_parse_mpack(handler, node, INDEX_DST_IP_LOCATION);
if (ret != 0)
return -1;
break;
case MPACK_ARRAY_SRC_IP_LOCATION_OBJ_ID:
ret = ip_location_obj_id_array_parse_mpack(handler, node, INDEX_SRC_IP_LOCATION_OBJ_ID);
if (ret != 0)
return -1;
break;
case MPACK_ARRAY_DST_IP_LOCATION_OBJ_ID:
ret = ip_location_obj_id_array_parse_mpack(handler, node, INDEX_DST_IP_LOCATION_OBJ_ID);
if (ret != 0)
return -1;
break;
default:
break;
}
return 0;
}
static int proxy_parse_messagepack(mpack_node_t node, void *ctx, void *logger)
{
int ret = 0;
2023-05-15 16:41:59 +08:00
struct ctrl_pkt_parser *handler = (struct ctrl_pkt_parser *)ctx;
if (mpack_node_is_nil(mpack_node_map_cstr(node, "rule_ids")))
{
TFE_LOG_ERROR(logger, "%s: session %lu unexpected control packet: (rule_ids no found)", LOG_TAG_CTRLPKT, handler->session_id);
return -1;
}
handler->tfe_policy_id_num = mpack_node_array_length(mpack_node_map_cstr(node, "rule_ids"));
for (int i = 0; i < handler->tfe_policy_id_num; i++) {
handler->tfe_policy_ids[i] = mpack_node_u64(mpack_node_array_at(mpack_node_map_cstr(node, "rule_ids"), i));
}
mpack_node_t tcp_handshake = mpack_node_map_cstr(node, "tcp_handshake");
int cmsg_array_cnt = mpack_node_array_length(tcp_handshake);
for (int i = 0; i < cmsg_array_cnt; i++) {
mpack_node_t ptr = mpack_node_array_at(tcp_handshake, i);
switch (mpack_node_type(ptr)) {
case mpack_type_uint:
ret = mpack_parse_uint(handler, ptr, i);
if (ret != 0)
return -1;
2023-05-15 16:41:59 +08:00
break;
case mpack_type_str:
mpack_parse_str(handler, ptr, i);
2023-05-15 16:41:59 +08:00
break;
case mpack_type_nil:
mpack_parse_nil(handler, ptr, i);
2023-05-15 16:41:59 +08:00
break;
case mpack_type_bin:
ret = mpack_parse_array(handler, ptr, i);
if (ret != 0)
return -1;
break;
2023-05-15 16:41:59 +08:00
case mpack_type_array:
ret = mpack_parse_array(handler, ptr, i);
if (ret != 0)
return -1;
2023-05-15 16:41:59 +08:00
break;
default:
break;
}
}
return 0;
}
// return 0 : success
// return -1 : error
int ctrl_packet_parser_parse(void *ctx, const char* data, size_t length, void *logger, int debug)
2023-05-15 16:41:59 +08:00
{
int ret = 0;
struct ctrl_pkt_parser *handler = (struct ctrl_pkt_parser *)ctx;
char buff[16] = {0};
mpack_node_t params;
mpack_node_t sce_map;
mpack_node_t proxy_map;
mpack_tree_t tree;
mpack_tree_init_data(&tree, data, length);
mpack_tree_parse(&tree);
mpack_node_t root = mpack_tree_root(&tree);
if (mpack_node_is_nil(root))
{
TFE_LOG_ERROR(logger, "%s: unexpected control packet: (invalid mpack format)", LOG_TAG_CTRLPKT);
goto error;
}
if (mpack_node_is_nil(mpack_node_map_cstr(root, "tsync")))
{
TFE_LOG_ERROR(logger, "%s: unexpected control packet: (tsync no found)", LOG_TAG_CTRLPKT);
goto error;
}
mpack_node_copy_cstr(mpack_node_map_cstr(root, "tsync"), handler->tsync, sizeof(handler->tsync));
if (strcmp(handler->tsync, "2.0") != 0)
{
TFE_LOG_ERROR(logger, "%s: unexpected control packet: (invalid tsync version) %s", LOG_TAG_CTRLPKT, handler->tsync);
goto error;
}
if (mpack_node_is_nil(mpack_node_map_cstr(root, "session_id")))
{
TFE_LOG_ERROR(logger, "%s: unexpected control packet: (session_id no found)", LOG_TAG_CTRLPKT);
goto error;
}
handler->session_id = mpack_node_u64(mpack_node_map_cstr(root, "session_id"));
if (mpack_node_is_nil(mpack_node_map_cstr(root, "state")))
{
TFE_LOG_ERROR(logger, "%s: session %lu unexpected control packet: (state no found)", LOG_TAG_CTRLPKT, handler->session_id);
goto error;
}
mpack_node_copy_cstr(mpack_node_map_cstr(root, "state"), buff, sizeof(buff));
if (strncasecmp(buff, "opening", sizeof(buff)) == 0)
{
handler->state = SESSION_STATE_OPENING;
goto succ;
}
else if (strncasecmp(buff, "active", sizeof(buff)) == 0)
{
handler->state = SESSION_STATE_ACTIVE;
}
else if (strncasecmp(buff, "closing", sizeof(buff)) == 0)
{
handler->state = SESSION_STATE_CLOSING;
goto succ;
}
else if (strncasecmp(buff, "resetall", sizeof(buff)) == 0)
{
handler->state = SESSION_STATE_RESETALL;
goto succ;
}
else
{
TFE_LOG_ERROR(logger, "%s: session %lu unexpected control packet: (invalid state value) %s", LOG_TAG_CTRLPKT, handler->session_id, buff);
2023-05-15 16:41:59 +08:00
}
if (mpack_node_is_nil(mpack_node_map_cstr(root, "method")))
{
TFE_LOG_ERROR(logger, "%s: session %lu unexpected control packet: (method no found)", LOG_TAG_CTRLPKT, handler->session_id);
goto error;
}
mpack_node_copy_cstr(mpack_node_map_cstr(root, "method"), handler->method, sizeof(handler->method));
if (mpack_node_is_nil(mpack_node_map_cstr(root, "params")))
{
TFE_LOG_ERROR(logger, "%s: session %lu unexpected control packet: (params no found)", LOG_TAG_CTRLPKT, handler->session_id);
goto error;
}
params = mpack_node_map_cstr(root, "params");
if (!mpack_node_is_missing(mpack_node_map_str_optional(params, "sce", strlen("sce"))))
{
sce_map = mpack_node_map_cstr(params, "sce");
if (mpack_node_is_nil(mpack_node_map_cstr(sce_map, "rule_ids")))
{
TFE_LOG_ERROR(logger, "%s: session %lu unexpected control packet: (sce rule_ids no found)", LOG_TAG_CTRLPKT, handler->session_id);
goto error;
}
handler->sce_policy_id_num = mpack_node_array_length(mpack_node_map_cstr(sce_map, "rule_ids"));
for (int i = 0; i < handler->sce_policy_id_num; i++) {
handler->sce_policy_ids[i] = mpack_node_u64(mpack_node_array_at(mpack_node_map_cstr(sce_map, "rule_ids"), i));
}
}
if (mpack_node_is_missing(mpack_node_map_str_optional(params, "proxy", strlen("proxy"))))
{
TFE_LOG_ERROR(logger, "%s: session %lu unexpected control packet: (proxy no found)", LOG_TAG_CTRLPKT, handler->session_id);
goto error;
}
2023-05-22 15:19:29 +08:00
handler->cmsg = tfe_cmsg_init();
2023-05-15 16:41:59 +08:00
proxy_map = mpack_node_map_cstr(params, "proxy");
ret = proxy_parse_messagepack(proxy_map, handler, logger);
if (debug)
ctrl_packet_parser_dump(handler, logger);
2023-05-15 16:41:59 +08:00
if (ret != 0)
goto error;
succ:
mpack_tree_destroy(&tree);
return 0;
error:
mpack_tree_destroy(&tree);
tfe_cmsg_destroy(&handler->cmsg);
2023-05-15 16:41:59 +08:00
return -1;
}
2023-04-18 16:03:57 +08:00
const char *session_state_to_string(enum session_state state)
{
switch (state)
{
case SESSION_STATE_OPENING:
return "opening";
case SESSION_STATE_CLOSING:
return "closing";
case SESSION_STATE_ACTIVE:
return "active";
case SESSION_STATE_RESETALL:
return "resetall";
default:
return "unknown";
}
}
void ctrl_packet_parser_init(struct ctrl_pkt_parser *handler)
{
memset(handler, 0, sizeof(struct ctrl_pkt_parser));
2023-05-22 15:19:29 +08:00
}
void ctrl_packet_cmsg_destroy(struct ctrl_pkt_parser *handler)
{
if (handler) {
tfe_cmsg_destroy(&handler->cmsg);
if (handler->seq_header) {
free(handler->seq_header);
handler->seq_header = NULL;
}
if (handler->ack_header) {
free(handler->ack_header);
handler->ack_header = NULL;
}
2023-05-22 15:19:29 +08:00
}
2023-04-18 16:03:57 +08:00
}
2023-05-15 16:41:59 +08:00
void ctrl_packet_parser_dump(struct ctrl_pkt_parser *handler, void *logger)
2023-04-18 16:03:57 +08:00
{
int ret = 0;
uint16_t size = 0;
char cmsg_data[256] = {0};
struct route_ctx *route_ctx = NULL;
char *header = NULL;
int header_len = 0;
struct sids *sid = NULL;
int map_index = 0;
if (handler) {
int log_len = 0;
char log_str[4096] = {0};
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, "%s: tsync: %s, session_id: %lu, state: %s, method: %s",
LOG_TAG_CTRLPKT,
2023-06-12 19:47:58 +08:00
handler->tsync,
handler->session_id,
session_state_to_string(handler->state),
handler->method
);
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", tfe policy_id_num: %d, tfe policy_ids[", handler->tfe_policy_id_num);
2023-04-18 16:03:57 +08:00
for (int i = 0; i < handler->tfe_policy_id_num; i++) {
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, "%03lu ", handler->tfe_policy_ids[i]);
2023-04-18 16:03:57 +08:00
}
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, "], sce policy_id_num: %d, sce policy_ids[", handler->sce_policy_id_num);
for (int i = 0; i < handler->sce_policy_id_num; i++) {
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, "%03lu ", handler->sce_policy_ids[i]);
}
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, "]");
int mpack_table_num = sizeof(mpack_table)/sizeof(struct mpack_mmap_id2type);
for (int i = 0; i < mpack_table_num; i++) {
if (mpack_table[i].mode == CMSG_MODE) {
memset(cmsg_data, 0, sizeof(cmsg_data));
ret = tfe_cmsg_get_value(handler->cmsg, (enum tfe_cmsg_tlv_type)mpack_table[i].type, (unsigned char *)cmsg_data, mpack_table[i].size, &size);
if (ret < 0) {
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", %s:null", mpack_table[i].str_name);
continue;
}
if (mpack_table[i].size <= 8)
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", %s:%lu", mpack_table[i].str_name, *((uint64_t *)cmsg_data));
else
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", %s:%s", mpack_table[i].str_name, cmsg_data);
}
else if (mpack_table[i].mode == ARRAY_MODE) {
switch(mpack_table[i].type) {
case MPACK_ARRAY_SEQ_ROUTE_CTX:
case MPACK_ARRAY_ACK_ROUTE_CTX:
route_ctx = mpack_table[i].type == MPACK_ARRAY_SEQ_ROUTE_CTX ? &handler->seq_route_ctx : &handler->ack_route_ctx;
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", %s ROUTE CTX len:%d, data:[", mpack_table[i].type == MPACK_ARRAY_SEQ_ROUTE_CTX ? "SEQ" : "ACK", route_ctx->len);
for (int j = 0; j < route_ctx->len; j++) {
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, "%02x ", route_ctx->data[j]&0xff);
}
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, "]");
break;
case MPACK_ARRAY_SEQ_PKT_HEADER:
case MPACK_ARRAY_ACK_PKT_HEADER:
header = mpack_table[i].type == MPACK_ARRAY_SEQ_PKT_HEADER ? handler->seq_header : handler->ack_header;
header_len = mpack_table[i].type == MPACK_ARRAY_SEQ_PKT_HEADER ? handler->seq_len : handler->ack_len;
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", %s HEADER len:%d, data:[", mpack_table[i].type == MPACK_ARRAY_SEQ_PKT_HEADER ? "SEQ" : "ACK", header_len);
for (int j = 0; j < header_len; j++) {
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, "%02x ", header[j]&0xff);
}
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, "]");
break;
case MPACK_ARRAY_SEQ_SIDS:
case MPACK_ARRAY_ACK_SIDS:
sid = mpack_table[i].type == MPACK_ARRAY_SEQ_SIDS ? &handler->seq_sids : &handler->ack_sids;
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", %s SID count:%d, data:[", mpack_table[i].type == MPACK_ARRAY_SEQ_SIDS ? "SEQ" : "ACK", sid->num);
for (int j = 0; j < sid->num; j++) {
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, "%hu ", sid->elems[j]);
}
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, "]");
break;
case MPACK_ARRAY_SRC_IP_LOCATION:
case MPACK_ARRAY_DST_IP_LOCATION:
map_index = mpack_table[i].type == MPACK_ARRAY_SRC_IP_LOCATION ? INDEX_SRC_IP_LOCATION : INDEX_DST_IP_LOCATION;
for (int j = 0; j < 4; j++) {
memset(cmsg_data, 0, sizeof(cmsg_data));
ret = tfe_cmsg_get_value(handler->cmsg, (enum tfe_cmsg_tlv_type)ip_location_cmsg_map[map_index][j], (unsigned char *)cmsg_data, mpack_table[i].size, &size);
if (ret < 0) {
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", %s:null", ip_location_string_map[map_index].name[j]);
continue;
}
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", %s:%s", ip_location_string_map[map_index].name[j], cmsg_data);
}
break;
case MPACK_ARRAY_SRC_IP_LOCATION_OBJ_ID:
case MPACK_ARRAY_DST_IP_LOCATION_OBJ_ID:
map_index = mpack_table[i].type == MPACK_ARRAY_SRC_IP_LOCATION_OBJ_ID ? INDEX_SRC_IP_LOCATION_OBJ_ID : INDEX_DST_IP_LOCATION_OBJ_ID;
for (int j = 0; j < 4; j++) {
memset(cmsg_data, 0, sizeof(cmsg_data));
ret = tfe_cmsg_get_value(handler->cmsg, (enum tfe_cmsg_tlv_type)ip_location_cmsg_map[map_index][j], (unsigned char *)cmsg_data, mpack_table[i].size, &size);
if (ret < 0) {
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", %s:null", ip_location_string_map[map_index].name[j]);
continue;
}
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", %s:%lu", ip_location_string_map[map_index].name[j], *((uint64_t *)cmsg_data));
}
break;
default:
break;
}
}
else if (mpack_table[i].mode == VARIABLE_MODE) {
switch(mpack_table[i].type) {
case MPACK_VAR_FLAG:
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", %s:%hhu", mpack_table[i].str_name, handler->intercpet_data);
break;
case MPACK_VAR_WSACLE_CLIENT_FLAG:
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", %s:%hhu", mpack_table[i].str_name, handler->wsacle_client_flag);
break;
case MPACK_VAR_WSACLE_SERVER_FLAG:
log_len += snprintf(log_str + log_len, sizeof(log_str) - log_len, ", %s:%hhu", mpack_table[i].str_name, handler->wsacle_server_flag);
break;
default:
break;
}
}
}
TFE_LOG_DEBUG(logger, "%s", log_str);
}
2023-04-18 16:03:57 +08:00
}