shithub: riscv

Download patch

ref: bf187247380252d3f79ad7089251600b7535815e
parent: d310da13ba8d31c84978f96f542b9929a4e54ed8
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Oct 17 17:28:25 EDT 2020

ndb/dns: mark ns record authoritative when in our area for delegation

I have the problem that i need to delegate a subdomain
to another name server that is confused about its own zone
(and its own name) returning unusable ns records.

With this, one can make up a nameserver entry in ndb that
is authoritative and owned by us for that nameserver,
and then put it in the soa=delegated ns entry.

This promotes the ns record in the soa=delegated to
Authoritative, which avoids overriding the ns rr's from
the confused server for the delegated zone.

--- a/sys/src/cmd/ndb/dn.c
+++ b/sys/src/cmd/ndb/dn.c
@@ -641,7 +641,8 @@
 						if(rp->ttl < minttl)
 							rp->ttl = minttl;
 						rp->auth = 1;
-					}
+					} else if(rp->type == Tns && inmyarea(rp->host->name))
+						rp->auth = 1;
 				}
 				l = &rp->next;
 			}
--- a/sys/src/cmd/ndb/dnarea.c
+++ b/sys/src/cmd/ndb/dnarea.c
@@ -7,6 +7,21 @@
 
 Area *owned, *delegated;
 
+static Area*
+nameinarea(char *name, Area *s)
+{
+	int len;
+	
+	for(len = strlen(name); s != nil; s = s->next){
+		if(s->len > len)
+			continue;
+		if(cistrcmp(s->soarr->owner->name, name + len - s->len) == 0)
+			if(len == s->len || name[len - s->len - 1] == '.')
+				return s;
+	}
+	return nil;
+}
+
 /*
  *  true if a name is in our area
  */
@@ -13,30 +28,15 @@
 Area*
 inmyarea(char *name)
 {
-	int len;
 	Area *s, *d;
 
-	len = strlen(name);
-	for(s = owned; s; s = s->next){
-		if(s->len > len)
-			continue;
-		if(cistrcmp(s->soarr->owner->name, name + len - s->len) == 0)
-			if(len == s->len || name[len - s->len - 1] == '.')
-				break;
-	}
+	s = nameinarea(name, owned);
 	if(s == nil)
 		return nil;
-
-	/* name is in area `s' */
-	for(d = delegated; d; d = d->next){
-		if(d->len > len)
-			continue;
-		if(cistrcmp(d->soarr->owner->name, name + len - d->len) == 0)
-			if(len == d->len || name[len - d->len - 1] == '.')
-				return nil; /* name is in a delegated subarea */
-	}
-
-	return s;	/* name is in area `s' and not in a delegated subarea */
+	d = nameinarea(name, delegated);
+	if(d && d->len > s->len)
+		return nil;
+	return s;	/* name is in owned area `s' and not in a delegated subarea */
 }
 
 /*
@@ -48,7 +48,10 @@
 {
 	Area *s;
 	Area **l;
+	int len;
 
+	len = strlen(dp->name);
+
 	lock(&dnlock);
 	if(t->val[0])
 		l = &delegated;
@@ -55,11 +58,14 @@
 	else
 		l = &owned;
 
-	for (s = *l; s != nil; s = s->next)
+	for (s = *l; s != nil; l = &s->next, s = s->next){
+		if(s->len < len)
+			break;
 		if(s->soarr->owner == dp) {
 			unlock(&dnlock);
 			return;		/* we've already got one */
 		}
+	}
 
 	/*
 	 *  The area contains a copy of the soa rr that created it.
@@ -67,7 +73,7 @@
 	 *  as the area does.
 	 */
 	s = emalloc(sizeof(*s));
-	s->len = strlen(dp->name);
+	s->len = len;
 	rrcopy(rp, &s->soarr);
 	s->soarr->owner = dp;
 	s->soarr->db = 1;