mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-30 02:47:56 +08:00
test dns module
This commit is contained in:
parent
845338db4a
commit
c21cc6c733
@ -151,7 +151,7 @@ ACL_API int acl_rfc1035_query_compare(const ACL_RFC1035_QUERY *a,
|
||||
/**
|
||||
* Takes the contents of a DNS reply and fills in an array
|
||||
* of resource record structures. The records array is allocated
|
||||
* here, and should be freed by calling RFC1035RRDestroy().
|
||||
* here, and should be freed by calling acl_rfc1035_message_destroy().
|
||||
* @param buf {const char*} the data of the DNS reply
|
||||
* @param sz {size_t} the buf's size
|
||||
* @return {ACL_RFC1035_MESSAGE*} return the parsing result
|
||||
@ -161,7 +161,7 @@ ACL_API ACL_RFC1035_MESSAGE *acl_rfc1035_response_unpack(const char *buf, size_t
|
||||
/**
|
||||
* Takes the contents of a DNS request and fills in an array
|
||||
* of resource record structures. The records array is allocated
|
||||
* here, and should be freed by calling RFC1035RRDestroy().
|
||||
* here, and should be freed by calling acl_rfc1035_message_destroy().
|
||||
* @param buf {const char*} the data of the DNS reply
|
||||
* @param sz {size_t} the buf's size
|
||||
* @return {ACL_RFC1035_MESSAGE*} return the parsing result
|
||||
|
@ -898,7 +898,6 @@ ACL_RFC1035_MESSAGE *acl_rfc1035_request_unpack(const char *buf, size_t sz)
|
||||
}
|
||||
|
||||
return msg;
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
@ -1075,7 +1074,7 @@ size_t acl_rfc1035_build_reply(const ACL_RFC1035_REPLY *reply, char *buf, size_t
|
||||
|
||||
for (i = 0; i < reply->ips->argc; i++) {
|
||||
memset(&rr, 0, sizeof(rr));
|
||||
snprintf(rr.name, sizeof(rr.name), "%s", reply->hostname);
|
||||
ACL_SAFE_STRNCPY(rr.name, reply->hostname, sizeof(rr.name));
|
||||
rr.type = reply->ip_type;
|
||||
rr.tclass = ACL_RFC1035_CLASS_IN;
|
||||
rr.ttl = reply->ttl;
|
||||
@ -1092,7 +1091,7 @@ size_t acl_rfc1035_build_reply(const ACL_RFC1035_REPLY *reply, char *buf, size_t
|
||||
|
||||
if (h.nscount) {
|
||||
memset(&rr, 0, sizeof(rr));
|
||||
snprintf(rr.name, sizeof(rr.name), "%s", reply->domain_root);
|
||||
ACL_SAFE_STRNCPY(rr.name, reply->domain_root, sizeof(rr.name));
|
||||
rr.type = ACL_RFC1035_TYPE_NS;
|
||||
rr.tclass = ACL_RFC1035_CLASS_IN;
|
||||
rr.ttl = reply->ttl;
|
||||
@ -1104,7 +1103,7 @@ size_t acl_rfc1035_build_reply(const ACL_RFC1035_REPLY *reply, char *buf, size_t
|
||||
|
||||
if (h.arcount) {
|
||||
memset(&rr, 0, sizeof(rr));
|
||||
snprintf(rr.name, sizeof(rr.name), "%s", reply->dns_name);
|
||||
ACL_SAFE_STRNCPY(rr.name, reply->dns_name, sizeof(rr.name));
|
||||
rr.type = reply->ip_type;
|
||||
rr.tclass = ACL_RFC1035_CLASS_IN;
|
||||
rr.ttl = reply->ttl;
|
||||
|
@ -479,11 +479,8 @@ static struct addrinfo *ns_lookup(const char *ip, unsigned short port,
|
||||
if (ret == -1) {
|
||||
break;
|
||||
}
|
||||
ret = rfc1035_message_unpack(buf, ret, &message);
|
||||
if (ret <= 0) {
|
||||
if (message) {
|
||||
rfc1035_message_destroy(message);
|
||||
}
|
||||
message = rfc1035_response_unpack(buf, ret);
|
||||
if (message == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -10,10 +10,11 @@
|
||||
|
||||
#include "common/strops.h"
|
||||
#include "common/msg.h"
|
||||
#include "common/argv.h"
|
||||
#include "rfc1035.h"
|
||||
|
||||
#define RFC1035_MAXLABELSZ 63
|
||||
#define RFC1035_unpack_error 15
|
||||
#define RFC1035_UNPACK_ERROR 15
|
||||
|
||||
#if 0
|
||||
#define RFC1035_UNPACK_DEBUG msg_error("unpack error at %s:%d", __FILE__,__LINE__)
|
||||
@ -195,13 +196,13 @@ static int rfc1035_name_unpack(const char *buf, size_t sz, size_t *off,
|
||||
|
||||
if (ns <= 0) {
|
||||
msg_error("%s: ns(%d) <= 0", myname, (int) ns);
|
||||
return -RFC1035_unpack_error;
|
||||
return -RFC1035_UNPACK_ERROR;
|
||||
}
|
||||
do {
|
||||
if (*off >= sz) {
|
||||
msg_error("%s: *off(%d) >= sz(%d)",
|
||||
myname, (int) *off, (int) sz);
|
||||
return -RFC1035_unpack_error;
|
||||
return -RFC1035_UNPACK_ERROR;
|
||||
}
|
||||
c = *(buf + (*off));
|
||||
if (c > 191) {
|
||||
@ -260,7 +261,7 @@ static int rfc1035_name_unpack(const char *buf, size_t sz, size_t *off,
|
||||
/* make sure we didn't allow someone to overflow the name buffer */
|
||||
if (no > (int) ns) {
|
||||
msg_error("%s: no(%d) > ns(%d)", myname, no, (int) ns);
|
||||
return -RFC1035_unpack_error;
|
||||
return -RFC1035_UNPACK_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -282,7 +283,7 @@ const char *rfc1035_strerror(int errnum)
|
||||
"not support the requested kind of query." },
|
||||
{ 5, "Refused: The name server refuses to "
|
||||
"perform the specified operation." },
|
||||
{ RFC1035_unpack_error, "The DNS reply message is corrupt or could "
|
||||
{ RFC1035_UNPACK_ERROR, "The DNS reply message is corrupt or could "
|
||||
"not be safely parsed." },
|
||||
{ -1, NULL },
|
||||
};
|
||||
@ -345,48 +346,48 @@ int rfc1035_query_compare(const RFC1035_QUERY * a, const RFC1035_QUERY * b)
|
||||
*
|
||||
* Returns > 0 (success) or 0 (error)
|
||||
*/
|
||||
static int rfc1035_rr_pack(const RFC1035_RR *RR, char *buf, size_t sz)
|
||||
static int rfc1035_rr_pack(const RFC1035_RR *rr, char *buf, size_t sz)
|
||||
{
|
||||
const char *myname = "rfc1035_rr_pack";
|
||||
unsigned short s;
|
||||
unsigned int i;
|
||||
int off = 0, off_saved;
|
||||
|
||||
off = rfc1035_name_pack(buf + off, sz, RR->name);
|
||||
s = htons(RR->type);
|
||||
off = rfc1035_name_pack(buf + off, sz, rr->name);
|
||||
s = htons(rr->type);
|
||||
memcpy(buf + off, &s,sizeof(s));
|
||||
off += sizeof(s);
|
||||
|
||||
s = htons(RR->tclass);
|
||||
s = htons(rr->tclass);
|
||||
memcpy(buf + off, &s ,sizeof(s));
|
||||
off += sizeof(s);
|
||||
|
||||
i = htonl(RR->ttl);
|
||||
i = htonl(rr->ttl);
|
||||
memcpy(buf + off, &i ,sizeof(i));
|
||||
off += sizeof(i);
|
||||
|
||||
switch (RR->type) {
|
||||
switch (rr->type) {
|
||||
case RFC1035_TYPE_PTR:
|
||||
case RFC1035_TYPE_NS:
|
||||
case RFC1035_TYPE_CNAME:
|
||||
case RFC1035_TYPE_TXT:
|
||||
if (strlen(RR->rdata) > RFC1035_MAXHOSTNAMESZ) {
|
||||
if (strlen(rr->rdata) > RFC1035_MAXHOSTNAMESZ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
off_saved = off;
|
||||
off += sizeof(s);
|
||||
off += rfc1035_name_pack(buf + off, sz, RR->rdata);
|
||||
off += rfc1035_name_pack(buf + off, sz, rr->rdata);
|
||||
s = off - off_saved - (unsigned short) sizeof(s);
|
||||
s = htons(s);
|
||||
memcpy(buf + off_saved, &s ,sizeof(s));
|
||||
break;
|
||||
default:
|
||||
s = htons(RR->rdlength);
|
||||
s = htons(rr->rdlength);
|
||||
memcpy(buf + off, &s ,sizeof(s));
|
||||
off += sizeof(s);
|
||||
memcpy(buf + off, RR->rdata, RR->rdlength);
|
||||
off += RR->rdlength;
|
||||
memcpy(buf + off, rr->rdata, rr->rdlength);
|
||||
off += rr->rdlength;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -529,7 +530,7 @@ static int rfc1035_header_unpack(const char *buf, size_t sz, size_t *off,
|
||||
|
||||
if (*off != 0) {
|
||||
msg_error("%s: *off(%d) != 0", myname, (int) *off);
|
||||
return -RFC1035_unpack_error;
|
||||
return -RFC1035_UNPACK_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -579,7 +580,7 @@ static int rfc1035_header_unpack(const char *buf, size_t sz, size_t *off,
|
||||
|
||||
if (*off != 12) {
|
||||
msg_error("%s: *off(%d) != 12", myname, (int) *off);
|
||||
return -RFC1035_unpack_error;
|
||||
return -RFC1035_UNPACK_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -724,7 +725,7 @@ static int rfc1035_rr_unpack(const char *buf, size_t sz, size_t *off, RFC1035_RR
|
||||
if (*off > sz) {
|
||||
msg_error("%s: *off(%d) > sz(%d)",
|
||||
myname, (int) *off, (int) sz);
|
||||
return -RFC1035_unpack_error;
|
||||
return -RFC1035_UNPACK_ERROR;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -764,45 +765,40 @@ static RFC1035_RR *rfc1035_unpack2rr(const char *buf, size_t sz,
|
||||
return rr;
|
||||
}
|
||||
|
||||
int rfc1035_message_unpack(const char *buf, size_t sz, RFC1035_MESSAGE **answer)
|
||||
RFC1035_MESSAGE *rfc1035_response_unpack(const char *buf, size_t sz)
|
||||
{
|
||||
int i, nr;
|
||||
size_t off = 0;
|
||||
RFC1035_MESSAGE *msg;
|
||||
|
||||
errno = 0;
|
||||
*answer = NULL;
|
||||
msg = (RFC1035_MESSAGE*) calloc(1, sizeof(*msg));
|
||||
|
||||
if (rfc1035_header_unpack(buf + off, sz - off, &off, msg)) {
|
||||
RFC1035_UNPACK_DEBUG;
|
||||
rfc1035_set_errno(RFC1035_unpack_error);
|
||||
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||
rfc1035_message_destroy(msg);
|
||||
*answer = NULL;
|
||||
return -RFC1035_unpack_error;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (msg->rcode) {
|
||||
int ret = -((int) msg->rcode);
|
||||
RFC1035_UNPACK_DEBUG;
|
||||
rfc1035_set_errno((int) msg->rcode);
|
||||
rfc1035_message_destroy(msg);
|
||||
*answer = NULL;
|
||||
return ret;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (msg->ancount == 0) {
|
||||
rfc1035_message_destroy(msg);
|
||||
*answer = NULL;
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (msg->qdcount != 1) {
|
||||
/* This can not be an answer to our queries.. */
|
||||
RFC1035_UNPACK_DEBUG;
|
||||
rfc1035_set_errno(RFC1035_unpack_error);
|
||||
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||
rfc1035_message_destroy(msg);
|
||||
return -RFC1035_unpack_error;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
msg->query = (RFC1035_QUERY*) calloc((int) msg->qdcount,
|
||||
@ -811,9 +807,9 @@ int rfc1035_message_unpack(const char *buf, size_t sz, RFC1035_MESSAGE **answer)
|
||||
for (i = 0; i < (int) msg->qdcount; i++) {
|
||||
if (rfc1035_query_unpack(buf, sz, &off, &msg->query[i])) {
|
||||
RFC1035_UNPACK_DEBUG;
|
||||
rfc1035_set_errno(RFC1035_unpack_error);
|
||||
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||
rfc1035_message_destroy(msg);
|
||||
return -RFC1035_unpack_error;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -826,12 +822,10 @@ int rfc1035_message_unpack(const char *buf, size_t sz, RFC1035_MESSAGE **answer)
|
||||
*/
|
||||
RFC1035_UNPACK_DEBUG;
|
||||
rfc1035_message_destroy(msg);
|
||||
*answer = NULL;
|
||||
rfc1035_set_errno(RFC1035_unpack_error);
|
||||
return -RFC1035_unpack_error;
|
||||
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (msg->nscount > 0) {
|
||||
msg->authority = rfc1035_unpack2rr(buf, sz, &off,
|
||||
msg->nscount, &nr);
|
||||
@ -839,9 +833,8 @@ int rfc1035_message_unpack(const char *buf, size_t sz, RFC1035_MESSAGE **answer)
|
||||
if (msg->authority == NULL) {
|
||||
RFC1035_UNPACK_DEBUG;
|
||||
rfc1035_message_destroy(msg);
|
||||
*answer = NULL;
|
||||
rfc1035_set_errno(RFC1035_unpack_error);
|
||||
return -RFC1035_unpack_error;
|
||||
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -852,14 +845,57 @@ int rfc1035_message_unpack(const char *buf, size_t sz, RFC1035_MESSAGE **answer)
|
||||
if (msg->additional == NULL) {
|
||||
RFC1035_UNPACK_DEBUG;
|
||||
rfc1035_message_destroy(msg);
|
||||
*answer = NULL;
|
||||
rfc1035_set_errno(RFC1035_unpack_error);
|
||||
return -RFC1035_unpack_error;
|
||||
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
*answer = msg;
|
||||
return (int) msg->ancount;
|
||||
return msg;
|
||||
}
|
||||
|
||||
RFC1035_MESSAGE *rfc1035_request_unpack(const char *buf, size_t sz)
|
||||
{
|
||||
int i;
|
||||
size_t off = 0;
|
||||
RFC1035_MESSAGE *msg;
|
||||
|
||||
errno = 0;
|
||||
msg = (RFC1035_MESSAGE*) calloc(1, sizeof(*msg));
|
||||
|
||||
if (rfc1035_header_unpack(buf + off, sz - off, &off, msg)) {
|
||||
RFC1035_UNPACK_DEBUG;
|
||||
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||
rfc1035_message_destroy(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (msg->rcode) {
|
||||
RFC1035_UNPACK_DEBUG;
|
||||
rfc1035_set_errno((int) msg->rcode);
|
||||
rfc1035_message_destroy(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (msg->qdcount != 1) {
|
||||
/* This can not be an answer to our queries.. */
|
||||
RFC1035_UNPACK_DEBUG;
|
||||
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||
rfc1035_message_destroy(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
msg->query = (RFC1035_QUERY*) calloc((int) msg->qdcount,
|
||||
sizeof(RFC1035_QUERY));
|
||||
|
||||
for (i = 0; i < (int) msg->qdcount; i++) {
|
||||
if (rfc1035_query_unpack(buf, sz, &off, &msg->query[i])) {
|
||||
RFC1035_UNPACK_DEBUG;
|
||||
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||
rfc1035_message_destroy(msg);
|
||||
}
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
@ -1004,6 +1040,8 @@ static size_t save_addr2rr(int type, const char *src, RFC1035_RR *rr)
|
||||
}
|
||||
}
|
||||
|
||||
#define SAFE_FREE(x) do { if ((x)) free ((x)); } while(0)
|
||||
|
||||
size_t rfc1035_build_reply(const RFC1035_REPLY *reply, char *buf, size_t sz)
|
||||
{
|
||||
RFC1035_MESSAGE h;
|
||||
@ -1011,6 +1049,11 @@ size_t rfc1035_build_reply(const RFC1035_REPLY *reply, char *buf, size_t sz)
|
||||
size_t offset = 0;
|
||||
int i;
|
||||
|
||||
if (reply->ips == NULL || reply->ips->argc <= 0) {
|
||||
msg_error("ips null");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&h, '\0', sizeof(h));
|
||||
h.id = reply->qid;
|
||||
h.qr = 1; /* response */
|
||||
@ -1031,11 +1074,7 @@ size_t rfc1035_build_reply(const RFC1035_REPLY *reply, char *buf, size_t sz)
|
||||
|
||||
for (i = 0; i < reply->ips->argc; i++) {
|
||||
memset(&rr, 0, sizeof(rr));
|
||||
#ifdef SYS_WIN
|
||||
_snprintf(rr.name, sizeof(rr.name), "%s", reply->hostname);
|
||||
#else
|
||||
snprintf(rr.name, sizeof(rr.name), "%s", reply->hostname);
|
||||
#endif
|
||||
SAFE_STRNCPY(rr.name, reply->hostname, sizeof(rr.name));
|
||||
rr.type = reply->ip_type;
|
||||
rr.tclass = htons(RFC1035_CLASS_IN);
|
||||
rr.ttl = reply->ttl;
|
||||
@ -1047,16 +1086,12 @@ size_t rfc1035_build_reply(const RFC1035_REPLY *reply, char *buf, size_t sz)
|
||||
}
|
||||
|
||||
offset += rfc1035_rr_pack(&rr, buf + offset, sz - offset);
|
||||
free(rr.rdata);
|
||||
SAFE_FREE(rr.rdata);
|
||||
}
|
||||
|
||||
if (h.nscount) {
|
||||
memset(&rr, 0, sizeof(rr));
|
||||
#ifdef SYS_WIN
|
||||
_snprintf(rr.name, sizeof(rr.name), "%s", reply->domain_root);
|
||||
#else
|
||||
snprintf(rr.name, sizeof(rr.name), "%s", reply->domain_root);
|
||||
#endif
|
||||
SAFE_STRNCPY(rr.name, reply->domain_root, sizeof(rr.name));
|
||||
rr.type = RFC1035_TYPE_NS;
|
||||
rr.tclass = RFC1035_CLASS_IN;
|
||||
rr.ttl = reply->ttl;
|
||||
@ -1067,16 +1102,12 @@ size_t rfc1035_build_reply(const RFC1035_REPLY *reply, char *buf, size_t sz)
|
||||
rr.rdata = strdup(reply->dns_name);
|
||||
#endif
|
||||
offset += rfc1035_rr_pack(&rr, buf + offset, sz - offset);
|
||||
free(rr.rdata);
|
||||
SAFE_FREE(rr.rdata);
|
||||
}
|
||||
|
||||
if (h.arcount) {
|
||||
memset(&rr, 0, sizeof(rr));
|
||||
#ifdef SYS_WIN
|
||||
_snprintf(rr.name, sizeof(rr.name), "%s", reply->dns_name);
|
||||
#else
|
||||
snprintf(rr.name, sizeof(rr.name), "%s", reply->dns_name);
|
||||
#endif
|
||||
SAFE_STRNCPY(rr.name, reply->dns_name, sizeof(rr.name));
|
||||
rr.type = reply->ip_type;
|
||||
rr.tclass = RFC1035_CLASS_IN;
|
||||
rr.ttl = reply->ttl;
|
||||
@ -1088,7 +1119,7 @@ size_t rfc1035_build_reply(const RFC1035_REPLY *reply, char *buf, size_t sz)
|
||||
}
|
||||
|
||||
offset += rfc1035_rr_pack(&rr, buf + offset, sz - offset);
|
||||
free(rr.rdata);
|
||||
SAFE_FREE(rr.rdata);
|
||||
}
|
||||
|
||||
return offset;
|
||||
|
@ -5,12 +5,12 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "common/argv.h"
|
||||
|
||||
#ifdef ACL_UNIX
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
struct ARGV;
|
||||
|
||||
/* RFC1035 - DNS */
|
||||
#define RFC1035_MAXHOSTNAMESZ 256
|
||||
|
||||
@ -151,16 +151,24 @@ void rfc1035_set_query_id(char *buf, size_t sz, unsigned short qid);
|
||||
int rfc1035_query_compare(const RFC1035_QUERY *a, const RFC1035_QUERY *b);
|
||||
|
||||
/**
|
||||
* Takes the contents of a DNS reply and fills in an array
|
||||
* Takes the contents of a DNS request and fills in an array
|
||||
* of resource record structures. The records array is allocated
|
||||
* here, and should be freed by calling RFC1035RRDestroy().
|
||||
* here, and should be freed by calling rfc1035_messager_destroy().
|
||||
* @param buf {const char*} the data of the DNS reply
|
||||
* @param sz {size_t} the buf's size
|
||||
* @param answer {RFC1035_MESSAGE*} store the parsing result
|
||||
* @return {int} Returns number of records unpacked, zero if DNS reply
|
||||
* indicates zero answers, or an error number < 0.
|
||||
* @return {RFC1035_MESSAGE*} return the parsing result
|
||||
*/
|
||||
int rfc1035_message_unpack(const char *buf, size_t sz, RFC1035_MESSAGE **answer);
|
||||
RFC1035_MESSAGE *rfc1035_request_unpack(const char *buf, size_t sz);
|
||||
|
||||
/**
|
||||
* Takes the contents of a DNS reply and fills in an array
|
||||
* of resource record structures. The records array is allocated
|
||||
* here, and should be freed by calling rfc1035_messager_destroy().
|
||||
* @param buf {const char*} the data of the DNS reply
|
||||
* @param sz {size_t} the buf's size
|
||||
* @return {RFC1035_MESSAGE*} return the parsing result
|
||||
*/
|
||||
RFC1035_MESSAGE *rfc1035_response_unpack(const char *buf, size_t sz);
|
||||
|
||||
/**
|
||||
* destroy and free the message created by RFC1035MessageUnpack()
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <thread>
|
||||
#include "lib_acl.h"
|
||||
#include "acl_cpp/lib_acl.hpp"
|
||||
#include "fiber/libfiber.h"
|
||||
#include "fiber/go_fiber.hpp"
|
||||
|
||||
static char __dns_ip[256];
|
||||
@ -127,7 +126,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
acl_msg_stdout_enable(1);
|
||||
acl_fiber_msg_stdout_enable(1);
|
||||
acl::fiber::stdout_open(true);
|
||||
|
||||
struct timeval begin;
|
||||
gettimeofday(&begin, NULL);
|
||||
|
3
lib_fiber/samples/dns_server/Makefile
Normal file
3
lib_fiber/samples/dns_server/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
include ../Makefile_cpp.in
|
||||
PROG = dns_server
|
||||
CFLAGS += -std=c++11 -I../../c/src/dns -I../../c/src/common
|
149
lib_fiber/samples/dns_server/main.cpp
Normal file
149
lib_fiber/samples/dns_server/main.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include "acl_cpp/lib_acl.hpp"
|
||||
#include "fiber/go_fiber.hpp"
|
||||
|
||||
#include "rfc1035.h"
|
||||
#include "argv.h"
|
||||
|
||||
static RFC1035_MESSAGE* parse_request(const char* data, size_t len)
|
||||
{
|
||||
RFC1035_MESSAGE *request;
|
||||
request = rfc1035_request_unpack(data, len);
|
||||
if (request == NULL) {
|
||||
logger_error("unpack request error, size=%d", (int) len);
|
||||
return NULL;
|
||||
}
|
||||
RFC1035_QUERY *query = request->query;
|
||||
if (query == NULL || query->name[0] == 0) {
|
||||
rfc1035_message_destroy(request);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf(">>>ask name=%s, query type=%d, class=%d\n",
|
||||
query->name, query->qtype, query->qclass);
|
||||
#endif
|
||||
|
||||
switch (query->qtype) {
|
||||
case RFC1035_TYPE_A:
|
||||
break;
|
||||
case RFC1035_TYPE_AAAA:
|
||||
break;
|
||||
default:
|
||||
logger_error("unsport qtype=%d, qclass=%d",
|
||||
query->qtype, query->qclass);
|
||||
rfc1035_message_destroy(request);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
static size_t build_reply(const RFC1035_MESSAGE* request, char* buf, size_t size)
|
||||
{
|
||||
ARGV* ips = argv_alloc(5);
|
||||
argv_add(ips, "192.168.1.1", NULL);
|
||||
argv_add(ips, "192.168.1.2", NULL);
|
||||
argv_add(ips, "192.168.1.3", NULL);
|
||||
|
||||
RFC1035_REPLY reply;
|
||||
reply.hostname = request->query->name;
|
||||
reply.domain_root = NULL;
|
||||
reply.dns_name = NULL;
|
||||
reply.dns_ip = NULL;
|
||||
reply.ips = ips;
|
||||
|
||||
reply.ip_type = RFC1035_TYPE_A;
|
||||
reply.ttl = 600;
|
||||
reply.qid = request->id;
|
||||
|
||||
size_t n = rfc1035_build_reply(&reply, buf, size);
|
||||
argv_free(ips);
|
||||
return n;
|
||||
}
|
||||
|
||||
static void handle_pkt(acl::socket_stream& stream, const char* data, size_t len)
|
||||
{
|
||||
RFC1035_MESSAGE* request = parse_request(data, len);
|
||||
if (request == NULL) {
|
||||
logger_error("parse request error");
|
||||
return;
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
size_t ret = build_reply(request, buf, sizeof(buf));
|
||||
rfc1035_message_destroy(request);
|
||||
if (!ret) {
|
||||
logger_error("build reply error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stream.write(buf, ret) == -1) {
|
||||
logger_error("write error");
|
||||
}
|
||||
}
|
||||
|
||||
static void dns_server(acl::socket_stream& stream)
|
||||
{
|
||||
char buf[1024];
|
||||
int ret;
|
||||
|
||||
while (true) {
|
||||
ret = stream.read(buf, sizeof(buf), false);
|
||||
if (ret == -1) {
|
||||
continue;
|
||||
}
|
||||
buf[ret] = 0;
|
||||
handle_pkt(stream, buf, ret);
|
||||
}
|
||||
}
|
||||
|
||||
static void usage(const char *procname)
|
||||
{
|
||||
printf("usage: %s -h [help]\r\n"
|
||||
" -s addr\r\n"
|
||||
, procname);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ch;
|
||||
acl::string addr("127.0.0.1:53");
|
||||
|
||||
while ((ch = getopt(argc, argv, "hs:")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
case 's':
|
||||
addr = optarg;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (addr.empty()) {
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
acl::log::stdout_open(true);
|
||||
acl::fiber::stdout_open(true);
|
||||
|
||||
acl::socket_stream stream;
|
||||
if (!stream.bind_udp(addr)) {
|
||||
printf("bind %s error %s\r\n", addr.c_str(), acl::last_serror());
|
||||
return 1;
|
||||
}
|
||||
|
||||
go[&] {
|
||||
dns_server(stream);
|
||||
};
|
||||
|
||||
acl::fiber::schedule();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user