From 44e8dfd512906d2bf9d159ebc0be1b2c934eec1e Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Sun, 6 Nov 2011 01:24:35 -0600 Subject: [PATCH] Bug 3299: dnsserver: various undefined references --- src/Makefile.am | 6 ++++- src/dnsserver.cc | 60 +++++++++++++++++++++++++++--------------------- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 136a5cd36c..7af538c3cb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -561,9 +561,13 @@ endif unlinkd_SOURCES = unlinkd_daemon.cc SquidNew.cc -dnsserver_SOURCES = dnsserver.cc SquidNew.cc recv_announce_SOURCES = recv-announce.cc SquidNew.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) + ## What requires what.. ## many things want ACLChecklist.cc ## ACLChecklist.cc wants AuthUserRequest.cc diff --git a/src/dnsserver.cc b/src/dnsserver.cc index 5a558c5fd5..139e655bcb 100644 --- a/src/dnsserver.cc +++ b/src/dnsserver.cc @@ -192,8 +192,7 @@ lookup(const char *buf) int ttl = 0; int retry = 0; unsigned int i = 0; - IpAddress ipa; - char ntoabuf[MAX_IPSTRLEN]; + char ntoabuf[256]; struct addrinfo hints; struct addrinfo *AI = NULL; struct addrinfo *aiptr = NULL; @@ -208,11 +207,20 @@ lookup(const char *buf) 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_CANONNAME; + 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) { xfreeaddrinfo(AI); @@ -231,9 +239,7 @@ lookup(const char *buf) 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) { @@ -249,7 +255,7 @@ lookup(const char *buf) 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 */ @@ -267,10 +273,10 @@ lookup(const char *buf) /* annoying inet_ntop breaks the nice code by requiring the in*_addr */ switch (aiptr->ai_family) { case AF_INET: - xinet_ntop(aiptr->ai_family, &((struct sockaddr_in*)aiptr->ai_addr)->sin_addr, ntoabuf, MAX_IPSTRLEN); + xinet_ntop(aiptr->ai_family, &((struct sockaddr_in*)aiptr->ai_addr)->sin_addr, ntoabuf, sizeof(ntoabuf)); break; case AF_INET6: - xinet_ntop(aiptr->ai_family, &((struct sockaddr_in6*)aiptr->ai_addr)->sin6_addr, ntoabuf, MAX_IPSTRLEN); + xinet_ntop(aiptr->ai_family, &((struct sockaddr_in6*)aiptr->ai_addr)->sin6_addr, ntoabuf, sizeof(ntoabuf)); break; default: aiptr = aiptr->ai_next; @@ -291,7 +297,7 @@ lookup(const char *buf) */ if (NULL != AI && NULL != AI->ai_addr) { for (;;) { - if ( 0 == (res = xgetnameinfo(AI->ai_addr, AI->ai_addrlen, ntoabuf, MAX_IPSTRLEN, NULL,0,0)) ) + if ( 0 == (res = xgetnameinfo(AI->ai_addr, AI->ai_addrlen, ntoabuf, sizeof(ntoabuf), NULL,0,0)) ) break; if (res != EAI_AGAIN) @@ -386,12 +392,9 @@ squid_res_setservers(int reset) /* Gone again on FreeBSD 6.2 along with _res_ext itself in any form. */ int ns6count = 0; #endif -#if HAVE_RES_INIT - IpAddress 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)) @@ -416,35 +419,40 @@ squid_res_setservers(int reset) * * 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) */ -- 2.47.2