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

Annotation of /rpms/djbdns/sme10/dnscache-cname-handling.patch

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


Revision 1.1 - (hide annotations) (download)
Thu Feb 4 12:33:24 2016 UTC (8 years, 8 months ago) by vip-ire
Branch: MAIN
CVS Tags: djbdns-1_05-10_el7_sme, djbdns-1_05-9_el7_sme, djbdns-1_05-8_el7_sme, djbdns-1_05-11_el7_sme, HEAD
sme10 branch

1 vip-ire 1.1 --- djbdns-1.05-original/query.c Sun Feb 11 21:11:45 2001
2     +++ djbdns-1.05/query.c Wed Mar 26 15:48:20 2003
3     @@ -91,6 +91,21 @@
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 @@
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 @@
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     @@ -252,7 +265,10 @@
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     @@ -261,8 +277,11 @@
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     @@ -351,7 +370,7 @@
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     @@ -471,29 +490,31 @@
86     if (rcode && (rcode != 3)) goto DIE; /* impossible; see irrelevant() */
87    
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     @@ -515,15 +536,6 @@
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     @@ -670,24 +682,36 @@
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,soattl);
189     cachegeneric(DNS_T_ANY,d,"",0,soattl);
190     @@ -700,10 +724,26 @@
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     @@ -815,6 +855,7 @@
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