diff options
-rw-r--r-- | sys/src/cmd/ndb/dn.c | 1 | ||||
-rw-r--r-- | sys/src/cmd/ndb/dnresolve.c | 39 | ||||
-rw-r--r-- | sys/src/cmd/ndb/dns.h | 1 |
3 files changed, 34 insertions, 7 deletions
diff --git a/sys/src/cmd/ndb/dn.c b/sys/src/cmd/ndb/dn.c index 7383c9e4b..fcf262259 100644 --- a/sys/src/cmd/ndb/dn.c +++ b/sys/src/cmd/ndb/dn.c @@ -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; diff --git a/sys/src/cmd/ndb/dnresolve.c b/sys/src/cmd/ndb/dnresolve.c index 6e8709e94..3c5942093 100644 --- a/sys/src/cmd/ndb/dnresolve.c +++ b/sys/src/cmd/ndb/dnresolve.c @@ -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) diff --git a/sys/src/cmd/ndb/dns.h b/sys/src/cmd/ndb/dns.h index 1e0ae2e86..e14a20cdd 100644 --- a/sys/src/cmd/ndb/dns.h +++ b/sys/src/cmd/ndb/dns.h @@ -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; }; /* |