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_mpack.cpp
2023-05-06 17:47:38 +08:00

217 lines
11 KiB
C++

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <msgpack.h>
#include "tfe_cmsg.h"
#include "tfe_utils.h"
#include "tfe_ctrl_packet.h"
enum ctr_pkt_index
{
INDEX_TSYNC = 0,
INDEX_SESSION_ID,
INDEX_STATE,
INDEX_METHOD,
INDEX_SCE,
INDEX_SHAPER,
INDEX_PROXY,
INDEX_MAX
};
struct mpack_mmap_id2type
{
int id;
enum tfe_cmsg_tlv_type type;
char *str_name;
int size;
}mpack_table[] = {
{.id = 0, .type = TFE_CMSG_POLICY_ID, .str_name = "TFE_CMSG_POLICY_ID", .size = 8},
{.id = 1, .type = TFE_CMSG_TCP_RESTORE_SEQ, .str_name = "TFE_CMSG_TCP_RESTORE_SEQ", .size = 4},
{.id = 2, .type = TFE_CMSG_TCP_RESTORE_ACK, .str_name = "TFE_CMSG_TCP_RESTORE_ACK", .size = 4},
{.id = 3, .type = TFE_CMSG_TCP_RESTORE_MSS_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_MSS_CLIENT", .size = 2},
{.id = 4, .type = TFE_CMSG_TCP_RESTORE_MSS_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_MSS_SERVER", .size = 2},
{.id = 5, .type = TFE_CMSG_TCP_RESTORE_WSACLE_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_WSACLE_CLIENT", .size = 1},
{.id = 6, .type = TFE_CMSG_TCP_RESTORE_WSACLE_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_WSACLE_SERVER", .size = 1},
{.id = 7, .type = TFE_CMSG_TCP_RESTORE_SACK_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_SACK_CLIENT", .size = 1},
{.id = 8, .type = TFE_CMSG_TCP_RESTORE_SACK_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_SACK_SERVER", .size = 1},
{.id = 9, .type = TFE_CMSG_TCP_RESTORE_TS_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_TS_CLIENT", .size = 1},
{.id = 10, .type = TFE_CMSG_TCP_RESTORE_TS_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_TS_SERVER", .size = 1},
{.id = 11, .type = TFE_CMSG_TCP_RESTORE_PROTOCOL, .str_name = "TFE_CMSG_TCP_RESTORE_PROTOCOL", .size = 1},
{.id = 12, .type = TFE_CMSG_TCP_RESTORE_WINDOW_CLIENT, .str_name = "TFE_CMSG_TCP_RESTORE_WINDOW_CLIENT", .size = 2},
{.id = 13, .type = TFE_CMSG_TCP_RESTORE_WINDOW_SERVER, .str_name = "TFE_CMSG_TCP_RESTORE_WINDOW_SERVER", .size = 2},
{.id = 14, .type = TFE_CMSG_TCP_RESTORE_TS_CLIENT_VAL, .str_name = "TFE_CMSG_TCP_RESTORE_TS_CLIENT_VAL", .size = 4},
{.id = 15, .type = TFE_CMSG_TCP_RESTORE_TS_SERVER_VAL, .str_name = "TFE_CMSG_TCP_RESTORE_TS_SERVER_VAL", .size = 4},
{.id = 16, .type = TFE_CMSG_TCP_RESTORE_INFO_PACKET_CUR_DIR, .str_name = "TFE_CMSG_TCP_RESTORE_INFO_PACKET_CUR_DIR", .size = 1},
{.id = 17, .type = TFE_CMSG_SRC_SUB_ID, .str_name = "TFE_CMSG_SRC_SUB_ID", .size = 256},
{.id = 18, .type = TFE_CMSG_DST_SUB_ID, .str_name = "TFE_CMSG_DST_SUB_ID", .size = 256},
{.id = 19, .type = TFE_CMSG_SRC_ASN, .str_name = "TFE_CMSG_SRC_ASN", .size = 64},
{.id = 20, .type = TFE_CMSG_DST_ASN, .str_name = "TFE_CMSG_DST_ASN", .size = 64},
{.id = 21, .type = TFE_CMSG_SRC_ORGANIZATION, .str_name = "TFE_CMSG_SRC_ORGANIZATION", .size = 256},
{.id = 22, .type = TFE_CMSG_DST_ORGANIZATION, .str_name = "TFE_CMSG_DST_ORGANIZATION", .size = 256},
{.id = 23, .type = TFE_CMSG_SRC_IP_LOCATION_COUNTRY, .str_name = "TFE_CMSG_SRC_IP_LOCATION_COUNTRY", .size = 256},
{.id = 24, .type = TFE_CMSG_DST_IP_LOCATION_COUNTRY, .str_name = "TFE_CMSG_DST_IP_LOCATION_COUNTRY", .size = 256},
{.id = 25, .type = TFE_CMSG_SRC_IP_LOCATION_PROVINE, .str_name = "TFE_CMSG_SRC_IP_LOCATION_PROVINE", .size = 256},
{.id = 26, .type = TFE_CMSG_DST_IP_LOCATION_PROVINE, .str_name = "TFE_CMSG_DST_IP_LOCATION_PROVINE", .size = 256},
{.id = 27, .type = TFE_CMSG_SRC_IP_LOCATION_CITY, .str_name = "TFE_CMSG_SRC_IP_LOCATION_CITY", .size = 256},
{.id = 28, .type = TFE_CMSG_DST_IP_LOCATION_CITY, .str_name = "TFE_CMSG_DST_IP_LOCATION_CITY", .size = 256},
{.id = 29, .type = TFE_CMSG_SRC_IP_LOCATION_SUBDIVISION, .str_name = "TFE_CMSG_SRC_IP_LOCATION_SUBDIVISION", .size = 256},
{.id = 30, .type = TFE_CMSG_DST_IP_LOCATION_SUBDIVISION, .str_name = "TFE_CMSG_DST_IP_LOCATION_SUBDIVISION", .size = 256},
{.id = 31, .type = TFE_CMSG_SSL_CLIENT_JA3_FINGERPRINT, .str_name = "TFE_CMSG_SSL_CLIENT_JA3_FINGERPRINT", .size = 32},
{.id = 32, .type = TFE_CMSG_FQDN_CAT_ID_VAL, .str_name = "TFE_CMSG_FQDN_CAT_ID_VAL", .size = 4}
};
static int proxy_parse_messagepack(msgpack_object obj, void *ctx)
{
struct ctrl_pkt_parser *handler = (struct ctrl_pkt_parser *)ctx;
uint32_t fqdn_val[8] = {0};
for (unsigned int i = 0; i < obj.via.array.size; i++) {
msgpack_object ptr = obj.via.array.ptr[i];
if (i == 0) {
if (ptr.type == MSGPACK_OBJECT_ARRAY) {
handler->tfe_policy_id_num = ptr.via.array.size;
for (uint32_t j = 0; j < ptr.via.array.size; j++) {
handler->tfe_policy_ids[j] = ptr.via.array.ptr[j].via.u64;
}
tfe_cmsg_set(handler->cmsg, mpack_table[i].type, (const unsigned char *)&handler->tfe_policy_ids[0], sizeof(uint64_t));
TFE_LOG_DEBUG(g_default_logger, "%s: interger msgpack cmsg: [%s] num: [%d]", LOG_TAG_CTRLPKT, mpack_table[i].str_name, handler->tfe_policy_id_num);
for (int j = 0; j < handler->tfe_policy_id_num; j++) {
TFE_LOG_DEBUG(g_default_logger, "%s: policy id:%lu ", LOG_TAG_CTRLPKT, handler->tfe_policy_ids[j]);
}
}
continue;
}
switch (ptr.type) {
case MSGPACK_OBJECT_POSITIVE_INTEGER:
tfe_cmsg_set(handler->cmsg, mpack_table[i].type, (const unsigned char *)&ptr.via.u64, mpack_table[i].size);
TFE_LOG_DEBUG(g_default_logger, "%s: interger msgpack cmsg: [%s] -> [%lu]", LOG_TAG_CTRLPKT, mpack_table[i].str_name, ptr.via.u64);
break;
case MSGPACK_OBJECT_STR:
tfe_cmsg_set(handler->cmsg, mpack_table[i].type, (const unsigned char *)ptr.via.str.ptr, ptr.via.str.size);
TFE_LOG_DEBUG(g_default_logger, "%s: string msgpack cmsg: [%s] -> [%s]", LOG_TAG_CTRLPKT, mpack_table[i].str_name, ptr.via.str.ptr);
break;
case MSGPACK_OBJECT_ARRAY:
if (i == 32) {
tfe_cmsg_set(handler->cmsg, TFE_CMSG_FQDN_CAT_ID_NUM, (const unsigned char *)&ptr.via.array.size, sizeof(uint32_t));
for (uint32_t j = 0; j < ptr.via.array.size; j++) {
fqdn_val[j] = ptr.via.array.ptr[j].via.u64;
TFE_LOG_DEBUG(g_default_logger, "%s: array msgpack cmsg: [%s] -> [%lu]", LOG_TAG_CTRLPKT, mpack_table[i].str_name, ptr.via.array.ptr[j].via.u64);
}
tfe_cmsg_set(handler->cmsg ,TFE_CMSG_FQDN_CAT_ID_VAL, (const unsigned char*)fqdn_val, ptr.via.array.size * sizeof(uint32_t));
}
break;
default:
break;
}
}
return 0;
}
int parse_messagepack(const char* data, size_t length, void *ctx)
{
struct ctrl_pkt_parser *handler = (struct ctrl_pkt_parser *)ctx;
size_t off = 0;
msgpack_unpacked unpacked;
msgpack_unpacked_init(&unpacked);
msgpack_unpack_return ret = msgpack_unpack_next(&unpacked, data, length, &off);
if (ret != MSGPACK_UNPACK_SUCCESS) {
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: data[%s]", LOG_TAG_CTRLPKT, data);
return -1;
}
msgpack_object obj = unpacked.data;
if (obj.type != MSGPACK_OBJECT_ARRAY || obj.via.array.size < INDEX_PROXY) {
// TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: msgpack type[%02x], array size:%d", LOG_TAG_CTRLPKT, obj.type, obj.via.array.size);
return -1;
}
for (unsigned int i = 0; i < obj.via.array.size; i++) {
msgpack_object ptr = obj.via.array.ptr[i];
switch (i) {
case INDEX_TSYNC:
if (ptr.type == MSGPACK_OBJECT_STR) {
memcpy(handler->tsync, ptr.via.str.ptr, ptr.via.str.size);
}
else {
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid tsync type) %02x", LOG_TAG_CTRLPKT, ptr.type);
}
break;
case INDEX_SESSION_ID:
if (ptr.type == MSGPACK_OBJECT_STR) {
char session_id[64] = {0};
memcpy(session_id, ptr.via.str.ptr, ptr.via.str.size);
handler->session_id = atoll(session_id);
}
else {
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid session id type) %02x", LOG_TAG_CTRLPKT, ptr.type);
}
break;
case INDEX_STATE:
if (ptr.type == MSGPACK_OBJECT_STR) {
if (strncasecmp(ptr.via.str.ptr, "opening", ptr.via.str.size) == 0)
{
handler->state = SESSION_STATE_OPENING;
}
else if (strncasecmp(ptr.via.str.ptr, "active", ptr.via.str.size) == 0)
{
handler->state = SESSION_STATE_ACTIVE;
}
else if (strncasecmp(ptr.via.str.ptr, "closing", ptr.via.str.size) == 0)
{
handler->state = SESSION_STATE_CLOSING;
}
else if (strncasecmp(ptr.via.str.ptr, "resetall", ptr.via.str.size) == 0)
{
handler->state = SESSION_STATE_RESETALL;
}
else
{
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid state value) %s", LOG_TAG_CTRLPKT, ptr.via.str.ptr);
}
}
else {
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid state type) %02x", LOG_TAG_CTRLPKT, ptr.type);
}
break;
case INDEX_METHOD:
if (ptr.type == MSGPACK_OBJECT_STR) {
memcpy(handler->method, ptr.via.str.ptr, ptr.via.str.size);
}
else {
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid method type) %02x", LOG_TAG_CTRLPKT, ptr.type);
}
break;
case INDEX_SCE:
if (ptr.type == MSGPACK_OBJECT_ARRAY) {
msgpack_object rule_id = ptr.via.array.ptr[0];
handler->sce_policy_id_num = rule_id.via.array.size;
for (uint32_t j = 0; j < rule_id.via.array.size; j++) {
handler->sce_policy_ids[j] = rule_id.via.array.ptr[j].via.u64;
}
}
break;
case INDEX_SHAPER:
break;
case INDEX_PROXY:
if (ptr.type == MSGPACK_OBJECT_ARRAY) {
proxy_parse_messagepack(ptr, handler);
}
else {
TFE_LOG_DEBUG(g_default_logger, "%s: unexpected control packet: (invalid proxy type) %02x", LOG_TAG_CTRLPKT, ptr.type);
}
break;
default:
break;
}
}
return 0;
}