shithub: riscv

Download patch

ref: 5f87d8dcc814700f10f40c10a0225400e4828ef9
parent: 2ce68c5aa1bb1691fe05622052d25859e6d6294f
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Nov 14 21:00:47 EST 2013

ndb/dns: various changes

stop absolute/relative dual use of RR.ttl. now RR.ttl is
*always* the *relative* ttl value. we derive absolute
timeout in RR.expire.

remove unused lookuptime field in DN. replace refs and
keep with mark field in DN. we do not care about the
number of references. only *iff* it is referenced, so
use a single bit for that (bit 0). for keep, we use
bit 1.

remove dolock parameter in dnagenever(), it is not
needed. we always need to lock.

mark local dns servers and domains as never to be aged.

the keeper bit is *just* a cache optimization, preventing
the domain and the domains it points to from being flushed.
it should not be used as a write protect bit in rrattach()
for preventing spoofing as it will prevent updates of say,
cname domains.

remove "removing spam ..." message. these are usualy just
hints, so normal. still, remove the hint as we currently
do no check if the nameserver has authority over the
cname domain.

remove "mydnsquery: trying to send to myself (%s); bzzzt"
message. this can happen when myaddr() fails for other
reasons. myaddr() will print error for us anyway.

--- a/sys/src/cmd/ndb/convDNS2M.c
+++ b/sys/src/cmd/ndb/convDNS2M.c
@@ -192,7 +192,8 @@
 convRR2M(RR *rp, uchar *p, uchar *ep, Dict *dp)
 {
 	uchar *lp, *data;
-	int len, ttl;
+	long ttl;
+	int len;
 	Txt *t;
 
 	NAME(rp->owner->name);
@@ -199,11 +200,8 @@
 	USHORT(rp->type);
 	USHORT(rp->owner->class);
 
-	/* egregious overuse of ttl (it's absolute time in the cache) */
-	if(rp->db)
+	if(rp->db || (ttl = (long)(rp->expire - now)) > rp->ttl)
 		ttl = rp->ttl;
-	else
-		ttl = rp->ttl - now;
 	if(ttl < 0)
 		ttl = 0;
 	ULONG(ttl);
--- a/sys/src/cmd/ndb/convM2DNS.c
+++ b/sys/src/cmd/ndb/convM2DNS.c
@@ -345,7 +345,6 @@
 	rp->type = type;
 
 	ULONG(rp->ttl);
-	rp->ttl += now;
 	USHORT(len);			/* length of data following */
 	data = sp->p;
 	assert(data != nil);
--- a/sys/src/cmd/ndb/dblookup.c
+++ b/sys/src/cmd/ndb/dblookup.c
@@ -17,7 +17,7 @@
 	 * confused by a zero ttl, and instead of using the data and then
 	 * discarding the RR, they conclude that they don't have valid data.
 	 */
-	Ptrttl = 120,
+	Ptrttl = 2*Min,
 };
 
 static Ndb *db;
@@ -611,10 +611,10 @@
 		return;
 
 	rp->owner = dp;
-	dnagenever(dp, 1);
 	rp->db = 1;
 	rp->ttl = intval(entry, pair, "ttl", rp->ttl);
 	rrattach(rp, Notauthoritative);
+	dnagenever(dp);
 }
 static void
 dbtuple2cache(Ndbtuple *t)
@@ -911,9 +911,9 @@
 	rp->owner = dp;			/* e.g., local#dns#servers */
 	rp->local = 1;
 	rp->db = 1;
-//	rp->ttl = 10*Min;		/* seems too short */
-	rp->ttl = (1UL<<31)-1;
+	rp->ttl = 10*Min;
 	rrattach(rp, Authoritative);	/* will not attach rrs in my area */
+	dnagenever(dp);
 
 	/* A or AAAA record */
 	if (parseip(ip, ipaddr) >= 0 && isv4(ip))
@@ -924,9 +924,9 @@
 	rp->owner = nsdp;
 	rp->local = 1;
 	rp->db = 1;
-//	rp->ttl = 10*Min;		/* seems too short */
-	rp->ttl = (1UL<<31)-1;
+	rp->ttl = 10*Min;
 	rrattach(rp, Authoritative);	/* will not attach rrs in my area */
+	dnagenever(nsdp);
 
 	dnslog("added local dns server %s at %s", buf, ipaddr);
 }
@@ -983,6 +983,7 @@
 	rp->db = 1;
 	rp->ttl = 10*Min;
 	rrattach(rp, Authoritative);
+	dnagenever(dp);
 }
 
 /*
--- a/sys/src/cmd/ndb/dn.c
+++ b/sys/src/cmd/ndb/dn.c
@@ -14,14 +14,10 @@
  * figure it out.
  */
 enum {
-//	Deftarget	= 1<<30,	/* effectively disable aging */
-//	Minage		= 1<<30,
-//	Defagefreq	= 1<<30,	/* age names this often (seconds) */
-
 	/* these settings will trigger frequent aging */
 	Deftarget	= 4000,
-	Minage		=  5*60,
-	Defagefreq	= 15*60,	/* age names this often (seconds) */
+	Minage		=  5*Min,
+	Defagefreq	= 15*Min,	/* age names this often (seconds) */
 };
 
 /*
@@ -305,9 +301,9 @@
 		for(dp = ht[i]; dp; dp = dp->next){
 			fprint(fd, "%s\n", dp->name);
 			for(rp = dp->rr; rp; rp = rp->next) {
-				fprint(fd, "\t%R %c%c %lud/%lud\n",
+				fprint(fd, "\t%R %c%c %ld/%lud\n",
 					rp, rp->auth? 'A': 'U',
-					rp->db? 'D': 'N', rp->expire, rp->ttl);
+					rp->db? 'D': 'N', (long)(rp->expire - now), rp->ttl);
 				if (rronlist(rp, rp->next))
 					fprint(fd, "*** duplicate:\n");
 			}
@@ -372,13 +368,13 @@
 	if (canlock(&dnlock))
 		abort();	/* dnage called with dnlock not held */
 	diff = now - dp->referenced;
-	if(diff < Reserved || dp->keep)
+	if(diff < Reserved || dp->mark != 0)
 		return;
 
 	l = &dp->rr;
 	while ((rp = *l) != nil){
 		assert(rp->magic == RRmagic && rp->cached);
-		if(!rp->db && (rp->expire < now || diff > dnvars.oldest))
+		if(!rp->db && ((long)(rp->expire - now) <= 0 || diff > dnvars.oldest))
 			rrdelhead(l); /* rp == *l before; *l == rp->next after */
 		else
 			l = &rp->next;
@@ -385,16 +381,15 @@
 	}
 }
 
-#define MARK(dp)	{ if (dp) (dp)->keep = 1; }
+#define MARK(dp)	{ if (dp) (dp)->mark |= 2; }
 
 /* mark a domain name and those in its RRs as never to be aged */
 void
-dnagenever(DN *dp, int dolock)
+dnagenever(DN *dp)
 {
 	RR *rp;
 
-	if (dolock)
-		lock(&dnlock);
+	lock(&dnlock);
 
 	/* mark all referenced domain names */
 	MARK(dp);
@@ -449,11 +444,10 @@
 		}
 	}
 
-	if (dolock)
-		unlock(&dnlock);
+	unlock(&dnlock);
 }
 
-#define REF(dp)	{ if (dp) (dp)->refs++; }
+#define REF(dp)	{ if (dp) (dp)->mark |= 1; }
 
 /*
  *  periodicly sweep for old records and remove unreferenced domain names
@@ -468,7 +462,7 @@
 	RR *rp;
 	static ulong nextage;
 
-	if(dnvars.names < target || (now < nextage && !doit)){
+	if(dnvars.names < target || ((long)(nextage - now) > 0 && !doit)){
 		dnvars.oldest = maxage;
 		return;
 	}
@@ -483,7 +477,7 @@
 	if (agefreq > dnvars.oldest / 2)
 		nextage = now + dnvars.oldest / 2;
 	else
-		nextage = now + agefreq;
+		nextage = now + (ulong)agefreq;
 
 	lock(&dnlock);
 
@@ -490,7 +484,7 @@
 	/* time out all old entries (and set refs to 0) */
 	for(i = 0; i < HTLEN; i++)
 		for(dp = ht[i]; dp; dp = dp->next){
-			dp->refs = 0;
+			dp->mark &= ~1;
 			dnage(dp);
 		}
 
@@ -552,7 +546,7 @@
 	for(i = 0; i < HTLEN; i++){
 		l = &ht[i];
 		for(dp = *l; dp; dp = *l){
-			if(dp->rr == nil && dp->refs == 0 && dp->keep == 0){
+			if(dp->rr == nil && dp->mark == 0){
 				assert(dp->magic == DNmagic);
 				*l = dp->next;
 
@@ -586,7 +580,7 @@
 	/* time out all database entries */
 	for(i = 0; i < HTLEN; i++)
 		for(dp = ht[i]; dp; dp = dp->next) {
-			dp->keep = 0;
+			dp->mark = 0;
 			for(rp = dp->rr; rp; rp = rp->next)
 				if(rp->db)
 					rp->expire = 0;
@@ -738,17 +732,10 @@
 	RR **l;
 	RR *rp;
 	DN *dp;
+	ulong ttl;
 
 	assert(new->magic == RRmagic && !new->cached);
-	if(!new->db) {
-		/*
-		 * try not to let responses expire before we
-		 * can use them to complete this query, by extending
-		 * past (or nearly past) expiration time.
-		 */
-		new->expire = new->ttl > now + Min? new->ttl: now + 10*Min;
-	} else
-		new->expire = now + Year;
+
 	dp = new->owner;
 	assert(dp != nil && dp->magic == DNmagic);
 	new->auth |= auth;
@@ -755,6 +742,19 @@
 	new->next = 0;
 
 	/*
+	 * try not to let responses expire before we
+	 * can use them to complete this query, by extending
+	 * past (or nearly past) expiration time.
+	 */
+	if(new->db)
+		ttl = Year;
+	else
+		ttl = new->ttl;
+	if(ttl <= Min)
+		ttl = 10*Min;
+	new->expire = now + ttl;
+
+	/*
 	 *  find first rr of the right type
 	 */
 	l = &dp->rr;
@@ -788,9 +788,8 @@
 			}
 			/* all things equal, pick the newer one */
 			else if(rp->arg0 == new->arg0 && rp->arg1 == new->arg1){
-				/* new drives out old */
-				if (new->ttl <= rp->ttl &&
-				    new->expire <= rp->expire) {
+				/* old drives out new */
+				if((long)(rp->expire - new->expire) > 0) {
 					rrfree(new);
 					return;
 				}
@@ -842,8 +841,8 @@
 		next = rp->next;
 		rp->next = nil;
 		dp = rp->owner;
-		/* avoid any outside spoofing; leave keepers alone */
-		if(cfg.cachedb && !rp->db && (dp->keep || inmyarea(dp->name)))
+		/* avoid any outside spoofing */
+		if(cfg.cachedb && !rp->db && inmyarea(dp->name))
 			rrfree(rp);
 		else
 			rrattach1(rp, auth);
@@ -974,8 +973,8 @@
 	for(rp = dp->rr; rp; rp = rp->next){
 		if(!rp->db)
 		if(rp->auth)
-		if(rp->ttl + 60 > now)
-		if(tsame(type, rp->type)){
+		if((long)(rp->expire - now) > 0)
+ 		if(tsame(type, rp->type)){
 			if(flag == NOneg && rp->negative)
 				goto out;
 			last = rrcopy(rp, last);
@@ -987,7 +986,7 @@
 	/* try for a living unauthoritative network entry */
 	for(rp = dp->rr; rp; rp = rp->next){
 		if(!rp->db)
-		if(rp->ttl + 60 > now)
+		if((long)(rp->expire - now) > 0)
 		if(tsame(type, rp->type)){
 			if(flag == NOneg && rp->negative)
 				goto out;
@@ -1822,7 +1821,9 @@
 	for(rp = first; rp != nil; rp = nrp){
 		nrp = rp->next;
 		rp->next = nil;
+		dp = rp->owner;
 		rrattach(rp, Authoritative);
+		dnagenever(dp);
 	}
 }
 
--- a/sys/src/cmd/ndb/dnresolve.c
+++ b/sys/src/cmd/ndb/dnresolve.c
@@ -346,7 +346,7 @@
 			nsrp = randomize(rrlookup(nsdp, Tns, NOneg));
 
 		/* if the entry timed out, ignore it */
-		if(nsrp && nsrp->ttl < now)
+		if(nsrp && !nsrp->db && (long)(nsrp->expire - now) <= 0)
 			rrfreelistptr(&nsrp);
 
 		if(nsrp){
@@ -397,7 +397,7 @@
 			}
 		} else
 			/* cached entry must still be valid */
-			if(rp->ttl > now)
+			if((long)(rp->expire - now) > 0)
 				/* but Tall entries are special */
 				if(type != Tall || rp->query == Tall) {
 					noteinmem();
@@ -850,7 +850,7 @@
 
 	/* the attach can cause soarr to be freed so mine it now */
 	if(soarr != nil && soarr->soa != nil)
-		ttl = soarr->soa->minttl+now;
+		ttl = soarr->soa->minttl;
 	else
 		ttl = 5*Min;
 
@@ -893,11 +893,8 @@
 
 	rv = -1;
 	snprint(domain, sizeof(domain), "%I", udppkt);
-	if (myaddr(domain)) {
-		dnslog("mydnsquery: trying to send to myself (%s); bzzzt",
-			domain);
+	if (myaddr(domain))
 		return rv;
-	}
 	switch (medium) {
 	case Udp:
 		nfd = dup(qp->udpfd, -1);
@@ -1094,13 +1091,11 @@
 	if(mp->an){
 		/*
 		 * only use cname answer when returned. some dns servers
-		 * attach spam address records which poisons the cache.
+		 * attach (potential) spam hint address records which poisons the cache.
 		 */
 		if((tp = rrremtype(&mp->an, Tcname)) != 0){
-			if(mp->an){
-				dnslog("removing spam %Q for %Q from %I", mp->an, tp, srcip);
+			if(mp->an)
 				rrfreelist(mp->an);
-			}
 			mp->an = tp;
 		}
 		rrattach(mp->an, (mp->flags & Fauth) != 0);
--- a/sys/src/cmd/ndb/dns.h
+++ b/sys/src/cmd/ndb/dns.h
@@ -194,13 +194,10 @@
 	char	*name;		/* owner */
 	RR	*rr;		/* resource records off this name */
 	ulong	referenced;	/* time last referenced */
-	ulong	lookuptime;	/* last time we tried to get a better value */
-	/* refs was `char' but we've seen refs > 120, so go whole hog */
-	ulong	refs;		/* for mark and sweep */
 	ulong	ordinal;
 	ushort	class;		/* RR class */
-	uchar	keep;		/* flag: never age this name */
 	uchar	respcode;	/* response code */
+	uchar	mark;		/* for mark and sweep */
 };
 
 /*
@@ -448,7 +445,7 @@
 void	dnage(DN*);
 void	dnageall(int);
 void	dnagedb(void);
-void	dnagenever(DN *, int);
+void	dnagenever(DN *);
 void	dnauthdb(void);
 void	dncheck(void);
 void	dndump(char*);
--- a/sys/src/cmd/ndb/dnsdebug.c
+++ b/sys/src/cmd/ndb/dnsdebug.c
@@ -141,7 +141,7 @@
 	p = buf;
 	e = buf + sizeof(buf);
 	p = seprint(p, e, "%-32.32s %-15.15s %-5.5s", rp->owner->name,
-		longtime(rp->db? rp->ttl: (rp->ttl - now)),
+		longtime(rp->ttl),
 		rrname(rp->type, buf, sizeof buf));
 
 	if(rp->negative){
@@ -308,9 +308,10 @@
 	/* look up the resolver address first */
 	cfg.resolver = 0;
 	debug = 0;
-	if(serveraddrs)
+	if(serveraddrs){
 		rrfreelist(serveraddrs);
-	serveraddrs = nil;
+		serveraddrs = nil;
+	}
 	rr = getdnsservers(Cin);
 	l = &serveraddrs;
 	for(rp = rr; rp != nil; rp = rp->next){
--