From: wessels <> Date: Fri, 14 Jul 2000 23:45:52 +0000 (+0000) Subject: DW: X-Git-Tag: SQUID_3_0_PRE1~1899 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=558be27a00732874f2f24048a883bcbefd5cdb90;p=thirdparty%2Fsquid.git DW: - This patch retries internal DNS queries that are returned with RCODE 2 (ServFail). --- diff --git a/include/rfc1035.h b/include/rfc1035.h index fedc09be0d..9b6b41c50d 100644 --- a/include/rfc1035.h +++ b/include/rfc1035.h @@ -1,5 +1,5 @@ /* - * $Id: rfc1035.h,v 1.2 1999/04/18 05:10:39 wessels Exp $ + * $Id: rfc1035.h,v 1.3 2000/07/14 17:45:52 wessels Exp $ * * AUTHOR: Harvest Derived * @@ -58,6 +58,7 @@ extern unsigned short rfc1035BuildAQuery(const char *hostname, extern unsigned short rfc1035BuildPTRQuery(const struct in_addr, char *buf, size_t * szp); +extern unsigned short rfc1035RetryQuery(char *); extern int rfc1035AnswersUnpack(const char *buf, size_t sz, rfc1035_rr ** records, diff --git a/lib/rfc1035.c b/lib/rfc1035.c index a0eb0205f1..971c1590c6 100644 --- a/lib/rfc1035.c +++ b/lib/rfc1035.c @@ -1,6 +1,6 @@ /* - * $Id: rfc1035.c,v 1.16 2000/05/12 00:37:25 wessels Exp $ + * $Id: rfc1035.c,v 1.17 2000/07/14 17:45:54 wessels Exp $ * * Low level DNS protocol routines * AUTHOR: Duane Wessels @@ -543,6 +543,20 @@ rfc1035BuildPTRQuery(const struct in_addr addr, char *buf, size_t * szp) return h.id; } +/* + * We're going to retry a former query, but we + * just need a new ID for it. Lucky for us ID + * is the first field in the message buffer. + */ +unsigned short +rfc1035RetryQuery(char *buf) +{ + unsigned short qid = rfc1035Qid(); + unsigned short s = htons(qid); + memcpy(buf, &s, sizeof(s)); + return qid; +} + #if DRIVER #include #include diff --git a/src/dns_internal.cc b/src/dns_internal.cc index 3a1f25e513..2f2e32fe8c 100644 --- a/src/dns_internal.cc +++ b/src/dns_internal.cc @@ -1,6 +1,6 @@ /* - * $Id: dns_internal.cc,v 1.29 2000/06/27 22:06:01 hno Exp $ + * $Id: dns_internal.cc,v 1.30 2000/07/14 17:45:54 wessels Exp $ * * DEBUG: section 78 DNS lookups; interacts with lib/rfc1035.c * AUTHOR: Duane Wessels @@ -42,6 +42,10 @@ #define DOMAIN_PORT 53 #endif +#define MAX_RCODE 6 +#define MAX_ATTEMPT 3 +static int RcodeMatrix[MAX_RCODE][MAX_ATTEMPT]; + typedef struct _idns_query idns_query; typedef struct _ns ns; @@ -55,6 +59,7 @@ struct _idns_query { dlink_node lru; IDNSCB *callback; void *callback_data; + int attempt; }; struct _ns { @@ -81,6 +86,7 @@ static void idnsGrokReply(const char *buf, size_t sz); static PF idnsRead; static EVH idnsCheckQueue; static void idnsTickleQueue(void); +static void idnsRcodeCount(int, int); static void idnsAddNameserver(const char *buf) @@ -161,6 +167,7 @@ idnsStats(StoreEntry * sentry) dlink_node *n; idns_query *q; int i; + int j; storeAppendPrintf(sentry, "Internal DNS Statistics:\n"); storeAppendPrintf(sentry, "\nThe Queue:\n"); storeAppendPrintf(sentry, " DELAY SINCE\n"); @@ -182,6 +189,16 @@ idnsStats(StoreEntry * sentry) nameservers[i].nqueries, nameservers[i].nreplies); } + storeAppendPrintf(sentry, "\nRcode Matrix:\n"); + storeAppendPrintf(sentry, "RCODE"); + for (i = 0; i < MAX_ATTEMPT; i++) + storeAppendPrintf(sentry, " ATTEMPT%d", i + 1); + for (j = 0; j < MAX_RCODE; j++) { + storeAppendPrintf(sentry, "%5d", j); + for (i = 0; i < MAX_ATTEMPT; i++) + storeAppendPrintf(sentry, " %8d", RcodeMatrix[j][i]); + storeAppendPrintf(sentry, "\n"); + } } static void @@ -283,8 +300,22 @@ idnsGrokReply(const char *buf, size_t sz) return; } dlinkDelete(&q->lru, &lru_list); - if (n < 0) + idnsRcodeCount(n, q->attempt); + if (n < 0) { debug(78, 3) ("idnsGrokReply: error %d\n", rfc1035_errno); + if (-2 == n && ++q->attempt < MAX_ATTEMPT) { + /* + * RCODE 2 is "Server failure - The name server was + * unable to process this query due to a problem with + * the name server." + */ + assert(NULL == answers); + q->start_t = current_time; + q->id = rfc1035RetryQuery(q->buf); + idnsSendQuery(q); + return; + } + } valid = cbdataValid(q->callback_data); cbdataUnlock(q->callback_data); if (valid) @@ -380,6 +411,21 @@ idnsCheckQueue(void *unused) idnsTickleQueue(); } +/* + * rcode < 0 indicates an error, rocde >= 0 indicates success + */ +static void +idnsRcodeCount(int rcode, int attempt) +{ + if (rcode > 0) + rcode = 0; + else if (rcode < 0) + rcode = -rcode; + if (rcode < MAX_RCODE) + if (attempt < MAX_ATTEMPT) + RcodeMatrix[rcode][attempt]++; +} + /* ====================================================================== */ void @@ -406,6 +452,7 @@ idnsInit(void) cachemgrRegister("idns", "Internal DNS Statistics", idnsStats, 0, 1); + memset(RcodeMatrix, '\0', sizeof(RcodeMatrix)); init++; } }