From: hno <> Date: Sat, 10 Apr 2004 19:10:17 +0000 (+0000) Subject: Bug #849: DNS log error messages should report the failed query X-Git-Tag: SQUID_3_0_PRE4~1098 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7ba8d0b88883880da0db95e29c37a9859aeff587;p=thirdparty%2Fsquid.git Bug #849: DNS log error messages should report the failed query --- diff --git a/src/dns.cc b/src/dns.cc index 40fb68321e..5d30955be5 100644 --- a/src/dns.cc +++ b/src/dns.cc @@ -1,6 +1,6 @@ /* - * $Id: dns.cc,v 1.92 2003/03/09 12:29:41 robertc Exp $ + * $Id: dns.cc,v 1.93 2004/04/10 13:10:17 hno Exp $ * * DEBUG: section 34 Dnsserver interface * AUTHOR: Harvest Derived @@ -122,7 +122,7 @@ dnsSubmit(const char *lookup, HLPCB * callback, void *data) debug(34, 1) ("dnsSubmit: queue overload, rejecting %s\n", lookup); - callback(data, "$fail Temporary network problem, please retry later"); + callback(data, (char *)"$fail Temporary network problem, please retry later"); return; } @@ -139,7 +139,7 @@ variable_list * snmp_netDnsFn(variable_list * Var, snint * ErrP) { variable_list *Answer = NULL; - debug(49, 5) ("snmp_netDnsFn: Processing request:\n", Var->name[LEN_SQ_NET + 1]); + debug(49, 5) ("snmp_netDnsFn: Processing request: %d\n", Var->name[LEN_SQ_NET + 1]); snmpDebugOid(5, Var->name, Var->name_length); *ErrP = SNMP_ERR_NOERROR; diff --git a/src/dns_internal.cc b/src/dns_internal.cc index 48356930a4..a73efbac5a 100644 --- a/src/dns_internal.cc +++ b/src/dns_internal.cc @@ -1,6 +1,6 @@ /* - * $Id: dns_internal.cc,v 1.62 2004/04/04 14:36:58 hno Exp $ + * $Id: dns_internal.cc,v 1.63 2004/04/10 13:10:17 hno Exp $ * * DEBUG: section 78 DNS lookups; interacts with lib/rfc1035.c * AUTHOR: Duane Wessels @@ -75,6 +75,8 @@ struct _idns_query IDNSCB *callback; void *callback_data; int attempt; + const char *error; + int rcode; }; struct _ns @@ -573,11 +575,15 @@ idnsGrokReply(const char *buf, size_t sz) dlinkDelete(&q->lru, &lru_list); idnsRcodeCount(n, q->attempt); + q->error = NULL; if (n < 0) { debug(78, 3) ("idnsGrokReply: error %d\n", rfc1035_errno); - if (-2 == n && ++q->attempt < MAX_ATTEMPT) { + q->error = rfc1035_error_message; + q->rcode = -n; + + if (q->rcode == 2 && ++q->attempt < MAX_ATTEMPT) { /* * RCODE 2 is "Server failure - The name server was * unable to process this query due to a problem with @@ -595,7 +601,7 @@ idnsGrokReply(const char *buf, size_t sz) q->callback = NULL; if (cbdataReferenceValidDone(q->callback_data, &cbdata)) - callback(cbdata, answers, n); + callback(cbdata, answers, n, q->error); rfc1035RRDestroy(answers, n); @@ -727,8 +733,12 @@ idnsCheckQueue(void *unused) callback = q->callback; q->callback = NULL; - if (cbdataReferenceValidDone(q->callback_data, &cbdata)) - callback(cbdata, NULL, 0); + if (cbdataReferenceValidDone(q->callback_data, &cbdata)) { + if (q->rcode != 0) + callback(cbdata, NULL, -q->rcode, q->error); + else + callback(cbdata, NULL, -16, "Timeout"); + } memFree(q, MEM_IDNS_QUERY); } @@ -846,7 +856,7 @@ idnsALookup(const char *name, IDNSCB * callback, void *data) if (0 == q->id) { /* problem with query data -- query not sent */ - callback(data, NULL, 0); + callback(data, NULL, 0, "Internal error"); memFree(q, MEM_IDNS_QUERY); return; } diff --git a/src/fqdncache.cc b/src/fqdncache.cc index 4074f36669..7d9e8a5a50 100644 --- a/src/fqdncache.cc +++ b/src/fqdncache.cc @@ -1,6 +1,6 @@ /* - * $Id: fqdncache.cc,v 1.158 2004/04/03 14:35:48 hno Exp $ + * $Id: fqdncache.cc,v 1.159 2004/04/10 13:10:17 hno Exp $ * * DEBUG: section 35 FQDN Cache * AUTHOR: Harvest Derived @@ -84,10 +84,10 @@ static dlink_list lru_list; #if USE_DNSSERVERS static HLPCB fqdncacheHandleReply; -static fqdncache_entry *fqdncacheParse(const char *buf); +static int fqdncacheParse(fqdncache_entry *, const char *buf); #else static IDNSCB fqdncacheHandleReply; -static fqdncache_entry *fqdncacheParse(rfc1035_rr *, int); +static int fqdncacheParse(fqdncache_entry *, rfc1035_rr *, int, const char *error_message); #endif static void fqdncacheRelease(fqdncache_entry *); static fqdncache_entry *fqdncacheCreateEntry(const char *name); @@ -262,21 +262,21 @@ fqdncacheCallback(fqdncache_entry * f) fqdncacheUnlockEntry(f); } -static fqdncache_entry * #if USE_DNSSERVERS -fqdncacheParse(const char *inbuf) +static int +fqdncacheParse(fqdncache_entry *f, const char *inbuf) { LOCAL_ARRAY(char, buf, DNS_INBUF_SZ); char *token; - static fqdncache_entry f; int ttl; - memset(&f, '\0', sizeof(f)); - f.expires = squid_curtime; - f.flags.negcached = 1; + const char *name = (const char *)f->hash.key; + f->expires = squid_curtime + Config.negativeDnsTtl; + f->flags.negcached = 1; if (inbuf == NULL) { - debug(35, 1) ("fqdncacheParse: Got reply\n"); - return &f; + debug(35, 1) ("fqdncacheParse: Got reply in response to '%s'\n", name); + f->error_message = xstrdup("Internal Error"); + return -1; } xstrncpy(buf, inbuf, DNS_INBUF_SZ); @@ -284,73 +284,81 @@ fqdncacheParse(const char *inbuf) token = strtok(buf, w_space); if (NULL == token) { - debug(35, 1) ("fqdncacheParse: Got , expecting '$name'\n"); - return &f; + debug(35, 1) ("fqdncacheParse: Got , expecting '$name' in response to '%s'\n", name); + f->error_message = xstrdup("Internal Error"); + return -1; } if (0 == strcmp(token, "$fail")) { - f.expires = squid_curtime + Config.negativeDnsTtl; token = strtok(NULL, "\n"); assert(NULL != token); - f.error_message = xstrdup(token); - return &f; + f->error_message = xstrdup(token); + return 0; } if (0 != strcmp(token, "$name")) { - debug(35, 1) ("fqdncacheParse: Got '%s', expecting '$name'\n", token); - return &f; + debug(35, 1) ("fqdncacheParse: Got '%s', expecting '$name' in response to '%s'\n", inbuf, name); + f->error_message = xstrdup("Internal Error"); + return -1; } token = strtok(NULL, w_space); if (NULL == token) { - debug(35, 1) ("fqdncacheParse: Got , expecting TTL\n"); - return &f; + debug(35, 1) ("fqdncacheParse: Got '%s', expecting TTL in response to '%s'\n", inbuf, name); + f->error_message = xstrdup("Internal Error"); + return -1; } - f.flags.negcached = 0; ttl = atoi(token); - if (ttl > 0 && ttl < Config.positiveDnsTtl) - f.expires = squid_curtime + ttl; - else - f.expires = squid_curtime + Config.positiveDnsTtl; - token = strtok(NULL, w_space); - if (NULL != token) { - f.names[0] = xstrdup(token); - f.name_count = 1; + if (NULL == token) { + debug(35, 1) ("fqdncacheParse: Got '%s', expecting hostname in response to '%s'\n", inbuf, name); + f->error_message = xstrdup("Internal Error"); + return -1; } - return &f; + f->names[0] = xstrdup(token); + f->name_count = 1; + + if (ttl == 0 || ttl > Config.positiveDnsTtl) + ttl = Config.positiveDnsTtl; + + if (ttl < Config.negativeDnsTtl) + ttl = Config.negativeDnsTtl; + + f->expires = squid_curtime + ttl; + + f->flags.negcached = 0; + + return f->name_count; } #else -fqdncacheParse(rfc1035_rr * answers, int nr) +static int +fqdncacheParse(fqdncache_entry *f, rfc1035_rr * answers, int nr, const char *error_message) { - static fqdncache_entry f; int k; - int na = 0; - memset(&f, '\0', sizeof(f)); - f.expires = squid_curtime + Config.negativeDnsTtl; - f.flags.negcached = 1; + int ttl = 0; + const char *name = (const char *)f->hash.key; + f->expires = squid_curtime + Config.negativeDnsTtl; + f->flags.negcached = 1; if (nr < 0) { - debug(35, 3) ("fqdncacheParse: Lookup failed (error %d)\n", - rfc1035_errno); - assert(rfc1035_error_message); - f.error_message = xstrdup(rfc1035_error_message); - return &f; + debug(35, 3) ("fqdncacheParse: Lookup of '%s' failed (%s)\n", name, error_message); + f->error_message = xstrdup(error_message); + return -1; } if (nr == 0) { - debug(35, 3) ("fqdncacheParse: No DNS records\n"); - f.error_message = xstrdup("No DNS records"); - return &f; + debug(35, 3) ("fqdncacheParse: No DNS records for '%s'\n", name); + f->error_message = xstrdup("No DNS records"); + return 0; } - debug(35, 3) ("fqdncacheParse: %d answers\n", nr); + debug(35, 3) ("fqdncacheParse: %d answers for '%s'\n", nr, name); assert(answers); for (k = 0; k < nr; k++) { @@ -360,25 +368,32 @@ fqdncacheParse(rfc1035_rr * answers, int nr) if (answers[k]._class != RFC1035_CLASS_IN) continue; - na++; + f->names[f->name_count++] = xstrndup(answers[k].rdata, answers[k].rdlength); - f.flags.negcached = 0; + if (ttl == 0 || (int) answers[k].ttl < ttl) + ttl = answers[k].ttl; - f.names[0] = xstrndup(answers[k].rdata, answers[k].rdlength); + if (f->name_count >= FQDN_MAX_NAMES) + break; + } - f.name_count = 1; + if (f->name_count == 0) { + debug(35, 1) ("fqdncacheParse: No PTR record\n"); + f->error_message = xstrdup("No PTR record"); + return 0; + } - if ((int) answers[k].ttl < Config.positiveDnsTtl) - f.expires = squid_curtime + answers[k].ttl; - else - f.expires = squid_curtime + Config.positiveDnsTtl; + if (ttl == 0 || ttl > Config.positiveDnsTtl) + ttl = Config.positiveDnsTtl; - return &f; - } + if (ttl < Config.negativeDnsTtl) + ttl = Config.negativeDnsTtl; + + f->expires = squid_curtime + ttl; - debug(35, 1) ("fqdncacheParse: No PTR record\n"); - f.error_message = xstrdup("No PTR record"); - return &f; + f->flags.negcached = 0; + + return f->name_count; } #endif @@ -387,13 +402,12 @@ static void #if USE_DNSSERVERS fqdncacheHandleReply(void *data, char *reply) #else -fqdncacheHandleReply(void *data, rfc1035_rr * answers, int na) +fqdncacheHandleReply(void *data, rfc1035_rr * answers, int na, const char *error_message) #endif { int n; generic_cbdata *c = (generic_cbdata *)data; fqdncache_entry *f = (fqdncache_entry *)c->data; - fqdncache_entry *x = NULL; cbdataFree(c); c = NULL; n = ++FqdncacheStats.replies; @@ -401,24 +415,13 @@ fqdncacheHandleReply(void *data, rfc1035_rr * answers, int na) tvSubMsec(f->request_time, current_time)); #if USE_DNSSERVERS - x = fqdncacheParse(reply); + fqdncacheParse(f, reply); + ; #else - x = fqdncacheParse(answers, na); + fqdncacheParse(f, answers, na, error_message); #endif - assert(x); - f->name_count = x->name_count; - - for (n = 0; n < (int) f->name_count; n++) - f->names[n] = x->names[n]; - - f->error_message = x->error_message; - - f->expires = x->expires; - - f->flags = x->flags; - fqdncacheAddEntry(f); fqdncacheCallback(f); diff --git a/src/ipcache.cc b/src/ipcache.cc index d562f5de6e..d2e76cea0f 100644 --- a/src/ipcache.cc +++ b/src/ipcache.cc @@ -1,6 +1,6 @@ /* - * $Id: ipcache.cc,v 1.243 2004/04/03 14:35:48 hno Exp $ + * $Id: ipcache.cc,v 1.244 2004/04/10 13:10:17 hno Exp $ * * DEBUG: section 14 IP Cache * AUTHOR: Harvest Derived @@ -88,9 +88,9 @@ static IPH dummy_handler; static int ipcacheExpiredEntry(ipcache_entry *); static int ipcache_testname(void); #if USE_DNSSERVERS -static ipcache_entry *ipcacheParse(const char *buf); +static int ipcacheParse(ipcache_entry *, const char *buf); #else -static ipcache_entry *ipcacheParse(rfc1035_rr *, int); +static int ipcacheParse(ipcache_entry *, rfc1035_rr *, int, const char *error); #endif static ipcache_entry *ipcache_get(const char *); static void ipcacheLockEntry(ipcache_entry *); @@ -266,26 +266,27 @@ ipcacheCallback(ipcache_entry * i) ipcacheUnlockEntry(i); } -static ipcache_entry * #if USE_DNSSERVERS -ipcacheParse(const char *inbuf) +static int +ipcacheParse(ipcache_entry *i, const char *inbuf) { LOCAL_ARRAY(char, buf, DNS_INBUF_SZ); char *token; - static ipcache_entry i; - int j; - int k; int ipcount = 0; int ttl; - char A[32][16]; - memset(&i, '\0', sizeof(i)); - i.expires = squid_curtime; - i.flags.negcached = 1; + char *A[32]; + const char *name = (const char *)i->hash.key; + i->expires = squid_curtime + Config.negativeDnsTtl; + i->flags.negcached = 1; + safe_free(i->addrs.in_addrs); + safe_free(i->addrs.bad_mask); + safe_free(i->error_message); + i->addrs.count = 0; if (inbuf == NULL) { debug(14, 1) ("ipcacheParse: Got reply\n"); - i.error_message = xstrdup("Internal Squid Error"); - return &i; + i->error_message = xstrdup("Internal Error"); + return -1; } xstrncpy(buf, inbuf, DNS_INBUF_SZ); @@ -293,88 +294,102 @@ ipcacheParse(const char *inbuf) token = strtok(buf, w_space); if (NULL == token) { - debug(14, 1) ("ipcacheParse: Got , expecting '$addr'\n"); - return &i; + debug(14, 1) ("ipcacheParse: expecting result, got '%s'\n", inbuf); + i->error_message = xstrdup("Internal Error"); + return -1; } if (0 == strcmp(token, "$fail")) { - i.expires = squid_curtime + Config.negativeDnsTtl; token = strtok(NULL, "\n"); assert(NULL != token); - i.error_message = xstrdup(token); - return &i; + i->error_message = xstrdup(token); + return 0; } if (0 != strcmp(token, "$addr")) { - debug(14, 1) ("ipcacheParse: Got '%s', expecting '$addr'\n", token); - return &i; + debug(14, 1) ("ipcacheParse: expecting '$addr', got '%s' in response to '%s'\n", inbuf, name); + i->error_message = xstrdup("Internal Error"); + return -1; } token = strtok(NULL, w_space); if (NULL == token) { - debug(14, 1) ("ipcacheParse: Got , expecting TTL\n"); - return &i; + debug(14, 1) ("ipcacheParse: expecting TTL, got '%s' in response to '%s'\n", inbuf, name); + i->error_message = xstrdup("Internal Error"); + return -1; } - i.flags.negcached = 0; ttl = atoi(token); - if (ttl > 0 && ttl < Config.positiveDnsTtl) - i.expires = squid_curtime + ttl; - else - i.expires = squid_curtime + Config.positiveDnsTtl; - while (NULL != (token = strtok(NULL, w_space))) { - xstrncpy(A[ipcount], token, 16); + A[ipcount] = token; if (++ipcount == 32) break; } - if (0 == ipcount) { - i.addrs.in_addrs = NULL; - i.addrs.bad_mask = NULL; - } else { + if (ipcount > 0) { + int j, k; + + i->addrs.in_addrs = xcalloc(ipcount, sizeof(struct in_addr)); + i->addrs.bad_mask = xcalloc(ipcount, sizeof(unsigned char)); - i.addrs.in_addrs = (struct in_addr *)xcalloc(ipcount, sizeof(struct in_addr)); - i.addrs.bad_mask = (unsigned char *)xcalloc(ipcount, sizeof(unsigned char)); + for (j = 0, k = 0; k < ipcount; k++) { + if (safe_inet_addr(A[k], &i->addrs.in_addrs[j])) + j++; + else + debug(14, 1) ("ipcacheParse: Invalid IP address '%s' in response to '%s'\n", A[k], name); + } + + i->addrs.count = (unsigned char) j; } - for (j = 0, k = 0; k < ipcount; k++) { - if (safe_inet_addr(A[k], &i.addrs.in_addrs[j])) - j++; - else - debug(14, 1) ("ipcacheParse: Invalid IP address '%s'\n", A[k]); + if (i->addrs.count <= 0) { + debug(14, 1) ("ipcacheParse: No addresses in response to '%s'\n", name); + return -1; } - i.addrs.count = (unsigned char) j; - return &i; + if (ttl == 0 || ttl > Config.positiveDnsTtl) + ttl = Config.positiveDnsTtl; + + if (ttl < Config.negativeDnsTtl) + ttl = Config.negativeDnsTtl; + + i->expires = squid_curtime + ttl; + + i->flags.negcached = 0; + + return i->addrs.count; } #else -ipcacheParse(rfc1035_rr * answers, int nr) +static int +ipcacheParse(ipcache_entry *i, rfc1035_rr * answers, int nr, const char *error_message) { - static ipcache_entry i; int k; int j; int na = 0; - memset(&i, '\0', sizeof(i)); - i.expires = squid_curtime + Config.negativeDnsTtl; - i.flags.negcached = 1; + int ttl = 0; + const char *name = (const char *)i->hash.key; + i->expires = squid_curtime + Config.negativeDnsTtl; + i->flags.negcached = 1; + safe_free(i->addrs.in_addrs); + safe_free(i->addrs.bad_mask); + safe_free(i->error_message); + i->addrs.count = 0; if (nr < 0) { - debug(14, 3) ("ipcacheParse: Lookup failed (error %d)\n", - rfc1035_errno); - assert(rfc1035_error_message); - i.error_message = xstrdup(rfc1035_error_message); - return &i; + debug(14, 3) ("ipcacheParse: Lookup failed '%s' for '%s'\n", + error_message, (const char *)i->hash.key); + i->error_message = xstrdup(error_message); + return -1; } if (nr == 0) { - debug(14, 3) ("ipcacheParse: No DNS records\n"); - i.error_message = xstrdup("No DNS records"); - return &i; + debug(14, 3) ("ipcacheParse: No DNS records in response to '%s'\n", name); + i->error_message = xstrdup("No DNS records"); + return 0; } assert(answers); @@ -390,16 +405,13 @@ ipcacheParse(rfc1035_rr * answers, int nr) } if (na == 0) { - debug(14, 1) ("ipcacheParse: No Address records\n"); - i.error_message = xstrdup("No Address records"); - return &i; + debug(14, 1) ("ipcacheParse: No Address records in response to '%s'\n", name); + i->error_message = xstrdup("No Address records"); + return 0; } - i.flags.negcached = 0; - - i.addrs.in_addrs = (struct in_addr *)xcalloc(na, sizeof(struct in_addr)); - i.addrs.bad_mask = (unsigned char *)xcalloc(na, sizeof(unsigned char)); - i.addrs.count = (unsigned char) na; + i->addrs.in_addrs = (struct in_addr *)xcalloc(na, sizeof(struct in_addr)); + i->addrs.bad_mask = (unsigned char *)xcalloc(na, sizeof(unsigned char)); for (j = 0, k = 0; k < nr; k++) { if (answers[k].type != RFC1035_TYPE_A) @@ -408,24 +420,33 @@ ipcacheParse(rfc1035_rr * answers, int nr) if (answers[k]._class != RFC1035_CLASS_IN) continue; - if (j == 0) { - if ((int) answers[k].ttl < Config.positiveDnsTtl) - i.expires = squid_curtime + answers[k].ttl; - else - i.expires = squid_curtime + Config.positiveDnsTtl; - } + if (ttl == 0 || (int) answers[k].ttl < ttl) + ttl = answers[k].ttl; assert(answers[k].rdlength == 4); - xmemcpy(&i.addrs.in_addrs[j++], answers[k].rdata, 4); + xmemcpy(&i->addrs.in_addrs[j++], answers[k].rdata, 4); debug(14, 3) ("ipcacheParse: #%d %s\n", j - 1, - inet_ntoa(i.addrs.in_addrs[j - 1])); + inet_ntoa(i->addrs.in_addrs[j - 1])); } assert(j == na); - return &i; + + i->addrs.count = (unsigned char) na; + + if (ttl == 0 || ttl > Config.positiveDnsTtl) + ttl = Config.positiveDnsTtl; + + if (ttl < Config.negativeDnsTtl) + ttl = Config.negativeDnsTtl; + + i->expires = squid_curtime + ttl; + + i->flags.negcached = 0; + + return i->addrs.count; } #endif @@ -434,12 +455,11 @@ static void #if USE_DNSSERVERS ipcacheHandleReply(void *data, char *reply) #else -ipcacheHandleReply(void *data, rfc1035_rr * answers, int na) +ipcacheHandleReply(void *data, rfc1035_rr * answers, int na, const char *error_message) #endif { generic_cbdata *c = (generic_cbdata *)data; ipcache_entry *i = (ipcache_entry *)c->data; - ipcache_entry *x = NULL; cbdataFree(c); c = NULL; IpcacheStats.replies++; @@ -447,17 +467,12 @@ ipcacheHandleReply(void *data, rfc1035_rr * answers, int na) tvSubMsec(i->request_time, current_time)); #if USE_DNSSERVERS - x = ipcacheParse(reply); + ipcacheParse(i, reply); #else - x = ipcacheParse(answers, na); + ipcacheParse(i, answers, na, error_message); #endif - assert(x); - i->addrs = x->addrs; - i->error_message = x->error_message; - i->expires = x->expires; - i->flags = x->flags; ipcacheAddEntry(i); ipcacheCallback(i); } diff --git a/src/typedefs.h b/src/typedefs.h index 40ce460481..ee2090263d 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.173 2004/04/04 14:31:05 hno Exp $ + * $Id: typedefs.h,v 1.174 2004/04/10 13:10:17 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -316,7 +316,7 @@ typedef stateful_helper_callback_t HLPSCB(void *, void *lastserver, char *buf); typedef int HLPSAVAIL(void *); typedef void HLPSONEQ(void *); typedef void HLPCMDOPTS(int *argc, char **argv); -typedef void IDNSCB(void *, rfc1035_rr *, int); +typedef void IDNSCB(void *, rfc1035_rr *, int, const char *); typedef double hbase_f(double); typedef void StatHistBinDumper(StoreEntry *, int idx, double val, double size, int count);