diff -Naur squid-2.5.STABLE9.orig/src/cf.data.pre squid-2.5.STABLE9/src/cf.data.pre --- squid-2.5.STABLE9.orig/src/cf.data.pre 2005-02-22 16:06:34.000000000 -0800 +++ squid-2.5.STABLE9/src/cf.data.pre 2005-03-23 22:31:23.000000000 -0800 @@ -1140,16 +1140,14 @@ 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 + Squid to handle single-component names, enable this option. DOC_END diff -Naur squid-2.5.STABLE9.orig/src/dns_internal.c squid-2.5.STABLE9/src/dns_internal.c --- squid-2.5.STABLE9.orig/src/dns_internal.c 2004-07-29 06:26:20.000000000 -0700 +++ squid-2.5.STABLE9/src/dns_internal.c 2005-03-29 15:26:11.000000000 -0800 @@ -52,11 +52,14 @@ typedef struct _idns_query idns_query; typedef struct _ns ns; +typedef struct _sp sp; struct _idns_query { hash_link hash; char query[RFC1035_MAXHOSTNAMESZ + 1]; char buf[512]; + char name[512]; + char orig[512]; size_t sz; unsigned short id; int nsends; @@ -69,6 +72,8 @@ const char *error; int rcode; idns_query *queue; + unsigned short domain; + unsigned short do_searchpath; }; struct _ns { @@ -78,16 +83,27 @@ int large_pkts; }; +struct _sp { + char domain[64]; + int queries; +}; + 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); static void idnsParseResolvConf(void); #if defined(_SQUID_MSWIN_) || defined(_SQUID_CYGWIN_) @@ -138,6 +154,29 @@ } static void +idnsAddPathComponent(const char *buf) +{ + if (npc == npc_alloc) { + int oldalloc = npc_alloc; + sp *oldptr = searchpath; + if (npc_alloc == 0) + npc_alloc = 2; + else + npc_alloc <<= 1; + searchpath = 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]); + npc++; +} + +static void idnsFreeNameservers(void) { safe_free(nameservers); @@ -145,6 +184,13 @@ } static void +idnsFreeSearchpath(void) +{ + safe_free(searchpath); + npc = npc_alloc = 0; +} + +static void idnsParseNameservers(void) { wordlist *w; @@ -170,15 +216,35 @@ #endif while (fgets(buf, 512, fp)) { t = strtok(buf, w_space); - if (NULL == t) - continue; - if (strcasecmp(t, "nameserver")) - continue; - t = strtok(NULL, w_space); - if (t == NULL) + if (NULL == t) { continue; - debug(78, 1) ("Adding nameserver %s from %s\n", t, _PATH_RESOLV_CONF); - idnsAddNameserver(t); + } else if (strcasecmp(t, "nameserver") == 0) { + t = strtok(NULL, w_space); + if (t == NULL) + continue; + debug(78, 1) ("Adding nameserver %s from %s\n", t, _PATH_RESOLV_CONF); + idnsAddNameserver(t); + } else if (strcasecmp(t, "search") == 0) { + while (t != NULL) { + t = strtok(NULL, w_space); + if (t == NULL) + continue; + debug(78, 1) ("Adding domain %s from %s\n", t, _PATH_RESOLV_CONF); + idnsAddPathComponent(t); + } + } else if (strcasecmp(t, "options") == 0) { + while (t != NULL) { + t = strtok(NULL, w_space); + if (t == NULL) + continue; + if (strncmp(t, "ndots:", 6) != NULL) { + ndots = atoi(t + 6); + if (ndots < 1) + ndots = 1; + debug(78, 1) ("Adding ndots %d from %s\n", ndots, _PATH_RESOLV_CONF); + } + } + } } fclose(fp); } @@ -508,6 +574,23 @@ idnsSendQuery(q); return; } + if (q->rcode == 3 && q->do_searchpath && q->attempt < MAX_ATTEMPT) { + assert(NULL == answers); + strcpy(q->name, q->orig); + if (q->domain < npc) { + q->domain++; + strcat(q->name, "."); + strcat(q->name, searchpath[q->domain].domain); + debug(78, 3) ("idnsGrokReply: searchpath used for %s\n", q->name); + } else if (q->domain == npc) { + q->attempt++; + } + q->start_t = current_time; + q->sz = sizeof(q->buf); + q->id = rfc1035BuildAQuery(q->name, q->buf, &q->sz); + idnsSendQuery(q); + return; + } } idnsCallback(q, answers, n, q->error); rfc1035RRDestroy(answers, n); @@ -704,6 +787,7 @@ comm_close(DnsSocket); DnsSocket = -1; idnsFreeNameservers(); + idnsFreeSearchpath(); } static int @@ -733,12 +817,31 @@ void idnsALookup(const char *name, IDNSCB * callback, void *data) { + int i; + int nd = 0; idns_query *q; if (idnsCachedLookup(name, callback, data)) return; q = memAllocate(MEM_IDNS_QUERY); q->sz = sizeof(q->buf); - q->id = rfc1035BuildAQuery(name, q->buf, &q->sz); + + 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); + } + q->id = rfc1035BuildAQuery(q->name, q->buf, &q->sz); if (0 == q->id) { /* problem with query data -- query not sent */ callback(data, NULL, 0, "Internal error"); @@ -746,7 +849,7 @@ return; } 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; q->callback_data = data; cbdataLock(q->callback_data); diff -Naur squid-2.5.STABLE9.orig/src/structs.h squid-2.5.STABLE9/src/structs.h --- squid-2.5.STABLE9.orig/src/structs.h 2005-02-22 16:06:35.000000000 -0800 +++ squid-2.5.STABLE9/src/structs.h 2005-03-23 22:52:19.000000000 -0800 @@ -564,9 +564,7 @@ } Netdb; struct { int log_udp; -#if USE_DNSSERVERS int res_defnames; -#endif int anonymizer; int client_db; int query_icmp;