|
@@ -53,7 +53,7 @@ struct Query {
|
|
|
Dest *curdest; /* pointer to one of them */
|
|
|
int ndest;
|
|
|
|
|
|
- int udpfd; /* can be shared by all udp users */
|
|
|
+ int udpfd;
|
|
|
|
|
|
QLock tcplock; /* only one tcp call at a time per query */
|
|
|
int tcpset;
|
|
@@ -290,9 +290,10 @@ static RR*
|
|
|
dnresolve1(char *name, int class, int type, Request *req, int depth,
|
|
|
int recurse)
|
|
|
{
|
|
|
+ char *cp;
|
|
|
+ Area *area;
|
|
|
DN *dp, *nsdp;
|
|
|
RR *rp, *nsrp, *dbnsrp;
|
|
|
- char *cp;
|
|
|
Query query;
|
|
|
|
|
|
if(debug)
|
|
@@ -338,6 +339,19 @@ dnresolve1(char *name, int class, int type, Request *req, int depth,
|
|
|
return nil;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * if the domain name is within an area of ours,
|
|
|
+ * we should have found its data in memory by now.
|
|
|
+ */
|
|
|
+ area = inmyarea(dp->name);
|
|
|
+ if (area) {
|
|
|
+// char buf[32];
|
|
|
+
|
|
|
+// dnslog("%s %s: no data in area %s", dp->name,
|
|
|
+// rrname(type, buf, sizeof buf), area->soarr->owner->name);
|
|
|
+ return nil;
|
|
|
+ }
|
|
|
+
|
|
|
queryinit(&query, dp, type, req);
|
|
|
|
|
|
/*
|
|
@@ -806,6 +820,8 @@ cacheneg(DN *dp, int type, int rcode, RR *soarr)
|
|
|
DN *soaowner;
|
|
|
ulong ttl;
|
|
|
|
|
|
+ stats.negcached++;
|
|
|
+
|
|
|
/* no cache time specified, don't make anything up */
|
|
|
if(soarr != nil){
|
|
|
if(soarr->next != nil){
|
|
@@ -1005,6 +1021,29 @@ xmitquery(Query *qp, int medium, int depth, uchar *obuf, int inns, int len)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int lckindex[Maxlcks] = {
|
|
|
+ 0, /* all others map here */
|
|
|
+ Ta,
|
|
|
+ Tns,
|
|
|
+ Tcname,
|
|
|
+ Tsoa,
|
|
|
+ Tptr,
|
|
|
+ Tmx,
|
|
|
+ Ttxt,
|
|
|
+ Taaaa,
|
|
|
+};
|
|
|
+
|
|
|
+static int
|
|
|
+qtype2lck(int qtype) /* map query type to querylck index */
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 1; i < nelem(lckindex); i++)
|
|
|
+ if (lckindex[i] == qtype)
|
|
|
+ return i;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int
|
|
|
procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
|
|
|
{
|
|
@@ -1014,6 +1053,9 @@ procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
|
|
|
Query nquery;
|
|
|
RR *tp, *soarr;
|
|
|
|
|
|
+ if (mp->an == nil)
|
|
|
+ stats.negans++;
|
|
|
+
|
|
|
/* ignore any error replies */
|
|
|
if((mp->flags & Rmask) == Rserver){
|
|
|
freeanswers(mp);
|
|
@@ -1104,13 +1146,13 @@ procansw(Query *qp, DNSmsg *mp, uchar *srcip, int depth, Dest *p)
|
|
|
}
|
|
|
procsetname("recursive query for %s %s", qp->dp->name,
|
|
|
rrname(qp->type, buf, sizeof buf));
|
|
|
- qunlock(&qp->dp->querylck);
|
|
|
+ qunlock(&qp->dp->querylck[qtype2lck(qp->type)]);
|
|
|
|
|
|
queryinit(&nquery, qp->dp, qp->type, qp->req);
|
|
|
nquery.nsrp = tp;
|
|
|
rv = netquery(&nquery, depth+1);
|
|
|
|
|
|
- qlock(&qp->dp->querylck);
|
|
|
+ qlock(&qp->dp->querylck[qtype2lck(qp->type)]);
|
|
|
rrfreelist(tp);
|
|
|
querydestroy(&nquery);
|
|
|
return rv;
|
|
@@ -1196,9 +1238,9 @@ netquery1(Query *qp, int depth, uchar *ibuf, uchar *obuf, int waitsecs, int inns
|
|
|
for(replywaits = 0; replywaits < ndest; replywaits++){
|
|
|
DNSmsg m;
|
|
|
|
|
|
- procsetname("reading %sside reply from %I for %s %s",
|
|
|
+ procsetname("reading %sside reply from %I: %s %s from %s",
|
|
|
(inns? "in": "out"), obuf, qp->dp->name,
|
|
|
- rrname(qp->type, buf, sizeof buf));
|
|
|
+ rrname(qp->type, buf, sizeof buf), qp->req->from);
|
|
|
|
|
|
/* read udp answer into m */
|
|
|
if (readreply(qp, Udp, req, ibuf, &m, endtime) >= 0)
|
|
@@ -1362,6 +1404,7 @@ static int
|
|
|
netquery(Query *qp, int depth)
|
|
|
{
|
|
|
int lock, rv, triedin, inname;
|
|
|
+ char buf[32];
|
|
|
RR *rp;
|
|
|
|
|
|
if(depth > 12) /* in a recursive loop? */
|
|
@@ -1378,7 +1421,8 @@ netquery(Query *qp, int depth)
|
|
|
if(1)
|
|
|
lock = qp->req->isslave != 0;
|
|
|
if(1 && lock) {
|
|
|
- procsetname("query lock wait for %s", qp->dp->name);
|
|
|
+ procsetname("query lock wait: %s %s from %s", qp->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
|
|
@@ -1386,7 +1430,7 @@ netquery(Query *qp, int depth)
|
|
|
* recognise a zone (area) as one of our own, thus
|
|
|
* causing us to query other nameservers.
|
|
|
*/
|
|
|
- qlock(&qp->dp->querylck);
|
|
|
+ qlock(&qp->dp->querylck[qtype2lck(qp->type)]);
|
|
|
}
|
|
|
procsetname("netquery: %s", qp->dp->name);
|
|
|
|
|
@@ -1429,7 +1473,7 @@ netquery(Query *qp, int depth)
|
|
|
// askoutdns(qp->dp, qp->type);
|
|
|
|
|
|
if(1 && lock)
|
|
|
- qunlock(&qp->dp->querylck);
|
|
|
+ qunlock(&qp->dp->querylck[qtype2lck(qp->type)]);
|
|
|
return rv;
|
|
|
}
|
|
|
|
|
@@ -1444,6 +1488,7 @@ seerootns(void)
|
|
|
memset(&req, 0, sizeof req);
|
|
|
req.isslave = 1;
|
|
|
req.aborttime = now + Maxreqtm;
|
|
|
+ req.from = "internal";
|
|
|
queryinit(&query, dnlookup(root, Cin, 1), Tns, &req);
|
|
|
query.nsrp = dblookup(root, Cin, Tns, 0, 0);
|
|
|
rv = netquery(&query, 0);
|