dnsmasq: backport fixes
[librecmc/librecmc.git] / package / network / services / dnsmasq / patches / 0118-Optimise-sort_rrset-for-the-case-where-the-RR-type-n.patch
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
5  canonicalisation.
6
7 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
8 ---
9  src/dnssec.c | 69 ++++++++++++++++++++++++++++++++++++----------------
10  1 file changed, 48 insertions(+), 21 deletions(-)
11
12 --- a/src/dnssec.c
13 +++ b/src/dnssec.c
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; 
18 -                 
19 -         while (1)
20 +
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)        
26             {
27 -             int ok1, ok2;
28 +             int rdmin = rdlen1 > rdlen2 ? rdlen2 : rdlen1;
29 +             int cmp = memcmp(state1.ip, state2.ip, rdmin);
30               
31 -             ok1 = get_rdata(header, plen, &state1);
32 -             ok2 = get_rdata(header, plen, &state2);
33 -
34 -             if (!ok1 && !ok2)
35 +             if (cmp > 0 || (cmp == 0 && rdlen1 > rdmin))
36 +               {
37 +                 unsigned char *tmp = rrset[i+1];
38 +                 rrset[i+1] = rrset[i];
39 +                 rrset[i] = tmp;
40 +                 swap = 1;
41 +               }
42 +             else if (cmp == 0 && (rdlen1 == rdlen2))
43                 {
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];
47                   rrsetidx--;
48                   i--;
49 -                 break;
50                 }
51 -             else if (ok1 && (!ok2 || *state1.op > *state2.op)) 
52 -               {
53 -                 unsigned char *tmp = rrset[i+1];
54 -                 rrset[i+1] = rrset[i];
55 -                 rrset[i] = tmp;
56 -                 swap = 1;
57 -                 break;
58 -               }
59 -             else if (ok2 && (!ok1 || *state2.op > *state1.op))
60 -               break;
61 -             
62 -             /* arrive here when bytes are equal, go round the loop again
63 -                and compare the next ones. */
64             }
65 +         else
66 +           /* Comparing canonicalised RRs, byte-at-a-time. */
67 +           while (1)
68 +             {
69 +               int ok1, ok2;
70 +               
71 +               ok1 = get_rdata(header, plen, &state1);
72 +               ok2 = get_rdata(header, plen, &state2);
73 +               
74 +               if (!ok1 && !ok2)
75 +                 {
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];
79 +                   rrsetidx--;
80 +                   i--;
81 +                   break;
82 +                 }
83 +               else if (ok1 && (!ok2 || *state1.op > *state2.op)) 
84 +                 {
85 +                   unsigned char *tmp = rrset[i+1];
86 +                   rrset[i+1] = rrset[i];
87 +                   rrset[i] = tmp;
88 +                   swap = 1;
89 +                   break;
90 +                 }
91 +               else if (ok2 && (!ok1 || *state2.op > *state1.op))
92 +                 break;
93 +               
94 +               /* arrive here when bytes are equal, go round the loop again
95 +                  and compare the next ones. */
96 +             }
97         }
98      } while (swap);
99