diff --git a/bin/dns_decoder.toml b/bin/dns_decoder.toml index fb60d1b..01957e3 100644 --- a/bin/dns_decoder.toml +++ b/bin/dns_decoder.toml @@ -12,3 +12,6 @@ stat_per_thread_enable="no" stat_name="DNS_DECODER" stat_interval_time_s=5 stat_output="metrics/dns_decoder_local_stat.json" + +[decoder.dns.test] +commit_result_enable="yes" diff --git a/bin/dns_decoder_local_stat.sh b/bin/dns_decoder_local_stat.sh index 588662f..4ed3f12 100644 --- a/bin/dns_decoder_local_stat.sh +++ b/bin/dns_decoder_local_stat.sh @@ -32,6 +32,5 @@ python3 $EXPORTER local -j $TARGET -e -t ' {{ print_tables("memory", ["new", "#Speed", "free", "#Speed"], True )}} {{"\n"}} {{"dns decoder decode status"}} - {{ print_tables("decode_field", ["error", "#Speed"], True )}} {{"\n"}} - + {{ print_tables("section", ["ok", "#Speed", "error", "#Speed"], True )}} {{"\n"}} ' diff --git a/include/dns_decoder.h b/include/dns_decoder.h index 6c4113e..3892d12 100644 --- a/include/dns_decoder.h +++ b/include/dns_decoder.h @@ -273,6 +273,8 @@ struct dns_query_question 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); diff --git a/src/dns_decoder.cpp b/src/dns_decoder.cpp index 4905642..f726d53 100644 --- a/src/dns_decoder.cpp +++ b/src/dns_decoder.cpp @@ -50,7 +50,8 @@ extern "C" #define TAG_KEY_MESSAGE_TYPE "message_type" #define TAG_KEY_MESSAGE_STATUS "message_status" -#define TAG_KEY_DECODE_FIELD "decode_field" +#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" @@ -92,6 +93,8 @@ struct dns_message uint8_t *payload; size_t payload_sz; size_t payload_offset; + struct session *ss; + struct dns_decoder_plugin_env *plugin_env; }; struct dns_decoder_stat @@ -1133,6 +1136,7 @@ void dns_message_free(struct session *ss, void *expr_str, void *msg_free_arg) msg->magic=0; msg->type=DNS_MESSAGE_MAX; + msg->ss=NULL; msg->payload=NULL; msg->payload_sz=0; msg->payload_offset=0; @@ -1205,6 +1209,7 @@ void dns_decoder_entry(struct session *ss, uint8_t *payload, size_t payload_sz, 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; data_msg->n_real_authority_rr=0; data_msg->n_real_additional_rr=0; @@ -1222,17 +1227,18 @@ void dns_decoder_entry(struct session *ss, uint8_t *payload, size_t payload_sz, data_msg->type=((dns_hdr.qr==0) ? DNS_MESSAGE_QUERY : DNS_MESSAGE_RESPONSE); 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"}; ret=dns_query_question_decode(&(data_msg->question), payload, payload_sz, &payload_offset); if(retss=ss; data_msg->payload=payload; data_msg->payload_sz=payload_sz; data_msg->payload_offset=payload_offset; @@ -1519,7 +1526,7 @@ int32_t dns_decoder_config_load(const char *cfg_path, struct dns_decoder_plugin_ toml_table_t *decoder_tbl=toml_table_in(root, "decoder"); if(NULL==decoder_tbl) { - fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.dns]", __FUNCTION__, __LINE__, cfg_path); + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder]", __FUNCTION__, __LINE__, cfg_path); toml_free(root); return -1; } @@ -1567,7 +1574,7 @@ int32_t dns_decoder_config_load(const char *cfg_path, struct dns_decoder_plugin_ toml_table_t *limited_tbl=toml_table_in(dns_tbl, "limited"); if(NULL==limited_tbl) { - fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.limited]", __FUNCTION__, __LINE__, cfg_path); + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.dns.limited]", __FUNCTION__, __LINE__, cfg_path); toml_free(root); return -1; } @@ -1726,6 +1733,7 @@ extern "C" void *dns_decoder_init(struct stellar *st) plugin_env->per_thread_data_msg=(struct dns_message *)CALLOC(struct dns_message, thread_count); for(int32_t i=0; iper_thread_data_msg[i].plugin_env=plugin_env; plugin_env->per_thread_data_msg[i].rr_capacity_sz=plugin_env->max_rr_num; plugin_env->per_thread_data_msg[i].rr_capacity=(struct dns_resource_record *)CALLOC(struct dns_resource_record, plugin_env->max_rr_num); } @@ -1802,18 +1810,23 @@ extern "C" void dns_decoder_exit(void *plugin_env_str) plugin_env->per_thread_data_msg=NULL; } - // if(plugin_env->per_thread_trans_new!=NULL) - // { - // FREE(plugin_env->per_thread_trans_new); - // plugin_env->per_thread_trans_new=NULL; - // } - FREE(plugin_env_str); } +int32_t dns_message_transaction_index_get(struct dns_message *msg) +{ + if(NULL==msg || msg->magic!=DNS_MESSAGE_MAGIC) + { + return -1; + } + + return msg->current_trans_idx; +} + enum dns_message_type dns_message_type_get(struct dns_message *msg) { - if (NULL==msg) { + if(NULL==msg) + { return DNS_MESSAGE_MAX; } @@ -1822,7 +1835,7 @@ enum dns_message_type dns_message_type_get(struct dns_message *msg) int32_t dns_message_header_id_get(struct dns_message *msg) { - if (NULL==msg || msg->magic!=DNS_MESSAGE_MAGIC) + if(NULL==msg || msg->magic!=DNS_MESSAGE_MAGIC || msg->type==DNS_MESSAGE_TRANSACTION_BEGIN || msg->type==DNS_MESSAGE_TRANSACTION_END) { return -1; } @@ -1832,7 +1845,7 @@ int32_t dns_message_header_id_get(struct dns_message *msg) struct dns_flag *dns_message_header_flag_get0(struct dns_message *msg) { - if (NULL==msg || msg->magic!=DNS_MESSAGE_MAGIC) + if(NULL==msg || msg->magic!=DNS_MESSAGE_MAGIC || msg->type==DNS_MESSAGE_TRANSACTION_BEGIN || msg->type==DNS_MESSAGE_TRANSACTION_END) { return NULL; } @@ -1842,8 +1855,10 @@ 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) { - if(msg==NULL || msg->magic!=DNS_MESSAGE_MAGIC) + if(msg==NULL || msg->magic!=DNS_MESSAGE_MAGIC || msg->type==DNS_MESSAGE_TRANSACTION_BEGIN || msg->type==DNS_MESSAGE_TRANSACTION_END || msg->n_question==0) { + (*question)=NULL; + (*n_question)=0; return ; } @@ -1877,6 +1892,25 @@ int32_t dns_resource_record_buff_get0(struct dns_resource_record *rr_capacity, i int32_t dns_message_resource_record_serialize(struct dns_message *msg) { + if(msg==NULL || msg->magic!=DNS_MESSAGE_MAGIC) + { + 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}; + + 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"}; + 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; + } + switch(msg->decode_rr_status) { case DNS_RR_STATUS_INIT: @@ -1889,8 +1923,21 @@ int32_t dns_message_resource_record_serialize(struct dns_message *msg) abort(); } + if(msg->payload_offset>=msg->payload_sz) + { + msg->answer_rr=NULL; + msg->n_real_answer_rr=0; + msg->authority_rr=NULL; + msg->n_real_authority_rr=0; + msg->additional_rr=NULL; + msg->n_real_additional_rr=0; + msg->decode_rr_status=DNS_RR_STATUS_SUCCESS; + return DNS_DECODER_TRUE; + } + if(msg->n_answer_rr>0) { + const char *tag_value[tag_offset]={ip_version, ip_protocol, ((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) @@ -1898,12 +1945,17 @@ int32_t dns_message_resource_record_serialize(struct dns_message *msg) msg->answer_rr=NULL; msg->n_real_answer_rr=0; msg->decode_rr_status=DNS_RR_STATUS_FAILURE; + + 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; } + + dns_decoder_local_file_counter_incby(msg->plugin_env, LOCAL_STAT_COUNTER_OK, tag_key, tag_value, tag_offset, 1, session_get_current_thread_id(msg->ss)); } if(msg->n_authority_rr>0) { + const char *tag_value[tag_offset]={ip_version, ip_protocol, ((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) @@ -1911,12 +1963,17 @@ int32_t dns_message_resource_record_serialize(struct dns_message *msg) msg->authority_rr=NULL; msg->n_real_authority_rr=0; msg->decode_rr_status=DNS_RR_STATUS_FAILURE; + + 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; } + + dns_decoder_local_file_counter_incby(msg->plugin_env, LOCAL_STAT_COUNTER_OK, tag_key, tag_value, tag_offset, 1, session_get_current_thread_id(msg->ss)); } if(msg->n_additional_rr>0) { + const char *tag_value[tag_offset]={ip_version, ip_protocol, ((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) @@ -1924,8 +1981,11 @@ int32_t dns_message_resource_record_serialize(struct dns_message *msg) msg->additional_rr=NULL; msg->n_real_additional_rr=0; msg->decode_rr_status=DNS_RR_STATUS_FAILURE; + 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; } + + dns_decoder_local_file_counter_incby(msg->plugin_env, LOCAL_STAT_COUNTER_OK, tag_key, tag_value, tag_offset, 1, session_get_current_thread_id(msg->ss)); } msg->decode_rr_status=DNS_RR_STATUS_SUCCESS; @@ -1934,11 +1994,6 @@ int32_t dns_message_resource_record_serialize(struct dns_message *msg) void dns_message_answer_resource_record_get0(struct dns_message *msg, struct dns_resource_record **answer_rr, uint16_t *n_answer_rr) { - if(msg==NULL || msg->magic!=DNS_MESSAGE_MAGIC) - { - return ; - } - int32_t ret=dns_message_resource_record_serialize(msg); (*answer_rr)=((ret==DNS_DECODER_TRUE) ? msg->answer_rr : NULL); (*n_answer_rr)=((ret==DNS_DECODER_TRUE) ? msg->n_real_answer_rr : 0); @@ -1946,11 +2001,6 @@ void dns_message_answer_resource_record_get0(struct dns_message *msg, struct dns void dns_message_authority_resource_record_get0(struct dns_message *msg, struct dns_resource_record **authority_rr, uint16_t *n_authority_rr) { - if(msg==NULL || msg->magic!=DNS_MESSAGE_MAGIC) - { - return ; - } - int32_t ret=dns_message_resource_record_serialize(msg); (*authority_rr)=((ret==DNS_DECODER_TRUE) ? msg->authority_rr : NULL); (*n_authority_rr)=((ret==DNS_DECODER_TRUE) ? msg->n_real_authority_rr : 0); @@ -1958,11 +2008,6 @@ void dns_message_authority_resource_record_get0(struct dns_message *msg, struct void dns_message_additional_resource_record_get0(struct dns_message *msg, struct dns_resource_record **additional_rr, uint16_t *n_additional_rr) { - if(msg==NULL || msg->magic!=DNS_MESSAGE_MAGIC) - { - return ; - } - int32_t ret=dns_message_resource_record_serialize(msg); (*additional_rr)=((ret==DNS_DECODER_TRUE) ? msg->additional_rr : NULL); (*n_additional_rr)=((ret==DNS_DECODER_TRUE) ? msg->n_real_additional_rr : 0); diff --git a/src/version.map b/src/version.map index 6a4c8ec..056069e 100644 --- a/src/version.map +++ b/src/version.map @@ -10,6 +10,7 @@ global: *dns_message_answer_resource_record_get0*; *dns_message_authority_resource_record_get0*; *dns_message_additional_resource_record_get0*; + *dns_message_transaction_index_get*; *GIT*; }; local: *; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 35c4e4b..bef97c4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,4 +1,7 @@ -add_library(${PROJECT_NAME}_test_plug SHARED dns_decoder_test.cpp) +include_directories(${PROJECT_SOURCE_DIR}/deps/) +aux_source_directory(${PROJECT_SOURCE_DIR}/deps/toml DEPS_SRC) + +add_library(${PROJECT_NAME}_test_plug SHARED dns_decoder_test.cpp ${DEPS_SRC}) add_dependencies(${PROJECT_NAME}_test_plug ${PROJECT_NAME}) target_link_libraries(${PROJECT_NAME}_test_plug MESA_prof_load cjson) set_target_properties(${PROJECT_NAME}_test_plug PROPERTIES PREFIX "") diff --git a/test/dns_decoder_test.cpp b/test/dns_decoder_test.cpp index 87ff3d3..aec2e21 100644 --- a/test/dns_decoder_test.cpp +++ b/test/dns_decoder_test.cpp @@ -13,6 +13,7 @@ extern "C" #include "cJSON.h" #include "dns_decoder.h" +#include "toml/toml.h" #include "stellar/stellar.h" #include "stellar/session.h" @@ -22,11 +23,14 @@ extern "C" } #endif +#define DNS_DECODER_TEST_TOML_PATH "./etc/dns/dns_decoder.toml" + struct dns_decoder_test_plugin_env { int plugin_id; int topic_id; int result_index; + int commit_result_enable; }; extern "C" int commit_test_result_json(cJSON *node, const char *name); @@ -327,7 +331,14 @@ void dns_decoder_test_message_cb(struct session *ss, int topic_id, const void *m dns_real_result_write_file(real_result_str); free(real_result_str); - commit_test_result_json(real_result, result_name); + if(plugin_env->commit_result_enable==1) + { + commit_test_result_json(real_result, result_name); + } + else + { + cJSON_Delete(real_result); + } } void *dns_decoder_test_per_session_context_new(struct session *sess, void *plugin_env) @@ -340,10 +351,81 @@ void dns_decoder_test_per_session_context_free(struct session *sess, void *sessi } + +int32_t dns_decoder_test_config_load(const char *cfg_path, struct dns_decoder_test_plugin_env *plugin_env) +{ + FILE *fp=fopen(cfg_path, "r"); + if (NULL==fp) + { + fprintf(stderr, "[%s:%d] Can't open config file: %s", __FUNCTION__, __LINE__, cfg_path); + return -1; + } + + int32_t ret=0; + char errbuf[256]={0}; + + toml_table_t *root=toml_parse_file(fp, errbuf, sizeof(errbuf)); + fclose(fp); + + toml_table_t *decoder_tbl=toml_table_in(root, "decoder"); + if(NULL==decoder_tbl) + { + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder]", __FUNCTION__, __LINE__, cfg_path); + toml_free(root); + return -1; + } + + toml_table_t *dns_tbl=toml_table_in(decoder_tbl, "dns"); + if(NULL==dns_tbl) + { + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.dns]", __FUNCTION__, __LINE__, cfg_path); + toml_free(root); + return -1; + } + + toml_table_t *test_tbl=toml_table_in(dns_tbl, "test"); + if(NULL==test_tbl) + { + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.dns.test]", __FUNCTION__, __LINE__, cfg_path); + toml_free(root); + return -1; + } + + toml_datum_t commit_result_enable_val=toml_string_in(test_tbl, "commit_result_enable"); + if(commit_result_enable_val.ok==0) + { + plugin_env->commit_result_enable=0; + fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.dns.test.commit_result_enable]", __FUNCTION__, __LINE__, cfg_path); + } + else + { + if(memcmp("no", commit_result_enable_val.u.s, strlen("no"))==0) + { + plugin_env->commit_result_enable=0; + } + else if(memcmp("yes", commit_result_enable_val.u.s, strlen("yes"))==0) + { + plugin_env->commit_result_enable=1; + } + else + { + plugin_env->commit_result_enable=1; + fprintf(stderr, "[%s:%d] config file: %s key: [decoder.dns.test.commit_result_enable] value is not yes or no", __FUNCTION__, __LINE__, cfg_path); + } + + } + + toml_free(root); + + return ret; +} + extern "C" void *dns_decoder_test_init(struct stellar *st) { struct dns_decoder_test_plugin_env *plugin_env=(struct dns_decoder_test_plugin_env *)calloc(1, sizeof(struct dns_decoder_test_plugin_env)); + plugin_env->result_index=1; + dns_decoder_test_config_load(DNS_DECODER_TEST_TOML_PATH, plugin_env); plugin_env->plugin_id=stellar_session_plugin_register(st, dns_decoder_test_per_session_context_new, dns_decoder_test_per_session_context_free, plugin_env); if(plugin_env->plugin_id<0)