/[smeserver]/rpms/djbdns/sme9/200-dnscache-cname-handling.patch
ViewVC logotype

Contents of /rpms/djbdns/sme9/200-dnscache-cname-handling.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download)
Wed Jul 12 04:56:18 2017 UTC (7 years, 4 months ago) by unnilennium
Branch: MAIN
CVS Tags: djbdns-1_05-11_el6_sme, djbdns-1_05-9_el6_sme, djbdns-1_05-10_el6_sme, HEAD
* Tue Jul 11 2017 Jean-Philipe Pialasse <tests@pialasse.com> 1.05-9.sme
-- backport SME10 fixes [SME: 10381]
--import patches from openwrt and rename already applied patches
--fix security issues [SME: 10374]
- 020-dnsroots-update.patch: update list of root DNS servers
- 070-dnscache-dpos-tcp-servfail.patch: SERVFAIL rename previous patch dns_transmit-bug.patch
- 210-dnscache-strict-forwardonly.patch: rename previous patch dnscache-strict-forwardonly.patch
- 270-dnscache-sigpipe-fix.patch: SIGPIPE
- 300-bugfix-dnscache-dempsky-poison.patch: CVE-2009-0858
- 310-bugfix-dnscache-merge-outgoing-requests.patch: CVE-2008-4392
- 320-bugfix-dnscache-cache-soa-records.patch: CVE-2008-4392
- 450-dnscache-ghost-domain-CVE-2012-1191.patch: CVE-2012-1191 http://marc.info/?l=djbdns&m=134190748729079&w=2
--bug fixes [SME: 10374]
- 060-dnscache-big-udp-packets.patch: accept and handle longer than 512 bytes UDP packets
- 230-tinydns-data-semantic-error.patch: handle semantic error to avoid publishing false dns records
- 240-tinydns-alias-chain-truncation.patch: rename previous patch tinydns-alias-chain-truncation.patch
--fix issue with short ttl cname like akamaid [SME: 8362]
- 200-dnscache-cname-handling.patch: rename previous patch dnscache-cname-handling.patch
- 330-fix-dnscache-cname-handling.patch: fix dnscache cname for short ttl
- 500-cutom-dnscache-maxloop.patch: set max loop to 200
--needed for previous patches to apply cleanly
- 030-srv-records-and-axfrget.patch: add SRV record type and axfr-get decompose SRC and PTR records (for 230-*.patch)
- 080-dnscache-cache-negatives.patch: rfc2308 ? (for 200-*.patch)
- 090-tinydns-one-second.patch: improve tinydns with 8 or more  concurent connections (for 240-*.patch)
- 120-compiler-temporary-filename.patch: change tmp filename to avoid conflicts (for 230-*.patch)
--not backported from SME10 branch
- 050-tinydns-mmap-leak.patch: report cdb leak

1 --- a/query.c
2 +++ b/query.c
3 @@ -91,6 +91,21 @@ static void cleanup(struct query *z)
4 }
5 }
6
7 +static int move_name_to_alias(struct query *z,uint32 ttl)
8 +{
9 + int j ;
10 +
11 + if (z->alias[QUERY_MAXALIAS - 1]) return 0 ;
12 + for (j = QUERY_MAXALIAS - 1;j > 0;--j)
13 + z->alias[j] = z->alias[j - 1];
14 + for (j = QUERY_MAXALIAS - 1;j > 0;--j)
15 + z->aliasttl[j] = z->aliasttl[j - 1];
16 + z->alias[0] = z->name[0];
17 + z->aliasttl[0] = ttl;
18 + z->name[0] = 0;
19 + return 1 ;
20 +}
21 +
22 static int rqa(struct query *z)
23 {
24 int i;
25 @@ -123,7 +138,6 @@ static int globalip(char *d,char ip[4])
26 static char *t1 = 0;
27 static char *t2 = 0;
28 static char *t3 = 0;
29 -static char *cname = 0;
30 static char *referral = 0;
31 static unsigned int *records = 0;
32
33 @@ -179,15 +193,14 @@ static int doit(struct query *z,int stat
34 uint16 datalen;
35 char *control;
36 char *d;
37 + char *owner_name = 0 ;
38 const char *dtype;
39 unsigned int dlen;
40 int flagout;
41 - int flagcname;
42 int flagreferral;
43 int flagsoa;
44 uint32 ttl;
45 uint32 soattl;
46 - uint32 cnamettl;
47 int i;
48 int j;
49 int k;
50 @@ -253,7 +266,10 @@ static int doit(struct query *z,int stat
51
52 byte_copy(key,2,DNS_T_CNAME);
53 cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
54 - if (cached) {
55 + /* A previous explicit query might have caused an empty RRSet to have been
56 + ** cached. Take care to ignore such a thing.
57 + */
58 + if (cached && cachedlen) {
59 if (typematch(DNS_T_CNAME,dtype)) {
60 log_cachedanswer(d,DNS_T_CNAME);
61 if (!rqa(z)) goto DIE;
62 @@ -262,8 +278,11 @@ static int doit(struct query *z,int stat
63 return 1;
64 }
65 log_cachedcname(d,cached);
66 - if (!dns_domain_copy(&cname,cached)) goto DIE;
67 - goto CNAME;
68 + if (!z->level) {
69 + if (!move_name_to_alias(z,ttl)) goto DIE ;
70 + }
71 + if (!dns_domain_copy(&z->name[z->level],cached)) goto DIE;
72 + goto NEWNAME;
73 }
74
75 if (typematch(DNS_T_NS,dtype)) {
76 @@ -352,7 +371,7 @@ static int doit(struct query *z,int stat
77 }
78 }
79
80 - if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) && !typematch(DNS_T_CNAME,dtype) && !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) && !typematch(DNS_T_A,dtype) && !typematch(DNS_T_MX,dtype)) {
81 + if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) && !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) && !typematch(DNS_T_A,dtype) && !typematch(DNS_T_MX,dtype)) {
82 byte_copy(key,2,dtype);
83 cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
84 if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
85 @@ -473,29 +492,31 @@ static int doit(struct query *z,int stat
86
87 cachettl = 0;
88 flagout = 0;
89 - flagcname = 0;
90 flagreferral = 0;
91 flagsoa = 0;
92 soattl = 0;
93 - cnamettl = 0;
94 + if (!dns_domain_copy(&owner_name,d)) goto DIE;
95 + /* This code assumes that the CNAME chain is presented in the correct
96 + ** order. The example algorithm in RFC 1034 will actually result in this
97 + ** being the case, but the words do not require it to be so.
98 + */
99 for (j = 0;j < numanswers;++j) {
100 pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
101 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
102
103 - if (dns_domain_equal(t1,d))
104 + if (dns_domain_equal(t1,owner_name))
105 if (byte_equal(header + 2,2,DNS_C_IN)) { /* should always be true */
106 if (typematch(header,dtype))
107 flagout = 1;
108 else if (typematch(header,DNS_T_CNAME)) {
109 - if (!dns_packet_getname(buf,len,pos,&cname)) goto DIE;
110 - flagcname = 1;
111 - cnamettl = ttlget(header + 4);
112 + if (!dns_packet_getname(buf,len,pos,&owner_name)) goto DIE;
113 }
114 }
115
116 uint16_unpack_big(header + 8,&datalen);
117 pos += datalen;
118 }
119 + dns_domain_free(&owner_name) ;
120 posauthority = pos;
121
122 for (j = 0;j < numauthority;++j) {
123 @@ -522,15 +543,6 @@ static int doit(struct query *z,int stat
124 }
125 posglue = pos;
126
127 -
128 - if (!flagcname && !rcode && !flagout && flagreferral && !flagsoa)
129 - if (dns_domain_equal(referral,control) || !dns_domain_suffix(referral,control)) {
130 - log_lame(whichserver,control,referral);
131 - byte_zero(whichserver,4);
132 - goto HAVENS;
133 - }
134 -
135 -
136 if (records) { alloc_free(records); records = 0; }
137
138 k = numanswers + numauthority + numglue;
139 @@ -677,24 +689,36 @@ static int doit(struct query *z,int stat
140
141 alloc_free(records); records = 0;
142
143 + if (byte_diff(DNS_T_CNAME,2,dtype)) {
144 + /* This code assumes that the CNAME chain is presented in the correct
145 + ** order. The example algorithm in RFC 1034 will actually result in this
146 + ** being the case, but the words do not require it to be so.
147 + */
148 + pos = posanswers;
149 + for (j = 0;j < numanswers;++j) {
150 + pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
151 + pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
152 +
153 + if (dns_domain_equal(t1,d))
154 + if (byte_equal(header + 2,2,DNS_C_IN)) { /* should always be true */
155 + if (typematch(header,DNS_T_CNAME)) {
156 + ttl = ttlget(header + 4);
157 + if (z->level == 0) {
158 + if (!move_name_to_alias(z,ttl)) goto DIE ;
159 + }
160 + if (!dns_packet_getname(buf,len,pos,&z->name[z->level])) goto DIE;
161 + d = z->name[z->level];
162 + if (!dns_domain_suffix(d,control) || !roots_same(d,control))
163 + goto NEWNAME ; /* Cannot trust the chain further - restart using current name */
164 + }
165 + }
166
167 - if (flagcname) {
168 - ttl = cnamettl;
169 - CNAME:
170 - if (!z->level) {
171 - if (z->alias[QUERY_MAXALIAS - 1]) goto DIE;
172 - for (j = QUERY_MAXALIAS - 1;j > 0;--j)
173 - z->alias[j] = z->alias[j - 1];
174 - for (j = QUERY_MAXALIAS - 1;j > 0;--j)
175 - z->aliasttl[j] = z->aliasttl[j - 1];
176 - z->alias[0] = z->name[0];
177 - z->aliasttl[0] = ttl;
178 - z->name[0] = 0;
179 + uint16_unpack_big(header + 8,&datalen);
180 + pos += datalen;
181 }
182 - if (!dns_domain_copy(&z->name[z->level],cname)) goto DIE;
183 - goto NEWNAME;
184 }
185
186 + /* A "no such name" error applies to the end of any CNAME chain, not to the start. */
187 if (rcode == 3) {
188 log_nxdomain(whichserver,d,cachettl);
189 cachegeneric(DNS_T_ANY,d,"",0,cachettl);
190 @@ -707,10 +731,26 @@ static int doit(struct query *z,int stat
191 return 1;
192 }
193
194 + /* We check for a lame server _after_ we have cached any records that it
195 + ** might have returned to us. This copes better with the incorrect
196 + ** behaviour of one content DNS server software that doesn't return
197 + ** complete CNAME chains but instead returns only the first link in a
198 + ** chain followed by a lame delegation to the same server.
199 + ** Also: We check for a lame server _after_ following the CNAME chain. The
200 + ** delegation in a referral answer applies to the _end_ of the chain, not
201 + ** to the beginning.
202 + */
203 + if (!rcode && !flagout && flagreferral && !flagsoa)
204 + if (dns_domain_equal(referral,control) || !dns_domain_suffix(referral,control)) {
205 + log_lame(whichserver,control,referral);
206 + byte_zero(whichserver,4);
207 + goto HAVENS;
208 + }
209 +
210 if (!flagout && flagsoa)
211 + /* Don't save empty RRSets for those types that we use as special markers. */
212 if (byte_diff(DNS_T_ANY,2,dtype))
213 - if (byte_diff(DNS_T_AXFR,2,dtype))
214 - if (byte_diff(DNS_T_CNAME,2,dtype)) {
215 + if (byte_diff(DNS_T_AXFR,2,dtype)) {
216 save_start();
217 save_finish(dtype,d,soattl);
218 log_nodata(whichserver,d,dtype,soattl);
219 @@ -822,6 +862,7 @@ static int doit(struct query *z,int stat
220 DIE:
221 cleanup(z);
222 if (records) { alloc_free(records); records = 0; }
223 + dns_domain_free(&owner_name) ;
224 return -1;
225 }
226

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed