summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/cmd/ndb/dblookup.c23
-rw-r--r--sys/src/cmd/ndb/dnresolve.c102
-rw-r--r--sys/src/cmd/ndb/dns.c2
-rw-r--r--sys/src/cmd/ndb/dnsdebug.c1
4 files changed, 47 insertions, 81 deletions
diff --git a/sys/src/cmd/ndb/dblookup.c b/sys/src/cmd/ndb/dblookup.c
index b7bb9097e..20d58502f 100644
--- a/sys/src/cmd/ndb/dblookup.c
+++ b/sys/src/cmd/ndb/dblookup.c
@@ -257,6 +257,7 @@ dblookup1(char *name, int type, int auth, int ttl)
/*
* find a matching entry in the database
*/
+ t = nil;
nstrcpy(dname, name, sizeof dname);
for(x=0; x<4; x++){
switch(x){
@@ -277,10 +278,23 @@ dblookup1(char *name, int type, int auth, int ttl)
continue;
break;
}
- t = nil;
- free(ndbgetvalue(db, &s, "dom", dname, attr, &t));
- if(t == nil && strchr(dname, '.') == nil)
- free(ndbgetvalue(db, &s, "sys", dname, attr, &t));
+ for(nt = ndbsearch(db, &s, "dom", dname); nt != nil; nt = ndbsnext(&s, "dom", dname)) {
+ if(ndbfindattr(nt, s.t, attr) == nil) {
+ ndbfree(nt);
+ continue;
+ }
+ t = ndbconcatenate(t, ndbreorder(nt, s.t));
+ }
+ if(t == nil && strchr(dname, '.') == nil) {
+ for(nt = ndbsearch(db, &s, "sys", dname); nt != nil; nt = ndbsnext(&s, "sys", dname)) {
+ if(ndbfindattr(nt, s.t, attr) == nil) {
+ ndbfree(nt);
+ continue;
+ }
+ t = ndbconcatenate(t, ndbreorder(nt, s.t));
+ }
+ }
+ s.t = t;
if(t != nil)
break;
}
@@ -290,6 +304,7 @@ dblookup1(char *name, int type, int auth, int ttl)
return nil;
}
+
/* search whole entry for default domain name */
for(nt = t; nt; nt = nt->entry)
if(strcmp(nt->attr, "dom") == 0){
diff --git a/sys/src/cmd/ndb/dnresolve.c b/sys/src/cmd/ndb/dnresolve.c
index eddf86ceb..bc2614c69 100644
--- a/sys/src/cmd/ndb/dnresolve.c
+++ b/sys/src/cmd/ndb/dnresolve.c
@@ -18,7 +18,7 @@ enum
Answerr= -1,
Answnone,
- Maxdest= 24, /* maximum destinations for a request message */
+ Maxdest= 32, /* maximum destinations for a request message */
Maxoutstanding= 15, /* max. outstanding queries per domain name */
/*
@@ -28,8 +28,6 @@ enum
*/
Maxtrans= 5, /* maximum transmissions to a server */
Maxretries= 10, /* cname+actual resends: was 32; have pity on user */
- Maxwaitms= 5000, /* wait no longer for a remote dns query */
- Minwaitms= 500, /* willing to wait for a remote dns query */
};
enum { Hurry, Patient, };
enum { Outns, Inns, };
@@ -63,21 +61,6 @@ struct Query {
uchar tcpip[IPaddrlen];
};
-/* estimated % probability of such a record existing at all */
-int likely[] = {
- [Ta] 95,
- [Taaaa] 10,
- [Tcname] 15,
- [Tmx] 60,
- [Tns] 90,
- [Tnull] 5,
- [Tptr] 35,
- [Tsoa] 90,
- [Tsrv] 60,
- [Ttxt] 15,
- [Tall] 95,
-};
-
static RR* dnresolve1(char*, int, int, Request*, int, int);
static int netquery(Query *, int);
@@ -764,12 +747,13 @@ queryloops(Query *qp, RR *rp)
}
/*
- * Get next server address(es) into qp->dest[nd] and beyond
+ * Get next server type address(es) into qp->dest[nd] and beyond
*/
static int
-serveraddrs(Query *qp, int nd, int depth)
+serveraddrs(Query *qp, int nd, int depth, int type)
{
RR *rp, *arp, *trp;
+ ulong mark;
Dest *p;
if(nd >= Maxdest) /* dest array is full? */
@@ -780,23 +764,20 @@ serveraddrs(Query *qp, int nd, int depth)
* if we find one, mark it so we ignore this on
* subsequent passes.
*/
- arp = 0;
+ mark = 1UL<<type;
+ arp = nil;
for(rp = qp->nsrp; rp; rp = rp->next){
assert(rp->magic == RRmagic);
- if(rp->marker)
+ if(rp->marker & mark)
continue;
- arp = rrlookup(rp->host, Ta, NOneg);
- if(arp == nil)
- arp = rrlookup(rp->host, Taaaa, NOneg);
+ arp = rrlookup(rp->host, type, NOneg);
if(arp){
- rp->marker = 1;
+ rp->marker |= mark;
break;
}
- arp = dblookup(rp->host->name, Cin, Ta, 0, 0);
- if(arp == nil)
- arp = dblookup(rp->host->name, Cin, Taaaa, 0, 0);
+ arp = dblookup(rp->host->name, Cin, type, 0, 0);
if(arp){
- rp->marker = 1;
+ rp->marker |= mark;
break;
}
}
@@ -806,9 +787,9 @@ serveraddrs(Query *qp, int nd, int depth)
* server addresses, try resolving one via the network.
* Mark any we try to resolve so we don't try a second time.
*/
- if(arp == 0){
+ if(arp == nil){
for(rp = qp->nsrp; rp; rp = rp->next)
- if(rp->marker == 0)
+ if((rp->marker & mark) == 0)
if(queryloops(qp, rp))
/*
* give up as we should have got the address
@@ -818,14 +799,11 @@ serveraddrs(Query *qp, int nd, int depth)
return nd;
for(rp = qp->nsrp; rp; rp = rp->next){
- if(rp->marker)
+ if(rp->marker & mark)
continue;
- rp->marker = 1;
- arp = dnresolve(rp->host->name, Cin, Ta, qp->req, 0,
+ rp->marker |= mark;
+ arp = dnresolve(rp->host->name, Cin, type, qp->req, 0,
depth+1, Recurse, 1, 0);
- if(arp == nil)
- arp = dnresolve(rp->host->name, Cin, Taaaa,
- qp->req, 0, depth+1, Recurse, 1, 0);
rrfreelist(rrremneg(&arp));
if(arp)
break;
@@ -836,7 +814,9 @@ serveraddrs(Query *qp, int nd, int depth)
for(trp = arp; trp && nd < Maxdest; trp = trp->next){
p = &qp->dest[nd];
memset(p, 0, sizeof *p);
- parseip(p->a, trp->ip->name);
+ if(parseip(p->a, trp->ip->name) == -1)
+ continue;
+
/*
* straddling servers can reject all nameservers if they are all
* inside, so be sure to list at least one outside ns at
@@ -1023,8 +1003,9 @@ xmitquery(Query *qp, int medium, int depth, uchar *obuf, int inns, int len)
p = qp->dest;
n = qp->curdest - p;
if (qp->ndest > n) {
- n = serveraddrs(qp, n, depth); /* populates qp->dest. */
- assert(n >= 0 && n <= Maxdest);
+ /* populates qp->dest with v4 and v6 addresses. */
+ n = serveraddrs(qp, n, depth, Ta);
+ n = serveraddrs(qp, n, depth, Taaaa);
if (n == 0 && cfg.straddle && cfg.inside) {
/* get ips of "outside-ns-ips" */
while(n < Maxdest){
@@ -1346,7 +1327,7 @@ queryns(Query *qp, int depth, uchar *ibuf, uchar *obuf, ulong waitms, int inns)
* each cycle send one more message than the previous.
* retry a query via tcp if its response is truncated.
*/
- for(ndest = 1; ndest < Maxdest; ndest++){
+ for(ndest = 2; ndest < Maxdest; ndest += 2){
qp->ndest = ndest;
qp->tcpset = 0;
if (xmitquery(qp, Udp, depth, obuf, inns, len) < 0)
@@ -1419,20 +1400,6 @@ queryns(Query *qp, int depth, uchar *ibuf, uchar *obuf, ulong waitms, int inns)
return Answnone;
}
-/* compute wait, weighted by probability of success, with bounds */
-static ulong
-weight(ulong ms, unsigned pcntprob)
-{
- ulong wait;
-
- wait = (ms * pcntprob) / 100;
- if (wait < Minwaitms)
- wait = Minwaitms;
- if (wait > Maxwaitms)
- wait = Maxwaitms;
- return wait;
-}
-
/*
* in principle we could use a single descriptor for a udp port
* to send all queries and receive all the answers to them,
@@ -1442,12 +1409,8 @@ static int
udpquery(Query *qp, char *mntpt, int depth, int patient, int inns)
{
int fd, rv;
- ulong pcntprob;
- uvlong wait, reqtm;
uchar *obuf, *ibuf;
- rv = -1;
-
/* use alloced buffers rather than ones from the stack */
ibuf = emalloc(64*1024); /* max. tcp reply size */
obuf = emalloc(Maxudp+Udphdrsize);
@@ -1456,24 +1419,11 @@ udpquery(Query *qp, char *mntpt, int depth, int patient, int inns)
if (fd < 0) {
dnslog("can't get udpport for %s query of name %s: %r",
mntpt, qp->dp->name);
+ rv = -1;
goto Out;
}
-
- /*
- * Our QIP servers are busted and respond to AAAA and CNAME queries
- * with (sometimes malformed [too short] packets and) no answers and
- * just NS RRs but not Rname errors. so make time-to-wait
- * proportional to estimated probability of an RR of that type existing.
- */
- if (qp->type >= nelem(likely))
- pcntprob = 35; /* unpopular query type */
- else
- pcntprob = likely[qp->type];
- reqtm = (patient? 2 * Maxreqtm: Maxreqtm);
- wait = weight(reqtm / 3, pcntprob); /* time for one udp query */
-
qp->udpfd = fd;
- rv = queryns(qp, depth, ibuf, obuf, wait, inns);
+ rv = queryns(qp, depth, ibuf, obuf, 500UL<<(patient != 0), inns);
qp->udpfd = -1;
close(fd);
@@ -1562,7 +1512,7 @@ seerootns(void)
req.aborttime = timems() + Maxreqtm;
req.from = "internal";
queryinit(&q, dnlookup(root, Cin, 1), Tns, &req);
- nsrp = dblookup(root, Cin, Tns, 0, 0);
+ nsrp = randomize(dblookup(root, Cin, Tns, 0, 0));
for (rr = nsrp; rr != nil; rr = rr->next)
dnslog("seerootns query nsrp: %R", rr);
rv = netqueryns(&q, 0, nsrp); /* lookup ". ns" using nsrp */
diff --git a/sys/src/cmd/ndb/dns.c b/sys/src/cmd/ndb/dns.c
index 0f748d48c..83fe86b71 100644
--- a/sys/src/cmd/ndb/dns.c
+++ b/sys/src/cmd/ndb/dns.c
@@ -197,7 +197,7 @@ main(int argc, char *argv[])
free(dir);
mountinit(servefile, mntpt); /* forks, parent exits */
- srand(now*getpid());
+ srand(truerand());
db2cache(1);
if (cfg.straddle && !seerootns())
diff --git a/sys/src/cmd/ndb/dnsdebug.c b/sys/src/cmd/ndb/dnsdebug.c
index 300434cff..b2f3cebf2 100644
--- a/sys/src/cmd/ndb/dnsdebug.c
+++ b/sys/src/cmd/ndb/dnsdebug.c
@@ -73,6 +73,7 @@ main(int argc, char *argv[])
dninit();
fmtinstall('R', prettyrrfmt);
opendatabase();
+ srand(truerand());
if(cfg.resolver)
squirrelserveraddrs();