diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2020-08-08 18:37:10 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2020-08-08 18:37:10 +0200 |
commit | ac4e21f52d8458732b6e18d6ca481ab880c6c9be (patch) | |
tree | d026fbd29aaf0ed5925d78fedb4eb7d451dbce19 /sys/src/cmd/ndb | |
parent | 93b475981e7326f53dee0369476344f8552f4e7b (diff) |
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.
Diffstat (limited to 'sys/src/cmd/ndb')
-rw-r--r-- | sys/src/cmd/ndb/dblookup.c | 8 | ||||
-rw-r--r-- | sys/src/cmd/ndb/dn.c | 78 |
2 files changed, 78 insertions, 8 deletions
diff --git a/sys/src/cmd/ndb/dblookup.c b/sys/src/cmd/ndb/dblookup.c index 1c8e5a86d..e6a31f2bc 100644 --- a/sys/src/cmd/ndb/dblookup.c +++ b/sys/src/cmd/ndb/dblookup.c @@ -238,6 +238,10 @@ dblookup1(char *name, int type, int auth, int ttl) attr = "srv"; f = srvrr; break; + case Ttxt: + attr = "txt"; + f = txtrr; + break; case Tmx: attr = "mx"; f = mxrr; @@ -366,6 +370,8 @@ dblookup1(char *name, int type, int auth, int ttl) } ndbfree(t); + unique(list); + // dnslog("dblookup1(%s) -> %#p", name, list); return list; } @@ -575,7 +581,7 @@ static RR* doaxfr(Ndb *db, char *name) { USED(db, name); - return 0; + return nil; } /* diff --git a/sys/src/cmd/ndb/dn.c b/sys/src/cmd/ndb/dn.c index f565a38fe..71768e7e3 100644 --- a/sys/src/cmd/ndb/dn.c +++ b/sys/src/cmd/ndb/dn.c @@ -245,8 +245,11 @@ ipalookup(uchar *ip, int class, int enter) static int rrsame(RR *rr1, RR *rr2) { - return rr1 == rr2 || rr2 && rrequiv(rr1, rr2) && - rr1->db == rr2->db && rr1->auth == rr2->auth; + return rr1 == rr2 || + rr1 != nil && rr2 != nil && + rr1->db == rr2->db && + rr1->auth == rr2->auth && + rrequiv(rr1, rr2); } static int @@ -798,7 +801,7 @@ rrattach1(RR *new, int auth) continue; } /* 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 */ if((long)(rp->expire - new->expire) > 0) { rrfree(new); @@ -1524,12 +1527,73 @@ 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 rrequiv(RR *r1, RR *r2) { - return r1->owner == r2->owner - && r1->type == r2->type - && r1->arg0 == r2->arg0 - && r1->arg1 == r2->arg1; + if(r1->owner != r2->owner + || r1->type != r2->type + || r1->arg0 != r2->arg0 + || 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 |