From: hno <> Date: Mon, 26 Sep 2005 02:25:55 +0000 (+0000) Subject: Bug #1326: Use DNS search path from /etc/resolv.conf X-Git-Tag: SQUID_3_0_PRE4~601 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=68836b581057d99bd0683927eb7809cf9481b962;p=thirdparty%2Fsquid.git Bug #1326: Use DNS search path from /etc/resolv.conf patch by Thien Vu with fixes by "Paul". --- diff --git a/src/cf.data.pre b/src/cf.data.pre index 985b7df1fb..a46f6500be 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.395 2005/09/07 19:24:49 wessels Exp $ +# $Id: cf.data.pre,v 1.396 2005/09/25 20:25:55 hno Exp $ # # # SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -1569,17 +1569,14 @@ DOC_END NAME: dns_defnames COMMENT: on|off -IFDEF: USE_DNSSERVERS TYPE: onoff DEFAULT: off LOC: Config.onoff.res_defnames -IFDEF: USE_DNSSERVERS DOC_START - Normally the 'dnsserver' disables the RES_DEFNAMES resolver - option (see res_init(3)). This prevents caches in a hierarchy + Normally the RES_DEFNAMES resolver option is disabled + (see res_init(3)). This prevents caches in a hierarchy from interpreting single-component hostnames locally. To allow - dnsserver to handle single-component names, enable this - option. + Squid to handle single-component names, enable this option. DOC_END NAME: dns_nameservers diff --git a/src/dns_internal.cc b/src/dns_internal.cc index 8b859cc79a..4f27cbe98a 100644 --- a/src/dns_internal.cc +++ b/src/dns_internal.cc @@ -1,6 +1,6 @@ /* - * $Id: dns_internal.cc,v 1.82 2005/09/17 05:50:08 wessels Exp $ + * $Id: dns_internal.cc,v 1.83 2005/09/25 20:25:56 hno Exp $ * * DEBUG: section 78 DNS lookups; interacts with lib/rfc1035.c * AUTHOR: Duane Wessels @@ -38,7 +38,16 @@ #include "comm.h" #include "MemBuf.h" -/* MS VisualStudio Projects are monolitich, so we need the following +#include "config.h" + +#if HAVE_ARPA_NAMESER_H +#include +#endif +#if HAVE_RESOLV_H +#include +#endif + +/* MS VisualStudio Projects are monolithic, so we need the following #ifndef to exclude the internal DNS code from compile process when using external DNS process. */ @@ -46,11 +55,24 @@ #ifdef _SQUID_WIN32_ #include "squid_windows.h" #endif -#ifndef _PATH_RESOLV_CONF -#define _PATH_RESOLV_CONF "/etc/resolv.conf" +#ifndef _PATH_RESCONF +#define _PATH_RESCONF "/etc/resolv.conf" +#endif +#ifndef NS_DEFAULTPORT +#define NS_DEFAULTPORT 53 +#endif + +#ifndef NS_MAXDNAME +#define NS_MAXDNAME 1025 +#endif + +#ifndef MAXDNSRCH +#define MAXDNSRCH 6 #endif -#ifndef DOMAIN_PORT -#define DOMAIN_PORT 53 + +/* The buffer size required to store the maximum allowed search path */ +#ifndef RESOLV_BUFSZ +#define RESOLV_BUFSZ NS_MAXDNAME * MAXDNSRCH + sizeof("search ") + 1 #endif #define IDNS_MAX_TRIES 20 @@ -62,13 +84,17 @@ typedef struct _idns_query idns_query; typedef struct _ns ns; +typedef struct _sp sp; + typedef struct _nsvc nsvc; struct _idns_query { hash_link hash; rfc1035_query query; - char buf[512]; + char buf[RESOLV_BUFSZ]; + char name[NS_MAXDNAME + 1]; + char orig[NS_MAXDNAME + 1]; size_t sz; unsigned short id; int nsends; @@ -84,6 +110,8 @@ struct _idns_query const char *error; int rcode; idns_query *queue; + unsigned short domain; + unsigned short do_searchpath; }; struct _nsvc @@ -107,18 +135,30 @@ struct _ns nsvc *vc; }; +struct _sp +{ + char domain[NS_MAXDNAME]; + int queries; +}; + CBDATA_TYPE(nsvc); static ns *nameservers = NULL; +static sp *searchpath = NULL; static int nns = 0; static int nns_alloc = 0; +static int npc = 0; +static int npc_alloc = 0; +static int ndots = 1; static dlink_list lru_list; static int event_queued = 0; static hash_table *idns_lookup_hash = NULL; static OBJH idnsStats; static void idnsAddNameserver(const char *buf); +static void idnsAddPathComponent(const char *buf); static void idnsFreeNameservers(void); +static void idnsFreeSearchpath(void); static void idnsParseNameservers(void); #ifndef _SQUID_MSWIN_ static void idnsParseResolvConf(void); @@ -126,6 +166,7 @@ static void idnsParseResolvConf(void); #ifdef _SQUID_WIN32_ static void idnsParseWIN32Registry(void); #endif +static void idnsCacheQuery(idns_query * q); static void idnsSendQuery(idns_query * q); static IOCB idnsReadVCHeader; @@ -174,13 +215,41 @@ idnsAddNameserver(const char *buf) assert(nns < nns_alloc); nameservers[nns].S.sin_family = AF_INET; - nameservers[nns].S.sin_port = htons(DOMAIN_PORT); + nameservers[nns].S.sin_port = htons(NS_DEFAULTPORT); nameservers[nns].S.sin_addr.s_addr = A.s_addr; debug(78, 3) ("idnsAddNameserver: Added nameserver #%d: %s\n", nns, inet_ntoa(nameservers[nns].S.sin_addr)); nns++; } +static void +idnsAddPathComponent(const char *buf) +{ + if (npc == npc_alloc) { + int oldalloc = npc_alloc; + sp *oldptr = searchpath; + + if (0 == npc_alloc) + npc_alloc = 2; + else + npc_alloc <<= 1; + + searchpath = (sp *)xcalloc(npc_alloc, sizeof(*searchpath)); + + if (oldptr && oldalloc) + xmemcpy(searchpath, oldptr, oldalloc * sizeof(*searchpath)); + + if (oldptr) + safe_free(oldptr); + } + + assert(npc < npc_alloc); + strcpy(searchpath[npc].domain, buf); + debug(78, 3) ("idnsAddPathComponent: Added domain #%d: %s\n", + npc, searchpath[npc].domain); + npc++; +} + static void idnsFreeNameservers(void) { @@ -188,6 +257,15 @@ idnsFreeNameservers(void) nns = nns_alloc = 0; } +static void +idnsFreeSearchpath(void) +{ + safe_free(searchpath); + npc = npc_alloc = 0; +} + + + static void idnsParseNameservers(void) { @@ -204,12 +282,12 @@ static void idnsParseResolvConf(void) { FILE *fp; - char buf[512]; + char buf[RESOLV_BUFSZ]; char *t; - fp = fopen(_PATH_RESOLV_CONF, "r"); + fp = fopen(_PATH_RESCONF, "r"); if (fp == NULL) { - debug(78, 1) ("%s: %s\n", _PATH_RESOLV_CONF, xstrerror()); + debug(78, 1) ("%s: %s\n", _PATH_RESCONF, xstrerror()); return; } @@ -218,23 +296,48 @@ idnsParseResolvConf(void) #endif - while (fgets(buf, 512, fp)) { + while (fgets(buf, RESOLV_BUFSZ, fp)) { t = strtok(buf, w_space); - if (NULL == t) + if (NULL == t) { continue; + } else if (strcasecmp(t, "nameserver") == 0) { + t = strtok(NULL, w_space); - if (strcasecmp(t, "nameserver")) - continue; + if (NULL == t) + continue; - t = strtok(NULL, w_space); + debug(78, 1) ("Adding nameserver %s from %s\n", t, _PATH_RESCONF); - if (t == NULL) - continue; + idnsAddNameserver(t); + } else if (strcasecmp(t, "search") == 0) { + while (NULL != t) { + t = strtok(NULL, w_space); + + if (NULL == t) + continue; + + debug(78, 1) ("Adding domain %s from %s\n", t, _PATH_RESCONF); + + idnsAddPathComponent(t); + } + } else if (strcasecmp(t, "options") == 0) { + while (NULL != t) { + t = strtok(NULL, w_space); - debug(78, 1) ("Adding nameserver %s from %s\n", t, _PATH_RESOLV_CONF); + if (NULL == t) + continue; - idnsAddNameserver(t); + if (strncmp(t, "ndots:", 6) != 0) { + ndots = atoi(t + 6); + + if (ndots < 1) + ndots = 1; + + debug(78, 1) ("Adding ndots %d from %s\n", ndots, _PATH_RESCONF); + } + } + } } fclose(fp); @@ -808,6 +911,32 @@ idnsGrokReply(const char *buf, size_t sz) idnsSendQuery(q); return; } + + if (q->rcode == 3 && q->do_searchpath && q->attempt < MAX_ATTEMPT) { + assert(NULL == message->answer); + strcpy(q->name, q->orig); + + if (q->domain < npc) { + strcat(q->name, "."); + strcat(q->name, searchpath[q->domain].domain); + debug(78, 3) ("idnsGrokReply: searchpath used for %s\n", + q->name); + q->domain++; + } else { + q->attempt++; + } + + rfc1035MessageDestroy(message); + q->start_t = current_time; + q->id = idnsQueryID(); + rfc1035SetQueryID(q->buf, q->id); + q->sz = rfc1035BuildAQuery(q->name, q->buf, sizeof(q->buf), q->id, + &q->query); + + idnsCacheQuery(q); + idnsSendQuery(q); + return; + } } idnsCallback(q, message->answer, n, q->error); @@ -1090,6 +1219,8 @@ idnsShutdown(void) DnsSocket = -1; idnsFreeNameservers(); + + idnsFreeSearchpath(); } static int @@ -1125,6 +1256,8 @@ idnsCacheQuery(idns_query *q) void idnsALookup(const char *name, IDNSCB * callback, void *data) { + unsigned int i; + int nd = 0; idns_query *q; if (idnsCachedLookup(name, callback, data)) @@ -1134,7 +1267,29 @@ idnsALookup(const char *name, IDNSCB * callback, void *data) q->id = idnsQueryID(); - q->sz = rfc1035BuildAQuery(name, q->buf, sizeof(q->buf), q->id, &q->query); + for (i = 0; i < strlen(name); i++) + if (name[i] == '.') + nd++; + + if (Config.onoff.res_defnames && npc > 0 && name[strlen(name)-1] != '.') { + q->do_searchpath = 1; + } else { + q->do_searchpath = 0; + } + + strcpy(q->orig, name); + strcpy(q->name, q->orig); + + if (q->do_searchpath && nd < ndots) { + q->domain = 0; + strcat(q->name, "."); + strcat(q->name, searchpath[q->domain].domain); + debug(78, 3) ("idnsALookup: searchpath used for %s\n", + q->name); + } + + q->sz = rfc1035BuildAQuery(q->name, q->buf, sizeof(q->buf), q->id, + &q->query); if (q->sz < 0) { /* problem with query data -- query not sent */ @@ -1144,7 +1299,7 @@ idnsALookup(const char *name, IDNSCB * callback, void *data) } debug(78, 3) ("idnsALookup: buf is %d bytes for %s, id = %#hx\n", - (int) q->sz, name, q->id); + (int) q->sz, q->name, q->id); q->callback = callback; diff --git a/src/structs.h b/src/structs.h index bd206c8576..a9d2b5dcf3 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.528 2005/09/17 04:53:44 wessels Exp $ + * $Id: structs.h,v 1.529 2005/09/25 20:25:56 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -523,11 +523,7 @@ struct _SquidConfig struct { int log_udp; -#if USE_DNSSERVERS - int res_defnames; -#endif - int anonymizer; int client_db; int query_icmp;