diff options
| -rw-r--r-- | sys/src/cmd/ndb/dblookup.c | 43 | ||||
| -rw-r--r-- | sys/src/cmd/ndb/dn.c | 95 | ||||
| -rw-r--r-- | sys/src/cmd/ndb/dnresolve.c | 390 | ||||
| -rw-r--r-- | sys/src/cmd/ndb/dns.c | 15 | ||||
| -rw-r--r-- | sys/src/cmd/ndb/dns.h | 19 | ||||
| -rw-r--r-- | sys/src/cmd/ndb/dnsdebug.c | 3 | ||||
| -rw-r--r-- | sys/src/cmd/ndb/dnserver.c | 19 | ||||
| -rw-r--r-- | sys/src/cmd/ndb/dnudpserver.c | 1 |
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++; |
