ndb/dns: make dblookup() consistent with cachedb operation, bring back txtrr for compatibility

- enforce same behaviour as cachedb server in dblookup():
	- force Taaaa record type on ipv6= attributes, regardless of value
	- return Taaaa records for ip= attributes containing ipv6 values
	- return Ta records only for ip= attributes containing ipv4 values

- for compatibility, bring back support for txtrr= type, but handle consistently
This commit is contained in:
cinap_lenrek 2021-09-08 17:34:04 +00:00
parent 1299ea4d89
commit df66e62842

View file

@ -26,6 +26,8 @@ static QLock dblock;
static Ipifc *ipifcs; static Ipifc *ipifcs;
static QLock ipifclock; static QLock ipifclock;
static RR* addr4rr(Ndbtuple*, Ndbtuple*);
static RR* addr6rr(Ndbtuple*, Ndbtuple*);
static RR* addrrr(Ndbtuple*, Ndbtuple*); static RR* addrrr(Ndbtuple*, Ndbtuple*);
static RR* cnamerr(Ndbtuple*, Ndbtuple*); static RR* cnamerr(Ndbtuple*, Ndbtuple*);
static void createptrs(void); static void createptrs(void);
@ -203,12 +205,13 @@ dblookup1(char *name, int type, int auth, int ttl)
RR *rp, *list, **l; RR *rp, *list, **l;
Ndbs s; Ndbs s;
char dname[Domlen]; char dname[Domlen];
char *attr; char *attr, *attr2;
DN *dp; DN *dp;
RR *(*f)(Ndbtuple*, Ndbtuple*); RR *(*f)(Ndbtuple*, Ndbtuple*);
int found, x; int found, x;
dp = nil; dp = nil;
attr2 = nil;
switch(type){ switch(type){
case Tptr: case Tptr:
attr = "ptr"; attr = "ptr";
@ -216,11 +219,12 @@ dblookup1(char *name, int type, int auth, int ttl)
break; break;
case Ta: case Ta:
attr = "ip"; attr = "ip";
f = addrrr; f = addr4rr;
break; break;
case Taaaa: case Taaaa:
attr = "ipv6"; attr = "ip";
f = addrrr; attr2 = "ipv6";
f = addr6rr;
break; break;
case Tnull: case Tnull:
attr = "nullrr"; attr = "nullrr";
@ -240,6 +244,7 @@ dblookup1(char *name, int type, int auth, int ttl)
break; break;
case Ttxt: case Ttxt:
attr = "txt"; attr = "txt";
attr2 = "txtrr"; /* undocumented */
f = txtrr; f = txtrr;
break; break;
case Tmx: case Tmx:
@ -283,19 +288,19 @@ dblookup1(char *name, int type, int auth, int ttl)
break; break;
} }
for(nt = ndbsearch(db, &s, "dom", dname); nt != nil; nt = ndbsnext(&s, "dom", dname)) { for(nt = ndbsearch(db, &s, "dom", dname); nt != nil; nt = ndbsnext(&s, "dom", dname)) {
if(ndbfindattr(nt, s.t, attr) == nil) { if(ndbfindattr(nt, s.t, attr) != nil
|| attr2 != nil && ndbfindattr(nt, s.t, attr2) != nil)
t = ndbconcatenate(t, ndbreorder(nt, s.t));
else
ndbfree(nt); ndbfree(nt);
continue;
}
t = ndbconcatenate(t, ndbreorder(nt, s.t));
} }
if(t == nil && strchr(dname, '.') == nil) { if(t == nil && strchr(dname, '.') == nil) {
for(nt = ndbsearch(db, &s, "sys", dname); nt != nil; nt = ndbsnext(&s, "sys", dname)) { for(nt = ndbsearch(db, &s, "sys", dname); nt != nil; nt = ndbsnext(&s, "sys", dname)) {
if(ndbfindattr(nt, s.t, attr) == nil) { if(ndbfindattr(nt, s.t, attr) != nil
|| attr2 != nil && ndbfindattr(nt, s.t, attr2) != nil)
t = ndbconcatenate(t, ndbreorder(nt, s.t));
else
ndbfree(nt); ndbfree(nt);
continue;
}
t = ndbconcatenate(t, ndbreorder(nt, s.t));
} }
} }
s.t = t; s.t = t;
@ -303,18 +308,16 @@ dblookup1(char *name, int type, int auth, int ttl)
break; break;
} }
if(t == nil) { if(t == nil)
// dnslog("dblookup1(%s) name not found", name);
return nil; return nil;
}
/* search whole entry for default domain name */ /* search whole entry for default domain name */
for(nt = t; nt; nt = nt->entry) for(nt = t; nt; nt = nt->entry) {
if(strcmp(nt->attr, "dom") == 0){ if(strcmp(nt->attr, "dom") == 0) {
nstrcpy(dname, nt->val, sizeof dname); nstrcpy(dname, nt->val, sizeof dname);
break; break;
} }
}
/* ttl is maximum of soa minttl and entry's ttl ala rfc883 */ /* ttl is maximum of soa minttl and entry's ttl ala rfc883 */
x = intval(t, s.t, "ttl", 0); x = intval(t, s.t, "ttl", 0);
@ -338,7 +341,8 @@ dblookup1(char *name, int type, int auth, int ttl)
nstrcpy(dname, nt->val, sizeof dname); nstrcpy(dname, nt->val, sizeof dname);
found = 1; found = 1;
} }
if(strcmp(attr, nt->attr) == 0 && (rp = (*f)(t, nt)) != nil){ if((strcmp(attr, nt->attr) == 0 || attr2 != nil && strcmp(attr2, nt->attr) == 0)
&& (rp = (*f)(t, nt)) != nil){
rp->auth = auth; rp->auth = auth;
rp->db = 1; rp->db = 1;
if(ttl) if(ttl)
@ -356,8 +360,10 @@ dblookup1(char *name, int type, int auth, int ttl)
} }
/* search whole entry */ /* search whole entry */
for(nt = t; nt; nt = nt->entry) for(nt = t; nt; nt = nt->entry){
if(nt->ptr == 0 && strcmp(attr, nt->attr) == 0 && (rp = (*f)(t, nt)) != nil){ if(nt->ptr == 0
&& (strcmp(attr, nt->attr) == 0 || attr2 != nil && strcmp(attr2, nt->attr) == 0)
&& (rp = (*f)(t, nt)) != nil){
rp->auth = auth; rp->auth = auth;
rp->db = 1; rp->db = 1;
if(ttl) if(ttl)
@ -368,17 +374,48 @@ dblookup1(char *name, int type, int auth, int ttl)
*l = rp; *l = rp;
l = &rp->next; l = &rp->next;
} }
}
ndbfree(t); ndbfree(t);
unique(list); unique(list);
// dnslog("dblookup1(%s) -> %#p", name, list);
return list; return list;
} }
/* /*
* make various types of resource records from a database entry * make various types of resource records from a database entry
*/ */
static RR*
addr4rr(Ndbtuple*, Ndbtuple *pair)
{
RR *rp;
uchar ip[IPaddrlen];
if(parseip(ip, pair->val) == -1)
return nil;
if(!isv4(ip) || strcmp(pair->attr, "ipv6") == 0)
return nil;
rp = rralloc(Ta);
rp->ip = ipalookup(ip, Cin, 1);
return rp;
}
static RR*
addr6rr(Ndbtuple*, Ndbtuple *pair)
{
RR *rp;
uchar ip[IPaddrlen];
if(parseip(ip, pair->val) == -1)
return nil;
if(isv4(ip) && strcmp(pair->attr, "ipv6") != 0)
return nil;
rp = rralloc(Taaaa);
rp->ip = ipalookup(ip, Cin, 1);
return rp;
}
static RR* static RR*
addrrr(Ndbtuple*, Ndbtuple *pair) addrrr(Ndbtuple*, Ndbtuple *pair)
{ {
@ -387,10 +424,11 @@ addrrr(Ndbtuple*, Ndbtuple *pair)
if(parseip(ip, pair->val) == -1) if(parseip(ip, pair->val) == -1)
return nil; return nil;
rp = rralloc(isv4(ip) ? Ta : Taaaa); rp = rralloc(isv4(ip) && strcmp(pair->attr, "ipv6") != 0 ? Ta : Taaaa);
rp->ip = ipalookup(ip, Cin, 1); rp->ip = ipalookup(ip, Cin, 1);
return rp; return rp;
} }
static RR* static RR*
nullrr(Ndbtuple*, Ndbtuple *pair) nullrr(Ndbtuple*, Ndbtuple *pair)
{ {
@ -613,6 +651,8 @@ dbpair2cache(DN *dp, Ndbtuple *entry, Ndbtuple *pair)
rp = cnamerr(entry, pair); rp = cnamerr(entry, pair);
else if(strcmp(pair->attr, "nullrr") == 0) else if(strcmp(pair->attr, "nullrr") == 0)
rp = nullrr(entry, pair); rp = nullrr(entry, pair);
else if(strcmp(pair->attr, "txtrr") == 0) /* undocumented */
rp = txtrr(entry, pair);
else if(strcmp(pair->attr, "txt") == 0) else if(strcmp(pair->attr, "txt") == 0)
rp = txtrr(entry, pair); rp = txtrr(entry, pair);
if(rp == nil) if(rp == nil)