support inet6 in DNS module

This commit is contained in:
zhengshuxin 2020-10-18 18:23:24 +08:00
parent b1fbe89645
commit 33456cc3af
5 changed files with 113 additions and 16 deletions

View File

@ -9,6 +9,11 @@ extern "C" {
#include "acl_netdb.h"
#include <time.h>
#ifdef ACL_UNIX
#include <netinet/in.h>
#include <sys/un.h>
#endif
/**
* DNS返回结果的存储结构
*/
@ -61,6 +66,10 @@ ACL_API void acl_res_free(ACL_RES *res);
*/
ACL_API ACL_DNS_DB *acl_res_lookup(ACL_RES *res, const char *domain);
#ifdef AF_INET6
ACL_API ACL_DNS_DB *acl_res_lookup6(ACL_RES *res, const char *domain);
#endif
/**
*
* @param errnum {int}

View File

@ -73,7 +73,11 @@ ACL_API const char *acl_inet_ntop4(const unsigned char *src, char *dst, size_t s
* @param size {size_t} dst
* @return {const char*} NULL: error; !NULL: ok
*/
ACL_API const char *acl_inet_ntoa(struct in_addr in, char *dst, size_t size);
ACL_API const char *acl_inet_ntoa(const struct in_addr in, char *dst, size_t size);
#ifdef AF_INET6
ACL_API const char *acl_inet6_ntoa(const struct in6_addr in6, char *buf, size_t size);
#endif
/**
* ip

View File

@ -1,7 +1,7 @@
#include "lib_acl.h"
static int dns_lookup(const char *domain, const char *dns_ip,
unsigned short dns_port, ACL_VSTRING *sbuf)
unsigned short dns_port, ACL_VSTRING *sbuf, int use_in6)
{
ACL_RES *res; /* DNS 查询句柄 */
ACL_DNS_DB *dns_db; /* DNS 查询结果 */
@ -11,7 +11,12 @@ static int dns_lookup(const char *domain, const char *dns_ip,
res = acl_res_new(dns_ip, dns_port);
/* 向 DNS 服务器发送域名查询信息 */
dns_db = acl_res_lookup(res, domain);
if (use_in6) {
dns_db = acl_res_lookup6(res, domain);
} else {
dns_db = acl_res_lookup(res, domain);
}
if (dns_db == NULL) {
acl_vstring_sprintf(sbuf, "failed for domain %s, %s",
domain, acl_res_errmsg(res));
@ -26,16 +31,32 @@ static int dns_lookup(const char *domain, const char *dns_ip,
acl_vstring_sprintf_append(sbuf, "type\tttl\tip\t\tnet\t\tqid\t\n");
acl_foreach(iter, dns_db) {
ACL_HOST_INFO *info;
struct in_addr in;
char buf[32];
const char *type;
info = (ACL_HOST_INFO*) iter.data;
in.s_addr = info->saddr.in.sin_addr.s_addr;
acl_mask_addr((unsigned char*) &in.s_addr, sizeof(in.s_addr), 24);
acl_inet_ntoa(in, buf, sizeof(buf));
acl_vstring_sprintf_append(sbuf, "A\t%d\t%s\t%s\t%d\r\n",
info->ttl, info->ip, buf, res->cur_qid);
if (info->saddr.sa.sa_family == AF_INET) {
struct in_addr in;
in.s_addr = info->saddr.in.sin_addr.s_addr;
acl_mask_addr((unsigned char*) &in.s_addr, sizeof(in.s_addr), 24);
acl_inet_ntoa(in, buf, sizeof(buf));
type = "A";
#ifdef AF_INET6
} else if (info->saddr.sa.sa_family == AF_INET6) {
struct in6_addr in6;
memcpy(&in6, &info->saddr.in6.sin6_addr, sizeof(in6));
acl_mask_addr((unsigned char*) &in6, sizeof(in6), 64);
acl_inet6_ntoa(in6, buf, sizeof(buf));
type = "AAAA";
#endif
} else {
buf[0] = 0;
type = "Unknown";
}
acl_vstring_sprintf_append(sbuf, "%s\t%d\t%s\t%s\t%d\r\n",
type, info->ttl, info->ip, buf, res->cur_qid);
}
/* 释放 DNS 查询句柄 */
@ -48,20 +69,20 @@ static int dns_lookup(const char *domain, const char *dns_ip,
static void usage(const char *procname)
{
printf("usage: %s -h dns_ip -p dns_port -d domain_name\r\n", procname);
printf("usage: %s -h dns_ip -p dns_port -x [if lookup for inet6 addr] -d domain_name\r\n", procname);
}
int main(int argc, char *argv[])
{
char ch;
char dns_ip[64], domain[128];
int dns_port = 53, ret;
int dns_port = 53, ret, use_in6 = 0;
ACL_VSTRING *sbuf;
dns_ip[0] = 0;
domain[0] = 0;
while ((ch = getopt(argc, argv, "h:p:d:")) > 0) {
while ((ch = getopt(argc, argv, "h:p:d:x")) > 0) {
switch (ch) {
case 'h':
ACL_SAFE_STRNCPY(dns_ip, optarg, sizeof(dns_ip));
@ -72,6 +93,9 @@ int main(int argc, char *argv[])
case 'd':
ACL_SAFE_STRNCPY(domain, optarg, sizeof(domain));
break;
case 'x':
use_in6 = 1;
break;
default:
usage(argv[0]);
return 0;
@ -84,7 +108,7 @@ int main(int argc, char *argv[])
}
sbuf = acl_vstring_alloc(128);
ret = dns_lookup(domain, dns_ip, dns_port, sbuf);
ret = dns_lookup(domain, dns_ip, dns_port, sbuf, use_in6);
if (ret < 0) {
printf("dns lookup(%s) error(%s)\r\n",
domain, acl_vstring_str(sbuf));

View File

@ -63,13 +63,45 @@ const char *acl_inet_ntop4(const unsigned char *src, char *dst, size_t size)
return (dst);
}
const char *acl_inet_ntoa(struct in_addr in, char *dst, size_t size)
const char *acl_inet_ntoa(const struct in_addr in, char *buf, size_t size)
{
#if 0
unsigned char *src = (unsigned char *) &in.s_addr;
return (acl_inet_ntop4(src, dst, size));
return acl_inet_ntop4(src, buf, size);
#else
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
memcpy(&sin.sin_addr, &in, sizeof(sin.sin_addr));
if (!acl_inet_ntop((const struct sockaddr*) &sin, buf, size)) {
return NULL;
} else {
return buf;
}
#endif
}
#ifdef AF_INET6
const char *acl_inet6_ntoa(const struct in6_addr in6, char *buf, size_t size)
{
struct sockaddr_in6 sin6;
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
memcpy(&sin6.sin6_addr, &in6, sizeof(sin6.sin6_addr));
if (!acl_inet_ntop((const struct sockaddr*) &sin6, buf, size)) {
return NULL;
} else {
return buf;
}
}
#endif
int acl_is_ipv4(const char *ip)
{
return acl_valid_ipv4_hostaddr(ip, 0);

View File

@ -182,7 +182,8 @@ static int res_lookup(ACL_RES *res, const char *data, int dlen,
}
}
ACL_DNS_DB *acl_res_lookup(ACL_RES *res, const char *domain)
static ACL_DNS_DB *acl_res_lookup_with_type(ACL_RES *res,
const char *domain, int type)
{
ACL_DNS_DB *dns_db;
char buf[1024];
@ -203,8 +204,21 @@ ACL_DNS_DB *acl_res_lookup(ACL_RES *res, const char *domain)
}
memset(buf, 0, sizeof(buf));
#ifdef AF_INET6
if (type == AF_INET6) {
ret = (ssize_t) rfc1035_build_query4aaaa(domain, buf,
sizeof(buf), res->cur_qid++, NULL);
} else {
ret = (ssize_t) rfc1035_build_query4a(domain, buf,
sizeof(buf), res->cur_qid++, NULL);
}
#else
(void) type;
ret = (ssize_t) rfc1035_build_query4a(domain, buf, sizeof(buf),
res->cur_qid++, NULL);
#endif
if (ret == 0) {
acl_msg_error("%s(%d), %s: build a query error",
__FILE__, __LINE__, __FUNCTION__);
@ -244,6 +258,7 @@ ACL_DNS_DB *acl_res_lookup(ACL_RES *res, const char *domain)
continue;
}
phost->saddr.sa.sa_family = AF_INET;
phost->ttl = answers->answer[i].ttl;
(void) acl_array_append(dns_db->h_db, phost);
dns_db->size++;
@ -260,6 +275,7 @@ ACL_DNS_DB *acl_res_lookup(ACL_RES *res, const char *domain)
continue;
}
phost->saddr.sa.sa_family = AF_INET6;
phost->ttl = answers->answer[i].ttl;
(void) acl_array_append(dns_db->h_db, phost);
dns_db->size++;
@ -275,6 +291,18 @@ ACL_DNS_DB *acl_res_lookup(ACL_RES *res, const char *domain)
return dns_db;
}
ACL_DNS_DB *acl_res_lookup(ACL_RES *res, const char *domain)
{
return acl_res_lookup_with_type(res, domain, AF_INET);
}
#ifdef AF_INET6
ACL_DNS_DB *acl_res_lookup6(ACL_RES *res, const char *domain)
{
return acl_res_lookup_with_type(res, domain, AF_INET6);
}
#endif
const char *acl_res_strerror(int errnum)
{
int i;