This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
stellar-dns-decoder/test/dns_decoder_test.cpp
2024-06-19 10:49:21 +00:00

328 lines
9.7 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <assert.h>
#ifdef __cplusplus
extern "C"
{
#include "cJSON.h"
#include "dns_decoder.h"
#include "toml/toml.h"
#include "stellar/stellar.h"
#include "stellar/session.h"
#include "stellar/session_exdata.h"
#include "stellar/session_mq.h"
}
#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;
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)
{
FILE *fp=fopen("dns_real_result.json", "a+");
if(fp!=NULL)
{
fwrite(result_str, 1, strlen(result_str), fp);
fclose(fp);
}
}
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;
enum dns_message_type type=dns_message_type_get(dns_msg);
if(type==DNS_MESSAGE_TRANSACTION_BEGIN || type==DNS_MESSAGE_TRANSACTION_END)
{
return;
}
//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));
uint16_t n_question=0;
struct dns_query_question *question=NULL;
dns_message_query_question_get0(dns_msg, &question, &n_question);
if(n_question>0 && question!=NULL)
{
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);
if(flag!=NULL)
{
cJSON_AddNumberToObject(real_result, "dns_qr", (double)(flag->qr));
cJSON_AddNumberToObject(real_result, "dns_opcode", (double)(flag->opcode));
cJSON_AddNumberToObject(real_result, "dns_rd", (double)(flag->rd));
}
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_Parse(answer);
cJSON_AddItemToObject(rr_array, "answer", rr_object);
free((void *)answer);
}
if(authority!=NULL)
{
cJSON *rr_object=cJSON_Parse(authority);
cJSON_AddItemToObject(rr_array, "authority", rr_object);
free((void *)authority);
}
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
{
cJSON_Delete(real_result);
}
}
void *dns_decoder_test_per_session_context_new(struct session *sess, void *plugin_env)
{
return NULL;
}
void dns_decoder_test_per_session_context_free(struct session *sess, void *session_ctx, void *plugin_env)
{
}
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_datum_t write_result_enable_val=toml_string_in(test_tbl, "write_result_enable");
if(write_result_enable_val.ok==0)
{
plugin_env->write_result_enable=0;
fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.dns.test.write_result_enable]", __FUNCTION__, __LINE__, cfg_path);
}
else
{
if(memcmp("no", write_result_enable_val.u.s, strlen("no"))==0)
{
plugin_env->write_result_enable=0;
}
else if(memcmp("yes", write_result_enable_val.u.s, strlen("yes"))==0)
{
plugin_env->write_result_enable=1;
}
else
{
plugin_env->write_result_enable=1;
fprintf(stderr, "[%s:%d] config file: %s key: [decoder.dns.test.write_result_enable] value is not yes or no", __FUNCTION__, __LINE__, cfg_path);
}
}
// decode_resource_record_enable
toml_datum_t decode_resource_record_enable_val=toml_string_in(test_tbl, "decode_resource_record_enable");
if(decode_resource_record_enable_val.ok==0)
{
plugin_env->decode_resource_record_enable=0;
fprintf(stderr, "[%s:%d] config file: %s has no key: [decoder.dns.test.decode_resource_record_enable]", __FUNCTION__, __LINE__, cfg_path);
}
else
{
if(memcmp("no", decode_resource_record_enable_val.u.s, strlen("no"))==0)
{
plugin_env->decode_resource_record_enable=0;
}
else if(memcmp("yes", decode_resource_record_enable_val.u.s, strlen("yes"))==0)
{
plugin_env->decode_resource_record_enable=1;
}
else
{
plugin_env->decode_resource_record_enable=1;
fprintf(stderr, "[%s:%d] config file: %s key: [decoder.dns.test.decode_resource_record_enable] value is not yes or no", __FUNCTION__, __LINE__, cfg_path);
}
}
// 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;
}
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)
{
printf("dns_decoder_test_init: stellar_plugin_register failed !!!\n");
exit(-1);
}
plugin_env->topic_id=stellar_session_mq_get_topic_id(st, DNS_MESSAGE_TOPIC);
if(plugin_env->topic_id<0)
{
printf("stellar_session_mq_get_topic_id failed, topic: %s \n", DNS_MESSAGE_TOPIC);
exit(-1);
}
stellar_session_mq_subscribe(st, plugin_env->topic_id, dns_decoder_test_message_cb, plugin_env->plugin_id);
return (void *)plugin_env;
}
extern "C" void dns_decoder_test_exit(void *plugin_env_str)
{
if(plugin_env_str!=NULL)
{
free(plugin_env_str);
}
}