/*
- * $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
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;
}
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;
/*
- * $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
IDNSCB *callback;
void *callback_data;
int attempt;
+ const char *error;
+ int rcode;
};
struct _ns
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
q->callback = NULL;
if (cbdataReferenceValidDone(q->callback_data, &cbdata))
- callback(cbdata, answers, n);
+ callback(cbdata, answers, n, q->error);
rfc1035RRDestroy(answers, n);
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);
}
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;
}
/*
- * $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
#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);
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 <NULL> reply\n");
- return &f;
+ debug(35, 1) ("fqdncacheParse: Got <NULL> reply in response to '%s'\n", name);
+ f->error_message = xstrdup("Internal Error");
+ return -1;
}
xstrncpy(buf, inbuf, DNS_INBUF_SZ);
token = strtok(buf, w_space);
if (NULL == token) {
- debug(35, 1) ("fqdncacheParse: Got <NULL>, expecting '$name'\n");
- return &f;
+ debug(35, 1) ("fqdncacheParse: Got <NULL>, 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 <NULL>, 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++) {
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
#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;
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);
/*
- * $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
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 *);
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 <NULL> 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);
token = strtok(buf, w_space);
if (NULL == token) {
- debug(14, 1) ("ipcacheParse: Got <NULL>, 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 <NULL>, 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);
}
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)
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
#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++;
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);
}
/*
- * $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/
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);