summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/cmd/ndb/dblookup.c43
-rw-r--r--sys/src/cmd/ndb/dn.c95
-rw-r--r--sys/src/cmd/ndb/dnresolve.c390
-rw-r--r--sys/src/cmd/ndb/dns.c15
-rw-r--r--sys/src/cmd/ndb/dns.h19
-rw-r--r--sys/src/cmd/ndb/dnsdebug.c3
-rw-r--r--sys/src/cmd/ndb/dnserver.c19
-rw-r--r--sys/src/cmd/ndb/dnudpserver.c1
8 files changed, 143 insertions, 442 deletions
diff --git a/sys/src/cmd/ndb/dblookup.c b/sys/src/cmd/ndb/dblookup.c
index 9ff423d2c..77784e01a 100644
--- a/sys/src/cmd/ndb/dblookup.c
+++ b/sys/src/cmd/ndb/dblookup.c
@@ -116,12 +116,9 @@ dblookup(char *name, int class, int type, int auth, int ttl)
if(type == Tall){
for (type = Ta; type < Tall; type++)
- if(implemented[type]) {
- tp = dblookup(name, class, type, auth, ttl);
- lock(&dnlock);
- rrcat(&rp, tp);
- unlock(&dnlock);
- }
+ if(implemented[type])
+ rrcat(&rp, dblookup(name, class, type, auth, ttl));
+
return rp;
}
@@ -756,14 +753,6 @@ db2cache(int doit)
unlock(&dblock);
}
-void
-dnforceage(void)
-{
- lock(&dblock);
- dnageall(1);
- unlock(&dblock);
-}
-
extern char mntpt[Maxpath]; /* net mountpoint */
static uchar ipaddr[IPaddrlen]; /* my ip address */
@@ -810,8 +799,6 @@ baddelegation(RR *rp, RR *nsrp, uchar *addr)
if(t == nil)
t = lookupinfo("dom");
- if(t == nil)
- return 0;
for(; rp; rp = rp->next){
if(rp->type != Tns)
@@ -827,6 +814,9 @@ baddelegation(RR *rp, RR *nsrp, uchar *addr)
return 1;
}
+ if(t == nil)
+ continue;
+
/* see if delegating to us what we don't own */
for(nt = t; nt != nil; nt = nt->entry)
if(rp->host && cistrcmp(rp->host->name, nt->val) == 0)
@@ -847,12 +837,13 @@ baddelegation(RR *rp, RR *nsrp, uchar *addr)
int
myaddr(char *addr)
{
- char *name, *line, *sp;
+ char *line, *sp;
char buf[64];
Biobuf *bp;
if(ipcmp(ipaddr, IPnoaddr) == 0)
- return -1;
+ if(myipaddr(ipaddr, mntpt) < 0)
+ return -1;
snprint(buf, sizeof buf, "%I", ipaddr);
if (strcmp(addr, buf) == 0) {
@@ -860,9 +851,8 @@ myaddr(char *addr)
return 1;
}
- name = smprint("%s/ipselftab", mntpt);
- bp = Bopen(name, OREAD);
- free(name);
+ snprint(buf, sizeof buf, "%s/ipselftab", mntpt);
+ bp = Bopen(buf, OREAD);
if (bp != nil) {
while ((line = Brdline(bp, '\n')) != nil) {
line[Blinelen(bp) - 1] = '\0';
@@ -1246,18 +1236,17 @@ insidens(uchar *ip)
return 0;
}
-uchar *
-outsidens(int n)
+int
+outsidensip(int n, uchar *ip)
{
int i;
Ndbtuple *t;
- static uchar ipa[IPaddrlen];
i = 0;
for (t = outnmsrvs; t != nil; t = t->entry)
if (strcmp(t->attr, "ip") == 0 && i++ == n) {
- parseip(ipa, t->val);
- return ipa;
+ parseip(ip, t->val);
+ return 0;
}
- return nil;
+ return -1;
}
diff --git a/sys/src/cmd/ndb/dn.c b/sys/src/cmd/ndb/dn.c
index 6c8df3dc0..04ce387cf 100644
--- a/sys/src/cmd/ndb/dn.c
+++ b/sys/src/cmd/ndb/dn.c
@@ -218,7 +218,7 @@ dnlookup(char *name, int class, int enter)
dp->magic = DNmagic;
dp->name = estrdup(name);
dp->class = class;
- dp->rr = 0;
+ dp->rr = nil;
dp->referenced = now;
/* add new DN to tail of the hash list. *l points to last next ptr. */
dp->next = nil;
@@ -366,8 +366,7 @@ rrdelhead(RR **l)
void
dnage(DN *dp)
{
- RR **l;
- RR *rp, *next;
+ RR **l, *rp;
ulong diff;
if (canlock(&dnlock))
@@ -377,9 +376,8 @@ dnage(DN *dp)
return;
l = &dp->rr;
- for(rp = dp->rr; rp; rp = next){
+ while ((rp = *l) != nil){
assert(rp->magic == RRmagic && rp->cached);
- next = rp->next;
if(!rp->db && (rp->expire < now || diff > dnvars.oldest))
rrdelhead(l); /* rp == *l before; *l == rp->next after */
else
@@ -455,28 +453,6 @@ dnagenever(DN *dp, int dolock)
unlock(&dnlock);
}
-/* mark all current domain names as never to be aged */
-void
-dnageallnever(void)
-{
- int i;
- DN *dp;
-
- lock(&dnlock);
-
- /* mark all referenced domain names */
- for(i = 0; i < HTLEN; i++)
- for(dp = ht[i]; dp; dp = dp->next)
- dnagenever(dp, 0);
-
- unlock(&dnlock);
-
- dnslog("%ld initial domain names; target is %ld", dnvars.names, target);
- if(dnvars.names >= target)
- dnslog("more initial domain names (%ld) than target (%ld)",
- dnvars.names, target);
-}
-
#define REF(dp) { if (dp) (dp)->refs++; }
/*
@@ -576,17 +552,16 @@ dnageall(int doit)
for(i = 0; i < HTLEN; i++){
l = &ht[i];
for(dp = *l; dp; dp = *l){
- if(dp->rr == 0 && dp->refs == 0 && dp->keep == 0){
+ if(dp->rr == nil && dp->refs == 0 && dp->keep == 0){
assert(dp->magic == DNmagic);
*l = dp->next;
- if(dp->name)
- free(dp->name);
- dp->magic = ~dp->magic;
- dnvars.names--;
+ free(dp->name);
memset(dp, 0, sizeof *dp); /* cause trouble */
+ dp->magic = ~DNmagic;
free(dp);
+ dnvars.names--;
continue;
}
l = &dp->next;
@@ -719,12 +694,15 @@ putactivity(int recursive)
}
unlock(&dnvars);
- dncheck(0, 1);
+ dncheck();
db2cache(needrefresh);
+ dncheck();
+
dnageall(0);
- dncheck(0, 1);
+ dncheck();
+
/* let others back in */
lastclean = now;
needrefresh = 0;
@@ -862,9 +840,7 @@ rrattach(RR *rp, int auth)
rp->next = nil;
dp = rp->owner;
/* avoid any outside spoofing; leave keepers alone */
- if(cfg.cachedb && !rp->db && inmyarea(dp->name)
-// || dp->keep /* TODO: make this work */
- )
+ if((cfg.cachedb && !rp->db && inmyarea(dp->name)) || dp->keep)
rrfree(rp);
else
rrattach1(rp, auth);
@@ -872,7 +848,6 @@ rrattach(RR *rp, int auth)
unlock(&dnlock);
}
-/* should be called with dnlock held */
RR**
rrcopy(RR *rp, RR **last)
{
@@ -886,8 +861,6 @@ rrcopy(RR *rp, RR **last)
Txt *t, *nt, **l;
assert(rp->magic == RRmagic);
- if (canlock(&dnlock))
- abort(); /* rrcopy called with dnlock not held */
nrp = rralloc(rp->type);
switch(rp->type){
case Tsoa:
@@ -954,7 +927,7 @@ rrcopy(RR *rp, RR **last)
nrp->pc = getcallerpc(&rp);
setmalloctag(nrp, nrp->pc);
nrp->cached = 0;
- nrp->next = 0;
+ nrp->next = nil;
*last = nrp;
return &nrp->next;
}
@@ -979,7 +952,7 @@ rrlookup(DN *dp, int type, int flag)
assert(dp->magic == DNmagic);
- first = 0;
+ first = nil;
last = &first;
lock(&dnlock);
@@ -1039,8 +1012,8 @@ rrlookup(DN *dp, int type, int flag)
}
out:
- unique(first);
unlock(&dnlock);
+ unique(first);
return first;
}
@@ -1086,9 +1059,7 @@ tsame(int t1, int t2)
}
/*
- * Add resource records to a list, duplicate them if they are cached
- * RR's since these are shared. should be called with dnlock held
- * to avoid racing down the start chain.
+ * Add resource records to a list.
*/
RR*
rrcat(RR **start, RR *rp)
@@ -1096,8 +1067,6 @@ rrcat(RR **start, RR *rp)
RR *olp, *nlp;
RR **last;
- if (canlock(&dnlock))
- abort(); /* rrcat called with dnlock not held */
/* check for duplicates */
for (olp = *start; 0 && olp; olp = olp->next)
for (nlp = rp; nlp; nlp = nlp->next)
@@ -1122,8 +1091,6 @@ rrremneg(RR **l)
RR **nl, *rp;
RR *first;
- if (canlock(&dnlock))
- abort(); /* rrremneg called with dnlock not held */
first = nil;
nl = &first;
while(*l != nil){
@@ -1541,41 +1508,33 @@ slave(Request *req)
* chasing down double free's
*/
void
-dncheck(void *p, int dolock)
+dncheck(void)
{
int i;
DN *dp;
RR *rp;
- if(p != nil){
- dp = p;
- assert(dp->magic == DNmagic);
- }
-
if(!testing)
return;
- if(dolock)
- lock(&dnlock);
+ lock(&dnlock);
poolcheck(mainmem);
for(i = 0; i < HTLEN; i++)
for(dp = ht[i]; dp; dp = dp->next){
- assert(dp != p);
assert(dp->magic == DNmagic);
for(rp = dp->rr; rp; rp = rp->next){
assert(rp->magic == RRmagic);
assert(rp->cached);
assert(rp->owner == dp);
/* also check for duplicate rrs */
- if (dolock && rronlist(rp, rp->next)) {
+ if (rronlist(rp, rp->next)) {
dnslog("%R duplicates its next chain "
"(%R); aborting", rp, rp->next);
abort();
}
}
}
- if(dolock)
- unlock(&dnlock);
+ unlock(&dnlock);
}
static int
@@ -1587,7 +1546,6 @@ rrequiv(RR *r1, RR *r2)
&& r1->arg1 == r2->arg1;
}
-/* called with dnlock held */
void
unique(RR *rp)
{
@@ -1995,19 +1953,10 @@ rralloc(int type)
void
rrfree(RR *rp)
{
- DN *dp;
- RR *nrp;
Txt *t;
assert(rp->magic == RRmagic && !rp->cached);
- dp = rp->owner;
- if(dp){
- assert(dp->magic == DNmagic);
- for(nrp = dp->rr; nrp; nrp = nrp->next)
- assert(nrp != rp); /* "rrfree of live rr" */
- }
-
switch(rp->type){
case Tsoa:
freeserverlist(rp->soa->slaves);
@@ -2048,7 +1997,7 @@ rrfree(RR *rp)
break;
}
- rp->magic = ~rp->magic;
memset(rp, 0, sizeof *rp); /* cause trouble */
+ rp->magic = ~RRmagic;
free(rp);
}
diff --git a/sys/src/cmd/ndb/dnresolve.c b/sys/src/cmd/ndb/dnresolve.c
index 67b060b71..0f2767176 100644
--- a/sys/src/cmd/ndb/dnresolve.c
+++ b/sys/src/cmd/ndb/dnresolve.c
@@ -36,9 +36,6 @@ enum
Maxretries= 5, /* 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 */
-
- Destmagic= 0xcafebabe,
- Querymagic= 0xdeadbeef,
};
enum { Hurry, Patient, };
enum { Outns, Inns, };
@@ -49,15 +46,8 @@ struct Dest
DN *s; /* name server */
int nx; /* number of transmissions */
int code; /* response code; used to clear dp->respcode */
-
- ulong magic;
};
-/*
- * Query has a QLock in it, thus it can't be an automatic
- * variable, since each process would see a separate copy
- * of the lock on its stack.
- */
struct Query {
DN *dp; /* domain */
ushort type; /* and type to look up */
@@ -71,13 +61,10 @@ struct Query {
int udpfd;
- QLock tcplock; /* only one tcp call at a time per query */
int tcpset;
int tcpfd; /* if Tcp, read replies from here */
int tcpctlfd;
uchar tcpip[IPaddrlen];
-
- ulong magic;
};
/* estimated % probability of such a record existing at all */
@@ -175,15 +162,10 @@ dnresolve(char *name, int class, int type, Request *req, RR **cn, int depth,
nrp->ptr->name);
rp = dnresolve(nname, class, type, req, cn, depth+1,
recurse, rooted, status);
- lock(&dnlock);
rrfreelist(rrremneg(&rp));
- unlock(&dnlock);
}
- if(drp != nil){
- lock(&dnlock);
+ if(drp != nil)
rrfreelist(drp);
- unlock(&dnlock);
- }
procsetname(procname);
free(procname);
return rp;
@@ -193,12 +175,11 @@ dnresolve(char *name, int class, int type, Request *req, RR **cn, int depth,
* try the name directly
*/
rp = dnresolve1(name, class, type, req, depth, recurse);
- if(rp == nil) {
+ if(rp == nil && (dp = dnlookup(name, class, 0)) != nil) {
/*
* try it as a canonical name if we weren't told
* that the name didn't exist
*/
- dp = dnlookup(name, class, 0);
if(type != Tptr && dp->respcode != Rname)
for(loops = 0; rp == nil && loops < Maxretries; loops++){
/* retry cname, then the actual type */
@@ -207,11 +188,9 @@ dnresolve(char *name, int class, int type, Request *req, RR **cn, int depth,
if(rp == nil)
break;
- lock(&dnlock);
/* rp->host == nil shouldn't happen, but does */
if(rp->negative || rp->host == nil){
rrfreelist(rp);
- unlock(&dnlock);
rp = nil;
break;
}
@@ -221,7 +200,6 @@ dnresolve(char *name, int class, int type, Request *req, RR **cn, int depth,
rrcat(cn, rp);
else
rrfreelist(rp);
- unlock(&dnlock);
rp = dnresolve1(name, class, type, req,
depth, recurse);
@@ -239,6 +217,8 @@ dnresolve(char *name, int class, int type, Request *req, RR **cn, int depth,
static void
queryinit(Query *qp, DN *dp, int type, Request *req)
{
+ assert(dp && dp->magic == DNmagic);
+
memset(qp, 0, sizeof *qp);
qp->udpfd = qp->tcpfd = qp->tcpctlfd = -1;
qp->dp = dp;
@@ -248,20 +228,11 @@ queryinit(Query *qp, DN *dp, int type, Request *req)
qp->req = req;
qp->nsrp = nil;
qp->dest = qp->curdest = nil;
- qp->magic = Querymagic;
-}
-
-static void
-queryck(Query *qp)
-{
- assert(qp);
- assert(qp->magic == Querymagic);
}
static void
querydestroy(Query *qp)
{
- queryck(qp);
/* leave udpfd open */
if (qp->tcpfd >= 0)
close(qp->tcpfd);
@@ -269,25 +240,10 @@ querydestroy(Query *qp)
hangup(qp->tcpctlfd);
close(qp->tcpctlfd);
}
- free(qp->dest);
memset(qp, 0, sizeof *qp); /* prevent accidents */
qp->udpfd = qp->tcpfd = qp->tcpctlfd = -1;
}
-static void
-destinit(Dest *p)
-{
- memset(p, 0, sizeof *p);
- p->magic = Destmagic;
-}
-
-static void
-destck(Dest *p)
-{
- assert(p);
- assert(p->magic == Destmagic);
-}
-
/*
* if the response to a query hasn't arrived within 100 ms.,
* it's unlikely to arrive at all. after 1 s., it's really unlikely.
@@ -335,9 +291,7 @@ netqueryns(Query *qp, int depth, RR *nsrp)
qp->nsrp = nsrp;
rv = netquery(qp, depth);
qp->nsrp = nil; /* prevent accidents */
- lock(&dnlock);
rrfreelist(nsrp);
- unlock(&dnlock);
return rv;
}
@@ -371,9 +325,7 @@ issuequery(Query *qp, char *name, int class, int depth, int recurse)
dbnsrp = randomize(dblookup(cp, class, Tns, 0, 0));
if(dbnsrp && dbnsrp->local){
rp = dblookup(name, class, qp->type, 1, dbnsrp->ttl);
- lock(&dnlock);
rrfreelist(dbnsrp);
- unlock(&dnlock);
return rp;
}
@@ -382,11 +334,8 @@ issuequery(Query *qp, char *name, int class, int depth, int recurse)
* entries
*/
if(recurse == Dontrecurse){
- if(dbnsrp) {
- lock(&dnlock);
+ if(dbnsrp)
rrfreelist(dbnsrp);
- unlock(&dnlock);
- }
continue;
}
@@ -397,16 +346,11 @@ issuequery(Query *qp, char *name, int class, int depth, int recurse)
nsrp = randomize(rrlookup(nsdp, Tns, NOneg));
/* if the entry timed out, ignore it */
- if(nsrp && nsrp->ttl < now){
- lock(&dnlock);
+ if(nsrp && nsrp->ttl < now)
rrfreelistptr(&nsrp);
- unlock(&dnlock);
- }
if(nsrp){
- lock(&dnlock);
rrfreelistptr(&dbnsrp);
- unlock(&dnlock);
/* query the name servers found in cache */
if(netqueryns(qp, depth+1, nsrp) > Answnone)
@@ -426,7 +370,7 @@ dnresolve1(char *name, int class, int type, Request *req, int depth,
Area *area;
DN *dp;
RR *rp;
- Query *qp;
+ Query q;
if(debug)
dnslog("[%d] dnresolve1 %s %d %d", getpid(), name, type, class);
@@ -462,9 +406,7 @@ dnresolve1(char *name, int class, int type, Request *req, int depth,
getpid(), name, type, class);
return rp;
}
- lock(&dnlock);
rrfreelist(rp);
- unlock(&dnlock);
rp = nil; /* accident prevention */
USED(rp);
@@ -475,9 +417,7 @@ dnresolve1(char *name, int class, int type, Request *req, int depth,
*/
if(type != Tcname){
rp = rrlookup(dp, Tcname, NOneg);
- lock(&dnlock);
rrfreelist(rp);
- unlock(&dnlock);
if(rp){
if(debug)
dnslog("[%d] dnresolve1 %s %d %d: rr from rrlookup for non-cname",
@@ -494,11 +434,10 @@ dnresolve1(char *name, int class, int type, Request *req, int depth,
if (area || strncmp(dp->name, "local#", 6) == 0)
return nil;
- qp = emalloc(sizeof *qp);
- queryinit(qp, dp, type, req);
- rp = issuequery(qp, name, class, depth, recurse);
- querydestroy(qp);
- free(qp);
+ queryinit(&q, dp, type, req);
+ rp = issuequery(&q, name, class, depth, recurse);
+ querydestroy(&q);
+
if(rp){
if(debug)
dnslog("[%d] dnresolve1 %s %d %d: rr from query",
@@ -620,12 +559,10 @@ mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno)
void
freeanswers(DNSmsg *mp)
{
- lock(&dnlock);
rrfreelistptr(&mp->qd);
rrfreelistptr(&mp->an);
rrfreelistptr(&mp->ns);
rrfreelistptr(&mp->ar);
- unlock(&dnlock);
mp->qdcount = mp->ancount = mp->nscount = mp->arcount = 0;
}
@@ -708,7 +645,6 @@ readreply(Query *qp, int medium, ushort req, uchar *ibuf, DNSmsg *mp,
uchar srcip[IPaddrlen];
RR *rp;
- queryck(qp);
for (; timems() < endms &&
(len = readnet(qp, medium, ibuf, endms, &reply, srcip)) >= 0;
freeanswers(mp)){
@@ -810,7 +746,7 @@ static int
serveraddrs(Query *qp, int nd, int depth)
{
RR *rp, *arp, *trp;
- Dest *cur;
+ Dest *p;
if(nd >= Maxdest) /* dest array is full? */
return Maxdest;
@@ -863,33 +799,30 @@ serveraddrs(Query *qp, int nd, int depth)
if(arp == nil)
arp = dnresolve(rp->host->name, Cin, Taaaa,
qp->req, 0, depth+1, Recurse, 1, 0);
- lock(&dnlock);
rrfreelist(rrremneg(&arp));
- unlock(&dnlock);
if(arp)
break;
}
/* use any addresses that we found */
for(trp = arp; trp && nd < Maxdest; trp = trp->next){
- cur = &qp->dest[nd];
- parseip(cur->a, trp->ip->name);
+ p = &qp->dest[nd];
+ memset(p, 0, sizeof *p);
+ parseip(p->a, trp->ip->name);
/*
* straddling servers can reject all nameservers if they are all
* inside, so be sure to list at least one outside ns at
* the end of the ns list in /lib/ndb for `dom='.
*/
- if (ipisbm(cur->a) ||
- cfg.straddle && !insideaddr(qp->dp->name) && insidens(cur->a))
+ if (ipisbm(p->a) ||
+ cfg.straddle && !insideaddr(qp->dp->name) && insidens(p->a))
continue;
- cur->nx = 0;
- cur->s = trp->owner;
- cur->code = Rtimeout;
+ p->nx = 0;
+ p->s = trp->owner;
+ p->code = Rtimeout;
nd++;
}
- lock(&dnlock);
rrfreelist(arp);
- unlock(&dnlock);
return nd;
}
@@ -909,10 +842,8 @@ cacheneg(DN *dp, int type, int rcode, RR *soarr)
/* no cache time specified, don't make anything up */
if(soarr != nil){
- lock(&dnlock);
if(soarr->next != nil)
rrfreelistptr(&soarr->next);
- unlock(&dnlock);
soaowner = soarr->owner;
} else
soaowner = nil;
@@ -938,16 +869,12 @@ cacheneg(DN *dp, int type, int rcode, RR *soarr)
static int
setdestoutns(Dest *p, int n)
{
- uchar *outns = outsidens(n);
-
- destck(p);
- destinit(p);
- if (outns == nil) {
+ memset(p, 0, sizeof *p);
+ if (outsidensip(n, p->a) < 0){
if (n == 0)
dnslog("[%d] no outside-ns in ndb", getpid());
return -1;
}
- memmove(p->a, outns, sizeof p->a);
p->s = dnlookup("outside-ns-ips", Cin, 1);
return 0;
}
@@ -960,22 +887,15 @@ static int
mydnsquery(Query *qp, int medium, uchar *udppkt, int len)
{
int rv, nfd;
- char *domain;
- char conndir[40], addr[128];
+ char conndir[40], addr[128], domain[64];
uchar belen[2];
NetConnInfo *nci;
rv = -1;
- queryck(qp);
- domain = smprint("%I", udppkt);
- if (domain == nil) {
- warning("mydnsquery: no memory for domain");
- return rv;
- }
+ snprint(domain, sizeof(domain), "%I", udppkt);
if (myaddr(domain)) {
dnslog("mydnsquery: trying to send to myself (%s); bzzzt",
domain);
- free(domain);
return rv;
}
switch (medium) {
@@ -1005,7 +925,7 @@ mydnsquery(Query *qp, int medium, uchar *udppkt, int len)
break;
case Tcp:
/* send via TCP & keep fd around for reply */
- parseip(qp->tcpip, domain);
+ memmove(qp->tcpip, udppkt, sizeof qp->tcpip);
snprint(addr, sizeof addr, "%s/tcp!%s!dns",
(mntpt && *mntpt) ? mntpt : "/net",
domain);
@@ -1033,7 +953,6 @@ mydnsquery(Query *qp, int medium, uchar *udppkt, int len)
rv = 0;
break;
}
- free(domain);
return rv;
}
@@ -1044,118 +963,78 @@ mydnsquery(Query *qp, int medium, uchar *udppkt, int len)
static int
xmitquery(Query *qp, int medium, int depth, uchar *obuf, int inns, int len)
{
- int j, n;
+ int n;
char buf[32];
Dest *p;
- queryck(qp);
if(timems() >= qp->req->aborttime)
return -1;
/*
- * get a nameserver address if we need one.
- * serveraddrs populates qp->dest.
+ * if we send tcp query, we just take the dest ip address from
+ * the udp header placed there by tcpquery().
*/
- p = qp->dest;
- destck(p);
- if (qp->ndest < 0 || qp->ndest > Maxdest) {
- dnslog("qp->ndest %d out of range", qp->ndest);
- abort();
+ if (medium == Tcp) {
+ procsetname("tcp %sside query for %s %s", (inns? "in": "out"),
+ qp->dp->name, rrname(qp->type, buf, sizeof buf));
+ if(mydnsquery(qp, medium, obuf, len) < 0) /* sets qp->tcpip from obuf */
+ return -1;
+ if(debug)
+ logsend(qp->req->id, depth, qp->tcpip, "", qp->dp->name,
+ qp->type);
+ return 0;
}
+
/*
+ * get a nameserver address if we need one.
* we're to transmit to more destinations than we currently have,
* so get another.
*/
- if (qp->ndest > qp->curdest - p) {
- j = serveraddrs(qp, qp->curdest - p, depth);
- if (j < 0 || j > Maxdest) {
- dnslog("serveraddrs() result %d out of range", j);
- abort();
- }
- qp->curdest = &qp->dest[j];
- }
-
- /* no servers, punt */
- if (qp->ndest == 0)
- if (cfg.straddle && cfg.inside) {
+ p = qp->dest;
+ n = qp->curdest - p;
+ if (qp->ndest > n) {
+ n = serveraddrs(qp, n, depth); /* populates qp->dest. */
+ assert(n >= 0 && n <= Maxdest);
+ if (n == 0 && cfg.straddle && cfg.inside) {
/* get ips of "outside-ns-ips" */
- qp->curdest = qp->dest;
- for(n = 0; n < Maxdest; n++, qp->curdest++)
- if (setdestoutns(qp->curdest, n) < 0)
+ while(n < Maxdest){
+ if (setdestoutns(&qp->dest[n], n) < 0)
break;
+ n++;
+ }
if(n == 0)
dnslog("xmitquery: %s: no outside-ns nameservers",
qp->dp->name);
- } else
- /* it's probably just a bogus domain, don't log it */
- return -1;
-
- /* send to first 'qp->ndest' destinations */
- j = 0;
- if (medium == Tcp) {
- j++;
- queryck(qp);
- assert(qp->dp);
- procsetname("tcp %sside query for %s %s", (inns? "in": "out"),
- qp->dp->name, rrname(qp->type, buf, sizeof buf));
- mydnsquery(qp, medium, obuf, len); /* sets qp->tcpip from obuf */
- if(debug)
- logsend(qp->req->id, depth, qp->tcpip, "", qp->dp->name,
- qp->type);
- } else
- for(; p < &qp->dest[qp->ndest] && p < qp->curdest; p++){
- /* skip destinations we've finished with */
- if(p->nx >= Maxtrans)
- continue;
-
- j++;
-
- /* exponential backoff of requests */
- if((1<<p->nx) > qp->ndest)
- continue;
-
- if(memcmp(p->a, IPnoaddr, sizeof IPnoaddr) == 0)
- continue; /* mistake */
-
- procsetname("udp %sside query to %I/%s %s %s",
- (inns? "in": "out"), p->a, p->s->name,
- qp->dp->name, rrname(qp->type, buf, sizeof buf));
- if(debug)
- logsend(qp->req->id, depth, p->a, p->s->name,
- qp->dp->name, qp->type);
-
- /* fill in UDP destination addr & send it */
- memmove(obuf, p->a, sizeof p->a);
- mydnsquery(qp, medium, obuf, len);
- p->nx++;
}
- if(j == 0) {
- return -1;
+ qp->curdest = &qp->dest[n];
}
- return 0;
-}
-static int lckindex[Maxlcks] = {
- 0, /* all others map here */
- Ta,
- Tns,
- Tcname,
- Tsoa,
- Tptr,
- Tmx,
- Ttxt,
- Taaaa,
-};
+ for(n = 0; p < &qp->dest[qp->ndest] && p < qp->curdest; p++){
+ /* skip destinations we've finished with */
+ if(p->nx >= Maxtrans)
+ continue;
+ /* exponential backoff of requests */
+ if((1<<p->nx) > qp->ndest)
+ continue;
-static int
-qtype2lck(int qtype) /* map query type to querylck index */
-{
- int i;
+ if(memcmp(p->a, IPnoaddr, sizeof IPnoaddr) == 0)
+ continue; /* mistake */
- for (i = 1; i < nelem(lckindex); i++)
- if (lckindex[i] == qtype)
- return i;
- return 0;
+ procsetname("udp %sside query to %I/%s %s %s",
+ (inns? "in": "out"), p->a, p->s->name,
+ qp->dp->name, rrname(qp->type, buf, sizeof buf));
+ if(debug)
+ logsend(qp->req->id, depth, p->a, p->s->name,
+ qp->dp->name, qp->type);
+
+ /* fill in UDP destination addr & send it */
+ memmove(obuf, p->a, sizeof p->a);
+ if(mydnsquery(qp, medium, obuf, len) == 0)
+ n++;
+ p->nx++;
+ }
+
+ return n == 0 ? -1 : 0;
}
/* is mp a cachable negative response (with Rname set)? */
@@ -1173,7 +1052,7 @@ procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
int rv;
char buf[32];
DN *ndp;
- Query *nqp;
+ Query nq;
RR *tp, *soarr;
if (mp->an == nil)
@@ -1183,7 +1062,7 @@ procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
if((mp->flags & Rmask) == Rserver){
stats.negserver++;
freeanswers(mp);
- if(p != qp->curdest)
+ if(p != nil)
p->code = Rserver;
return Answerr;
}
@@ -1194,27 +1073,23 @@ procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
if(mp->an == nil){
stats.negbdnoans++;
freeanswers(mp);
- if(p != qp->curdest)
+ if(p != nil)
p->code = Rserver;
dnslog(" and no answers");
return Answerr;
}
dnslog(" but has answers; ignoring ns");
- lock(&dnlock);
rrfreelistptr(&mp->ns);
- unlock(&dnlock);
mp->nscount = 0;
}
/* remove any soa's from the authority section */
- lock(&dnlock);
soarr = rrremtype(&mp->ns, Tsoa);
/* incorporate answers */
unique(mp->an);
unique(mp->ns);
unique(mp->ar);
- unlock(&dnlock);
if(mp->an)
rrattach(mp->an, (mp->flags & Fauth) != 0);
@@ -1225,17 +1100,13 @@ procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
rrattach(mp->ns, Notauthoritative);
} else {
ndp = nil;
- lock(&dnlock);
rrfreelistptr(&mp->ns);
- unlock(&dnlock);
mp->nscount = 0;
}
/* free the question */
if(mp->qd) {
- lock(&dnlock);
rrfreelistptr(&mp->qd);
- unlock(&dnlock);
mp->qdcount = 0;
}
@@ -1257,11 +1128,8 @@ procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
*/
if( /* (mp->flags & Fauth) && */ mp->an == nil)
cacheneg(qp->dp, qp->type, (mp->flags & Rmask), soarr);
- else {
- lock(&dnlock);
+ else
rrfreelist(soarr);
- unlock(&dnlock);
- }
return 1;
} else if (isnegrname(mp)) {
qp->dp->respcode = Rname;
@@ -1274,9 +1142,7 @@ procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
return 1;
}
stats.negnorname++;
- lock(&dnlock);
rrfreelist(soarr);
- unlock(&dnlock);
/*
* if we've been given better name servers, recurse.
@@ -1287,19 +1153,16 @@ procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
return Answnone;
tp = rrlookup(ndp, Tns, NOneg);
if(contains(qp->nsrp, tp)){
- lock(&dnlock);
rrfreelist(tp);
- unlock(&dnlock);
return Answnone;
}
procsetname("recursive query for %s %s", qp->dp->name,
rrname(qp->type, buf, sizeof buf));
- nqp = emalloc(sizeof *nqp);
- queryinit(nqp, qp->dp, qp->type, qp->req);
- rv = netqueryns(nqp, depth+1, tp);
- querydestroy(nqp);
- free(nqp);
+ queryinit(&nq, qp->dp, qp->type, qp->req);
+ rv = netqueryns(&nq, depth+1, tp);
+ querydestroy(&nq);
+
return rv;
}
@@ -1322,7 +1185,6 @@ tcpquery(Query *qp, DNSmsg *mp, int depth, uchar *ibuf, uchar *obuf, int len,
dnslog("%s: udp reply truncated; retrying query via tcp to %I",
qp->dp->name, qp->tcpip);
- qlock(&qp->tcplock);
memmove(obuf, ibuf, IPaddrlen); /* send back to respondent */
memset(mp, 0, sizeof *mp);
if (xmitquery(qp, Tcp, depth, obuf, inns, len) < 0 ||
@@ -1334,7 +1196,7 @@ tcpquery(Query *qp, DNSmsg *mp, int depth, uchar *ibuf, uchar *obuf, int len,
close(qp->tcpfd);
}
qp->tcpfd = qp->tcpctlfd = -1;
- qunlock(&qp->tcplock);
+
return rv;
}
@@ -1349,21 +1211,16 @@ queryns(Query *qp, int depth, uchar *ibuf, uchar *obuf, ulong waitms, int inns)
int ndest, len, replywaits, rv;
ushort req;
uvlong endms;
- char buf[12];
+ char buf[32];
uchar srcip[IPaddrlen];
- Dest *p, *np, *dest;
+ Dest *p, *np, dest[Maxdest];
/* pack request into a udp message */
req = rand();
len = mkreq(qp->dp, qp->type, obuf, Frecurse|Oquery, req);
/* no server addresses yet */
- queryck(qp);
- dest = emalloc(Maxdest * sizeof *dest); /* dest can't be on stack */
- for (p = dest; p < dest + Maxdest; p++)
- destinit(p);
- /* this dest array is local to this call of queryns() */
- free(qp->dest);
+ memset(dest, 0, sizeof dest);
qp->curdest = qp->dest = dest;
/*
@@ -1413,16 +1270,17 @@ queryns(Query *qp, int depth, uchar *ibuf, uchar *obuf, ulong waitms, int inns)
if(memcmp(p->a, srcip, sizeof p->a) == 0)
break;
- /* remove all addrs of responding server from list */
- if(p != qp->curdest)
+ if(p != qp->curdest) {
+ /* remove all addrs of responding server from list */
for(np = qp->dest; np < qp->curdest; np++)
if(np->s == p->s)
np->nx = Maxtrans;
+ } else
+ p = nil;
/* free or incorporate RRs in m */
rv = procansw(qp, &m, srcip, depth, p);
if (rv > Answnone) {
- free(qp->dest);
qp->dest = qp->curdest = nil; /* prevent accidents */
return rv;
}
@@ -1431,17 +1289,13 @@ queryns(Query *qp, int depth, uchar *ibuf, uchar *obuf, ulong waitms, int inns)
/* if all servers returned failure, propagate it */
qp->dp->respcode = Rserver;
- for(p = dest; p < qp->curdest; p++) {
- destck(p);
+ for(p = dest; p < qp->curdest; p++)
if(p->code != Rserver)
qp->dp->respcode = Rok;
- p->magic = 0; /* prevent accidents */
- }
// if (qp->dp->respcode)
// dnslog("queryns setting Rserver for %s", qp->dp->name);
- free(qp->dest);
qp->dest = qp->curdest = nil; /* prevent accidents */
return Answnone;
}
@@ -1570,12 +1424,8 @@ Out:
static int
netquery(Query *qp, int depth)
{
- int lock, rv, triedin, inname;
- char buf[32];
+ int rv, triedin, inname;
RR *rp;
- DN *dp;
- Querylck *qlp;
- static int whined;
rv = Answnone; /* pessimism */
if(depth > 12) /* in a recursive loop? */
@@ -1592,39 +1442,7 @@ netquery(Query *qp, int depth)
if(!qp->req->isslave && strcmp(qp->req->from, "9p") == 0)
return Answnone;
- /*
- * don't lock before call to slave so only children can block.
- * just lock at top-level invocation.
- */
- lock = depth <= 1 && qp->req->isslave;
- dp = qp->dp; /* ensure that it doesn't change underfoot */
- qlp = nil;
- if(lock) {
- procsetname("query lock wait: %s %s from %s", dp->name,
- rrname(qp->type, buf, sizeof buf), qp->req->from);
- /*
- * don't make concurrent queries for this name.
- * dozens of processes blocking here probably indicates
- * an error in our dns data that causes us to not
- * recognise a zone (area) as one of our own, thus
- * causing us to query other nameservers.
- */
- qlp = &dp->querylck[qtype2lck(qp->type)];
- qlock(qlp);
- if (qlp->Ref.ref > Maxoutstanding) {
- qunlock(qlp);
- if (!whined) {
- whined = 1;
- dnslog("too many outstanding queries for %s;"
- " dropping this one; no further logging"
- " of drops", dp->name);
- }
- return Answnone;
- }
- ++qlp->Ref.ref;
- qunlock(qlp);
- }
- procsetname("netquery: %s", dp->name);
+ procsetname("netquery: %s", qp->dp->name);
/* prepare server RR's for incremental lookup */
for(rp = qp->nsrp; rp; rp = rp->next)
@@ -1638,7 +1456,7 @@ netquery(Query *qp, int depth)
* for inside addresses and /net.alt for outside addresses,
* thus bypassing other inside nameservers.
*/
- inname = insideaddr(dp->name);
+ inname = insideaddr(qp->dp->name);
if (!cfg.straddle || inname) {
rv = udpquery(qp, mntpt, depth, Hurry, (cfg.inside? Inns: Outns));
triedin = 1;
@@ -1652,7 +1470,7 @@ netquery(Query *qp, int depth)
if (triedin)
dnslog(
"[%d] netquery: internal nameservers failed for %s; trying external",
- getpid(), dp->name);
+ getpid(), qp->dp->name);
/* prepare server RR's for incremental lookup */
for(rp = qp->nsrp; rp; rp = rp->next)
@@ -1661,12 +1479,6 @@ netquery(Query *qp, int depth)
rv = udpquery(qp, "/net.alt", depth, Patient, Outns);
}
- if(lock && qlp) {
- qlock(qlp);
- assert(qlp->Ref.ref > 0);
- qunlock(qlp);
- decref(qlp);
- }
return rv;
}
@@ -1677,19 +1489,17 @@ seerootns(void)
char root[] = "";
Request req;
RR *rr, *nsrp;
- Query *qp;
+ Query q;
memset(&req, 0, sizeof req);
req.isslave = 1;
req.aborttime = timems() + Maxreqtm;
req.from = "internal";
- qp = emalloc(sizeof *qp);
- queryinit(qp, dnlookup(root, Cin, 1), Tns, &req);
+ queryinit(&q, dnlookup(root, Cin, 1), Tns, &req);
nsrp = dblookup(root, Cin, Tns, 0, 0);
- for (rr = nsrp; rr != nil; rr = rr->next) /* DEBUG */
+ for (rr = nsrp; rr != nil; rr = rr->next)
dnslog("seerootns query nsrp: %R", rr);
- rv = netqueryns(qp, 0, nsrp); /* lookup ". ns" using nsrp */
- querydestroy(qp);
- free(qp);
+ rv = netqueryns(&q, 0, nsrp); /* lookup ". ns" using nsrp */
+ querydestroy(&q);
return rv;
}
diff --git a/sys/src/cmd/ndb/dns.c b/sys/src/cmd/ndb/dns.c
index e21c3ab88..8fc4f5167 100644
--- a/sys/src/cmd/ndb/dns.c
+++ b/sys/src/cmd/ndb/dns.c
@@ -212,7 +212,6 @@ main(int argc, char *argv[])
srand(now*getpid());
db2cache(1);
-// dnageallnever();
if (cfg.straddle && !seerootns())
dnslog("straddle server misconfigured; can't see root name servers");
@@ -723,12 +722,7 @@ rwrite(Job *job, Mfile *mf, Request *req)
*/
// dnslog("rwrite got: %s", job->request.data);
send = 1;
- if(strcmp(job->request.data, "age")==0){
- dnslog("dump, age & dump forced");
- dndump("/lib/ndb/dnsdump1");
- dnforceage();
- dndump("/lib/ndb/dnsdump2");
- } else if(strcmp(job->request.data, "debug")==0)
+ if(strcmp(job->request.data, "debug")==0)
debug ^= 1;
else if(strcmp(job->request.data, "testing")==0)
testing ^= 1;
@@ -806,7 +800,6 @@ rwrite(Job *job, Mfile *mf, Request *req)
err = lookupquery(job, mf, req, errbuf, p, wantsav, rooted);
send:
- dncheck(0, 1);
job->reply.count = cnt;
sendmsg(job, err);
}
@@ -828,18 +821,14 @@ lookupquery(Job *job, Mfile *mf, Request *req, char *errbuf, char *p,
int status;
RR *rp, *neg;
- dncheck(0, 1);
status = Rok;
rp = dnresolve(p, Cin, mf->type, req, 0, 0, Recurse, rooted, &status);
- dncheck(0, 1);
- lock(&dnlock);
neg = rrremneg(&rp);
if(neg){
status = neg->negrcode;
rrfreelist(neg);
}
- unlock(&dnlock);
return respond(job, mf, rp, errbuf, status, wantsav);
}
@@ -880,9 +869,7 @@ respond(Job *job, Mfile *mf, RR *rp, char *errbuf, int status, int wantsav)
}
unlock(&joblock);
- lock(&dnlock);
rrfreelist(rp);
- unlock(&dnlock);
return nil;
}
diff --git a/sys/src/cmd/ndb/dns.h b/sys/src/cmd/ndb/dns.h
index 0b40d76e4..4c66ac1c4 100644
--- a/sys/src/cmd/ndb/dns.h
+++ b/sys/src/cmd/ndb/dns.h
@@ -1,5 +1,3 @@
-#include <thread.h> /* for Ref */
-
#define NS2MS(ns) ((ns) / 1000000L)
#define S2MS(s) ((s) * 1000LL)
@@ -186,14 +184,6 @@ struct Request
char *from; /* who asked us? */
};
-typedef struct Querylck Querylck;
-struct Querylck
-{
- QLock;
-// Rendez;
- Ref;
-};
-
/*
* a domain name
*/
@@ -211,9 +201,6 @@ struct DN
ushort class; /* RR class */
uchar keep; /* flag: never age this name */
uchar respcode; /* response code */
-/* was: char nonexistent; /* true if we get an authoritative nx for this domain */
- /* permit only 1 query per (domain name, type) at a time */
- Querylck querylck[Maxlcks];
};
/*
@@ -461,10 +448,9 @@ void db2cache(int);
void dnage(DN*);
void dnageall(int);
void dnagedb(void);
-void dnageallnever(void);
void dnagenever(DN *, int);
void dnauthdb(void);
-void dncheck(void*, int);
+void dncheck(void);
void dndump(char*);
void dnget(void);
void dninit(void);
@@ -511,14 +497,13 @@ void addarea(DN *dp, RR *rp, Ndbtuple *t);
int baddelegation(RR*, RR*, uchar*);
RR* dbinaddr(DN*, int);
RR* dblookup(char*, int, int, int, int);
-void dnforceage(void);
RR* dnsservers(int);
RR* domainlist(int);
int insideaddr(char *dom);
int insidens(uchar *ip);
int myaddr(char *addr);
int opendatabase(void);
-uchar* outsidens(int);
+int outsidensip(int, uchar *ip);
/* dns.c */
char* walkup(char*);
diff --git a/sys/src/cmd/ndb/dnsdebug.c b/sys/src/cmd/ndb/dnsdebug.c
index 8a9623f11..29da15ea9 100644
--- a/sys/src/cmd/ndb/dnsdebug.c
+++ b/sys/src/cmd/ndb/dnsdebug.c
@@ -341,11 +341,10 @@ preloadserveraddrs(void)
{
RR *rp, **l, *first;
+ first = nil;
l = &first;
for(rp = serveraddrs; rp != nil; rp = rp->next){
- lock(&dnlock);
rrcopy(rp, l);
- unlock(&dnlock);
rrattach(first, Authoritative);
}
}
diff --git a/sys/src/cmd/ndb/dnserver.c b/sys/src/cmd/ndb/dnserver.c
index 801fa2213..87a35ab28 100644
--- a/sys/src/cmd/ndb/dnserver.c
+++ b/sys/src/cmd/ndb/dnserver.c
@@ -22,8 +22,6 @@ dnserver(DNSmsg *reqp, DNSmsg *repp, Request *req, uchar *srcip, int rcode)
Area *myarea;
RR *tp, *neg, *rp;
- dncheck(nil, 1);
-
recursionflag = norecursion? 0: Fcanrec;
memset(repp, 0, sizeof(*repp));
repp->id = reqp->id;
@@ -109,11 +107,9 @@ dnserver(DNSmsg *reqp, DNSmsg *repp, Request *req, uchar *srcip, int rcode)
if(repp->ns){
/* don't pass on anything we know is wrong */
if(repp->ns->negative){
- lock(&dnlock);
rp = repp->ns;
repp->ns = nil;
rrfreelist(rp);
- unlock(&dnlock);
}
break;
}
@@ -135,24 +131,18 @@ dnserver(DNSmsg *reqp, DNSmsg *repp, Request *req, uchar *srcip, int rcode)
hint(&repp->ar, tp);
}
- /* hint calls rrlookup which holds dnlock, so don't lock before this. */
-
/*
* add an soa to the authority section to help client
* with negative caching
*/
if(repp->an == nil)
if(myarea != nil){
- lock(&dnlock);
rrcopy(myarea->soarr, &tp);
rrcat(&repp->ns, tp);
- unlock(&dnlock);
} else if(neg != nil) {
if(neg->negsoaowner != nil) {
tp = rrlookup(neg->negsoaowner, Tsoa, NOneg);
- lock(&dnlock);
rrcat(&repp->ns, tp);
- unlock(&dnlock);
}
repp->flags |= neg->negrcode;
}
@@ -160,15 +150,11 @@ dnserver(DNSmsg *reqp, DNSmsg *repp, Request *req, uchar *srcip, int rcode)
/*
* get rid of duplicates
*/
- lock(&dnlock);
unique(repp->an);
unique(repp->ns);
unique(repp->ar);
rrfreelist(neg);
- unlock(&dnlock);
-
- dncheck(nil, 1);
}
/*
@@ -185,7 +171,6 @@ doextquery(DNSmsg *mp, Request *req, int recurse)
type = mp->qd->type;
rp = dnresolve(name, Cin, type, req, &mp->an, 0, recurse, 1, 0);
- lock(&dnlock);
/* don't return soa hints as answers, it's wrong */
if(rp && rp->db && !rp->auth && rp->type == Tsoa) {
rrfreelist(rp);
@@ -195,7 +180,7 @@ doextquery(DNSmsg *mp, Request *req, int recurse)
/* don't let negative cached entries escape */
neg = rrremneg(&rp);
rrcat(&mp->an, rp);
- unlock(&dnlock);
+
return neg;
}
@@ -219,9 +204,7 @@ hint(RR **last, RR *rp)
hp = dblookup(rp->host->name, Cin, Taaaa, 0, 0);
if (hp && strncmp(hp->owner->name, "local#", 6) == 0)
dnslog("returning %s as hint", hp->owner->name);
- lock(&dnlock);
rrcat(last, hp);
- unlock(&dnlock);
break;
}
}
diff --git a/sys/src/cmd/ndb/dnudpserver.c b/sys/src/cmd/ndb/dnudpserver.c
index bac4af058..bcd03e96f 100644
--- a/sys/src/cmd/ndb/dnudpserver.c
+++ b/sys/src/cmd/ndb/dnudpserver.c
@@ -189,7 +189,6 @@ restart:
// ((Udphdr*)buf)->raddr, ((Udphdr*)buf)->laddr);
getactivity(&req, 0);
req.aborttime = timems() + Maxreqtm;
-// req.from = smprint("%I", ((Udphdr*)buf)->raddr);
req.from = smprint("%I", buf);
rcode = 0;
stats.qrecvdudp++;