]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
DW:
authorwessels <>
Fri, 14 Jul 2000 23:45:52 +0000 (23:45 +0000)
committerwessels <>
Fri, 14 Jul 2000 23:45:52 +0000 (23:45 +0000)
   - This patch retries internal DNS queries that are returned with
     RCODE 2 (ServFail).

include/rfc1035.h
lib/rfc1035.c
src/dns_internal.cc

index fedc09be0d4b0d7319f4b6f934da172eab65ba1e..9b6b41c50d18b3d6717da74ed3963e2ca5587c55 100644 (file)
@@ -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,
index a0eb0205f1e9be36df0d36c879614ccbdd28d45d..971c1590c659a1aa3691833ef3d3b4a1c8997633 100644 (file)
@@ -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 <sys/socket.h>
 #include <sys/time.h>
index 3a1f25e513c1098e8d664de6a2ba1e15973a315e..2f2e32fe8c2a9a5292c45f1dc8a0cdaf450f0ca8 100644 (file)
@@ -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
 #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++;
     }
 }