mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-02 03:47:53 +08:00
support inet6 in DNS module
This commit is contained in:
parent
b1fbe89645
commit
33456cc3af
@ -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} 错误号
|
||||
|
@ -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 地址
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user