|
|
|
|
@@ -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(ret<DNS_DECODER_FALSE)
|
|
|
|
|
{
|
|
|
|
|
dns_message_free(ss, data_msg, NULL);
|
|
|
|
|
|
|
|
|
|
size_t tag_offset=3;
|
|
|
|
|
const char *tag_key[tag_offset]={TAG_KEY_IP_VERSION, TAG_KEY_IP_PROTOCOL, TAG_KEY_DECODE_FIELD};
|
|
|
|
|
const char *tag_value[tag_offset]={ip_version, ip_protocol, "question"};
|
|
|
|
|
dns_decoder_local_file_counter_incby(plugin_env, LOCAL_STAT_COUNTER_ERROR, tag_key, tag_value, tag_offset, 1, session_get_current_thread_id(ss));
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dns_decoder_local_file_counter_incby(plugin_env, LOCAL_STAT_COUNTER_OK, tag_key, tag_value, tag_offset, 1, session_get_current_thread_id(ss));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct dns_transaction *current_trans=NULL;
|
|
|
|
|
@@ -1266,6 +1272,7 @@ void dns_decoder_entry(struct session *ss, uint8_t *payload, size_t payload_sz,
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data_msg->ss=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; i<thread_count; i++)
|
|
|
|
|
{
|
|
|
|
|
plugin_env->per_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);
|
|
|
|
|
|