diff --git a/README.md b/README.md index c565cc3..9e8759f 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,6 @@ Already a pro? Just edit this README.md and make it your own. Want to make it ea ## Add your files -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: ``` cd existing_repo diff --git a/bin/dns_decoder.toml b/bin/dns_decoder.toml index d60dc6b..431e518 100644 --- a/bin/dns_decoder.toml +++ b/bin/dns_decoder.toml @@ -14,7 +14,10 @@ stat_interval_time_s=5 stat_output="metrics/dns_decoder_local_stat.json" [decoder.dns.test] -perf_worker_thread_num=1 write_result_enable="no" commit_result_enable="yes" -decode_resource_record_enable="no" + +[decoder.dns.test.perf] +perf_worker_thread_num=1 +decode_resource_record_enable="yes" +export_resource_record_enable="no" \ No newline at end of file diff --git a/include/dns_decoder.h b/include/dns_decoder.h index 3892d12..b41f7b9 100644 --- a/include/dns_decoder.h +++ b/include/dns_decoder.h @@ -1,13 +1,3 @@ -/* -********************************************************************************************** -* File: dns_decoder.h -* Description: dns decoder api -* Authors: Liu XueLi -* Date: 2024-02-07 -* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved. -*********************************************************************************************** -*/ - #pragma once #ifdef __cplusplus @@ -19,223 +9,11 @@ extern "C" #include #include -#define DNS_MESSAGE_TOPIC "TOPIC_DNS" - -#define DNS_NAME_MAX (NAME_MAX + 1) -// #define HINFO_NAME_MAX (40 + 1) /* https://www.ietf.org/rfc/rfc1010.txt */ - -#define DNS_CLASS_UNKNOWN 0 -#define DNS_CLASS_IN 1 -#define DNS_CLASS_CS 2 -#define DNS_CLASS_CH 3 -#define DNS_CLASS_HS 4 -#define DNS_CLASS_ANY 255 - -/* RR(resource record) type, defined in https://www.ietf.org/rfc/rfc1035.txt */ -enum dns_rr_type -{ - DNS_RR_TYPE_A = 1, - DNS_RR_TYPE_NS, - DNS_RR_TYPE_MD, /* Obsolete - use MX, rfc973 */ - DNS_RR_TYPE_MF, /* Obsolete - use MX, rfc973 */ - DNS_RR_TYPE_CNAME, - DNS_RR_TYPE_SOA, - DNS_RR_TYPE_MB, /* EXPERIMENTAL, rfc883,rfc2505 */ - DNS_RR_TYPE_MG, /* EXPERIMENTAL, rfc883,rfc2505 */ - DNS_RR_TYPE_MR, /* EXPERIMENTAL, rfc883 */ - DNS_RR_TYPE_NULL, /* EXPERIMENTAL, rfc1035 */ - DNS_RR_TYPE_WKS, /* Not to be relied upon, rfc1123 */ - DNS_RR_TYPE_PTR, - DNS_RR_TYPE_HINFO, - DNS_RR_TYPE_MINFO, - DNS_RR_TYPE_MX, - DNS_RR_TYPE_TXT, - DNS_RR_TYPE_RP, - DNS_RR_TYPE_ISDN = 20, - DNS_RR_TYPE_AAAA = 28, /* dns_ipv6 */ - DNS_RR_TYPE_SRV = 33, - DNS_RR_TYPE_DNAME = 39, - DNS_RR_TYPE_OPT = 41, - DNS_RR_TYPE_DS = 43, - DNS_RR_TYPE_RRSIG = 46, - DNS_RR_TYPE_NSEC, - DNS_RR_TYPE_DNSKEY, - DNS_RR_TYPE_NSEC3 = 50, - DNS_RR_TYPE_NSEC3PARAM, - DNS_RR_TYPE_HTTPS = 65, - DNS_RR_TYPE_AXFR = 252, - DNS_RR_TYPE_MAILB, - DNS_RR_TYPE_MAILA, /* Obsolete - see MX */ - DNS_RR_TYPE_ANY, - DNS_RR_TYPE_DLV = 32769, /* DSNSEC Lokkaside Validation */ - DNS_RR_TYPE_UNKNOWN = 65534 -}; - -struct dstring -{ - size_t value_sz; - uint8_t value[DNS_NAME_MAX]; -}; - -struct rdata_hinfo -{ - struct dstring os; - struct dstring cpu; -}; - -struct rdata_minfo -{ - struct dstring rmailbx; - struct dstring emailbx; -}; - -struct rdata_mx -{ - uint16_t preference; - struct dstring exchange; -}; - -struct rdata_soa -{ - struct dstring mname; - struct dstring rname; - uint32_t serial; - uint32_t refresh; - uint32_t retry; - uint32_t expire; - uint32_t minimum; -}; - -struct rdata_rp -{ - struct dstring txt_rr; - struct dstring mailbox; -}; - -struct rdata_wks -{ - uint8_t protocol; - uint32_t addr; - uint32_t size; - uint8_t *bitmap; -}; - -struct rdata_srv -{ - uint16_t priority; - uint16_t weight; - uint16_t port; - struct dstring target; -}; - -struct rdata_ds -{ - uint16_t key_tag; - uint8_t algo; - uint8_t digest_type; - uint32_t digest_len; - uint8_t *digest; -}; - -struct rdata_rrsig -{ - uint16_t type_covered; - uint8_t algo; - uint8_t labels; - uint32_t original_ttl; - uint32_t sig_expiration; - uint32_t sig_inception; - uint16_t key_tag; - uint32_t signature_len; - uint8_t *signature; - struct dstring signer_name; -}; - -struct rdata_nsec -{ - uint16_t maps_len; - struct dstring next_domain; - struct dstring type_bit_maps; -}; - -struct rdata_dnskey -{ - uint16_t flags; - uint8_t protocol; - uint8_t algo; - uint32_t public_key_len; - uint8_t *public_key; -}; - -struct rdata_nsec3 -{ - uint8_t hash_algo; - uint8_t flags; - uint8_t salt_len; - uint8_t hash_len; - uint16_t iteration; - uint16_t maps_len; - uint8_t *salt_value; - uint8_t *next_hash_owner; - struct dstring type_bit_maps; -}; - -struct rdata_nsec3param -{ - uint8_t hash_algo; - uint8_t flags; - uint8_t salt_len; - uint16_t iteration; - uint8_t *salt_value; -}; - -/* rr is short for resource record */ -struct dns_resource_record -{ - struct dstring qname; - enum dns_rr_type type; - uint16_t rr_class; - uint32_t ttl; /* 1byte: extended RCODE; 1byte: version; 2bytes: Z(upper bit) if type is OPT */ - uint16_t rdlength; - union - { - - struct dstring cname; - struct dstring mb; - struct dstring md; - struct dstring mf; - struct dstring mg; - struct dstring mr; - struct dstring ns; - struct dstring ptr; - struct dstring a; - struct dstring aaaa; - struct dstring dname; - struct dstring isdn; - struct dstring unknown; - - struct dstring txt; - struct dstring null; - - struct rdata_hinfo hinfo; - struct rdata_minfo minfo; - struct rdata_mx mx; - struct rdata_soa soa; - struct rdata_rp rp; - struct rdata_wks wks; - struct rdata_srv srv; - struct rdata_ds ds; - struct rdata_rrsig rrsig; - struct rdata_nsec nsec; - struct rdata_dnskey dnskey; - struct rdata_nsec3 nsec3; - struct rdata_nsec3param nsec3param; - struct dstring string; - } rdata; -}; +#define DNS_MESSAGE_TOPIC "TOPIC_DNS_MESSAGE" struct dns_message; - +struct dns_query_question; +struct dns_resource_record; /*. First call DNS_MESSAGE_TRANSACTION_BEGIN to create the transaction, @@ -265,23 +43,22 @@ struct dns_flag uint8_t rcode:4; }; -struct dns_query_question -{ - enum dns_rr_type qtype; - uint16_t qclass; - size_t qname_sz; - uint8_t qname[DNS_NAME_MAX]; -}; - int32_t dns_message_transaction_index_get(struct dns_message *msg); int32_t dns_message_header_id_get(struct dns_message *msg); struct dns_flag *dns_message_header_flag_get0(struct dns_message *msg); -void dns_message_question_get0(struct dns_message *msg, struct dns_query_question **question, uint16_t *n_question); + +void dns_message_query_question_get0(struct dns_message *msg, struct dns_query_question **question, uint16_t *n_question); +const char *dns_query_question_qname_get0(struct dns_query_question *question); +int32_t dns_query_question_qtype_get0(struct dns_query_question *question); +int32_t dns_query_question_qclass_get0(struct dns_query_question *question); + void dns_message_answer_resource_record_get0(struct dns_message *msg, struct dns_resource_record **answer_rr, uint16_t *n_answer_rr); void dns_message_authority_resource_record_get0(struct dns_message *msg, struct dns_resource_record **authority_rr, uint16_t *n_authority_rr); void dns_message_additional_resource_record_get0(struct dns_message *msg, struct dns_resource_record **additional_rr, uint16_t *n_additional_rr); +const char *dns_resource_record_json_exporter(struct dns_resource_record *rr_array, uint16_t n_rr); + #ifdef __cplusplus } #endif diff --git a/perf/byte_to_hex_highly_optimized b/perf/byte_to_hex_highly_optimized new file mode 100755 index 0000000..253ef7a Binary files /dev/null and b/perf/byte_to_hex_highly_optimized differ diff --git a/perf/string_to_hex_perf_test.cpp b/perf/string_to_hex_perf_test.cpp new file mode 100644 index 0000000..74e8dfa --- /dev/null +++ b/perf/string_to_hex_perf_test.cpp @@ -0,0 +1,97 @@ +#include +#include +#include + +// Function declarations +void byteArrayToHexString_point(const unsigned char* byteArray, size_t length, char* hexString); +void byteArrayToHexString_snprintf(const unsigned char* byteArray, size_t length, char* hexString); +void byteArrayToHexString_idx(const unsigned char* byteArray, size_t length, char* hexString); + +int main() { + // Example large byte array + size_t length = 256; // 1 million bytes + unsigned char *byteArray = (unsigned char*)malloc(length * sizeof(unsigned char)); + for (size_t i = 0; i < length; i++) { + byteArray[i] = i % 256; // Filling with example data + } + + // Allocate memory for the hex string (2 characters per byte + 1 for the null terminator) + char* hexString = (char*)malloc((length * 2 + 1) * sizeof(char)); + if (hexString == NULL || byteArray == NULL) { + fprintf(stderr, "Memory allocation failed\n"); + return EXIT_FAILURE; + } + + int loop_times=1000; + + // Measure the time taken for the conversion + clock_t start = clock(); + for(int i=0; i> 4) & 0x0F]; + *ptr++ = hexChars[byteArray[i] & 0x0F]; + } + *ptr = '\0'; // Null-terminate the string +} + +// Function to convert byte array to hex string +void byteArrayToHexString_snprintf(const unsigned char* byteArray, size_t length, char* hexString) { + for (size_t i = 0; i < length; i++) { + sprintf(hexString + (i * 2), "%02x", byteArray[i]); + } + hexString[length * 2] = '\0'; // Null-terminate the string +} + +void byteArrayToHexString_idx(const unsigned char* byteArray, size_t length, char* hexString) { + const char hexChars[] = "0123456789abcdef"; + for (size_t i = 0; i < length; i++) { + hexString[i * 2] = hexChars[(byteArray[i] >> 4) & 0x0F]; + hexString[i * 2 + 1] = hexChars[byteArray[i] & 0x0F]; + } + hexString[length * 2] = '\0'; // Null-terminate the string +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a0102cd..9d858c9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,7 +5,7 @@ include_directories(${PROJECT_SOURCE_DIR}/deps/) aux_source_directory(${PROJECT_SOURCE_DIR}/deps/toml DEPS_SRC) -set(DNS_DECODER_SRC ${DEPS_SRC} dns_decoder.cpp) +set(DNS_DECODER_SRC ${DEPS_SRC} dns_decoder.cpp dns_resource_record_exporter.cpp) add_library(dns_decoder SHARED ${DNS_DECODER_SRC}) set_target_properties(dns_decoder PROPERTIES LINK_FLAGS "-Wl,--version-script=${PROJECT_SOURCE_DIR}/src/version.map") diff --git a/src/dns_decoder.cpp b/src/dns_decoder.cpp index 70fba40..23a0ccf 100644 --- a/src/dns_decoder.cpp +++ b/src/dns_decoder.cpp @@ -1,19 +1,11 @@ -/* -********************************************************************************************** -* File: dns_decoder.c -* Description: -* Authors: Liu XueLi -* Date: 2024-02-07 -* Copyright: (c) Since 2022 Geedge Networks, Ltd. All rights reserved. -*********************************************************************************************** -*/ - #include #include #include #include #include "dns_decoder.h" +#include "dns_resource_record.h" + #include "toml/toml.h" #include "uthash/uthash.h" #include "uthash/utlist.h" @@ -53,17 +45,23 @@ extern "C" #define TAG_KEY_DNS_SECTION "section" #define TAG_KEY_DNS_QR "qr" -#define TAG_KEY_IP_PROTOCOL "ip_protocol" -#define TAG_VALUE_IP_PROTOCOL_TCP "tcp" -#define TAG_VALUE_IP_PROTOCOL_UDP "udp" - -#define TAG_KEY_IP_VERSION "ip_version" -#define TAG_VALUE_IP_VERSION_IPV4 "ipv4" -#define TAG_VALUE_IP_VERSION_IPV6 "ipv6" +#define TAG_KEY_IPPROTO "ipproto" +#define TAG_VALUE_IPV4_TCP "ipv4_tcp" +#define TAG_VALUE_IPV6_TCP "ipv6_tcp" +#define TAG_VALUE_IPV4_UDP "ipv4_udp" +#define TAG_VALUE_IPV6_UDP "ipv6_udp" +#define TAG_VALUE_UNKNOWN "unknown" #define DNS_MESSAGE_MAGIC 0x53535353 #define DNS_DECODER_TOML_PATH "./etc/dns/dns_decoder.toml" +#define DNS_CLASS_UNKNOWN 0 +#define DNS_CLASS_IN 1 +#define DNS_CLASS_CS 2 +#define DNS_CLASS_CH 3 +#define DNS_CLASS_HS 4 +#define DNS_CLASS_ANY 255 + struct dns_message { int32_t magic; @@ -222,7 +220,7 @@ int32_t dns_read_be_u16(uint8_t *payload, size_t payload_sz, size_t *payload_off if(value!=NULL) { - *value=ntohs(*(uint16_t *)(payload+(*payload_offset))); + *value=((uint16_t)payload[*payload_offset] << 8) | (uint16_t)payload[*payload_offset+1]; } (*payload_offset)+=2; @@ -1156,8 +1154,8 @@ void dns_message_free(struct session *ss, void *expr_str, void *msg_free_arg) msg->trans_identifier_id=0; msg->decode_rr_status=DNS_RR_STATUS_INIT; - memset(&(msg->flag), 0, sizeof(struct dns_flag)); - memset(&(msg->question), 0, sizeof(struct dns_query_question)); + msg->flag={0}; + //memset(&(msg->question), 0, sizeof(struct dns_query_question)); msg->rr_capacity_offset=0; } @@ -1173,7 +1171,6 @@ void dns_decoder_session_transaction_del(struct dns_decoder_context *per_ss_ctx, { if(per_ss_ctx->trans_list_head==NULL || current_trans==NULL) { - assert(per_ss_ctx->trans_list_num==0); return ; } @@ -1194,6 +1191,27 @@ void dns_message_transaction_publish(struct session *ss, enum dns_message_type t session_mq_publish_message(ss, topic_id, msg); } +const char *dns_decoder_ipproto_string_get(struct session *ss) +{ + enum session_addr_type addr_type=SESSION_ADDR_TYPE_UNKNOWN; + session_get0_addr(ss, &addr_type); + switch(addr_type) + { + case SESSION_ADDR_TYPE_IPV4_TCP: + return TAG_VALUE_IPV4_TCP; + case SESSION_ADDR_TYPE_IPV4_UDP: + return TAG_VALUE_IPV4_UDP; + case SESSION_ADDR_TYPE_IPV6_TCP: + return TAG_VALUE_IPV6_TCP; + case SESSION_ADDR_TYPE_IPV6_UDP: + return TAG_VALUE_IPV6_UDP; + default: + break; + } + + return TAG_VALUE_UNKNOWN; +} + void dns_decoder_entry(struct session *ss, uint8_t *payload, size_t payload_sz, void *per_session_ctx, void *plugin_env_str) { struct dns_header dns_hdr={0}; @@ -1207,13 +1225,9 @@ void dns_decoder_entry(struct session *ss, uint8_t *payload, size_t payload_sz, size_t payload_offset=DNS_HEADER_SIZE; int32_t thread_id=session_get_current_thread_id(ss); + const char *ipproto=dns_decoder_ipproto_string_get(ss); struct dns_decoder_plugin_env *plugin_env=(struct dns_decoder_plugin_env *)plugin_env_str; - enum session_addr_type addr_type=SESSION_ADDR_TYPE_UNKNOWN; - session_get0_addr(ss, &addr_type); - const char *ip_version=(addr_type==SESSION_ADDR_TYPE_IPV4_TCP || addr_type==SESSION_ADDR_TYPE_IPV4_UDP) ? TAG_VALUE_IP_VERSION_IPV4 : TAG_VALUE_IP_VERSION_IPV6; - const char *ip_protocol=(addr_type==SESSION_ADDR_TYPE_IPV4_TCP || addr_type==SESSION_ADDR_TYPE_IPV6_TCP) ? TAG_VALUE_IP_PROTOCOL_TCP : TAG_VALUE_IP_PROTOCOL_UDP; - struct dns_message *data_msg=&(plugin_env->per_thread_data_msg[thread_id]); data_msg->ss=NULL; data_msg->n_real_answer_rr=0; @@ -1232,9 +1246,9 @@ void dns_decoder_entry(struct session *ss, uint8_t *payload, size_t payload_sz, if(data_msg->n_question==1) { - size_t tag_offset=4; - const char *tag_key[tag_offset]={TAG_KEY_IP_VERSION, TAG_KEY_IP_PROTOCOL, TAG_KEY_DNS_QR, TAG_KEY_DNS_SECTION}; - const char *tag_value[tag_offset]={ip_version, ip_protocol, ((dns_hdr.qr==0) ? "query" : "response"), "question"}; + size_t tag_offset=3; + const char *tag_key[tag_offset]={TAG_KEY_IPPROTO, TAG_KEY_DNS_QR, TAG_KEY_DNS_SECTION}; + const char *tag_value[tag_offset]={ipproto, ((dns_hdr.qr==0) ? "query" : "response"), "question"}; ret=dns_query_question_decode(&(data_msg->question), payload, payload_sz, &payload_offset); if(rettrans_idx=(++per_ss_ctx->trans_count); - current_trans->message_id=message_id; - dns_decoder_session_transaction_add(per_ss_ctx, current_trans); - dns_message_transaction_publish(ss, DNS_MESSAGE_TRANSACTION_BEGIN, plugin_env->dns.topic_id, current_trans->trans_idx); + current_trans_idx=(++per_ss_ctx->trans_count); + if(msg_type==DNS_MESSAGE_QUERY) + { + current_trans=(struct dns_transaction *)CALLOC(struct dns_transaction, 1); + current_trans->trans_idx=current_trans_idx; + current_trans->message_id=message_id; + dns_decoder_session_transaction_add(per_ss_ctx, current_trans); + } + + dns_message_transaction_publish(ss, DNS_MESSAGE_TRANSACTION_BEGIN, plugin_env->dns.topic_id, current_trans_idx); - size_t tag_offset=4; - const char *tag_key[tag_offset]={TAG_KEY_IP_VERSION, TAG_KEY_IP_PROTOCOL, TAG_KEY_MESSAGE_TYPE, TAG_KEY_MESSAGE_STATUS}; - const char *tag_value[tag_offset]={ip_version, ip_protocol, "transaction_begin", "normal"}; + size_t tag_offset=3; + const char *tag_key[tag_offset]={TAG_KEY_IPPROTO, TAG_KEY_MESSAGE_TYPE, TAG_KEY_MESSAGE_STATUS}; + const char *tag_value[tag_offset]={ipproto, "transaction_begin", "normal"}; dns_decoder_local_file_counter_incby(plugin_env, LOCAL_STAT_COUNTER_SEND, tag_key, tag_value, tag_offset, 1, session_get_current_thread_id(ss)); } @@ -1285,24 +1305,24 @@ void dns_decoder_entry(struct session *ss, uint8_t *payload, size_t payload_sz, data_msg->payload_sz=payload_sz; data_msg->payload_offset=payload_offset; data_msg->decode_rr_status=DNS_RR_STATUS_INIT; - data_msg->current_trans_idx=current_trans->trans_idx; + data_msg->current_trans_idx=current_trans_idx; session_mq_publish_message(ss, plugin_env->dns.topic_id, data_msg); - size_t tag_offset=4; + size_t tag_offset=3; const char *type=((msg_type==DNS_MESSAGE_RESPONSE) ? "response" : "query"); - const char *tag_key[tag_offset]={TAG_KEY_IP_VERSION, TAG_KEY_IP_PROTOCOL, TAG_KEY_MESSAGE_TYPE, TAG_KEY_MESSAGE_STATUS}; - const char *tag_value[tag_offset]={ip_version, ip_protocol, type, "normal"}; + const char *tag_key[tag_offset]={TAG_KEY_IPPROTO, TAG_KEY_MESSAGE_TYPE, TAG_KEY_MESSAGE_STATUS}; + const char *tag_value[tag_offset]={ipproto, type, "normal"}; dns_decoder_local_file_counter_incby(plugin_env, LOCAL_STAT_COUNTER_SEND, tag_key, tag_value, tag_offset, 1, session_get_current_thread_id(ss)); if(msg_type==DNS_MESSAGE_RESPONSE) { - dns_message_transaction_publish(ss, DNS_MESSAGE_TRANSACTION_END, plugin_env->dns.topic_id, current_trans->trans_idx); + dns_message_transaction_publish(ss, DNS_MESSAGE_TRANSACTION_END, plugin_env->dns.topic_id, current_trans_idx); dns_decoder_session_transaction_del(per_ss_ctx, current_trans); - size_t tag_offset=4; - const char *tag_key[tag_offset]={TAG_KEY_IP_VERSION, TAG_KEY_IP_PROTOCOL, TAG_KEY_MESSAGE_TYPE, TAG_KEY_MESSAGE_STATUS}; - const char *tag_value[tag_offset]={ip_version, ip_protocol, "transaction_end", "normal"}; + size_t tag_offset=3; + const char *tag_key[tag_offset]={TAG_KEY_IPPROTO, TAG_KEY_MESSAGE_TYPE, TAG_KEY_MESSAGE_STATUS}; + const char *tag_value[tag_offset]={ipproto, "transaction_end", "normal"}; dns_decoder_local_file_counter_incby(plugin_env, LOCAL_STAT_COUNTER_SEND, tag_key, tag_value, tag_offset, 1, session_get_current_thread_id(ss)); } @@ -1312,9 +1332,9 @@ void dns_decoder_entry(struct session *ss, uint8_t *payload, size_t payload_sz, dns_message_transaction_publish(ss, DNS_MESSAGE_TRANSACTION_END, plugin_env->dns.topic_id, current_trans->trans_idx); dns_decoder_session_transaction_del(per_ss_ctx, current_trans); - size_t tag_offset=4; - const char *tag_key[tag_offset]={TAG_KEY_IP_VERSION, TAG_KEY_IP_PROTOCOL, TAG_KEY_MESSAGE_TYPE, TAG_KEY_MESSAGE_STATUS}; - const char *tag_value[tag_offset]={ip_version, ip_protocol, "transaction_end", "terminate"}; + size_t tag_offset=3; + const char *tag_key[tag_offset]={TAG_KEY_IPPROTO, TAG_KEY_MESSAGE_TYPE, TAG_KEY_MESSAGE_STATUS}; + const char *tag_value[tag_offset]={ipproto, "transaction_end", "terminate"}; dns_decoder_local_file_counter_incby(plugin_env, LOCAL_STAT_COUNTER_SEND, tag_key, tag_value, tag_offset, 1, session_get_current_thread_id(ss)); } } @@ -1327,17 +1347,13 @@ int dns_decoder_transaction_end_in_closing(struct session *ss, void *per_session return DNS_DECODER_FALSE; } + const char *ipproto=dns_decoder_ipproto_string_get(ss); struct dns_decoder_context *per_ss_ctx=(struct dns_decoder_context *)per_session_ctx; struct dns_decoder_plugin_env *plugin_env=(struct dns_decoder_plugin_env *)plugin_env_str; - enum session_addr_type addr_type=SESSION_ADDR_TYPE_UNKNOWN; - session_get0_addr(ss, &addr_type); - const char *ip_version=(addr_type==SESSION_ADDR_TYPE_IPV4_TCP || addr_type==SESSION_ADDR_TYPE_IPV4_UDP) ? TAG_VALUE_IP_VERSION_IPV4 : TAG_VALUE_IP_VERSION_IPV6; - const char *ip_protocol=(addr_type==SESSION_ADDR_TYPE_IPV4_TCP || addr_type==SESSION_ADDR_TYPE_IPV6_TCP) ? TAG_VALUE_IP_PROTOCOL_TCP : TAG_VALUE_IP_PROTOCOL_UDP; - - size_t tag_offset=4; - const char *tag_key[tag_offset]={TAG_KEY_IP_VERSION, TAG_KEY_IP_PROTOCOL, TAG_KEY_MESSAGE_TYPE, TAG_KEY_MESSAGE_STATUS}; - const char *tag_value[tag_offset]={ip_version, ip_protocol, "transaction_end", "closing"}; + size_t tag_offset=3; + const char *tag_key[tag_offset]={TAG_KEY_IPPROTO, TAG_KEY_MESSAGE_TYPE, TAG_KEY_MESSAGE_STATUS}; + const char *tag_value[tag_offset]={ipproto, "transaction_end", "closing"}; dns_decoder_local_file_counter_incby(plugin_env, LOCAL_STAT_COUNTER_SEND, tag_key, tag_value, tag_offset, per_ss_ctx->trans_list_num, session_get_current_thread_id(ss)); struct dns_transaction *current_trans=NULL, *tmp_trans=NULL; @@ -1450,8 +1466,6 @@ void *dns_decoder_per_session_context_new(struct session *ss, void *plugin_env_s return NULL; } - const char *ip_version=NULL; - const char *ip_protocol=NULL; uint16_t sport=0,dport=0; enum session_addr_type addr_type=SESSION_ADDR_TYPE_UNKNOWN; struct session_addr *addr=session_get0_addr(ss, &addr_type); @@ -1462,15 +1476,11 @@ void *dns_decoder_per_session_context_new(struct session *ss, void *plugin_env_s case SESSION_ADDR_TYPE_IPV4_UDP: sport=addr->ipv4.sport; dport=addr->ipv4.dport; - ip_version=TAG_VALUE_IP_VERSION_IPV4; - ip_protocol=(addr_type==SESSION_ADDR_TYPE_IPV4_TCP) ? TAG_VALUE_IP_PROTOCOL_TCP : TAG_VALUE_IP_PROTOCOL_UDP; break; case SESSION_ADDR_TYPE_IPV6_TCP: case SESSION_ADDR_TYPE_IPV6_UDP: sport=addr->ipv6.sport; dport=addr->ipv6.dport; - ip_version=TAG_VALUE_IP_VERSION_IPV6; - ip_protocol=(addr_type==SESSION_ADDR_TYPE_IPV6_TCP) ? TAG_VALUE_IP_PROTOCOL_TCP : TAG_VALUE_IP_PROTOCOL_UDP; break; default: stellar_session_plugin_dettach_current_session(ss); @@ -1482,9 +1492,11 @@ void *dns_decoder_per_session_context_new(struct session *ss, void *plugin_env_s { if((sport==plugin_env->net_port[i]) || (dport==plugin_env->net_port[i])) { - const char *tag_key[3]={TAG_KEY_IP_VERSION, TAG_KEY_IP_PROTOCOL, "memory"}; - const char *tag_value[3]={ip_version, ip_protocol, "ss_ctx"}; - dns_decoder_local_file_counter_incby(plugin_env, LOCAL_STAT_COUNTER_NEW, tag_key, tag_value, 3, 1, session_get_current_thread_id(ss)); + size_t tag_offset=2; + const char *tag_key[tag_offset]={TAG_KEY_IPPROTO, "memory"}; + const char *ipproto=dns_decoder_ipproto_string_get(ss); + const char *tag_value[tag_offset]={ipproto, "ss_ctx"}; + dns_decoder_local_file_counter_incby(plugin_env, LOCAL_STAT_COUNTER_NEW, tag_key, tag_value, tag_offset, 1, session_get_current_thread_id(ss)); return CALLOC(struct dns_decoder_context, 1); } @@ -1504,16 +1516,13 @@ void dns_decoder_per_session_context_free(struct session *ss, void *per_session_ FREE(per_session_ctx); - enum session_addr_type addr_type=SESSION_ADDR_TYPE_UNKNOWN; - session_get0_addr(ss, &addr_type); - const char *ip_version=(addr_type==SESSION_ADDR_TYPE_IPV4_TCP || addr_type==SESSION_ADDR_TYPE_IPV4_UDP) ? TAG_VALUE_IP_VERSION_IPV4 : TAG_VALUE_IP_VERSION_IPV6; - const char *ip_protocol=(addr_type==SESSION_ADDR_TYPE_IPV4_TCP || addr_type==SESSION_ADDR_TYPE_IPV6_TCP) ? TAG_VALUE_IP_PROTOCOL_TCP : TAG_VALUE_IP_PROTOCOL_UDP; - - const char *tag_key[3]={TAG_KEY_IP_VERSION, TAG_KEY_IP_PROTOCOL, "memory"}; - const char *tag_value[3]={ip_version, ip_protocol, "ss_ctx"}; + size_t tag_offset=2; + const char *tag_key[tag_offset]={TAG_KEY_IPPROTO, "memory"}; + const char *ipproto=dns_decoder_ipproto_string_get(ss); + const char *tag_value[tag_offset]={ipproto, "ss_ctx"}; struct dns_decoder_plugin_env *plugin_env=(struct dns_decoder_plugin_env *)plugin_env_str; - dns_decoder_local_file_counter_incby(plugin_env, LOCAL_STAT_COUNTER_FREE, tag_key, tag_value, 3, 1, session_get_current_thread_id(ss)); + dns_decoder_local_file_counter_incby(plugin_env, LOCAL_STAT_COUNTER_FREE, tag_key, tag_value, tag_offset, 1, session_get_current_thread_id(ss)); } int32_t dns_decoder_config_load(const char *cfg_path, struct dns_decoder_plugin_env *plugin_env) @@ -1861,7 +1870,22 @@ struct dns_flag *dns_message_header_flag_get0(struct dns_message *msg) return &(msg->flag); } -void dns_message_question_get0(struct dns_message *msg, struct dns_query_question **question, uint16_t *n_question) +const char *dns_query_question_qname_get0(struct dns_query_question *question) +{ + return ((question!=NULL) ? (char *)(question->qname) : NULL); +} + +int32_t dns_query_question_qtype_get0(struct dns_query_question *question) +{ + return ((question!=NULL) ? question->qtype : -1); +} + +int32_t dns_query_question_qclass_get0(struct dns_query_question *question) +{ + return ((question!=NULL) ? question->qclass : -1); +} + +void dns_message_query_question_get0(struct dns_message *msg, struct dns_query_question **question, uint16_t *n_question) { if(msg==NULL || msg->magic!=DNS_MESSAGE_MAGIC || msg->type==DNS_MESSAGE_TRANSACTION_BEGIN || msg->type==DNS_MESSAGE_TRANSACTION_END || msg->n_question==0) { @@ -1905,16 +1929,13 @@ int32_t dns_message_resource_record_serialize(struct dns_message *msg) return DNS_DECODER_FALSE; } - enum session_addr_type addr_type=SESSION_ADDR_TYPE_UNKNOWN; - session_get0_addr(msg->ss, &addr_type); - const char *ip_version=(addr_type==SESSION_ADDR_TYPE_IPV4_TCP || addr_type==SESSION_ADDR_TYPE_IPV4_UDP) ? TAG_VALUE_IP_VERSION_IPV4 : TAG_VALUE_IP_VERSION_IPV6; - const char *ip_protocol=(addr_type==SESSION_ADDR_TYPE_IPV4_TCP || addr_type==SESSION_ADDR_TYPE_IPV6_TCP) ? TAG_VALUE_IP_PROTOCOL_TCP : TAG_VALUE_IP_PROTOCOL_UDP; - size_t tag_offset=4; - const char *tag_key[tag_offset]={TAG_KEY_IP_VERSION, TAG_KEY_IP_PROTOCOL, TAG_KEY_DNS_QR, TAG_KEY_DNS_SECTION}; + const char *ipproto=dns_decoder_ipproto_string_get(msg->ss); + size_t tag_offset=3; + const char *tag_key[tag_offset]={TAG_KEY_IPPROTO, TAG_KEY_DNS_QR, TAG_KEY_DNS_SECTION}; if(msg->type==DNS_MESSAGE_TRANSACTION_BEGIN || msg->type==DNS_MESSAGE_TRANSACTION_END) { - const char *tag_value[tag_offset]={ip_version, ip_protocol, ((msg->type==DNS_MESSAGE_TRANSACTION_BEGIN) ? "begin" : "end"), "none"}; + const char *tag_value[tag_offset]={ipproto, ((msg->type==DNS_MESSAGE_TRANSACTION_BEGIN) ? "begin" : "end"), "none"}; dns_decoder_local_file_counter_incby(msg->plugin_env, LOCAL_STAT_COUNTER_ERROR, tag_key, tag_value, tag_offset, 1, session_get_current_thread_id(msg->ss)); return DNS_DECODER_FALSE; } @@ -1945,7 +1966,7 @@ int32_t dns_message_resource_record_serialize(struct dns_message *msg) if(msg->n_answer_rr>0) { - const char *tag_value[tag_offset]={ip_version, ip_protocol, ((msg->type==DNS_MESSAGE_QUERY) ? "query" : "response"), "answer"}; + const char *tag_value[tag_offset]={ipproto, ((msg->type==DNS_MESSAGE_QUERY) ? "query" : "response"), "answer"}; dns_resource_record_buff_get0(msg->rr_capacity, msg->rr_capacity_sz, &(msg->rr_capacity_offset), &(msg->answer_rr), msg->n_answer_rr, &(msg->n_real_answer_rr)); int32_t ret=dns_resource_record_decode(msg->payload, msg->payload_sz, &(msg->payload_offset), msg->answer_rr, msg->n_real_answer_rr); if(ret==DNS_DECODER_FALSE) @@ -1963,7 +1984,7 @@ int32_t dns_message_resource_record_serialize(struct dns_message *msg) if(msg->n_authority_rr>0) { - const char *tag_value[tag_offset]={ip_version, ip_protocol, ((msg->type==DNS_MESSAGE_QUERY) ? "query" : "response"), "authority"}; + const char *tag_value[tag_offset]={ipproto, ((msg->type==DNS_MESSAGE_QUERY) ? "query" : "response"), "authority"}; dns_resource_record_buff_get0(msg->rr_capacity, msg->rr_capacity_sz, &(msg->rr_capacity_offset), &(msg->authority_rr), msg->n_authority_rr, &(msg->n_real_authority_rr)); int32_t ret=dns_resource_record_decode(msg->payload, msg->payload_sz, &(msg->payload_offset), msg->authority_rr, msg->n_real_authority_rr); if(ret==DNS_DECODER_FALSE) @@ -1981,7 +2002,7 @@ int32_t dns_message_resource_record_serialize(struct dns_message *msg) if(msg->n_additional_rr>0) { - const char *tag_value[tag_offset]={ip_version, ip_protocol, ((msg->type==DNS_MESSAGE_QUERY) ? "query" : "response"), "additional"}; + const char *tag_value[tag_offset]={ipproto, ((msg->type==DNS_MESSAGE_QUERY) ? "query" : "response"), "additional"}; dns_resource_record_buff_get0(msg->rr_capacity, msg->rr_capacity_sz, &(msg->rr_capacity_offset), &(msg->additional_rr), msg->n_additional_rr, &(msg->n_real_additional_rr)); int32_t ret=dns_resource_record_decode(msg->payload, msg->payload_sz, &(msg->payload_offset), msg->additional_rr, msg->n_real_additional_rr); if(ret==DNS_DECODER_FALSE) diff --git a/src/dns_resource_record.h b/src/dns_resource_record.h new file mode 100644 index 0000000..6070b20 --- /dev/null +++ b/src/dns_resource_record.h @@ -0,0 +1,219 @@ +#pragma once + +#include +#include +#include + +#define DNS_NAME_MAX (NAME_MAX + 1) +// #define HINFO_NAME_MAX (40 + 1) /* https://www.ietf.org/rfc/rfc1010.txt */ + +/* RR(resource record) type, defined in https://www.ietf.org/rfc/rfc1035.txt */ +enum dns_rr_type +{ + DNS_RR_TYPE_A = 1, + DNS_RR_TYPE_NS, + DNS_RR_TYPE_MD, /* Obsolete - use MX, rfc973 */ + DNS_RR_TYPE_MF, /* Obsolete - use MX, rfc973 */ + DNS_RR_TYPE_CNAME, + DNS_RR_TYPE_SOA, + DNS_RR_TYPE_MB, /* EXPERIMENTAL, rfc883,rfc2505 */ + DNS_RR_TYPE_MG, /* EXPERIMENTAL, rfc883,rfc2505 */ + DNS_RR_TYPE_MR, /* EXPERIMENTAL, rfc883 */ + DNS_RR_TYPE_NULL, /* EXPERIMENTAL, rfc1035 */ + DNS_RR_TYPE_WKS, /* Not to be relied upon, rfc1123 */ + DNS_RR_TYPE_PTR, + DNS_RR_TYPE_HINFO, + DNS_RR_TYPE_MINFO, + DNS_RR_TYPE_MX, + DNS_RR_TYPE_TXT, + DNS_RR_TYPE_RP, + DNS_RR_TYPE_ISDN = 20, + DNS_RR_TYPE_AAAA = 28, /* dns_ipv6 */ + DNS_RR_TYPE_SRV = 33, + DNS_RR_TYPE_DNAME = 39, + DNS_RR_TYPE_OPT = 41, + DNS_RR_TYPE_DS = 43, + DNS_RR_TYPE_RRSIG = 46, + DNS_RR_TYPE_NSEC, + DNS_RR_TYPE_DNSKEY, + DNS_RR_TYPE_NSEC3 = 50, + DNS_RR_TYPE_NSEC3PARAM, + DNS_RR_TYPE_HTTPS = 65, + DNS_RR_TYPE_AXFR = 252, + DNS_RR_TYPE_MAILB, + DNS_RR_TYPE_MAILA, /* Obsolete - see MX */ + DNS_RR_TYPE_ANY, + DNS_RR_TYPE_DLV = 32769, /* DSNSEC Lokkaside Validation */ + DNS_RR_TYPE_UNKNOWN = 65534 +}; + +struct dstring +{ + size_t value_sz; + uint8_t value[DNS_NAME_MAX]; +}; + +struct rdata_hinfo +{ + struct dstring os; + struct dstring cpu; +}; + +struct rdata_minfo +{ + struct dstring rmailbx; + struct dstring emailbx; +}; + +struct rdata_mx +{ + uint16_t preference; + struct dstring exchange; +}; + +struct rdata_soa +{ + struct dstring mname; + struct dstring rname; + uint32_t serial; + uint32_t refresh; + uint32_t retry; + uint32_t expire; + uint32_t minimum; +}; + +struct rdata_rp +{ + struct dstring txt_rr; + struct dstring mailbox; +}; + +struct rdata_wks +{ + uint8_t protocol; + uint32_t addr; + uint32_t size; + uint8_t *bitmap; +}; + +struct rdata_srv +{ + uint16_t priority; + uint16_t weight; + uint16_t port; + struct dstring target; +}; + +struct rdata_ds +{ + uint16_t key_tag; + uint8_t algo; + uint8_t digest_type; + uint32_t digest_len; + uint8_t *digest; +}; + +struct rdata_rrsig +{ + uint16_t type_covered; + uint8_t algo; + uint8_t labels; + uint32_t original_ttl; + uint32_t sig_expiration; + uint32_t sig_inception; + uint16_t key_tag; + uint32_t signature_len; + uint8_t *signature; + struct dstring signer_name; +}; + +struct rdata_nsec +{ + uint16_t maps_len; + struct dstring next_domain; + struct dstring type_bit_maps; +}; + +struct rdata_dnskey +{ + uint16_t flags; + uint8_t protocol; + uint8_t algo; + uint32_t public_key_len; + uint8_t *public_key; +}; + +struct rdata_nsec3 +{ + uint8_t hash_algo; + uint8_t flags; + uint8_t salt_len; + uint8_t hash_len; + uint16_t iteration; + uint16_t maps_len; + uint8_t *salt_value; + uint8_t *next_hash_owner; + struct dstring type_bit_maps; +}; + +struct rdata_nsec3param +{ + uint8_t hash_algo; + uint8_t flags; + uint8_t salt_len; + uint16_t iteration; + uint8_t *salt_value; +}; + +/* rr is short for resource record */ +struct dns_resource_record +{ + struct dstring qname; + enum dns_rr_type type; + uint16_t rr_class; + uint32_t ttl; /* 1byte: extended RCODE; 1byte: version; 2bytes: Z(upper bit) if type is OPT */ + uint16_t rdlength; + union + { + + struct dstring cname; + struct dstring mb; + struct dstring md; + struct dstring mf; + struct dstring mg; + struct dstring mr; + struct dstring ns; + struct dstring ptr; + struct dstring a; + struct dstring aaaa; + struct dstring dname; + struct dstring isdn; + struct dstring unknown; + + struct dstring txt; + struct dstring null; + + struct rdata_hinfo hinfo; + struct rdata_minfo minfo; + struct rdata_mx mx; + struct rdata_soa soa; + struct rdata_rp rp; + struct rdata_wks wks; + struct rdata_srv srv; + struct rdata_ds ds; + struct rdata_rrsig rrsig; + struct rdata_nsec nsec; + struct rdata_dnskey dnskey; + struct rdata_nsec3 nsec3; + struct rdata_nsec3param nsec3param; + struct dstring string; + } rdata; +}; + +struct dns_query_question +{ + enum dns_rr_type qtype; + uint16_t qclass; + size_t qname_sz; + uint8_t qname[DNS_NAME_MAX]; +}; diff --git a/src/dns_resource_record_exporter.cpp b/src/dns_resource_record_exporter.cpp new file mode 100644 index 0000000..7dd5900 --- /dev/null +++ b/src/dns_resource_record_exporter.cpp @@ -0,0 +1,230 @@ +#include +#include +#include +#include + +#include "cJSON.h" +#include "dns_decoder.h" +#include "dns_resource_record.h" + + +void dns_resource_record_str2hex_append(cJSON *one_rr_object, uint8_t *str, size_t str_sz, const char *key) +{ + if(one_rr_object==NULL || str==NULL || str_sz==0 || key==NULL) + { + return; + } + + size_t offset=0; + char hex_buff[4096]={0}; + size_t hex_buff_sz=sizeof(hex_buff); + const char hexChars[] = "0123456789abcdef"; + + for (size_t i = 0; i < str_sz && i<((hex_buff_sz/2)-2); i++) + { + hex_buff[offset++]=hexChars[(str[i] >> 4) & 0x0F]; + hex_buff[offset++]=hexChars[str[i] & 0x0F]; + } + + if(offset>0) + { + hex_buff[offset]='\0'; + cJSON_AddStringToObject(one_rr_object, key, hex_buff); + } +} + +void dns_resource_record_dstring_append(cJSON *one_rr_object, struct dstring *dstr, const char *key) +{ + if(dstr->value_sz > 0) + { + cJSON_AddStringToObject(one_rr_object, key, (char *)(dstr->value)); + } +} + +const char *dns_resource_record_json_exporter(struct dns_resource_record *rr_array, uint16_t n_rr) +{ + if(rr_array==NULL || n_rr==0) + { + return NULL; + } + + char ip_str[128]; + cJSON *dns_rr_array=cJSON_CreateArray(); + + for(uint16_t i=0; itype == DNS_RR_TYPE_OPT) + { + cJSON_AddStringToObject(one_rr_object, "name", (const char *)(dns_rr->qname.value)); + 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->qname.value)); + 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->rdlength==0) + { + cJSON_AddItemToArray(dns_rr_array, one_rr_object); + continue; + } + + switch(dns_rr->type) + { + case DNS_RR_TYPE_A: + inet_ntop(AF_INET, (void *)(dns_rr->rdata.a.value), ip_str, sizeof(ip_str)); + cJSON_AddStringToObject(one_rr_object, "a", ip_str); + break; + case DNS_RR_TYPE_AAAA: + inet_ntop(AF_INET6, dns_rr->rdata.aaaa.value, ip_str, sizeof(ip_str)); + cJSON_AddStringToObject(one_rr_object, "aaaa", ip_str); + break; + case DNS_RR_TYPE_NS: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.ns), "ns"); + break; + case DNS_RR_TYPE_MD: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.md), "md"); + break; + case DNS_RR_TYPE_MF: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.mf), "mf"); + break; + case DNS_RR_TYPE_CNAME: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.cname), "cname"); + break; + case DNS_RR_TYPE_MB: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.mb), "mb"); + break; + case DNS_RR_TYPE_MG: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.mg), "mg"); + break; + case DNS_RR_TYPE_MR: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.mr), "mr"); + break; + case DNS_RR_TYPE_TXT: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.txt), "txt"); + cJSON_AddNumberToObject(one_rr_object, "size", dns_rr->rdata.txt.value_sz); + break; + case DNS_RR_TYPE_NULL: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.null), "null"); + cJSON_AddNumberToObject(one_rr_object, "size", dns_rr->rdata.null.value_sz); + break; + case DNS_RR_TYPE_PTR: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.ptr), "ptr"); + break; + case DNS_RR_TYPE_HINFO: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.hinfo.cpu), "cpu"); + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.hinfo.os), "os"); + break; + case DNS_RR_TYPE_MINFO: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.minfo.rmailbx), "rmailbx"); + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.minfo.emailbx), "emailbx"); + break; + case DNS_RR_TYPE_MX: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.mx.exchange), "exchange"); + cJSON_AddNumberToObject(one_rr_object, "preference", dns_rr->rdata.mx.preference); + break; + case DNS_RR_TYPE_RP: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.rp.mailbox), "mailbox"); + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.rp.txt_rr), "txt_rr"); + break; + case DNS_RR_TYPE_SOA: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.soa.mname), "mname"); + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.soa.rname), "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_RR_TYPE_WKS: + cJSON_AddStringToObject(one_rr_object, "addr", ip_str); + cJSON_AddNumberToObject(one_rr_object, "protocol", dns_rr->rdata.wks.protocol); + cJSON_AddNumberToObject(one_rr_object, "size", dns_rr->rdata.wks.size); + + dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.wks.bitmap, dns_rr->rdata.wks.size, "bitmap"); + break; + case DNS_RR_TYPE_OPT: + break; + case DNS_RR_TYPE_DS: + 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_AddNumberToObject(one_rr_object, "digest_len", dns_rr->rdata.ds.digest_len); + + dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.ds.digest, dns_rr->rdata.ds.digest_len, "digest"); + break; + case DNS_RR_TYPE_RRSIG: + 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); + + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.rrsig.signer_name), "signer_name"); + + cJSON_AddNumberToObject(one_rr_object, "signature_len", dns_rr->rdata.rrsig.signature_len); + dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.rrsig.signature, dns_rr->rdata.rrsig.signature_len, "signature"); + break; + case DNS_RR_TYPE_NSEC: + dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.nsec.next_domain), "next_domain"); + cJSON_AddNumberToObject(one_rr_object, "maps_len", dns_rr->rdata.nsec.type_bit_maps.value_sz); + + dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.nsec.type_bit_maps.value, dns_rr->rdata.nsec.type_bit_maps.value_sz, "type_bit_maps"); + break; + case DNS_RR_TYPE_DNSKEY: + 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_AddNumberToObject(one_rr_object, "public_key_len", dns_rr->rdata.dnskey.public_key_len); + + dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.dnskey.public_key, dns_rr->rdata.dnskey.public_key_len, "public_key"); + break; + case DNS_RR_TYPE_NSEC3: + 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); + dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.nsec3.salt_value, dns_rr->rdata.nsec3.salt_len, "salt_value"); + + cJSON_AddNumberToObject(one_rr_object, "hash_len", dns_rr->rdata.nsec3.hash_len); + dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.nsec3.next_hash_owner, dns_rr->rdata.nsec3.hash_len, "next_hash_owner"); + + cJSON_AddNumberToObject(one_rr_object, "maps_len", dns_rr->rdata.nsec3.type_bit_maps.value_sz); + dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.nsec3.type_bit_maps.value,dns_rr->rdata.nsec3.type_bit_maps.value_sz, "type_bit_maps"); + break; + case DNS_RR_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); + + dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.nsec3param.salt_value, dns_rr->rdata.nsec3param.salt_len, "salt_value"); + break; + default: + break; + } + + cJSON_AddItemToArray(dns_rr_array, one_rr_object); + } + + char *json_str=cJSON_PrintUnformatted(dns_rr_array); + cJSON_Delete(dns_rr_array); + + return json_str; +} \ No newline at end of file diff --git a/src/version.map b/src/version.map index 056069e..dbead6a 100644 --- a/src/version.map +++ b/src/version.map @@ -6,10 +6,14 @@ global: *dns_message_type_get*; *dns_message_header_id_get*; *dns_message_header_flag_get0*; - *dns_message_question_get0*; + *dns_message_query_question_get0*; + *dns_query_question_qname_get0*; + *dns_query_question_qtype_get0*; + *dns_query_question_qclass_get0*; *dns_message_answer_resource_record_get0*; *dns_message_authority_resource_record_get0*; *dns_message_additional_resource_record_get0*; + *dns_resource_record_json_exporter*; *dns_message_transaction_index_get*; *GIT*; }; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 766d204..b878303 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,7 +6,14 @@ add_dependencies(${PROJECT_NAME}_test_plug ${PROJECT_NAME}) target_link_libraries(${PROJECT_NAME}_test_plug cjson) set_target_properties(${PROJECT_NAME}_test_plug PROPERTIES PREFIX "") -add_executable(dns_decoder_perf_test dns_decoder_perf_main.cpp dns_decoder_perf_dummy.cpp ${DEPS_SRC} dns_decoder_test.cpp ${PROJECT_SOURCE_DIR}/src/dns_decoder.cpp) +add_executable(dns_decoder_perf_test + dns_decoder_perf_main.cpp + dns_decoder_perf_dummy.cpp + ${DEPS_SRC} dns_decoder_test.cpp + ${PROJECT_SOURCE_DIR}/src/dns_decoder.cpp + ${PROJECT_SOURCE_DIR}/src/dns_resource_record_exporter.cpp + ) + target_link_libraries(dns_decoder_perf_test fieldstat4 pthread cjson) set(TEST_RUN_DIR ${CMAKE_CURRENT_BINARY_DIR}/sapp) diff --git a/test/dns_decoder_perf_dummy.h b/test/dns_decoder_perf_dummy.h index d7ebcca..c223065 100644 --- a/test/dns_decoder_perf_dummy.h +++ b/test/dns_decoder_perf_dummy.h @@ -9,6 +9,8 @@ extern "C" #include "stellar/session.h" #include +void perf_resource_record_decode(struct dns_message *dns_msg); + #ifdef __cplusplus } #endif @@ -27,4 +29,4 @@ struct stellar *stellar_init(int worker_thread_num); struct session *stellar_session_new(struct stellar *st, struct stellar_packet *cur_pkt, int tid); void stellar_session_free(struct session *ss); -int session_mq_publish_message_by_name(struct session *ss, const char *topic_name, struct stellar_packet *msg); \ No newline at end of file +int session_mq_publish_message_by_name(struct session *ss, const char *topic_name, struct stellar_packet *msg); diff --git a/test/dns_decoder_perf_main.cpp b/test/dns_decoder_perf_main.cpp index adf8434..078e560 100644 --- a/test/dns_decoder_perf_main.cpp +++ b/test/dns_decoder_perf_main.cpp @@ -100,9 +100,21 @@ extern "C" int commit_test_result_json(cJSON *node, const char *name) return 0; } -void perf_resource_record_decode() +void perf_resource_record_decode(struct dns_message *dns_msg) { + TIME_START(); + uint16_t n_answer_rr=0; + uint16_t n_additional_rr=0; + uint16_t n_authority_rr=0; + struct dns_resource_record *answer_rr=NULL; + struct dns_resource_record *additional_rr=NULL; + struct dns_resource_record *authority_rr=NULL; + dns_message_answer_resource_record_get0(dns_msg, &answer_rr, &n_answer_rr); + dns_message_authority_resource_record_get0(dns_msg, &authority_rr, &n_authority_rr); + dns_message_additional_resource_record_get0(dns_msg, &additional_rr, &n_additional_rr); + TIME_DIFF(); + //fieldstat_easy_histogram_record(main_env->fse.handle, tid, main_env->fse.id[PERF_TAG_QUESTION], &(main_env->fse.tag[PERF_TAG_QUESTION]), 1, time_diff_ns) } void *pthread_message_publish(void *arg) diff --git a/test/dns_decoder_test.cpp b/test/dns_decoder_test.cpp index f0ddbd3..44931e5 100644 --- a/test/dns_decoder_test.cpp +++ b/test/dns_decoder_test.cpp @@ -4,13 +4,11 @@ #include #include #include -#include #ifdef __cplusplus extern "C" { - #include "cJSON.h" #include "dns_decoder.h" #include "toml/toml.h" @@ -33,8 +31,10 @@ struct dns_decoder_test_plugin_env int commit_result_enable; int write_result_enable; int decode_resource_record_enable; + int export_resource_record_enable; }; +extern "C" void perf_resource_record_decode(struct dns_message *dns_msg); extern "C" int commit_test_result_json(cJSON *node, const char *name); void dns_real_result_write_file(char *result_str) @@ -47,232 +47,6 @@ void dns_real_result_write_file(char *result_str) } } -void dns_resource_record_str2hex_append(cJSON *one_rr_object, uint8_t *str, size_t str_sz, const char *key) -{ - if(one_rr_object==NULL || str==NULL || str_sz==0 || key==NULL) - { - return; - } - - size_t offset=0; - char hex_buff[4096]={0}; - size_t hex_buff_sz=sizeof(hex_buff); - - for(size_t i=0; i= hex_buff_sz) - { - break; - } - } - - if(offset>0) - { - cJSON_AddStringToObject(one_rr_object, key, hex_buff); - } -} - -void dns_resource_record_dstring_append(cJSON *one_rr_object, struct dstring *dstr, const char *key) -{ - if(dstr->value_sz > 0) - { - cJSON_AddStringToObject(one_rr_object, key, (char *)(dstr->value)); - } -} - -int dns_resource_record_json_exporter(cJSON *object, struct dns_resource_record *rr_array, uint16_t n_rr, const char *rr_type, int *dns_sec) -{ - if(object==NULL || rr_array==NULL || n_rr==0 || dns_sec==NULL) - { - return 0; - } - - char ip_str[128]; - cJSON *dns_rr_array=cJSON_CreateArray(); - - for(uint16_t i=0; itype == DNS_RR_TYPE_OPT) - { - cJSON_AddStringToObject(one_rr_object, "name", (const char *)(dns_rr->qname.value)); - 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->qname.value)); - 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->rdlength==0) - { - cJSON_AddItemToArray(dns_rr_array, one_rr_object); - continue; - } - - switch(dns_rr->type) - { - case DNS_RR_TYPE_A: - inet_ntop(AF_INET, (void *)(dns_rr->rdata.a.value), ip_str, sizeof(ip_str)); - cJSON_AddStringToObject(one_rr_object, "a", ip_str); - break; - case DNS_RR_TYPE_AAAA: - inet_ntop(AF_INET6, dns_rr->rdata.aaaa.value, ip_str, sizeof(ip_str)); - cJSON_AddStringToObject(one_rr_object, "aaaa", ip_str); - break; - case DNS_RR_TYPE_NS: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.ns), "ns"); - break; - case DNS_RR_TYPE_MD: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.md), "md"); - break; - case DNS_RR_TYPE_MF: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.mf), "mf"); - break; - case DNS_RR_TYPE_CNAME: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.cname), "cname"); - break; - case DNS_RR_TYPE_MB: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.mb), "mb"); - break; - case DNS_RR_TYPE_MG: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.mg), "mg"); - break; - case DNS_RR_TYPE_MR: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.mr), "mr"); - break; - case DNS_RR_TYPE_TXT: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.txt), "txt"); - cJSON_AddNumberToObject(one_rr_object, "size", dns_rr->rdata.txt.value_sz); - break; - case DNS_RR_TYPE_NULL: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.null), "null"); - cJSON_AddNumberToObject(one_rr_object, "size", dns_rr->rdata.null.value_sz); - break; - case DNS_RR_TYPE_PTR: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.ptr), "ptr"); - break; - case DNS_RR_TYPE_HINFO: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.hinfo.cpu), "cpu"); - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.hinfo.os), "os"); - break; - case DNS_RR_TYPE_MINFO: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.minfo.rmailbx), "rmailbx"); - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.minfo.emailbx), "emailbx"); - break; - case DNS_RR_TYPE_MX: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.mx.exchange), "exchange"); - cJSON_AddNumberToObject(one_rr_object, "preference", dns_rr->rdata.mx.preference); - break; - case DNS_RR_TYPE_RP: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.rp.mailbox), "mailbox"); - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.rp.txt_rr), "txt_rr"); - break; - case DNS_RR_TYPE_SOA: - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.soa.mname), "mname"); - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.soa.rname), "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_RR_TYPE_WKS: - cJSON_AddStringToObject(one_rr_object, "addr", ip_str); - cJSON_AddNumberToObject(one_rr_object, "protocol", dns_rr->rdata.wks.protocol); - cJSON_AddNumberToObject(one_rr_object, "size", dns_rr->rdata.wks.size); - - dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.wks.bitmap, dns_rr->rdata.wks.size, "bitmap"); - break; - case DNS_RR_TYPE_OPT: - break; - case DNS_RR_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_AddNumberToObject(one_rr_object, "digest_len", dns_rr->rdata.ds.digest_len); - - dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.ds.digest, dns_rr->rdata.ds.digest_len, "digest"); - break; - case DNS_RR_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); - - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.rrsig.signer_name), "signer_name"); - - cJSON_AddNumberToObject(one_rr_object, "signature_len", dns_rr->rdata.rrsig.signature_len); - dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.rrsig.signature, dns_rr->rdata.rrsig.signature_len, "signature"); - break; - case DNS_RR_TYPE_NSEC: - *dns_sec = 2; - dns_resource_record_dstring_append(one_rr_object, &(dns_rr->rdata.nsec.next_domain), "next_domain"); - cJSON_AddNumberToObject(one_rr_object, "maps_len", dns_rr->rdata.nsec.type_bit_maps.value_sz); - - dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.nsec.type_bit_maps.value, dns_rr->rdata.nsec.type_bit_maps.value_sz, "type_bit_maps"); - break; - case DNS_RR_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_AddNumberToObject(one_rr_object, "public_key_len", dns_rr->rdata.dnskey.public_key_len); - - dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.dnskey.public_key, dns_rr->rdata.dnskey.public_key_len, "public_key"); - break; - case DNS_RR_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); - dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.nsec3.salt_value, dns_rr->rdata.nsec3.salt_len, "salt_value"); - - cJSON_AddNumberToObject(one_rr_object, "hash_len", dns_rr->rdata.nsec3.hash_len); - dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.nsec3.next_hash_owner, dns_rr->rdata.nsec3.hash_len, "next_hash_owner"); - - cJSON_AddNumberToObject(one_rr_object, "maps_len", dns_rr->rdata.nsec3.type_bit_maps.value_sz); - dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.nsec3.type_bit_maps.value,dns_rr->rdata.nsec3.type_bit_maps.value_sz, "type_bit_maps"); - break; - case DNS_RR_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); - - dns_resource_record_str2hex_append(one_rr_object, dns_rr->rdata.nsec3param.salt_value, dns_rr->rdata.nsec3param.salt_len, "salt_value"); - break; - default: - break; - } - - cJSON_AddItemToArray(dns_rr_array, one_rr_object); - } - - cJSON_AddItemToObject(object, rr_type, dns_rr_array); - - return 1; -} - void dns_decoder_test_message_cb(struct session *ss, int topic_id, const void *msg, void *per_session_ctx, void *plugin_env_str) { struct dns_message *dns_msg=(struct dns_message *)msg; @@ -284,18 +58,23 @@ void dns_decoder_test_message_cb(struct session *ss, int topic_id, const void *m //uint16_t id=dns_message_header_id_get(dns_msg); struct dns_decoder_test_plugin_env *plugin_env=(struct dns_decoder_test_plugin_env *)plugin_env_str; + if(plugin_env->decode_resource_record_enable==1) + { + perf_resource_record_decode(dns_msg); + return ; + } - cJSON *real_result=cJSON_CreateObject(); - cJSON_AddStringToObject(real_result, "Tuple4", session_get0_readable_addr(ss)); + cJSON *real_result=cJSON_CreateObject(); + cJSON_AddStringToObject(real_result, "Tuple4", session_get0_readable_addr(ss)); uint16_t n_question=0; struct dns_query_question *question=NULL; - dns_message_question_get0(dns_msg, &question, &n_question); + dns_message_query_question_get0(dns_msg, &question, &n_question); if(n_question>0 && question!=NULL) { - cJSON_AddStringToObject(real_result, "dns_qname", (char *)question->qname); - cJSON_AddNumberToObject(real_result, "dns_qtype", question->qtype); - cJSON_AddNumberToObject(real_result, "dns_qclass", question->qclass); + cJSON_AddStringToObject(real_result, "dns_qname", dns_query_question_qname_get0(question)); + cJSON_AddNumberToObject(real_result, "dns_qtype", dns_query_question_qtype_get0(question)); + cJSON_AddNumberToObject(real_result, "dns_qclass", dns_query_question_qclass_get0(question)); } struct dns_flag *flag=dns_message_header_flag_get0(dns_msg); @@ -306,38 +85,57 @@ void dns_decoder_test_message_cb(struct session *ss, int topic_id, const void *m cJSON_AddNumberToObject(real_result, "dns_rd", (double)(flag->rd)); } - if(plugin_env->decode_resource_record_enable==1) + uint16_t n_answer_rr=0; + struct dns_resource_record *answer_rr=NULL; + dns_message_answer_resource_record_get0(dns_msg, &answer_rr, &n_answer_rr); + + uint16_t n_authority_rr=0; + struct dns_resource_record *authority_rr=NULL; + dns_message_authority_resource_record_get0(dns_msg, &authority_rr, &n_authority_rr); + + uint16_t n_additional_rr=0; + struct dns_resource_record *additional_rr=NULL; + dns_message_additional_resource_record_get0(dns_msg, &additional_rr, &n_additional_rr); + + const char *answer=dns_resource_record_json_exporter(answer_rr, n_answer_rr); + const char *authority=dns_resource_record_json_exporter(authority_rr, n_authority_rr); + const char *additional=dns_resource_record_json_exporter(additional_rr, n_additional_rr); + + cJSON *rr_array=cJSON_CreateObject(); + if(answer!=NULL) { - cJSON *rr_object=cJSON_CreateObject(); - uint16_t n_answer_rr=0; - struct dns_resource_record *answer_rr=NULL; - dns_message_answer_resource_record_get0(dns_msg, &answer_rr, &n_answer_rr); - - uint16_t n_authority_rr=0; - struct dns_resource_record *authority_rr=NULL; - dns_message_authority_resource_record_get0(dns_msg, &authority_rr, &n_authority_rr); - - uint16_t n_additional_rr=0; - struct dns_resource_record *additional_rr=NULL; - dns_message_additional_resource_record_get0(dns_msg, &additional_rr, &n_additional_rr); - - int dns_sec=1; - dns_resource_record_json_exporter(rr_object, answer_rr, n_answer_rr, "answer", &dns_sec); - dns_resource_record_json_exporter(rr_object, authority_rr, n_authority_rr, "authority", &dns_sec); - dns_resource_record_json_exporter(rr_object, additional_rr, n_additional_rr, "additional", &dns_sec); - - cJSON_AddItemToObject(real_result, "rr", rr_object); + cJSON *rr_object=cJSON_Parse(answer); + cJSON_AddItemToObject(rr_array, "answer", rr_object); + free((void *)answer); } - char result_name[16]=""; - sprintf(result_name, "DNS_RESULT_%d", plugin_env->result_index++); + if(authority!=NULL) + { + cJSON *rr_object=cJSON_Parse(authority); + cJSON_AddItemToObject(rr_array, "authority", rr_object); + free((void *)authority); + } - char *real_result_str=cJSON_Print(real_result); - dns_real_result_write_file(real_result_str); - free(real_result_str); + if(additional!=NULL) + { + cJSON *rr_object=cJSON_Parse(additional); + cJSON_AddItemToObject(rr_array, "additional", rr_object); + free((void *)additional); + } + + cJSON_AddItemToObject(real_result, "rr", rr_array); + + if(plugin_env->write_result_enable==1) + { + char *real_result_str=cJSON_Print(real_result); + dns_real_result_write_file(real_result_str); + free(real_result_str); + } if(plugin_env->commit_result_enable==1) { + char result_name[16]=""; + sprintf(result_name, "DNS_RESULT_%d", plugin_env->result_index++); commit_test_result_json(real_result, result_name); } else @@ -465,6 +263,30 @@ int32_t dns_decoder_test_config_load(const char *cfg_path, struct dns_decoder_te } } + // export_resource_record_enable + toml_datum_t export_resource_record_enable_val=toml_string_in(test_tbl, "export_resource_record_enable"); + if(export_resource_record_enable_val.ok==0) + { + plugin_env->export_resource_record_enable=0; + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.dns.test.export_resource_record_enable]", __FUNCTION__, __LINE__, cfg_path); + } + else + { + if(memcmp("no", export_resource_record_enable_val.u.s, strlen("no"))==0) + { + plugin_env->export_resource_record_enable=0; + } + else if(memcmp("yes", export_resource_record_enable_val.u.s, strlen("yes"))==0) + { + plugin_env->export_resource_record_enable=1; + } + else + { + plugin_env->export_resource_record_enable=1; + fprintf(stderr, "[%s:%d] config file: %s key: [decoder.dns.test.export_resource_record_enable] value is not yes or no", __FUNCTION__, __LINE__, cfg_path); + } + } + toml_free(root); return ret;