2020-06-11 17:57:18 +08:00
|
|
|
|
#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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int doh_kafka_init(const char *profile, struct doh_conf *conf)
|
|
|
|
|
|
{
|
|
|
|
|
|
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);
|
|
|
|
|
|
if (!conf->en_sendlog)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
2020-06-24 16:40:53 +08:00
|
|
|
|
conf->device_id = (const char *)tfe_bussiness_resouce_get(DEVICE_ID);
|
2021-10-18 18:29:10 +08:00
|
|
|
|
conf->effective_device_tag = (const char *)tfe_bussiness_resouce_get(EFFECTIVE_DEVICE_TAG);
|
2020-06-24 16:40:53 +08:00
|
|
|
|
conf->kafka_logger = (tfe_kafka_logger_t *)tfe_bussiness_resouce_get(KAFKA_LOGGER);
|
|
|
|
|
|
if (conf->kafka_logger && !conf->kafka_logger->enable)
|
2020-06-11 17:57:18 +08:00
|
|
|
|
{
|
2020-06-24 16:40:53 +08:00
|
|
|
|
TFE_LOG_ERROR(conf->local_logger, "Doh sendlog ENABLE, but tfe kafka logger DISABLED.");
|
2020-06-11 17:57:18 +08:00
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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]);
|
2020-11-18 20:24:44 +06:00
|
|
|
|
cJSON_AddStringToObject(common_obj, "common_schema_type", "DoH");
|
2020-06-11 17:57:18 +08:00
|
|
|
|
|
2020-09-25 17:46:41 +08:00
|
|
|
|
char opt_val[24] = { 0 };
|
2020-12-04 18:20:36 +08:00
|
|
|
|
uint16_t opt_out_size; unsigned int common_direction=0;
|
2020-06-11 17:57:18 +08:00
|
|
|
|
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)
|
|
|
|
|
|
{
|
2021-11-15 18:46:52 +08:00
|
|
|
|
cJSON_AddStringToObject(common_obj, "common_stream_trace_id", opt_val);
|
2020-12-04 18:20:36 +08:00
|
|
|
|
}
|
|
|
|
|
|
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_COMMON_DIRECTION, (unsigned char *)&common_direction, sizeof(common_direction), &opt_out_size);
|
|
|
|
|
|
if (ret==0)
|
|
|
|
|
|
{
|
|
|
|
|
|
cJSON_AddNumberToObject(common_obj, "common_direction", common_direction); //0:域内->域外,1:域外->域内,描述的是CLIENT_IP信息
|
2020-06-11 17:57:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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_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);
|
2022-09-23 15:34:50 +08:00
|
|
|
|
cJSON_AddNumberToObject(common_obj, "common_vsys_id", handle->kafka_logger->vsys_id);
|
2020-06-11 17:57:18 +08:00
|
|
|
|
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);
|
2021-10-18 18:29:10 +08:00
|
|
|
|
if(handle->effective_device_tag)
|
2020-10-23 19:03:08 +08:00
|
|
|
|
{
|
2021-10-18 18:29:10 +08:00
|
|
|
|
cJSON_AddStringToObject(common_obj, "common_device_tag", handle->effective_device_tag);
|
2020-10-23 19:03:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-11 17:57:18 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-15 11:30:11 +08:00
|
|
|
|
if (ctx->location_client)
|
|
|
|
|
|
{
|
|
|
|
|
|
cJSON_AddStringToObject(common_obj, "common_client_location", ctx->location_client);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (ctx->location_server)
|
|
|
|
|
|
{
|
|
|
|
|
|
cJSON_AddStringToObject(common_obj, "common_server_location", ctx->location_server);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (ctx->asn_client)
|
|
|
|
|
|
{
|
|
|
|
|
|
cJSON_AddStringToObject(common_obj, "common_client_asn", ctx->asn_client);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (ctx->asn_server)
|
|
|
|
|
|
{
|
|
|
|
|
|
cJSON_AddStringToObject(common_obj, "common_server_asn", ctx->asn_server);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-11 17:57:18 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|