ndb/dns: allow multiple txt, nullrr, cert, key and sig records (thanks kvik)
The de-duplication of txt, nullrr, cert, key and sig records reduced all records to a single one. Also, dblookup1() missed the txt record case and did not return a unique list of rr's. Now we consider these records unique if their value is different. The new txtequiv() function does that for TXT records, which is a bit tricky as it needs to take different segmentation into account.
This commit is contained in:
parent
93b475981e
commit
ac4e21f52d
2 changed files with 78 additions and 8 deletions
|
@ -238,6 +238,10 @@ dblookup1(char *name, int type, int auth, int ttl)
|
||||||
attr = "srv";
|
attr = "srv";
|
||||||
f = srvrr;
|
f = srvrr;
|
||||||
break;
|
break;
|
||||||
|
case Ttxt:
|
||||||
|
attr = "txt";
|
||||||
|
f = txtrr;
|
||||||
|
break;
|
||||||
case Tmx:
|
case Tmx:
|
||||||
attr = "mx";
|
attr = "mx";
|
||||||
f = mxrr;
|
f = mxrr;
|
||||||
|
@ -366,6 +370,8 @@ dblookup1(char *name, int type, int auth, int ttl)
|
||||||
}
|
}
|
||||||
ndbfree(t);
|
ndbfree(t);
|
||||||
|
|
||||||
|
unique(list);
|
||||||
|
|
||||||
// dnslog("dblookup1(%s) -> %#p", name, list);
|
// dnslog("dblookup1(%s) -> %#p", name, list);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -575,7 +581,7 @@ static RR*
|
||||||
doaxfr(Ndb *db, char *name)
|
doaxfr(Ndb *db, char *name)
|
||||||
{
|
{
|
||||||
USED(db, name);
|
USED(db, name);
|
||||||
return 0;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -245,8 +245,11 @@ ipalookup(uchar *ip, int class, int enter)
|
||||||
static int
|
static int
|
||||||
rrsame(RR *rr1, RR *rr2)
|
rrsame(RR *rr1, RR *rr2)
|
||||||
{
|
{
|
||||||
return rr1 == rr2 || rr2 && rrequiv(rr1, rr2) &&
|
return rr1 == rr2 ||
|
||||||
rr1->db == rr2->db && rr1->auth == rr2->auth;
|
rr1 != nil && rr2 != nil &&
|
||||||
|
rr1->db == rr2->db &&
|
||||||
|
rr1->auth == rr2->auth &&
|
||||||
|
rrequiv(rr1, rr2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -798,7 +801,7 @@ rrattach1(RR *new, int auth)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* all things equal, pick the newer one */
|
/* all things equal, pick the newer one */
|
||||||
else if(rp->arg0 == new->arg0 && rp->arg1 == new->arg1){
|
else if(rrequiv(rp, new)){
|
||||||
/* old drives out new */
|
/* old drives out new */
|
||||||
if((long)(rp->expire - new->expire) > 0) {
|
if((long)(rp->expire - new->expire) > 0) {
|
||||||
rrfree(new);
|
rrfree(new);
|
||||||
|
@ -1523,13 +1526,74 @@ slave(Request *req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
blockequiv(Block *a, Block *b)
|
||||||
|
{
|
||||||
|
return a->dlen == b->dlen &&
|
||||||
|
memcmp(a->data, b->data, a->dlen) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
keyequiv(Key *a, Key *b)
|
||||||
|
{
|
||||||
|
return a->flags == b->flags &&
|
||||||
|
a->proto == b->proto &&
|
||||||
|
a->alg == b->alg &&
|
||||||
|
blockequiv(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
certequiv(Cert *a, Cert *b)
|
||||||
|
{
|
||||||
|
return a->type == a->type &&
|
||||||
|
a->tag == a->tag &&
|
||||||
|
a->alg == a->alg &&
|
||||||
|
blockequiv(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
txtequiv(Txt *a, Txt *b)
|
||||||
|
{
|
||||||
|
char *ap, *ae, *bp, *be;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for(ap = ae = bp = be = nil;;ap += n, bp += n){
|
||||||
|
while(a != nil && (ap == nil || (ap == ae && (a = a->next) != nil)))
|
||||||
|
ap = a->p, ae = ap + strlen(ap);
|
||||||
|
while(b != nil && (bp == nil || (bp == be && (b = b->next) != nil)))
|
||||||
|
bp = b->p, be = bp + strlen(bp);
|
||||||
|
if(a == b || a == nil || b == nil)
|
||||||
|
break;
|
||||||
|
n = ae - ap;
|
||||||
|
if(be - bp < n)
|
||||||
|
n = be - bp;
|
||||||
|
if(memcmp(ap, bp, n) != 0)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rrequiv(RR *r1, RR *r2)
|
rrequiv(RR *r1, RR *r2)
|
||||||
{
|
{
|
||||||
return r1->owner == r2->owner
|
if(r1->owner != r2->owner
|
||||||
&& r1->type == r2->type
|
|| r1->type != r2->type
|
||||||
&& r1->arg0 == r2->arg0
|
|| r1->arg0 != r2->arg0
|
||||||
&& r1->arg1 == r2->arg1;
|
|| r1->arg1 != r2->arg1)
|
||||||
|
return 0;
|
||||||
|
switch(r1->type){
|
||||||
|
case Tkey:
|
||||||
|
return keyequiv(r1->key, r2->key);
|
||||||
|
case Tcert:
|
||||||
|
return certequiv(r1->cert, r2->cert);
|
||||||
|
case Tsig:
|
||||||
|
return r1->sig->signer == r2->sig->signer && certequiv(r1->sig, r2->sig);
|
||||||
|
case Tnull:
|
||||||
|
return blockequiv(r1->null, r2->null);
|
||||||
|
case Ttxt:
|
||||||
|
return txtequiv(r1->txt, r2->txt);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue