shithub: front

Download patch

ref: 473ebd0f9e117f3c7e1d5504b8b97cedee580ccd
parent: d1b72a27b72317790124f1790b5f6f823bae21bf
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){
--