git: 9front

Download patch

ref: e2d8479a029334d8bcd66be2d7cf1ed52abeca12
parent: effc5f4f6cd0ffea758a131315bb6640bebc6f6b
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri Dec 13 20:49:55 EST 2024

ndb/dns: don't refuse queries when delegated subareas

We used to always provide soa and ns hints when
we where not authoritative.

This changed with the last commit, where we
would instead return refused error.

But this breaks when we want to explicitely
delegate to another nameserver, so add parameter
to inmyarea() to get the delegated soa out,
and provide delegated nameservers when we have one.

--- a/sys/src/cmd/ndb/dblookup.c
+++ b/sys/src/cmd/ndb/dblookup.c
@@ -164,7 +164,7 @@
 		 * don't call it non-existent if it's not ours
 		 * (unless we're a resolver).
 		 */
-		if(err == Rname && (!inmyarea(dp->name) || cfg.resolver))
+		if(err == Rname && (!inmyarea(dp->name, nil) || cfg.resolver))
 			err = Rserver;
 		dp->respcode = err;
 	}
@@ -848,7 +848,7 @@
 	for(nt = mydoms; nt != nil; nt = nt->entry)
 		if(rp->host && cistrcmp(rp->host->name, nt->val) == 0)
 			break;
-	if(nt == nil || inmyarea(rp->owner->name))
+	if(nt == nil || inmyarea(rp->owner->name, nil))
 		return 0;
 	dnslog("bad delegation %R from %I/%s; "
 		"no further logging of them",
--- a/sys/src/cmd/ndb/dn.c
+++ b/sys/src/cmd/ndb/dn.c
@@ -526,7 +526,7 @@
 
 	for(i = 0; i < HTLEN; i++)
 		for(dp = ht[i]; dp; dp = dp->next){
-			area = inmyarea(dp->name);
+			area = inmyarea(dp->name, nil);
 			l = &dp->rr;
 			for(rp = *l; rp; rp = *l){
 				if(rp->db){
@@ -539,7 +539,7 @@
 						if(rp->ttl < minttl)
 							rp->ttl = minttl;
 						rp->auth = 1;
-					} else if(rp->type == Tns && inmyarea(rp->host->name))
+					} else if(rp->type == Tns && inmyarea(rp->host->name, nil))
 						rp->auth = 1;
 				} else if(area){
 					/* no outside spoofing */
@@ -707,7 +707,7 @@
 		next = rp->next;
 		rp->next = nil;
 		if(rp->type == Tall || rp->type == Topt || !rrsupported(rp->type)
-		|| cfg.cachedb && !rp->db && inmyarea(rp->owner->name))
+		|| cfg.cachedb && !rp->db && inmyarea(rp->owner->name, nil))
 			rrfree(rp);
 		else
 			rrattach1(rp, auth);
--- a/sys/src/cmd/ndb/dnarea.c
+++ b/sys/src/cmd/ndb/dnarea.c
@@ -26,17 +26,22 @@
  *  true if a name is in our area
  */
 Area*
-inmyarea(char *name)
+inmyarea(char *name, Area **delegation)
 {
 	Area *s, *d;
 
 	s = nameinarea(name, owned);
-	if(s == nil)
+	if(s == nil){
+		if(delegation)
+			*delegation = nil;
 		return nil;
+	}
 	d = nameinarea(name, delegated);
-	if(d && d->len > s->len)
+	if(delegation)
+		*delegation = d;
+	if(d != nil && d->len > s->len)
 		return nil;
-	return s;	/* name is in owned area `s' and not in a delegated subarea */
+	return s;	/* name is in owned area `s' and not in a delegated subarea `d' */
 }
 
 /*
--- a/sys/src/cmd/ndb/dnnotify.c
+++ b/sys/src/cmd/ndb/dnnotify.c
@@ -26,7 +26,7 @@
 		return;
 
 	/* is it something we care about? */
-	a = inmyarea(repp->qd->owner->name);
+	a = inmyarea(repp->qd->owner->name, nil);
 	if(a == nil)
 		return;
 
--- a/sys/src/cmd/ndb/dnresolve.c
+++ b/sys/src/cmd/ndb/dnresolve.c
@@ -403,7 +403,7 @@
 	 * if the domain name is within an area of ours,
 	 * we should have found its data in memory by now.
 	 */
-	area = inmyarea(dp->name);
+	area = inmyarea(dp->name, nil);
 	if (area || strncmp(dp->name, "local#", 6) == 0)
 		return nil;
 
--- a/sys/src/cmd/ndb/dns.h
+++ b/sys/src/cmd/ndb/dns.h
@@ -489,7 +489,7 @@
 extern Area	*owned;
 void	addarea(RR *rp, Ndbtuple *t);
 void	freeareas(Area**);
-Area*	inmyarea(char*);
+Area*	inmyarea(char*, Area**);
 
 /* dblookup.c */
 int	baddelegation(RR*, RR*, uchar*);
--- a/sys/src/cmd/ndb/dnserver.c
+++ b/sys/src/cmd/ndb/dnserver.c
@@ -14,7 +14,7 @@
 {
 	char tname[32], *cp;
 	DN *nsdp;
-	Area *myarea;
+	Area *myarea, *delegation;
 	RR *rp, *neg;
 
 	repp->id = reqp->id;
@@ -49,7 +49,7 @@
 		return;
 	}
 
-	myarea = inmyarea(repp->qd->owner->name);
+	myarea = inmyarea(repp->qd->owner->name, &delegation);
 	if(myarea){
 		if(repp->qd->type == Tixfr || repp->qd->type == Taxfr){
 			if(debug)
@@ -64,9 +64,15 @@
 	} else {
 		if(cfg.nonrecursive
 		|| cfg.localrecursive && !localip(srcip)){
-			/* we don't recurse and we're not authoritative */
-			setercode(repp, Rrefused);
-			return;
+			if(delegation == nil){
+				/*
+				 * we don't recurse and we're not authoritative
+				 * nor lies the domain in a delegated sub area.
+				 */
+				setercode(repp, Rrefused);
+				return;
+			}
+			neg = nil;
 		} else {
 			repp->flags |= Fcanrec;
 			if(reqp->flags & Frecurse){
--