aboutsummaryrefslogtreecommitdiffstats
path: root/package/network/services/dnsmasq/patches/0105-Optimse-RR-digest-calculation-in-DNSSEC.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/network/services/dnsmasq/patches/0105-Optimse-RR-digest-calculation-in-DNSSEC.patch')
-rw-r--r--package/network/services/dnsmasq/patches/0105-Optimse-RR-digest-calculation-in-DNSSEC.patch122
1 files changed, 122 insertions, 0 deletions
diff --git a/package/network/services/dnsmasq/patches/0105-Optimse-RR-digest-calculation-in-DNSSEC.patch b/package/network/services/dnsmasq/patches/0105-Optimse-RR-digest-calculation-in-DNSSEC.patch
new file mode 100644
index 0000000000..10f966237b
--- /dev/null
+++ b/package/network/services/dnsmasq/patches/0105-Optimse-RR-digest-calculation-in-DNSSEC.patch
@@ -0,0 +1,122 @@
+From 059aded0700309308dafd9720b0313ce52f6e189 Mon Sep 17 00:00:00 2001
+From: Simon Kelley <simon@thekelleys.org.uk>
+Date: Thu, 12 Nov 2020 23:09:15 +0000
+Subject: 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.
+---
+ src/dnssec.c | 82 +++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 49 insertions(+), 33 deletions(-)
+
+--- a/src/dnssec.c
++++ b/src/dnssec.c
+@@ -559,7 +559,7 @@ static int validate_rrset(time_t now, st
+ hash->update(ctx, (unsigned int)wire_len, (unsigned char*)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)
+ {
+@@ -597,50 +597,66 @@ static int validate_rrset(time_t now, st
+ hash->update(ctx, (unsigned int)wire_len, (unsigned char *)name_start);
+ hash->update(ctx, 4, p); /* class and type */
+ hash->update(ctx, 4, (unsigned char *)&nsigttl);
+-
+- p += 8; /* skip class, type, ttl */
++
++ p += 8; /* skip type, class, ttl */
+ GETSHORT(rdlen, p);
+ if (!CHECK_LEN(header, p, plen, rdlen))
+ return STAT_BOGUS;
+-
+- /* canonicalise rdata and calculate length of same, use
+- name buffer as workspace for get_rdata. */
+- state.ip = p;
+- state.op = NULL;
+- state.desc = rr_desc;
+- state.buff = name;
+- state.end = p + rdlen;
+-
+- for (j = 0; get_rdata(header, plen, &state); j++)
+- if (j < RRBUFLEN)
+- rrbuf[j] = *state.op;
+
+- len = htons((u16)j);
+- hash->update(ctx, 2, (unsigned char *)&len);
+-
+- /* If the RR is shorter than RRBUFLEN (most of them, in practice)
+- then we can just digest it now. If it exceeds RRBUFLEN we have to
+- go back to the start and do it in chunks. */
+- if (j >= RRBUFLEN)
++ /* 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
++ name buffer as workspace for get_rdata. */
+ state.ip = p;
+ state.op = NULL;
+ state.desc = rr_desc;
+-
++ state.buff = name;
++ state.end = p + rdlen;
++
+ for (j = 0; get_rdata(header, plen, &state); j++)
++ if (j < RRBUFLEN)
++ rrbuf[j] = *state.op;
++
++ len = htons((u16)j);
++ hash->update(ctx, 2, (unsigned char *)&len);
++
++ /* If the RR is shorter than RRBUFLEN (most of them, in practice)
++ then we can just digest it now. If it exceeds RRBUFLEN we have to
++ go back to the start and do it in chunks. */
++ if (j >= RRBUFLEN)
+ {
+- rrbuf[j] = *state.op;
+-
+- if (j == RRBUFLEN - 1)
+- {
+- hash->update(ctx, RRBUFLEN, rrbuf);
+- j = -1;
+- }
++ state.ip = p;
++ state.op = NULL;
++ state.desc = rr_desc;
++
++ for (j = 0; get_rdata(header, plen, &state); j++)
++ {
++ rrbuf[j] = *state.op;
++
++ if (j == RRBUFLEN - 1)
++ {
++ hash->update(ctx, RRBUFLEN, rrbuf);
++ j = -1;
++ }
++ }
+ }
++
++ if (j != 0)
++ hash->update(ctx, j, rrbuf);
+ }
+-
+- if (j != 0)
+- hash->update(ctx, j, rrbuf);
+ }
+
+ hash->digest(ctx, hash->digest_size, digest);