/*
- * $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
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>
/*
- * $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;
dlink_node lru;
IDNSCB *callback;
void *callback_data;
+ int attempt;
};
struct _ns {
static PF idnsRead;
static EVH idnsCheckQueue;
static void idnsTickleQueue(void);
+static void idnsRcodeCount(int, int);
static void
idnsAddNameserver(const char *buf)
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");
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
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)
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
cachemgrRegister("idns",
"Internal DNS Statistics",
idnsStats, 0, 1);
+ memset(RcodeMatrix, '\0', sizeof(RcodeMatrix));
init++;
}
}