Commit e921101e authored by Mark Andrews's avatar Mark Andrews

complain about CNAME nameservers; use siginfo to get query statistics

parent c7ee9a89
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <errno.h> #include <errno.h>
#include <netdb.h> #include <netdb.h>
#include <resolv.h> #include <resolv.h>
#include <signal.h>
#define ns_t_dname 39 #define ns_t_dname 39
#define ns_t_sink 40 #define ns_t_sink 40
...@@ -82,7 +83,8 @@ static int badtag = 0; ...@@ -82,7 +83,8 @@ static int badtag = 0;
static int ednsonly = 0; static int ednsonly = 0;
static int debug = 0; static int debug = 0;
static int inorder = 0; static int inorder = 0;
static int serial = 0; static int serial = 0;
static long long sent;
static union res_sockaddr_union servers[10]; static union res_sockaddr_union servers[10];
static int nservers = 0; static int nservers = 0;
...@@ -333,6 +335,8 @@ struct summary { ...@@ -333,6 +335,8 @@ struct summary {
int nxdomainaaaa; /* recursive query got nxdomain */ int nxdomainaaaa; /* recursive query got nxdomain */
int faileda; int faileda;
int failedaaaa; int failedaaaa;
int cnamea; /* Nameserver is CNAME */
int cnameaaaa; /* Nameserver is CNAME */
int seenrrsig; /* a rrsig was seen in "do" test */ int seenrrsig; /* a rrsig was seen in "do" test */
int seenopt; /* see a EDNS response */ int seenopt; /* see a EDNS response */
int seenedns; /* see a EDNS response */ int seenedns; /* see a EDNS response */
...@@ -475,6 +479,7 @@ printandfree(struct summary *summary) { ...@@ -475,6 +479,7 @@ printandfree(struct summary *summary) {
freesummary(summary); freesummary(summary);
return; return;
} }
if ((summary->type == ns_t_a || summary->type == ns_t_aaaa) && if ((summary->type == ns_t_a || summary->type == ns_t_aaaa) &&
summary->faileda && summary->failedaaaa) { summary->faileda && summary->failedaaaa) {
printf("%s. %s: address lookups failed\n", printf("%s. %s: address lookups failed\n",
...@@ -483,28 +488,40 @@ printandfree(struct summary *summary) { ...@@ -483,28 +488,40 @@ printandfree(struct summary *summary) {
return; return;
} }
if ((summary->type == ns_t_a || summary->type == ns_t_aaaa) &&
(summary->cnamea || summary->cnameaaaa)) {
printf("%s. %s: nameserver is a CNAME\n",
summary->zone, summary->ns);
freesummary(summary);
return;
}
/* /*
* Do deferred xlink failure reports. * Do deferred xlink failure reports.
*/ */
if (summary->type == ns_t_a && summary->nodataa && summary->failedaaaa) { if (summary->type == ns_t_a &&
summary->nodataa && summary->failedaaaa) {
printf("%s. %s:", summary->zone, summary->ns); printf("%s. %s:", summary->zone, summary->ns);
printf(" AAAAA lookup failed\n"); printf(" AAAAA lookup failed\n");
freesummary(summary); freesummary(summary);
return; return;
} }
if (summary->type == ns_t_aaaa && summary->nodataaaaa && summary->faileda) { if (summary->type == ns_t_aaaa &&
summary->nodataaaaa && summary->faileda) {
printf("%s. %s:", summary->zone, summary->ns); printf("%s. %s:", summary->zone, summary->ns);
printf(" A lookup failed\n"); printf(" A lookup failed\n");
freesummary(summary); freesummary(summary);
return; return;
} }
if (summary->type == ns_t_a && summary->faileda && summary->nxdomainaaaa) { if (summary->type == ns_t_a &&
summary->faileda && summary->nxdomainaaaa) {
printf("%s. %s:", summary->zone, summary->ns); printf("%s. %s:", summary->zone, summary->ns);
printf(" AAAAA nxdomain\n"); printf(" AAAAA nxdomain\n");
freesummary(summary); freesummary(summary);
return; return;
} }
if (summary->type == ns_t_aaaa && summary->failedaaaa && summary->nxdomaina) { if (summary->type == ns_t_aaaa &&
summary->failedaaaa && summary->nxdomaina) {
printf("%s. %s:", summary->zone, summary->ns); printf("%s. %s:", summary->zone, summary->ns);
printf(" A nxdomain\n"); printf(" A nxdomain\n");
freesummary(summary); freesummary(summary);
...@@ -636,6 +653,14 @@ report(struct summary *summary) { ...@@ -636,6 +653,14 @@ report(struct summary *summary) {
* structure. * structure.
*/ */
if (summary->xlink) { if (summary->xlink) {
if (summary->cnamea) {
summary->xlink->cnamea = 1;
summary->done = 1;
}
if (summary->cnameaaaa) {
summary->xlink->cnameaaaa = 1;
summary->done = 1;
}
if (summary->nodataa) { if (summary->nodataa) {
summary->xlink->nodataa = 1; summary->xlink->nodataa = 1;
summary->done = 1; summary->done = 1;
...@@ -770,6 +795,7 @@ resend(struct workitem *item) { ...@@ -770,6 +795,7 @@ resend(struct workitem *item) {
opts[item->test].udpsize, opts[item->test].flags, opts[item->test].udpsize, opts[item->test].flags,
opts[item->test].version, opts[item->test].tcp, opts[item->test].version, opts[item->test].tcp,
opts[item->test].ignore, item->id); opts[item->test].ignore, item->id);
sent++;
if (!item->outstanding++) if (!item->outstanding++)
outstanding++; outstanding++;
gettimeofday(&item->when, NULL); gettimeofday(&item->when, NULL);
...@@ -941,6 +967,7 @@ dotest(struct workitem *item) { ...@@ -941,6 +967,7 @@ dotest(struct workitem *item) {
opts[item->test].ignore, item->id); opts[item->test].ignore, item->id);
if (!item->outstanding++) if (!item->outstanding++)
outstanding++; outstanding++;
sent++;
gettimeofday(&item->when, NULL); gettimeofday(&item->when, NULL);
item->when.tv_sec += 1; item->when.tv_sec += 1;
item->sends = 1; item->sends = 1;
...@@ -1155,6 +1182,7 @@ dolookup(struct workitem *item, int type) { ...@@ -1155,6 +1182,7 @@ dolookup(struct workitem *item, int type) {
printf("lookup %u id=%u\n", item->type, item->id); printf("lookup %u id=%u\n", item->type, item->id);
if (!item->outstanding++) if (!item->outstanding++)
outstanding++; outstanding++;
sent++;
gettimeofday(&item->when, NULL); gettimeofday(&item->when, NULL);
item->when.tv_sec += 1; item->when.tv_sec += 1;
item->sends++; item->sends++;
...@@ -1325,10 +1353,6 @@ process(struct workitem *item, unsigned char *buf, int n) { ...@@ -1325,10 +1353,6 @@ process(struct workitem *item, unsigned char *buf, int n) {
} }
/* process message body */ /* process message body */
if (item->type == ns_t_a || item->type == ns_t_aaaa)
strlcpy(ns, item->summary->ns, sizeof(ns));
cp = buf + 12; cp = buf + 12;
eom = buf + n; eom = buf + n;
for (i = 0; i < qrcount; i++) { for (i = 0; i < qrcount; i++) {
...@@ -1397,14 +1421,22 @@ process(struct workitem *item, unsigned char *buf, int n) { ...@@ -1397,14 +1421,22 @@ process(struct workitem *item, unsigned char *buf, int n) {
cp += 2; cp += 2;
if ((eom - cp) < rdlen) if ((eom - cp) < rdlen)
goto err; goto err;
/* Don't follow CNAME for A and AAAA lookups. */
if ((item->type == ns_t_a || item->type == ns_t_aaaa) && if ((item->type == ns_t_a || item->type == ns_t_aaaa) &&
type == ns_t_cname && strcasecmp(ns, name) == 0) { type == ns_t_cname &&
n = dn_expand(buf, eom, cp, ns, sizeof(ns)); strcasecmp(item->summary->ns, name) == 0) {
if (n != rdlen) if (item->type == ns_t_a)
goto err; item->summary->cnamea = 1;
else
item->summary->cnameaaaa = 1;
}
/* Don't follow CNAME for NS lookups. */
if (item->type == ns_t_ns && type == ns_t_cname &&
strcasecmp(item->summary->zone, name) == 0) {
item->summary->done = 1;
} }
if (item->type == ns_t_a && type == ns_t_a && if (item->type == ns_t_a && type == ns_t_a &&
strcasecmp(ns, name) == 0) strcasecmp(item->summary->ns, name) == 0)
{ {
if (rdlen != 4) if (rdlen != 4)
goto err; goto err;
...@@ -1414,7 +1446,7 @@ process(struct workitem *item, unsigned char *buf, int n) { ...@@ -1414,7 +1446,7 @@ process(struct workitem *item, unsigned char *buf, int n) {
item->summary->done = 1; item->summary->done = 1;
} }
if (item->type == ns_t_aaaa && type == ns_t_aaaa && if (item->type == ns_t_aaaa && type == ns_t_aaaa &&
strcasecmp(ns, name) == 0) strcasecmp(item->summary->ns, name) == 0)
{ {
if (rdlen != 16) if (rdlen != 16)
goto err; goto err;
...@@ -2075,9 +2107,16 @@ addserver(const char *hostname) { ...@@ -2075,9 +2107,16 @@ addserver(const char *hostname) {
} }
} }
static int stats;
static void
info(int sig) {
stats = 1;
}
int int
main(int argc, char **argv) { main(int argc, char **argv) {
struct timeval now, to, *tpo = NULL; struct timeval now, to, start, *tpo = NULL;
struct workitem *item = NULL, *citem, *ritem; struct workitem *item = NULL, *citem, *ritem;
fd_set myrfds, mywfds; fd_set myrfds, mywfds;
unsigned int i; unsigned int i;
...@@ -2138,6 +2177,8 @@ main(int argc, char **argv) { ...@@ -2138,6 +2177,8 @@ main(int argc, char **argv) {
} }
} }
signal(SIGINFO, info);
FD_ZERO(&rfds); FD_ZERO(&rfds);
FD_ZERO(&wfds); FD_ZERO(&wfds);
...@@ -2173,6 +2214,8 @@ main(int argc, char **argv) { ...@@ -2173,6 +2214,8 @@ main(int argc, char **argv) {
nservers = res_getservers(&_res, servers, nservers = res_getservers(&_res, servers,
sizeof(servers)/sizeof(servers[0])); sizeof(servers)/sizeof(servers[0]));
gettimeofday(&start, NULL);
/* /*
* Main work loop. * Main work loop.
*/ */
...@@ -2219,8 +2262,16 @@ main(int argc, char **argv) { ...@@ -2219,8 +2262,16 @@ main(int argc, char **argv) {
item = HEAD(work); item = HEAD(work);
ritem = HEAD(reading); ritem = HEAD(reading);
citem = HEAD(connecting); citem = HEAD(connecting);
if (item || citem || ritem) if (item || citem || ritem || stats)
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
if (stats) {
long long usecs, qps;
usecs = (now.tv_sec - start.tv_sec) * 1000000;
usecs += now.tv_usec - start.tv_usec;
qps = (sent * 1000000000) / usecs;
fprintf(stderr, "%llu.%03llu\n", qps/1000, qps%1000);
stats = 0;
}
/* /*
* UDP work queue. * UDP work queue.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment