1 From 8ebdc364afd886461d209284ad4c946ac65e6d2b Mon Sep 17 00:00:00 2001
2 From: Simon Kelley <simon@thekelleys.org.uk>
3 Date: Fri, 22 Jan 2021 18:50:43 +0000
4 Subject: [PATCH 3/4] Optimise sort_rrset for the case where the RR type no
7 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
9 src/dnssec.c | 69 ++++++++++++++++++++++++++++++++++++----------------
10 1 file changed, 48 insertions(+), 21 deletions(-)
14 @@ -333,37 +333,64 @@ static int sort_rrset(struct dns_header
15 if (!CHECK_LEN(header, state2.ip, plen, rdlen2))
16 return rrsetidx; /* short packet */
17 state2.end = state2.ip + rdlen2;
21 + /* If the RR has no names in it then canonicalisation
22 + is the identity function and we can compare
23 + the RRs directly. If not we compare the
24 + canonicalised RRs one byte at a time. */
25 + if (*rr_desc == (u16)-1)
28 + int rdmin = rdlen1 > rdlen2 ? rdlen2 : rdlen1;
29 + int cmp = memcmp(state1.ip, state2.ip, rdmin);
31 - ok1 = get_rdata(header, plen, &state1);
32 - ok2 = get_rdata(header, plen, &state2);
35 + if (cmp > 0 || (cmp == 0 && rdlen1 > rdmin))
37 + unsigned char *tmp = rrset[i+1];
38 + rrset[i+1] = rrset[i];
42 + else if (cmp == 0 && (rdlen1 == rdlen2))
44 /* Two RRs are equal, remove one copy. RFC 4034, para 6.3 */
45 for (j = i+1; j < rrsetidx-1; j++)
46 rrset[j] = rrset[j+1];
51 - else if (ok1 && (!ok2 || *state1.op > *state2.op))
53 - unsigned char *tmp = rrset[i+1];
54 - rrset[i+1] = rrset[i];
59 - else if (ok2 && (!ok1 || *state2.op > *state1.op))
62 - /* arrive here when bytes are equal, go round the loop again
63 - and compare the next ones. */
66 + /* Comparing canonicalised RRs, byte-at-a-time. */
71 + ok1 = get_rdata(header, plen, &state1);
72 + ok2 = get_rdata(header, plen, &state2);
76 + /* Two RRs are equal, remove one copy. RFC 4034, para 6.3 */
77 + for (j = i+1; j < rrsetidx-1; j++)
78 + rrset[j] = rrset[j+1];
83 + else if (ok1 && (!ok2 || *state1.op > *state2.op))
85 + unsigned char *tmp = rrset[i+1];
86 + rrset[i+1] = rrset[i];
91 + else if (ok2 && (!ok1 || *state2.op > *state1.op))
94 + /* arrive here when bytes are equal, go round the loop again
95 + and compare the next ones. */