ndb/dns: detect query loops

never try to resolve a nameserver address when that nameserver
is in the set of nameservers already being queried.

this situation can happen when the Ta and Taaaa RR's expire, but
the Tns records are still in the cache so there is no usable
nameserver but they still refer to each another.
This commit is contained in:
cinap_lenrek 2013-11-16 04:42:09 +01:00
parent 5f87d8dcc8
commit c45386588b
3 changed files with 34 additions and 7 deletions

View file

@ -655,6 +655,7 @@ getactivity(Request *req, int recursive)
now = time(nil);
nowns = nsec();
req->id = ++dnvars.id;
req->aux = nil;
unlock(&dnvars);
return rv;

View file

@ -52,6 +52,8 @@ struct Query {
DN *dp; /* domain */
ushort type; /* and type to look up */
Request *req;
Query *prev; /* previous query */
RR *nsrp; /* name servers to consult */
/* dest must not be on the stack due to forking in slave() */
@ -225,14 +227,18 @@ queryinit(Query *qp, DN *dp, int type, Request *req)
qp->type = type;
if (qp->type != type)
dnslog("queryinit: bogus type %d", type);
qp->req = req;
qp->nsrp = nil;
qp->dest = qp->curdest = nil;
qp->prev = req->aux;
qp->req = req;
req->aux = qp;
}
static void
querydestroy(Query *qp)
{
if(qp->req->aux == qp)
qp->req->aux = qp->prev;
/* leave udpfd open */
if (qp->tcpfd >= 0)
close(qp->tcpfd);
@ -739,6 +745,30 @@ ipisbm(uchar *ip)
return 0;
}
static int
queryloops(Query *qp, RR *rp)
{
DN *ns;
ns = rp->host;
/*
* avoid loops looking up a server under itself
*/
if(subsume(rp->owner->name, ns->name))
return 1;
/*
* must not cycle on name servers refering
* to each another.
*/
for(qp = qp->prev; qp; qp = qp->prev)
for(rp = qp->nsrp; rp; rp = rp->next)
if(rp->host == ns)
return 1;
return 0;
}
/*
* Get next server address(es) into qp->dest[nd] and beyond
*/
@ -787,13 +817,8 @@ serveraddrs(Query *qp, int nd, int depth)
if(rp->marker)
continue;
rp->marker = 1;
/*
* avoid loops looking up a server under itself
*/
if(subsume(rp->owner->name, rp->host->name))
if(queryloops(qp, rp))
continue;
arp = dnresolve(rp->host->name, Cin, Ta, qp->req, 0,
depth+1, Recurse, 1, 0);
if(arp == nil)

View file

@ -182,6 +182,7 @@ struct Request
jmp_buf mret; /* where master jumps to after starting a slave */
int id;
char *from; /* who asked us? */
void *aux;
};
/*