TSG-1531 TFE 新增 DOH 插件
1.DOH 协议解析 2.DOH 协议还原 3.DOH POST请求 early response 4.DOH 策略扫描 5.tfe plugin 支持多个 bussiness 插件调用 6.Maat_feather 的创建从 pangu 剥离(涉及pangu/doh/ssl-policy) 7.增加 kafka 日志 8.增加测试用例
This commit is contained in:
519
plugin/business/doh/src/logger.cpp
Normal file
519
plugin/business/doh/src/logger.cpp
Normal file
@@ -0,0 +1,519 @@
|
||||
#include "logger.h"
|
||||
|
||||
struct json_spec
|
||||
{
|
||||
const char *log_filed_name;
|
||||
enum tfe_http_std_field field_id;
|
||||
};
|
||||
|
||||
enum _log_action //Bigger action number is prior.
|
||||
{
|
||||
LG_ACTION_NONE = 0x00,
|
||||
LG_ACTION_MONIT = 0x01,
|
||||
LG_ACTION_FORWARD = 0x02, /* N/A */
|
||||
LG_ACTION_REJECT = 0x10,
|
||||
LG_ACTION_DROP = 0x20, /* N/A */
|
||||
LG_ACTION_MANIPULATE = 0x30,
|
||||
LG_ACTION_RATELIMIT = 0x40, /* N/A */
|
||||
LG_ACTION_LOOP = 0x60, /* N/A */
|
||||
LG_ACTION_WHITELIST = 0x80,
|
||||
__LG_ACTION_MAX
|
||||
};
|
||||
|
||||
static int get_rr_str2json(cJSON *object, dns_info_t *dns_info, int *dns_sec)
|
||||
{
|
||||
int i = 0;
|
||||
char ip_str[128];
|
||||
dns_rr_t *dns_rr = NULL;
|
||||
cJSON *one_rr_object = NULL;
|
||||
cJSON *dns_rr_array = NULL;
|
||||
|
||||
if (object == NULL || dns_info == NULL || dns_sec == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
dns_rr_array = cJSON_CreateArray();
|
||||
|
||||
for (i = 0; i < dns_info->rr_count; i++)
|
||||
{
|
||||
one_rr_object = cJSON_CreateObject();
|
||||
dns_rr = &(dns_info->rr[i]);
|
||||
|
||||
if (dns_rr->type == DNS_TYPE_OPT)
|
||||
{
|
||||
cJSON_AddStringToObject(one_rr_object, "name", (const char *)(dns_rr->name));
|
||||
cJSON_AddNumberToObject(one_rr_object, "type", dns_rr->type);
|
||||
cJSON_AddNumberToObject(one_rr_object, "udp_payload", dns_rr->rr_class);
|
||||
cJSON_AddNumberToObject(one_rr_object, "rcode", (int)(dns_rr->ttl >> 24));
|
||||
cJSON_AddNumberToObject(one_rr_object, "version", (int)((dns_rr->ttl >> 16) & 0xFF));
|
||||
cJSON_AddNumberToObject(one_rr_object, "Z", (int)(dns_rr->ttl && 0xFFFF));
|
||||
cJSON_AddNumberToObject(one_rr_object, "rdlength", dns_rr->rdlength);
|
||||
}
|
||||
else
|
||||
{
|
||||
cJSON_AddStringToObject(one_rr_object, "name", (const char *)(dns_rr->name));
|
||||
cJSON_AddNumberToObject(one_rr_object, "type", dns_rr->type);
|
||||
cJSON_AddNumberToObject(one_rr_object, "class", dns_rr->rr_class);
|
||||
cJSON_AddNumberToObject(one_rr_object, "ttl", dns_rr->ttl);
|
||||
cJSON_AddNumberToObject(one_rr_object, "rdlength", dns_rr->rdlength);
|
||||
}
|
||||
|
||||
if (dns_rr->rdata.a == NULL)
|
||||
{
|
||||
cJSON_AddItemToArray(dns_rr_array, one_rr_object);
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (dns_rr->type)
|
||||
{
|
||||
case DNS_TYPE_A:
|
||||
inet_ntop(AF_INET, (void *)(dns_rr->rdata.a), ip_str, sizeof(ip_str));
|
||||
cJSON_AddStringToObject(one_rr_object, "a", ip_str);
|
||||
break;
|
||||
case DNS_TYPE_NS:
|
||||
cJSON_AddStringToObject(one_rr_object, "ns", (const char *)(dns_rr->rdata.ns));
|
||||
break;
|
||||
case DNS_TYPE_MD:
|
||||
cJSON_AddStringToObject(one_rr_object, "md", (const char *)(dns_rr->rdata.md));
|
||||
break;
|
||||
case DNS_TYPE_MF:
|
||||
cJSON_AddStringToObject(one_rr_object, "mf", (const char *)(dns_rr->rdata.mf));
|
||||
break;
|
||||
case DNS_TYPE_CNAME:
|
||||
cJSON_AddStringToObject(one_rr_object, "cname", (const char *)(dns_rr->rdata.cname));
|
||||
break;
|
||||
case DNS_TYPE_SOA:
|
||||
cJSON_AddStringToObject(one_rr_object, "mname", (const char *)(dns_rr->rdata.soa.mname));
|
||||
cJSON_AddStringToObject(one_rr_object, "rname", (const char *)(dns_rr->rdata.soa.rname));
|
||||
cJSON_AddNumberToObject(one_rr_object, "serial", dns_rr->rdata.soa.serial);
|
||||
cJSON_AddNumberToObject(one_rr_object, "refresh", dns_rr->rdata.soa.refresh);
|
||||
cJSON_AddNumberToObject(one_rr_object, "retry", dns_rr->rdata.soa.retry);
|
||||
cJSON_AddNumberToObject(one_rr_object, "cname", dns_rr->rdata.soa.expire);
|
||||
cJSON_AddNumberToObject(one_rr_object, "minimum", dns_rr->rdata.soa.minimum);
|
||||
break;
|
||||
case DNS_TYPE_MB:
|
||||
cJSON_AddStringToObject(one_rr_object, "mb", (const char *)(dns_rr->rdata.mb));
|
||||
break;
|
||||
case DNS_TYPE_MG:
|
||||
cJSON_AddStringToObject(one_rr_object, "mg", (const char *)(dns_rr->rdata.mg));
|
||||
break;
|
||||
case DNS_TYPE_MR:
|
||||
cJSON_AddStringToObject(one_rr_object, "mr", (const char *)(dns_rr->rdata.mr));
|
||||
break;
|
||||
case DNS_TYPE_NULL:
|
||||
cJSON_AddNumberToObject(one_rr_object, "size", dns_rr->rdata.null.size);
|
||||
cJSON_AddStringToObject(one_rr_object, "null", (const char *)(dns_rr->rdata.null.null));
|
||||
break;
|
||||
case DNS_TYPE_WKS:
|
||||
cJSON_AddStringToObject(one_rr_object, "addr", ip_str);
|
||||
cJSON_AddNumberToObject(one_rr_object, "protocol", dns_rr->rdata.wks.protocol);
|
||||
cJSON_AddStringToObject(one_rr_object, "bitmap", (const char *)(dns_rr->rdata.wks.bitmap));
|
||||
cJSON_AddNumberToObject(one_rr_object, "size", dns_rr->rdata.wks.size);
|
||||
break;
|
||||
case DNS_TYPE_PTR:
|
||||
cJSON_AddStringToObject(one_rr_object, "ptr", (const char *)(dns_rr->rdata.ptr));
|
||||
break;
|
||||
case DNS_TYPE_HINFO:
|
||||
cJSON_AddStringToObject(one_rr_object, "cpu", (const char *)(dns_rr->rdata.hinfo.cpu));
|
||||
cJSON_AddStringToObject(one_rr_object, "os", (const char *)(dns_rr->rdata.hinfo.os));
|
||||
break;
|
||||
case DNS_TYPE_MINFO:
|
||||
cJSON_AddStringToObject(one_rr_object, "rmailbx", (const char *)(dns_rr->rdata.minfo.rmailbx));
|
||||
cJSON_AddStringToObject(one_rr_object, "emailbx", (const char *)(dns_rr->rdata.minfo.emailbx));
|
||||
break;
|
||||
case DNS_TYPE_MX:
|
||||
cJSON_AddStringToObject(one_rr_object, "exchange", (const char *)(dns_rr->rdata.mx.exchange));
|
||||
cJSON_AddNumberToObject(one_rr_object, "preference", dns_rr->rdata.mx.preference);
|
||||
break;
|
||||
case DNS_TYPE_TXT:
|
||||
cJSON_AddStringToObject(one_rr_object, "txt", (char *)(dns_rr->rdata.txt.txt));
|
||||
cJSON_AddNumberToObject(one_rr_object, "size", dns_rr->rdata.txt.size);
|
||||
break;
|
||||
case DNS_TYPE_RP:
|
||||
cJSON_AddStringToObject(one_rr_object, "mailbox", (char *)(dns_rr->rdata.rp.mailbox));
|
||||
cJSON_AddStringToObject(one_rr_object, "txt_rr", (char *)(dns_rr->rdata.rp.txt_rr));
|
||||
break;
|
||||
case DNS_TYPE_AAAA:
|
||||
inet_ntop(AF_INET6, dns_rr->rdata.aaaa, ip_str, sizeof(ip_str));
|
||||
cJSON_AddStringToObject(one_rr_object, "aaaa", ip_str);
|
||||
break;
|
||||
case DNS_TYPE_OPT:
|
||||
break;
|
||||
case DNS_TYPE_DS:
|
||||
*dns_sec = 2;
|
||||
cJSON_AddNumberToObject(one_rr_object, "key_tag", dns_rr->rdata.ds.key_tag);
|
||||
cJSON_AddNumberToObject(one_rr_object, "algo", dns_rr->rdata.ds.algo);
|
||||
cJSON_AddNumberToObject(one_rr_object, "digest_type", dns_rr->rdata.ds.digest_type);
|
||||
cJSON_AddStringToObject(one_rr_object, "digest", (char *)(dns_rr->rdata.ds.digest));
|
||||
break;
|
||||
case DNS_TYPE_RRSIG:
|
||||
*dns_sec = 2;
|
||||
cJSON_AddNumberToObject(one_rr_object, "type_covered", dns_rr->rdata.rrsig.type_covered);
|
||||
cJSON_AddNumberToObject(one_rr_object, "algo", dns_rr->rdata.rrsig.algo);
|
||||
cJSON_AddNumberToObject(one_rr_object, "labels", dns_rr->rdata.rrsig.labels);
|
||||
cJSON_AddNumberToObject(one_rr_object, "original_ttl", dns_rr->rdata.rrsig.original_ttl);
|
||||
cJSON_AddNumberToObject(one_rr_object, "sig_expiration", dns_rr->rdata.rrsig.sig_expiration);
|
||||
cJSON_AddNumberToObject(one_rr_object, "sig_inception", dns_rr->rdata.rrsig.sig_inception);
|
||||
cJSON_AddNumberToObject(one_rr_object, "key_tag", dns_rr->rdata.rrsig.key_tag);
|
||||
cJSON_AddStringToObject(one_rr_object, "signer_name", (const char *)(dns_rr->rdata.rrsig.signer_name));
|
||||
cJSON_AddStringToObject(one_rr_object, "signature", (char *)(dns_rr->rdata.rrsig.signature));
|
||||
break;
|
||||
case DNS_TYPE_NSEC:
|
||||
*dns_sec = 2;
|
||||
cJSON_AddStringToObject(one_rr_object, "next_domain", (const char *)(dns_rr->rdata.nsec.next_domain));
|
||||
cJSON_AddStringToObject(one_rr_object, "type_bit_maps", (char *)(dns_rr->rdata.nsec.type_bit_maps));
|
||||
break;
|
||||
case DNS_TYPE_DNSKEY:
|
||||
*dns_sec = 2;
|
||||
cJSON_AddNumberToObject(one_rr_object, "flags", dns_rr->rdata.dnskey.flags);
|
||||
cJSON_AddNumberToObject(one_rr_object, "protocol", dns_rr->rdata.dnskey.protocol);
|
||||
cJSON_AddNumberToObject(one_rr_object, "algo", dns_rr->rdata.dnskey.algo);
|
||||
cJSON_AddStringToObject(one_rr_object, "public_key", (char *)(dns_rr->rdata.dnskey.public_key));
|
||||
break;
|
||||
case DNS_TYPE_NSEC3:
|
||||
*dns_sec = 2;
|
||||
cJSON_AddNumberToObject(one_rr_object, "hash_algo", dns_rr->rdata.nsec3.hash_algo);
|
||||
cJSON_AddNumberToObject(one_rr_object, "flags", dns_rr->rdata.nsec3.flags);
|
||||
cJSON_AddNumberToObject(one_rr_object, "iteration", dns_rr->rdata.nsec3.iteration);
|
||||
cJSON_AddNumberToObject(one_rr_object, "salt_len", dns_rr->rdata.nsec3.salt_len);
|
||||
cJSON_AddNumberToObject(one_rr_object, "hash_len", dns_rr->rdata.nsec3.hash_len);
|
||||
cJSON_AddStringToObject(one_rr_object, "salt_value", (char *)(dns_rr->rdata.nsec3.salt_value));
|
||||
cJSON_AddStringToObject(one_rr_object, "next_hash_owner", (char *)(dns_rr->rdata.nsec3.next_hash_owner));
|
||||
cJSON_AddStringToObject(one_rr_object, "type_bit_maps", (char *)(dns_rr->rdata.nsec3.type_bit_maps));
|
||||
break;
|
||||
case DNS_TYPE_NSEC3PARAM:
|
||||
cJSON_AddNumberToObject(one_rr_object, "hash_algo", dns_rr->rdata.nsec3param.hash_algo);
|
||||
cJSON_AddNumberToObject(one_rr_object, "flags", dns_rr->rdata.nsec3param.flags);
|
||||
cJSON_AddNumberToObject(one_rr_object, "iteration", dns_rr->rdata.nsec3param.iteration);
|
||||
cJSON_AddNumberToObject(one_rr_object, "salt_len", dns_rr->rdata.nsec3param.salt_len);
|
||||
cJSON_AddStringToObject(one_rr_object, "salt_value", (char *)(dns_rr->rdata.nsec3param.salt_value));
|
||||
break;
|
||||
case DNS_QTYPE_AXFR:
|
||||
break;
|
||||
case DNS_QTYPE_MAILB:
|
||||
continue;
|
||||
break;
|
||||
case DNS_QTYPE_MAILA:
|
||||
break;
|
||||
case DNS_QTYPE_ANY:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
cJSON_AddItemToArray(dns_rr_array, one_rr_object);
|
||||
}
|
||||
|
||||
cJSON_AddItemToObject(object, "rr", dns_rr_array);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void add_dns_info_to_log(cJSON *common_obj, dns_info_t *dns_info)
|
||||
{
|
||||
int i = 0;
|
||||
dns_rr_t *rr = NULL;
|
||||
int dns_sec = 1;
|
||||
char *cname = NULL, *rr_buf = NULL;
|
||||
|
||||
cJSON_AddNumberToObject(common_obj, "doh_qr", dns_info->hdr_info.qr);
|
||||
cJSON_AddNumberToObject(common_obj, "doh_aa", dns_info->hdr_info.aa);
|
||||
cJSON_AddNumberToObject(common_obj, "doh_message_id", dns_info->hdr_info.id);
|
||||
cJSON_AddNumberToObject(common_obj, "doh_opcode", dns_info->hdr_info.opcode);
|
||||
cJSON_AddNumberToObject(common_obj, "doh_ra", dns_info->hdr_info.ra);
|
||||
cJSON_AddNumberToObject(common_obj, "doh_rcode", dns_info->hdr_info.rcode);
|
||||
cJSON_AddNumberToObject(common_obj, "doh_rd", dns_info->hdr_info.rd);
|
||||
cJSON_AddNumberToObject(common_obj, "doh_tc", dns_info->hdr_info.tc);
|
||||
cJSON_AddNumberToObject(common_obj, "doh_qdcount", dns_info->hdr_info.qdcount);
|
||||
cJSON_AddNumberToObject(common_obj, "doh_ancount", dns_info->hdr_info.ancount);
|
||||
cJSON_AddNumberToObject(common_obj, "doh_nscount", dns_info->hdr_info.aucount);
|
||||
cJSON_AddNumberToObject(common_obj, "doh_arcount", dns_info->hdr_info.adcount);
|
||||
|
||||
if ((strlen((char *)dns_info->query_question.qname)) > 0)
|
||||
{
|
||||
cJSON_AddStringToObject(common_obj, "doh_qname", (char *)dns_info->query_question.qname);
|
||||
cJSON_AddNumberToObject(common_obj, "doh_qtype", dns_info->query_question.qtype);
|
||||
cJSON_AddNumberToObject(common_obj, "doh_qclass", dns_info->query_question.qclass);
|
||||
}
|
||||
|
||||
cJSON *item = NULL;
|
||||
cJSON *cname_array = cJSON_CreateArray();
|
||||
for (i = 0; i < dns_info->rr_count && dns_info->rr != NULL; i++)
|
||||
{
|
||||
rr = &dns_info->rr[i];
|
||||
if (rr != NULL && rr->type == DNS_TYPE_CNAME)
|
||||
{
|
||||
if (rr->rdata.cname != NULL)
|
||||
{
|
||||
item = cJSON_CreateString((const char *)rr->rdata.cname);
|
||||
cJSON_AddItemToArray(cname_array, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cname = cJSON_PrintUnformatted(cname_array);
|
||||
if (cname)
|
||||
{
|
||||
if (strlen(cname) > 0)
|
||||
{
|
||||
cJSON_AddStringToObject(common_obj, "doh_cname", cname);
|
||||
}
|
||||
free(cname);
|
||||
}
|
||||
cJSON_Delete(cname_array);
|
||||
cname_array = NULL;
|
||||
|
||||
cJSON *object = cJSON_CreateObject();
|
||||
get_rr_str2json(object, dns_info, &dns_sec);
|
||||
rr_buf = cJSON_PrintUnformatted(object);
|
||||
cJSON_AddStringToObject(common_obj, "doh_rr", rr_buf);
|
||||
free(rr_buf);
|
||||
rr_buf = NULL;
|
||||
cJSON_Delete(object);
|
||||
object = NULL;
|
||||
|
||||
cJSON_AddNumberToObject(common_obj, "doh_sub", dns_sec);
|
||||
}
|
||||
|
||||
static const char *tfe_device_id_create(const char *profile, const char *section, void *local_logger)
|
||||
{
|
||||
int ret = -1;
|
||||
size_t device_id_size = 0;
|
||||
char *tsg_sn_file = NULL, *device_id;
|
||||
const char *device_def_id = "DFT2201925000001";
|
||||
cJSON *json = NULL, *item = NULL;
|
||||
char device_id_filepath[TFE_STRING_MAX] = {0};
|
||||
|
||||
ret = MESA_load_profile_string_def(profile, section, "device_id_filepath", device_id_filepath, sizeof(device_id_filepath), NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
TFE_LOG_ERROR(local_logger, "Doh log init failed, no device_path in profile %s section %s.", profile, section);
|
||||
goto finish;
|
||||
}
|
||||
tsg_sn_file = tfe_read_file(device_id_filepath, &device_id_size);
|
||||
if (tsg_sn_file == NULL)
|
||||
{
|
||||
TFE_LOG_ERROR(local_logger, "Doh log init failed, %s not existed.", tsg_sn_file);
|
||||
goto finish;
|
||||
}
|
||||
json = cJSON_Parse(tsg_sn_file);
|
||||
if (json == NULL)
|
||||
{
|
||||
TFE_LOG_ERROR(local_logger, "invalid device parameter: file = %s", tsg_sn_file);
|
||||
goto finish;
|
||||
}
|
||||
item = cJSON_GetObjectItem(json, "sn");
|
||||
if (unlikely(!item || !cJSON_IsString(item)))
|
||||
{
|
||||
TFE_LOG_ERROR(local_logger, "Invalid device parameter: %s invalid json format", tsg_sn_file);
|
||||
}
|
||||
device_id = tfe_strdup(item->valuestring);
|
||||
|
||||
cJSON_Delete(json);
|
||||
return device_id;
|
||||
finish:
|
||||
return device_def_id;
|
||||
}
|
||||
|
||||
int doh_kafka_init(const char *profile, struct doh_conf *conf)
|
||||
{
|
||||
char nic_name[64] = {0};
|
||||
char brokerlist[TFE_STRING_MAX] = {0};
|
||||
char topic_name[TFE_STRING_MAX] = {0};
|
||||
const char *section = "kafka";
|
||||
|
||||
MESA_load_profile_int_def(profile, section, "ENTRANCE_ID", &(conf->entry_id), 0);
|
||||
MESA_load_profile_int_def(profile, section, "en_sendlog", &conf->en_sendlog, 1);
|
||||
MESA_load_profile_string_def(profile, section, "NIC_NAME", nic_name, sizeof(nic_name), "eth0");
|
||||
MESA_load_profile_string_def(profile, section, "KAFKA_BROKERLIST", brokerlist, sizeof(brokerlist), "");
|
||||
MESA_load_profile_string_def(profile, section, "KAFKA_TOPIC", topic_name, sizeof(topic_name), "POLICY-DOH-LOG");
|
||||
|
||||
TFE_LOG_INFO(conf->local_logger, "Doh sendlog : %s", conf->en_sendlog ? "ENABLE" : "DISABLE");
|
||||
if (!conf->en_sendlog)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
conf->device_id = tfe_device_id_create(profile, section, conf->local_logger);
|
||||
if (!strlen(brokerlist))
|
||||
{
|
||||
TFE_LOG_ERROR(conf->local_logger, "Doh log init failed, no brokerlist in profile %s section %s.", profile, section);
|
||||
return -1;
|
||||
}
|
||||
conf->kafka_logger = tfe_kafka_logger_create(conf->en_sendlog, nic_name, brokerlist, topic_name, conf->local_logger);
|
||||
if (conf->kafka_logger == NULL)
|
||||
{
|
||||
TFE_LOG_ERROR(conf->local_logger, "Doh kafka init failed, error to create kafka logger.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
TFE_LOG_INFO(conf->local_logger, "Doh device id : %s", conf->device_id);
|
||||
TFE_LOG_INFO(conf->local_logger, "Doh kafka topic : %s", topic_name);
|
||||
TFE_LOG_INFO(conf->local_logger, "Doh kafka brokerlist : %s", brokerlist);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int doh_send_log(struct doh_conf *handle, const struct tfe_http_session *http, const struct tfe_stream *stream, struct doh_ctx *ctx)
|
||||
{
|
||||
Maat_rule_t *result = ctx->result;
|
||||
size_t result_num = ctx->result_num;
|
||||
dns_info_t *dns_info = ctx->doh_req;
|
||||
const struct tfe_stream_addr *addr = stream->addr;
|
||||
const char *tmp_val = NULL;
|
||||
cJSON *common_obj = NULL, *per_hit_obj = NULL;
|
||||
char *log_payload = NULL;
|
||||
int kafka_status = 0;
|
||||
int send_cnt = 0;
|
||||
time_t cur_time;
|
||||
char src_ip_str[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)] = {0};
|
||||
char dst_ip_str[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)] = {0};
|
||||
|
||||
const char *app_proto[] = {"unkonw", "http1", "http2"};
|
||||
struct json_spec req_fields[] = {{"doh_cookie", TFE_HTTP_COOKIE},
|
||||
{"doh_referer", TFE_HTTP_REFERER},
|
||||
{"doh_user_agent", TFE_HTTP_USER_AGENT}};
|
||||
struct json_spec resp_fields[] = {{"doh_content_type", TFE_HTTP_CONT_TYPE},
|
||||
{"doh_content_length", TFE_HTTP_CONT_LENGTH},
|
||||
{"doh_set_cookie", TFE_HTTP_SET_COOKIE}};
|
||||
|
||||
if (!handle->en_sendlog)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
common_obj = cJSON_CreateObject();
|
||||
cur_time = time(NULL);
|
||||
|
||||
cJSON_AddNumberToObject(common_obj, "common_start_time", cur_time);
|
||||
cJSON_AddNumberToObject(common_obj, "common_end_time", cur_time);
|
||||
cJSON_AddStringToObject(common_obj, "doh_version", app_proto[http->major_version]);
|
||||
cJSON_AddStringToObject(common_obj, "common_schema_type", "DOH");
|
||||
|
||||
char opt_val[24];
|
||||
uint16_t opt_out_size;
|
||||
struct tfe_cmsg *cmsg = tfe_stream_get0_cmsg(stream);
|
||||
if (cmsg != NULL)
|
||||
{
|
||||
int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_STREAM_TRACE_ID, (unsigned char *)opt_val, sizeof(opt_val), &opt_out_size);
|
||||
if (ret == 0)
|
||||
{
|
||||
cJSON_AddNumberToObject(common_obj, "common_stream_trace_id", atoll(opt_val));
|
||||
}
|
||||
}
|
||||
|
||||
if (http->req)
|
||||
{
|
||||
char *request_line = NULL;
|
||||
struct tfe_http_req_spec req_spec = http->req->req_spec;
|
||||
asprintf(&request_line, "%s %s HTTP/%d.%d", http_std_method_to_string(req_spec.method), req_spec.url, http->major_version, http->minor_version);
|
||||
cJSON_AddStringToObject(common_obj, "doh_request_line", request_line);
|
||||
free(request_line);
|
||||
}
|
||||
|
||||
if (http->resp)
|
||||
{
|
||||
char *response_line = NULL;
|
||||
struct tfe_http_resp_spec resp_spec = http->resp->resp_spec;
|
||||
asprintf(&response_line, "HTTP/%d.%d %d OK", http->major_version, http->minor_version, resp_spec.resp_code);
|
||||
cJSON_AddStringToObject(common_obj, "doh_response_line", response_line);
|
||||
free(response_line);
|
||||
}
|
||||
|
||||
switch (addr->addrtype)
|
||||
{
|
||||
case TFE_ADDR_STREAM_TUPLE4_V4:
|
||||
cJSON_AddNumberToObject(common_obj, "common_address_type", 4);
|
||||
inet_ntop(AF_INET, &addr->tuple4_v4->saddr, src_ip_str, sizeof(src_ip_str));
|
||||
inet_ntop(AF_INET, &addr->tuple4_v4->daddr, dst_ip_str, sizeof(dst_ip_str));
|
||||
cJSON_AddStringToObject(common_obj, "common_client_ip", src_ip_str);
|
||||
cJSON_AddStringToObject(common_obj, "common_server_ip", dst_ip_str);
|
||||
cJSON_AddNumberToObject(common_obj, "common_client_port", ntohs(addr->tuple4_v4->source));
|
||||
cJSON_AddNumberToObject(common_obj, "common_server_port", ntohs(addr->tuple4_v4->dest));
|
||||
cJSON_AddStringToObject(common_obj, "common_l4_protocol", "IPv4_TCP");
|
||||
break;
|
||||
case TFE_ADDR_STREAM_TUPLE4_V6:
|
||||
cJSON_AddNumberToObject(common_obj, "common_address_type", 6);
|
||||
inet_ntop(AF_INET6, &addr->tuple4_v6->saddr, src_ip_str, sizeof(src_ip_str));
|
||||
inet_ntop(AF_INET6, &addr->tuple4_v6->daddr, dst_ip_str, sizeof(dst_ip_str));
|
||||
cJSON_AddStringToObject(common_obj, "common_client_ip", src_ip_str);
|
||||
cJSON_AddStringToObject(common_obj, "common_server_ip", dst_ip_str);
|
||||
cJSON_AddNumberToObject(common_obj, "common_client_port", ntohs(addr->tuple4_v6->source));
|
||||
cJSON_AddNumberToObject(common_obj, "common_server_port", ntohs(addr->tuple4_v6->dest));
|
||||
cJSON_AddStringToObject(common_obj, "common_l4_protocol", "IPv6_TCP");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
size_t c2s_byte_num = 0, s2c_byte_num = 0;
|
||||
tfe_stream_info_get(stream, INFO_FROM_DOWNSTREAM_RX_OFFSET, &c2s_byte_num, sizeof(c2s_byte_num));
|
||||
tfe_stream_info_get(stream, INFO_FROM_UPSTREAM_RX_OFFSET, &s2c_byte_num, sizeof(s2c_byte_num));
|
||||
|
||||
cJSON_AddNumberToObject(common_obj, "common_direction", 0); //0:域内->域外,1:域外->域内,描述的是CLIENT_IP信息
|
||||
cJSON_AddNumberToObject(common_obj, "common_link_id", 0);
|
||||
cJSON_AddNumberToObject(common_obj, "common_stream_dir", 3); //1:c2s, 2:s2c, 3:double
|
||||
cJSON_AddStringToObject(common_obj, "common_sled_ip", handle->kafka_logger->local_ip_str);
|
||||
cJSON_AddNumberToObject(common_obj, "common_entrance_id", handle->entry_id);
|
||||
cJSON_AddStringToObject(common_obj, "common_device_id", handle->device_id);
|
||||
cJSON_AddNumberToObject(common_obj, "common_c2s_byte_num", c2s_byte_num);
|
||||
cJSON_AddNumberToObject(common_obj, "common_s2c_byte_num", s2c_byte_num);
|
||||
cJSON_AddStringToObject(common_obj, "doh_url", http->req->req_spec.url);
|
||||
cJSON_AddStringToObject(common_obj, "doh_host", http->req->req_spec.host);
|
||||
for (size_t i = 0; i < sizeof(req_fields) / sizeof(struct json_spec); i++)
|
||||
{
|
||||
tmp_val = tfe_http_std_field_read(http->req, req_fields[i].field_id);
|
||||
if (tmp_val != NULL)
|
||||
{
|
||||
cJSON_AddStringToObject(common_obj, req_fields[i].log_filed_name, tmp_val);
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < sizeof(resp_fields) / sizeof(struct json_spec) && http->resp != NULL; i++)
|
||||
{
|
||||
tmp_val = tfe_http_std_field_read(http->resp, resp_fields[i].field_id);
|
||||
if (tmp_val != NULL)
|
||||
{
|
||||
cJSON_AddStringToObject(common_obj, resp_fields[i].log_filed_name, tmp_val);
|
||||
}
|
||||
}
|
||||
|
||||
add_dns_info_to_log(common_obj, dns_info);
|
||||
for (size_t i = 0; i < result_num; i++)
|
||||
{
|
||||
|
||||
TFE_LOG_DEBUG(handle->local_logger, "URL: %s, policy_id: %d, service: %d, do_log:%d",
|
||||
http->req->req_spec.url,
|
||||
result[i].config_id,
|
||||
result[i].service_id,
|
||||
result[i].do_log);
|
||||
|
||||
if (result[i].do_log == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
per_hit_obj = cJSON_Duplicate(common_obj, 1);
|
||||
cJSON_AddNumberToObject(per_hit_obj, "common_policy_id", result[i].config_id);
|
||||
cJSON_AddNumberToObject(per_hit_obj, "common_service", result[i].service_id);
|
||||
cJSON_AddNumberToObject(per_hit_obj, "common_action", LG_ACTION_MANIPULATE);
|
||||
cJSON_AddStringToObject(per_hit_obj, "common_sub_action", "redirect");
|
||||
|
||||
log_payload = cJSON_PrintUnformatted(per_hit_obj);
|
||||
|
||||
TFE_LOG_DEBUG(handle->local_logger, "%s", log_payload);
|
||||
|
||||
kafka_status = tfe_kafka_logger_send(handle->kafka_logger, log_payload, strlen(log_payload));
|
||||
free(log_payload);
|
||||
cJSON_Delete(per_hit_obj);
|
||||
if (kafka_status < 0)
|
||||
{
|
||||
TFE_LOG_ERROR(handle->local_logger, "Kafka produce failed: %s", rd_kafka_err2name(rd_kafka_last_error()));
|
||||
}
|
||||
else
|
||||
{
|
||||
send_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
cJSON_Delete(common_obj);
|
||||
return send_cnt;
|
||||
}
|
||||
Reference in New Issue
Block a user