mirror of
https://github.com/sogou/workflow.git
synced 2026-02-08 01:33:17 +08:00
tutorial-17-dns_client
This commit is contained in:
@@ -42,6 +42,7 @@ set(TUTORIAL_LIST
|
||||
tutorial-09-http_file_server
|
||||
tutorial-11-graph_task
|
||||
tutorial-15-name_service
|
||||
tutorial-17-dns_client
|
||||
tutorial-20-reducer
|
||||
)
|
||||
|
||||
|
||||
163
tutorial/tutorial-17-dns_cli.cc
Normal file
163
tutorial/tutorial-17-dns_cli.cc
Normal file
@@ -0,0 +1,163 @@
|
||||
#include <cstdio>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
#include "workflow/DnsUtil.h"
|
||||
#include "workflow/WFDnsClient.h"
|
||||
#include "workflow/WFFacilities.h"
|
||||
|
||||
static const std::map<std::string, int> qtype_map =
|
||||
{
|
||||
{"A", DNS_TYPE_A },
|
||||
{"AAAA", DNS_TYPE_AAAA },
|
||||
{"CNAME", DNS_TYPE_CNAME },
|
||||
{"SOA", DNS_TYPE_SOA },
|
||||
{"NS", DNS_TYPE_NS },
|
||||
{"SRV", DNS_TYPE_SRV },
|
||||
{"MX", DNS_TYPE_MX }
|
||||
};
|
||||
WFFacilities::WaitGroup wait_group(1);
|
||||
|
||||
void show_result(protocol::DnsResultCursor &cursor)
|
||||
{
|
||||
char information[1024];
|
||||
const char *info;
|
||||
struct dns_record *record;
|
||||
struct dns_record_soa *soa;
|
||||
struct dns_record_srv *srv;
|
||||
struct dns_record_mx *mx;
|
||||
|
||||
while(cursor.next(&record))
|
||||
{
|
||||
switch (record->type)
|
||||
{
|
||||
case DNS_TYPE_A:
|
||||
info = inet_ntop(AF_INET, record->rdata, information, 64);
|
||||
break;
|
||||
case DNS_TYPE_AAAA:
|
||||
info = inet_ntop(AF_INET6, record->rdata, information, 64);
|
||||
break;
|
||||
case DNS_TYPE_NS:
|
||||
case DNS_TYPE_CNAME:
|
||||
case DNS_TYPE_PTR:
|
||||
info = (const char *)(record->rdata);
|
||||
break;
|
||||
case DNS_TYPE_SOA:
|
||||
soa = (struct dns_record_soa *)(record->rdata);
|
||||
sprintf(information, "%s %s %u %d %d %d %u",
|
||||
soa->mname, soa->rname, soa->serial, soa->refresh,
|
||||
soa->retry, soa->expire, soa->minimum
|
||||
);
|
||||
info = information;
|
||||
break;
|
||||
case DNS_TYPE_SRV:
|
||||
srv = (struct dns_record_srv *)(record->rdata);
|
||||
sprintf(information, "%u %u %u %s",
|
||||
srv->priority, srv->weight, srv->port, srv->target
|
||||
);
|
||||
info = information;
|
||||
break;
|
||||
case DNS_TYPE_MX:
|
||||
mx = (struct dns_record_mx *)(record->rdata);
|
||||
sprintf(information, "%d %s", mx->preference, mx->exchange);
|
||||
info = information;
|
||||
break;
|
||||
default:
|
||||
info = "Unknown";
|
||||
}
|
||||
|
||||
printf("%s\t%d\t%s\t%s\t%s\n",
|
||||
record->name, record->ttl,
|
||||
dns_class2str(record->rclass),
|
||||
dns_type2str(record->type),
|
||||
info
|
||||
);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void dns_callback(WFDnsTask *task)
|
||||
{
|
||||
int state = task->get_state();
|
||||
int error = task->get_error();
|
||||
auto *resp = task->get_resp();
|
||||
|
||||
if (state != WFT_STATE_SUCCESS)
|
||||
{
|
||||
printf("State: %d, Error: %d\n", state, error);
|
||||
printf("Error: %s\n", WFGlobal::get_error_string(state, error));
|
||||
wait_group.done();
|
||||
return;
|
||||
}
|
||||
|
||||
printf("; Workflow DNSResolver\n");
|
||||
printf(";; HEADER opcode:%s status:%s id:%d\n",
|
||||
dns_opcode2str(resp->get_opcode()),
|
||||
dns_rcode2str(resp->get_rcode()),
|
||||
resp->get_id()
|
||||
);
|
||||
printf(";; QUERY:%d ANSWER:%d AUTHORITY:%d ADDITIONAL:%d\n",
|
||||
resp->get_qdcount(), resp->get_ancount(),
|
||||
resp->get_nscount(), resp->get_arcount()
|
||||
);
|
||||
|
||||
printf("\n");
|
||||
|
||||
protocol::DnsResultCursor cursor(resp);
|
||||
if(resp->get_ancount() > 0)
|
||||
{
|
||||
cursor.reset_answer_cursor();
|
||||
printf(";; ANSWER SECTION:\n");
|
||||
show_result(cursor);
|
||||
}
|
||||
if(resp->get_nscount() > 0)
|
||||
{
|
||||
cursor.reset_authority_cursor();
|
||||
printf(";; AUTHORITY SECTION\n");
|
||||
show_result(cursor);
|
||||
}
|
||||
if(resp->get_arcount() > 0)
|
||||
{
|
||||
cursor.reset_additional_cursor();
|
||||
printf(";; ADDITIONAL SECTION\n");
|
||||
show_result(cursor);
|
||||
}
|
||||
|
||||
wait_group.done();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *domain = "www.sogou.com";
|
||||
int qtype = DNS_TYPE_ALL;
|
||||
|
||||
if (argc > 3)
|
||||
{
|
||||
fprintf(stderr, "USAGE: %s <domain> <query type>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc > 1)
|
||||
domain = argv[1];
|
||||
|
||||
if (argc > 2)
|
||||
{
|
||||
auto it = qtype_map.find(argv[2]);
|
||||
if (it != qtype_map.end())
|
||||
qtype = it->second;
|
||||
}
|
||||
|
||||
std::string url = "dns://119.29.29.29/";
|
||||
WFDnsTask *task = WFTaskFactory::create_dns_task(url, 0, dns_callback);
|
||||
|
||||
protocol::DnsRequest *req = task->get_req();
|
||||
req->set_rd(1);
|
||||
req->set_question(domain, qtype, DNS_CLASS_IN);
|
||||
|
||||
task->start();
|
||||
|
||||
wait_group.wait();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user