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
|
* Takes the contents of a DNS reply and fills in an array
|
||||||
* of resource record structures. The records array is allocated
|
* 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 buf {const char*} the data of the DNS reply
|
||||||
* @param sz {size_t} the buf's size
|
* @param sz {size_t} the buf's size
|
||||||
* @return {ACL_RFC1035_MESSAGE*} return the parsing result
|
* @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
|
* Takes the contents of a DNS request and fills in an array
|
||||||
* of resource record structures. The records array is allocated
|
* 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 buf {const char*} the data of the DNS reply
|
||||||
* @param sz {size_t} the buf's size
|
* @param sz {size_t} the buf's size
|
||||||
* @return {ACL_RFC1035_MESSAGE*} return the parsing result
|
* @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;
|
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++) {
|
for (i = 0; i < reply->ips->argc; i++) {
|
||||||
memset(&rr, 0, sizeof(rr));
|
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.type = reply->ip_type;
|
||||||
rr.tclass = ACL_RFC1035_CLASS_IN;
|
rr.tclass = ACL_RFC1035_CLASS_IN;
|
||||||
rr.ttl = reply->ttl;
|
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) {
|
if (h.nscount) {
|
||||||
memset(&rr, 0, sizeof(rr));
|
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.type = ACL_RFC1035_TYPE_NS;
|
||||||
rr.tclass = ACL_RFC1035_CLASS_IN;
|
rr.tclass = ACL_RFC1035_CLASS_IN;
|
||||||
rr.ttl = reply->ttl;
|
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) {
|
if (h.arcount) {
|
||||||
memset(&rr, 0, sizeof(rr));
|
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.type = reply->ip_type;
|
||||||
rr.tclass = ACL_RFC1035_CLASS_IN;
|
rr.tclass = ACL_RFC1035_CLASS_IN;
|
||||||
rr.ttl = reply->ttl;
|
rr.ttl = reply->ttl;
|
||||||
|
@ -479,11 +479,8 @@ static struct addrinfo *ns_lookup(const char *ip, unsigned short port,
|
|||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret = rfc1035_message_unpack(buf, ret, &message);
|
message = rfc1035_response_unpack(buf, ret);
|
||||||
if (ret <= 0) {
|
if (message == NULL) {
|
||||||
if (message) {
|
|
||||||
rfc1035_message_destroy(message);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,10 +10,11 @@
|
|||||||
|
|
||||||
#include "common/strops.h"
|
#include "common/strops.h"
|
||||||
#include "common/msg.h"
|
#include "common/msg.h"
|
||||||
|
#include "common/argv.h"
|
||||||
#include "rfc1035.h"
|
#include "rfc1035.h"
|
||||||
|
|
||||||
#define RFC1035_MAXLABELSZ 63
|
#define RFC1035_MAXLABELSZ 63
|
||||||
#define RFC1035_unpack_error 15
|
#define RFC1035_UNPACK_ERROR 15
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define RFC1035_UNPACK_DEBUG msg_error("unpack error at %s:%d", __FILE__,__LINE__)
|
#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) {
|
if (ns <= 0) {
|
||||||
msg_error("%s: ns(%d) <= 0", myname, (int) ns);
|
msg_error("%s: ns(%d) <= 0", myname, (int) ns);
|
||||||
return -RFC1035_unpack_error;
|
return -RFC1035_UNPACK_ERROR;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
if (*off >= sz) {
|
if (*off >= sz) {
|
||||||
msg_error("%s: *off(%d) >= sz(%d)",
|
msg_error("%s: *off(%d) >= sz(%d)",
|
||||||
myname, (int) *off, (int) sz);
|
myname, (int) *off, (int) sz);
|
||||||
return -RFC1035_unpack_error;
|
return -RFC1035_UNPACK_ERROR;
|
||||||
}
|
}
|
||||||
c = *(buf + (*off));
|
c = *(buf + (*off));
|
||||||
if (c > 191) {
|
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 */
|
/* make sure we didn't allow someone to overflow the name buffer */
|
||||||
if (no > (int) ns) {
|
if (no > (int) ns) {
|
||||||
msg_error("%s: no(%d) > ns(%d)", myname, no, (int) ns);
|
msg_error("%s: no(%d) > ns(%d)", myname, no, (int) ns);
|
||||||
return -RFC1035_unpack_error;
|
return -RFC1035_UNPACK_ERROR;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -282,7 +283,7 @@ const char *rfc1035_strerror(int errnum)
|
|||||||
"not support the requested kind of query." },
|
"not support the requested kind of query." },
|
||||||
{ 5, "Refused: The name server refuses to "
|
{ 5, "Refused: The name server refuses to "
|
||||||
"perform the specified operation." },
|
"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." },
|
"not be safely parsed." },
|
||||||
{ -1, NULL },
|
{ -1, NULL },
|
||||||
};
|
};
|
||||||
@ -345,48 +346,48 @@ int rfc1035_query_compare(const RFC1035_QUERY * a, const RFC1035_QUERY * b)
|
|||||||
*
|
*
|
||||||
* Returns > 0 (success) or 0 (error)
|
* 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";
|
const char *myname = "rfc1035_rr_pack";
|
||||||
unsigned short s;
|
unsigned short s;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int off = 0, off_saved;
|
int off = 0, off_saved;
|
||||||
|
|
||||||
off = rfc1035_name_pack(buf + off, sz, RR->name);
|
off = rfc1035_name_pack(buf + off, sz, rr->name);
|
||||||
s = htons(RR->type);
|
s = htons(rr->type);
|
||||||
memcpy(buf + off, &s,sizeof(s));
|
memcpy(buf + off, &s,sizeof(s));
|
||||||
off += sizeof(s);
|
off += sizeof(s);
|
||||||
|
|
||||||
s = htons(RR->tclass);
|
s = htons(rr->tclass);
|
||||||
memcpy(buf + off, &s ,sizeof(s));
|
memcpy(buf + off, &s ,sizeof(s));
|
||||||
off += sizeof(s);
|
off += sizeof(s);
|
||||||
|
|
||||||
i = htonl(RR->ttl);
|
i = htonl(rr->ttl);
|
||||||
memcpy(buf + off, &i ,sizeof(i));
|
memcpy(buf + off, &i ,sizeof(i));
|
||||||
off += sizeof(i);
|
off += sizeof(i);
|
||||||
|
|
||||||
switch (RR->type) {
|
switch (rr->type) {
|
||||||
case RFC1035_TYPE_PTR:
|
case RFC1035_TYPE_PTR:
|
||||||
case RFC1035_TYPE_NS:
|
case RFC1035_TYPE_NS:
|
||||||
case RFC1035_TYPE_CNAME:
|
case RFC1035_TYPE_CNAME:
|
||||||
case RFC1035_TYPE_TXT:
|
case RFC1035_TYPE_TXT:
|
||||||
if (strlen(RR->rdata) > RFC1035_MAXHOSTNAMESZ) {
|
if (strlen(rr->rdata) > RFC1035_MAXHOSTNAMESZ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
off_saved = off;
|
off_saved = off;
|
||||||
off += sizeof(s);
|
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 = off - off_saved - (unsigned short) sizeof(s);
|
||||||
s = htons(s);
|
s = htons(s);
|
||||||
memcpy(buf + off_saved, &s ,sizeof(s));
|
memcpy(buf + off_saved, &s ,sizeof(s));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
s = htons(RR->rdlength);
|
s = htons(rr->rdlength);
|
||||||
memcpy(buf + off, &s ,sizeof(s));
|
memcpy(buf + off, &s ,sizeof(s));
|
||||||
off += sizeof(s);
|
off += sizeof(s);
|
||||||
memcpy(buf + off, RR->rdata, RR->rdlength);
|
memcpy(buf + off, rr->rdata, rr->rdlength);
|
||||||
off += RR->rdlength;
|
off += rr->rdlength;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,7 +530,7 @@ static int rfc1035_header_unpack(const char *buf, size_t sz, size_t *off,
|
|||||||
|
|
||||||
if (*off != 0) {
|
if (*off != 0) {
|
||||||
msg_error("%s: *off(%d) != 0", myname, (int) *off);
|
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) {
|
if (*off != 12) {
|
||||||
msg_error("%s: *off(%d) != 12", myname, (int) *off);
|
msg_error("%s: *off(%d) != 12", myname, (int) *off);
|
||||||
return -RFC1035_unpack_error;
|
return -RFC1035_UNPACK_ERROR;
|
||||||
}
|
}
|
||||||
return 0;
|
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) {
|
if (*off > sz) {
|
||||||
msg_error("%s: *off(%d) > sz(%d)",
|
msg_error("%s: *off(%d) > sz(%d)",
|
||||||
myname, (int) *off, (int) sz);
|
myname, (int) *off, (int) sz);
|
||||||
return -RFC1035_unpack_error;
|
return -RFC1035_UNPACK_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -764,45 +765,40 @@ static RFC1035_RR *rfc1035_unpack2rr(const char *buf, size_t sz,
|
|||||||
return rr;
|
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;
|
int i, nr;
|
||||||
size_t off = 0;
|
size_t off = 0;
|
||||||
RFC1035_MESSAGE *msg;
|
RFC1035_MESSAGE *msg;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
*answer = NULL;
|
|
||||||
msg = (RFC1035_MESSAGE*) calloc(1, sizeof(*msg));
|
msg = (RFC1035_MESSAGE*) calloc(1, sizeof(*msg));
|
||||||
|
|
||||||
if (rfc1035_header_unpack(buf + off, sz - off, &off, msg)) {
|
if (rfc1035_header_unpack(buf + off, sz - off, &off, msg)) {
|
||||||
RFC1035_UNPACK_DEBUG;
|
RFC1035_UNPACK_DEBUG;
|
||||||
rfc1035_set_errno(RFC1035_unpack_error);
|
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||||
rfc1035_message_destroy(msg);
|
rfc1035_message_destroy(msg);
|
||||||
*answer = NULL;
|
return NULL;
|
||||||
return -RFC1035_unpack_error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg->rcode) {
|
if (msg->rcode) {
|
||||||
int ret = -((int) msg->rcode);
|
|
||||||
RFC1035_UNPACK_DEBUG;
|
RFC1035_UNPACK_DEBUG;
|
||||||
rfc1035_set_errno((int) msg->rcode);
|
rfc1035_set_errno((int) msg->rcode);
|
||||||
rfc1035_message_destroy(msg);
|
rfc1035_message_destroy(msg);
|
||||||
*answer = NULL;
|
return NULL;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg->ancount == 0) {
|
if (msg->ancount == 0) {
|
||||||
rfc1035_message_destroy(msg);
|
rfc1035_message_destroy(msg);
|
||||||
*answer = NULL;
|
return NULL;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg->qdcount != 1) {
|
if (msg->qdcount != 1) {
|
||||||
/* This can not be an answer to our queries.. */
|
/* This can not be an answer to our queries.. */
|
||||||
RFC1035_UNPACK_DEBUG;
|
RFC1035_UNPACK_DEBUG;
|
||||||
rfc1035_set_errno(RFC1035_unpack_error);
|
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||||
rfc1035_message_destroy(msg);
|
rfc1035_message_destroy(msg);
|
||||||
return -RFC1035_unpack_error;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg->query = (RFC1035_QUERY*) calloc((int) msg->qdcount,
|
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++) {
|
for (i = 0; i < (int) msg->qdcount; i++) {
|
||||||
if (rfc1035_query_unpack(buf, sz, &off, &msg->query[i])) {
|
if (rfc1035_query_unpack(buf, sz, &off, &msg->query[i])) {
|
||||||
RFC1035_UNPACK_DEBUG;
|
RFC1035_UNPACK_DEBUG;
|
||||||
rfc1035_set_errno(RFC1035_unpack_error);
|
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||||
rfc1035_message_destroy(msg);
|
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_UNPACK_DEBUG;
|
||||||
rfc1035_message_destroy(msg);
|
rfc1035_message_destroy(msg);
|
||||||
*answer = NULL;
|
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||||
rfc1035_set_errno(RFC1035_unpack_error);
|
return NULL;
|
||||||
return -RFC1035_unpack_error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (msg->nscount > 0) {
|
if (msg->nscount > 0) {
|
||||||
msg->authority = rfc1035_unpack2rr(buf, sz, &off,
|
msg->authority = rfc1035_unpack2rr(buf, sz, &off,
|
||||||
msg->nscount, &nr);
|
msg->nscount, &nr);
|
||||||
@ -839,9 +833,8 @@ int rfc1035_message_unpack(const char *buf, size_t sz, RFC1035_MESSAGE **answer)
|
|||||||
if (msg->authority == NULL) {
|
if (msg->authority == NULL) {
|
||||||
RFC1035_UNPACK_DEBUG;
|
RFC1035_UNPACK_DEBUG;
|
||||||
rfc1035_message_destroy(msg);
|
rfc1035_message_destroy(msg);
|
||||||
*answer = NULL;
|
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||||
rfc1035_set_errno(RFC1035_unpack_error);
|
return NULL;
|
||||||
return -RFC1035_unpack_error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -852,14 +845,57 @@ int rfc1035_message_unpack(const char *buf, size_t sz, RFC1035_MESSAGE **answer)
|
|||||||
if (msg->additional == NULL) {
|
if (msg->additional == NULL) {
|
||||||
RFC1035_UNPACK_DEBUG;
|
RFC1035_UNPACK_DEBUG;
|
||||||
rfc1035_message_destroy(msg);
|
rfc1035_message_destroy(msg);
|
||||||
*answer = NULL;
|
rfc1035_set_errno(RFC1035_UNPACK_ERROR);
|
||||||
rfc1035_set_errno(RFC1035_unpack_error);
|
return NULL;
|
||||||
return -RFC1035_unpack_error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*answer = msg;
|
return msg;
|
||||||
return (int) msg->ancount;
|
}
|
||||||
|
|
||||||
|
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)
|
size_t rfc1035_build_reply(const RFC1035_REPLY *reply, char *buf, size_t sz)
|
||||||
{
|
{
|
||||||
RFC1035_MESSAGE h;
|
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;
|
size_t offset = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (reply->ips == NULL || reply->ips->argc <= 0) {
|
||||||
|
msg_error("ips null");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&h, '\0', sizeof(h));
|
memset(&h, '\0', sizeof(h));
|
||||||
h.id = reply->qid;
|
h.id = reply->qid;
|
||||||
h.qr = 1; /* response */
|
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++) {
|
for (i = 0; i < reply->ips->argc; i++) {
|
||||||
memset(&rr, 0, sizeof(rr));
|
memset(&rr, 0, sizeof(rr));
|
||||||
#ifdef SYS_WIN
|
SAFE_STRNCPY(rr.name, reply->hostname, sizeof(rr.name));
|
||||||
_snprintf(rr.name, sizeof(rr.name), "%s", reply->hostname);
|
|
||||||
#else
|
|
||||||
snprintf(rr.name, sizeof(rr.name), "%s", reply->hostname);
|
|
||||||
#endif
|
|
||||||
rr.type = reply->ip_type;
|
rr.type = reply->ip_type;
|
||||||
rr.tclass = htons(RFC1035_CLASS_IN);
|
rr.tclass = htons(RFC1035_CLASS_IN);
|
||||||
rr.ttl = reply->ttl;
|
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);
|
offset += rfc1035_rr_pack(&rr, buf + offset, sz - offset);
|
||||||
free(rr.rdata);
|
SAFE_FREE(rr.rdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h.nscount) {
|
if (h.nscount) {
|
||||||
memset(&rr, 0, sizeof(rr));
|
memset(&rr, 0, sizeof(rr));
|
||||||
#ifdef SYS_WIN
|
SAFE_STRNCPY(rr.name, reply->domain_root, sizeof(rr.name));
|
||||||
_snprintf(rr.name, sizeof(rr.name), "%s", reply->domain_root);
|
|
||||||
#else
|
|
||||||
snprintf(rr.name, sizeof(rr.name), "%s", reply->domain_root);
|
|
||||||
#endif
|
|
||||||
rr.type = RFC1035_TYPE_NS;
|
rr.type = RFC1035_TYPE_NS;
|
||||||
rr.tclass = RFC1035_CLASS_IN;
|
rr.tclass = RFC1035_CLASS_IN;
|
||||||
rr.ttl = reply->ttl;
|
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);
|
rr.rdata = strdup(reply->dns_name);
|
||||||
#endif
|
#endif
|
||||||
offset += rfc1035_rr_pack(&rr, buf + offset, sz - offset);
|
offset += rfc1035_rr_pack(&rr, buf + offset, sz - offset);
|
||||||
free(rr.rdata);
|
SAFE_FREE(rr.rdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h.arcount) {
|
if (h.arcount) {
|
||||||
memset(&rr, 0, sizeof(rr));
|
memset(&rr, 0, sizeof(rr));
|
||||||
#ifdef SYS_WIN
|
SAFE_STRNCPY(rr.name, reply->dns_name, sizeof(rr.name));
|
||||||
_snprintf(rr.name, sizeof(rr.name), "%s", reply->dns_name);
|
|
||||||
#else
|
|
||||||
snprintf(rr.name, sizeof(rr.name), "%s", reply->dns_name);
|
|
||||||
#endif
|
|
||||||
rr.type = reply->ip_type;
|
rr.type = reply->ip_type;
|
||||||
rr.tclass = RFC1035_CLASS_IN;
|
rr.tclass = RFC1035_CLASS_IN;
|
||||||
rr.ttl = reply->ttl;
|
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);
|
offset += rfc1035_rr_pack(&rr, buf + offset, sz - offset);
|
||||||
free(rr.rdata);
|
SAFE_FREE(rr.rdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "common/argv.h"
|
|
||||||
|
|
||||||
#ifdef ACL_UNIX
|
#ifdef ACL_UNIX
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct ARGV;
|
||||||
|
|
||||||
/* RFC1035 - DNS */
|
/* RFC1035 - DNS */
|
||||||
#define RFC1035_MAXHOSTNAMESZ 256
|
#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);
|
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
|
* 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 buf {const char*} the data of the DNS reply
|
||||||
* @param sz {size_t} the buf's size
|
* @param sz {size_t} the buf's size
|
||||||
* @param answer {RFC1035_MESSAGE*} store the parsing result
|
* @return {RFC1035_MESSAGE*} return the parsing result
|
||||||
* @return {int} Returns number of records unpacked, zero if DNS reply
|
|
||||||
* indicates zero answers, or an error number < 0.
|
|
||||||
*/
|
*/
|
||||||
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()
|
* destroy and free the message created by RFC1035MessageUnpack()
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include "lib_acl.h"
|
#include "lib_acl.h"
|
||||||
#include "acl_cpp/lib_acl.hpp"
|
#include "acl_cpp/lib_acl.hpp"
|
||||||
#include "fiber/libfiber.h"
|
|
||||||
#include "fiber/go_fiber.hpp"
|
#include "fiber/go_fiber.hpp"
|
||||||
|
|
||||||
static char __dns_ip[256];
|
static char __dns_ip[256];
|
||||||
@ -127,7 +126,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
acl_msg_stdout_enable(1);
|
acl_msg_stdout_enable(1);
|
||||||
acl_fiber_msg_stdout_enable(1);
|
acl::fiber::stdout_open(true);
|
||||||
|
|
||||||
struct timeval begin;
|
struct timeval begin;
|
||||||
gettimeofday(&begin, NULL);
|
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