I adapted Florin Andrei's patch for support of the search directive in
/etc/resolv.conf and added support for ndots resolution as well (since
having one and not the other can seriously break name resolution).
I was hoping to get this integrated, because the search path stuff has
been put off for a long time now, and the ndots is a critical
component of name resolution through resolv.conf
Thien
diff -Nur /home/thien/squid-2.5.STABLE9.orig/src/cf.data.pre
/home/thien/squid-2.5.STABLE9/src/cf.data.pre
--- /home/thien/squid-2.5.STABLE9.orig/src/cf.data.pre 2005-02-22
16:06:34.000000000 -0800
+++ /home/thien/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 -Nur /home/thien/squid-2.5.STABLE9.orig/src/dns_internal.c
/home/thien/squid-2.5.STABLE9/src/dns_internal.c
--- /home/thien/squid-2.5.STABLE9.orig/src/dns_internal.c 2004-07-29
06:26:20.000000000 -0700
+++ /home/thien/squid-2.5.STABLE9/src/dns_internal.c 2005-03-28
15:36:57.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,33 @@
}
static void
+idnsAddPathComponent(const char *buf)
+{
+ if (strlen(buf) > 63) {
+ debug(78, 0) ("WARNING: rejecting '%s' as a domain, because it is
longer than 63 chars\n", buf);
+ return;
+ }
+ 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 +188,13 @@
}
static void
+idnsFreeSearchpath(void)
+{
+ safe_free(searchpath);
+ npc = npc_alloc = 0;
+}
+
+static void
idnsParseNameservers(void)
{
wordlist *w;
@@ -170,15 +220,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 +578,20 @@
idnsSendQuery(q);
return;
}
+ if (q->rcode == 3 && q->do_searchpath) {
+ assert(NULL == answers);
+ 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->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 +788,7 @@
comm_close(DnsSocket);
DnsSocket = -1;
idnsFreeNameservers();
+ idnsFreeSearchpath();
}
static int
@@ -733,12 +818,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 +850,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 -Nur /home/thien/squid-2.5.STABLE9.orig/src/structs.h
/home/thien/squid-2.5.STABLE9/src/structs.h
--- /home/thien/squid-2.5.STABLE9.orig/src/structs.h 2005-02-22
16:06:35.000000000 -0800
+++ /home/thien/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;