Optimse RR digest calculation in DNSSEC.

If an RR is of a type which doesn't need canonicalisation,
bypass the relatively slow canonicalisation code, and insert
it direct into the digest.
This commit is contained in:
Simon Kelley
2020-11-12 23:09:15 +00:00
parent 2d765867c5
commit 059aded070

View File

@@ -579,7 +579,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
hash->update(ctx, (unsigned int)wire_len, (unsigned char*)keyname); hash->update(ctx, (unsigned int)wire_len, (unsigned char*)keyname);
from_wire(keyname); from_wire(keyname);
#define RRBUFLEN 300 /* Most RRs are smaller than this. */ #define RRBUFLEN 128 /* Most RRs are smaller than this. */
for (i = 0; i < rrsetidx; ++i) for (i = 0; i < rrsetidx; ++i)
{ {
@@ -618,11 +618,26 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
hash->update(ctx, 4, p); /* class and type */ hash->update(ctx, 4, p); /* class and type */
hash->update(ctx, 4, (unsigned char *)&nsigttl); hash->update(ctx, 4, (unsigned char *)&nsigttl);
p += 8; /* skip class, type, ttl */ p += 8; /* skip type, class, ttl */
GETSHORT(rdlen, p); GETSHORT(rdlen, p);
if (!CHECK_LEN(header, p, plen, rdlen)) if (!CHECK_LEN(header, p, plen, rdlen))
return STAT_BOGUS; return STAT_BOGUS;
/* Optimisation for RR types which need no cannonicalisation.
This includes DNSKEY DS NSEC and NSEC3, which are also long, so
it saves lots of calls to get_rdata, and avoids the pessimal
segmented insertion, even with a small rrbuf[].
If canonicalisation is not needed, a simple insertion into the hash works.
*/
if (*rr_desc == (u16)-1)
{
len = htons(rdlen);
hash->update(ctx, 2, (unsigned char *)&len);
hash->update(ctx, rdlen, p);
}
else
{
/* canonicalise rdata and calculate length of same, use /* canonicalise rdata and calculate length of same, use
name buffer as workspace for get_rdata. */ name buffer as workspace for get_rdata. */
state.ip = p; state.ip = p;
@@ -662,6 +677,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
if (j != 0) if (j != 0)
hash->update(ctx, j, rrbuf); hash->update(ctx, j, rrbuf);
} }
}
hash->digest(ctx, hash->digest_size, digest); hash->digest(ctx, hash->digest_size, digest);