This is step one of cleaning up the DNS system according to SourceLayout.
Breaking the dependencies dnsserver has to Ip::Address and thus all the
libmisc* libraries etc which get pulled in by chain reaction.
It has some simple operational testing and appears to work (on Ubuntu at
least).
Amos
=== modified file 'src/Makefile.am'
--- src/Makefile.am 2011-09-11 23:40:46 +0000
+++ src/Makefile.am 2011-09-14 05:58:29 +0000
@@ -624,7 +624,11 @@
$(COMPAT_LIB) \
$(XTRA_LIBS)
-dnsserver_SOURCES = dnsserver.cc SquidNew.cc tests/stub_debug.cc test_tools.cc time.cc
+## dnsserver is a standalone helper. Do not link to any internal libraries
+dnsserver_SOURCES = dnsserver.cc
+## SquidNew.cc tests/stub_debug.cc test_tools.cc time.cc
+dnsserver_LDADD = $(COMPAT_LIB)
+
recv_announce_SOURCES = recv-announce.cc
## What requires what..
=== modified file 'src/dnsserver.cc'
--- src/dnsserver.cc 2011-07-23 08:37:52 +0000
+++ src/dnsserver.cc 2011-09-12 11:49:49 +0000
@@ -31,11 +31,6 @@
*/
#include "config.h"
-//#include "compat/inet_ntop.h"
-//#include "compat/getaddrinfo.h"
-//#include "compat/getnameinfo.h"
-#include "ip/Address.h"
-//#include "util.h"
#if HAVE_UNISTD_H
#include <unistd.h>
@@ -177,8 +172,7 @@
int ttl = 0;
int retry = 0;
unsigned int i = 0;
- Ip::Address ipa;
- char ntoabuf[MAX_IPSTRLEN];
+ char ntoabuf[256];
struct addrinfo hints;
struct addrinfo *AI = NULL;
struct addrinfo *aiptr = NULL;
@@ -193,11 +187,20 @@
return;
}
- /* setup 'hints' for the system lookup */
+ /* check if it's already an IP address in text form. */
+ memset(&hints, '\0', sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_flags = AI_NUMERICHOST; // only succeed if its numeric.
+ const bool isDomain = (getaddrinfo(buf,NULL,&hints,&AI) != 0);
+
+ // reset for real lookup
+ freeaddrinfo(AI);
+ AI = NULL;
+
+ // resolve the address/name
memset(&hints, '\0', sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_CANONNAME;
-
for (;;) {
if (AI != NULL) {
freeaddrinfo(AI);
@@ -216,9 +219,7 @@
sleep(1);
}
- /* check if it's already an IP address in text form. */
- ipa = buf;
- if ( ipa.IsAnyAddr() ) {
+ if (isDomain) {
/* its a domain name. Use the forward-DNS lookup already done */
if (res == 0) {
@@ -234,7 +235,7 @@
i = 0;
aiptr = AI;
while (NULL != aiptr && 32 >= i) {
- memset(ntoabuf, 0, MAX_IPSTRLEN);
+ memset(ntoabuf, 0, sizeof(ntoabuf));
/* getaddrinfo given a host has a nasty tendency to return duplicate addr's */
/* BUT sorted fortunately, so we can drop most of them easily */
@@ -252,10 +253,10 @@
/* annoying inet_ntop breaks the nice code by requiring the in*_addr */
switch (aiptr->ai_family) {
case AF_INET:
- inet_ntop(aiptr->ai_family, &((struct sockaddr_in*)aiptr->ai_addr)->sin_addr, ntoabuf, MAX_IPSTRLEN);
+ inet_ntop(aiptr->ai_family, &((struct sockaddr_in*)aiptr->ai_addr)->sin_addr, ntoabuf, sizeof(ntoabuf));
break;
case AF_INET6:
- inet_ntop(aiptr->ai_family, &((struct sockaddr_in6*)aiptr->ai_addr)->sin6_addr, ntoabuf, MAX_IPSTRLEN);
+ inet_ntop(aiptr->ai_family, &((struct sockaddr_in6*)aiptr->ai_addr)->sin6_addr, ntoabuf, sizeof(ntoabuf));
break;
default:
aiptr = aiptr->ai_next;
@@ -276,7 +277,7 @@
*/
if (NULL != AI && NULL != AI->ai_addr) {
for (;;) {
- if ( 0 == (res = getnameinfo(AI->ai_addr, AI->ai_addrlen, ntoabuf, MAX_IPSTRLEN, NULL,0,0)) )
+ if ( 0 == (res = getnameinfo(AI->ai_addr, AI->ai_addrlen, ntoabuf, sizeof(ntoabuf), NULL,0,0)) )
break;
if (res != EAI_AGAIN)
@@ -366,17 +367,14 @@
void
squid_res_setservers(int reset)
{
-#if defined(_SQUID_FREEBSD_) && defined(_SQUID_RES_NSADDR6_COUNT)
+#if _SQUID_FREEBSD_ && defined(_SQUID_RES_NSADDR6_COUNT)
/* Only seems to be valid on FreeBSD 5.5 where _res_ext was provided without an ns6addr counter! */
/* Gone again on FreeBSD 6.2 along with _res_ext itself in any form. */
int ns6count = 0;
#endif
-#if HAVE_RES_INIT
- Ip::Address ipa;
-#ifdef _SQUID_RES_NSADDR_LIST
+#if HAVE_RES_INIT && defined(_SQUID_RES_NSADDR_LIST)
extern char *optarg;
#endif
-#endif
#if HAVE_RES_INIT && (defined(_SQUID_RES_NSADDR_LIST) || defined(_SQUID_RES_NSADDR6_LIST))
@@ -401,35 +399,40 @@
*
* BUT, even if _res.nsaddrs is memset to NULL, it resolves IFF IPv6 set in _ext.
*
- * SO, am splittig the IPv4/v6 into the seperate _res fields
+ * SO, am splitting the IPv4/v6 into the seperate _res fields
* and making nscount a total of IPv4+IPv6 /w nscount6 the IPv6 sub-counter
* ie. nscount = count(NSv4)+count(NSv6) & nscount6 = count(NSv6)
*
* If ANYONE knows better please let us know.
*/
- if ( !(ipa = optarg) ) {
+ struct addrinfo hints;
+ memset(&hints, '\0', sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_flags = AI_NUMERICHOST; // prevent repeated DNS lookups!
+ struct addrinfo *AI = NULL;
+ if ( getaddrinfo(optarg, NULL, &hints, &AI) != 0) {
fprintf(stderr, "%s appears to be a bad nameserver FQDN/IP.\n",optarg);
- } else if ( ipa.IsIPv4() ) {
+ } else if ( AI->ai_family == AF_INET ) {
if (_SQUID_RES_NSADDR_COUNT == MAXNS) {
fprintf(stderr, "Too many -s options, only %d are allowed\n", MAXNS);
- return;
+ } else {
+ _SQUID_RES_NSADDR_LIST[_SQUID_RES_NSADDR_COUNT] = _SQUID_RES_NSADDR_LIST[0];
+ memcpy(&_SQUID_RES_NSADDR_LIST[_SQUID_RES_NSADDR_COUNT++].sin_addr, &((struct sockaddr_in*)AI->ai_addr)->sin_addr, sizeof(struct in_addr));
}
- _SQUID_RES_NSADDR_LIST[_SQUID_RES_NSADDR_COUNT] = _SQUID_RES_NSADDR_LIST[0];
- ipa.GetInAddr(_SQUID_RES_NSADDR_LIST[_SQUID_RES_NSADDR_COUNT++].sin_addr);
- } else if ( ipa.IsIPv6() ) {
+ } else if ( AI->ai_family == AF_INET6 ) {
#if USE_IPV6 && defined(_SQUID_RES_NSADDR6_LIST)
/* because things NEVER seem to resolve in tests without _res.nscount being a total. */
if (_SQUID_RES_NSADDR_COUNT == MAXNS) {
fprintf(stderr, "Too many -s options, only %d are allowed\n", MAXNS);
- return;
+ } else {
+ _SQUID_RES_NSADDR_COUNT++;
+ memcpy(&_SQUID_RES_NSADDR6_LIST(_SQUID_RES_NSADDR6_COUNT++), &((struct sockaddr_in6*)AI->ai_addr)->sin6_addr, sizeof(struct in6_addr));
}
- _SQUID_RES_NSADDR_COUNT++;
-
- ipa.GetInAddr(_SQUID_RES_NSADDR6_LIST(_SQUID_RES_NSADDR6_COUNT++));
#else
fprintf(stderr, "IPv6 nameservers not supported on this resolver\n");
#endif
}
+ freeaddrinfo(AI);
#else /* !HAVE_RES_INIT || !defined(_SQUID_RES_NSADDR_LIST) */