deda82fee0a515cb840a06231a881b3092e907a1
[openwrt/openwrt.git] / package / network / services / dnsmasq / patches / 0020-Futher-address-union-tidying.patch
1 From ab194ed7ca433e4e2e8b2ec338bfa4e6aa886a4b Mon Sep 17 00:00:00 2001
2 From: Simon Kelley <simon@thekelleys.org.uk>
3 Date: Tue, 1 Jan 2019 01:35:30 +0000
4 Subject: [PATCH 20/32] Futher address union tidying.
5
6 Pass DNSKEY and DS data into cache_insert via the address argument,
7 now these data types are included in struct all_addr.
8
9 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
10 ---
11 src/cache.c | 116 ++++++++++++++++----------------------------------
12 src/dnsmasq.h | 26 +++++------
13 src/dnssec.c | 53 +++++++++++------------
14 3 files changed, 73 insertions(+), 122 deletions(-)
15
16 --- a/src/cache.c
17 +++ b/src/cache.c
18 @@ -202,9 +202,9 @@ static void cache_hash(struct crec *crec
19 static void cache_blockdata_free(struct crec *crecp)
20 {
21 if (crecp->flags & F_DNSKEY)
22 - blockdata_free(crecp->addr.key.keydata);
23 + blockdata_free(crecp->addr.addr.addr.key.keydata);
24 else if ((crecp->flags & F_DS) && !(crecp->flags & F_NEG))
25 - blockdata_free(crecp->addr.ds.keydata);
26 + blockdata_free(crecp->addr.addr.addr.ds.keydata);
27 }
28 #endif
29
30 @@ -659,33 +659,22 @@ void cache_end_insert(void)
31 read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->ttd, sizeof(new_chain->ttd), 0);
32 read_write(daemon->pipe_to_parent, (unsigned char *)&flags, sizeof(flags), 0);
33
34 - if (flags & (F_IPV4 | F_IPV6))
35 + if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS))
36 read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr, sizeof(new_chain->addr), 0);
37 #ifdef HAVE_DNSSEC
38 - else if (flags & F_DNSKEY)
39 + if (flags & F_DNSKEY)
40 {
41 read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0);
42 - read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.key.algo, sizeof(new_chain->addr.key.algo), 0);
43 - read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.key.keytag, sizeof(new_chain->addr.key.keytag), 0);
44 - read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.key.flags, sizeof(new_chain->addr.key.flags), 0);
45 - read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.key.keylen, sizeof(new_chain->addr.key.keylen), 0);
46 - blockdata_write(new_chain->addr.key.keydata, new_chain->addr.key.keylen, daemon->pipe_to_parent);
47 + blockdata_write(new_chain->addr.addr.addr.key.keydata, new_chain->addr.addr.addr.key.keylen, daemon->pipe_to_parent);
48 }
49 else if (flags & F_DS)
50 {
51 read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0);
52 /* A negative DS entry is possible and has no data, obviously. */
53 if (!(flags & F_NEG))
54 - {
55 - read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.ds.algo, sizeof(new_chain->addr.ds.algo), 0);
56 - read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.ds.keytag, sizeof(new_chain->addr.ds.keytag), 0);
57 - read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.ds.digest, sizeof(new_chain->addr.ds.digest), 0);
58 - read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr.ds.keylen, sizeof(new_chain->addr.ds.keylen), 0);
59 - blockdata_write(new_chain->addr.ds.keydata, new_chain->addr.ds.keylen, daemon->pipe_to_parent);
60 - }
61 + blockdata_write(new_chain->addr.addr.addr.ds.keydata, new_chain->addr.addr.addr.ds.keylen, daemon->pipe_to_parent);
62 }
63 #endif
64 -
65 }
66 }
67
68 @@ -736,11 +725,30 @@ int cache_recv_insert(time_t now, int fd
69
70 ttl = difftime(ttd, now);
71
72 - if (flags & (F_IPV4 | F_IPV6))
73 + if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS))
74 {
75 + unsigned short class = C_IN;
76 +
77 if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1))
78 return 0;
79 - crecp = really_insert(daemon->namebuff, &addr, C_IN, now, ttl, flags);
80 +
81 +#ifdef HAVE_DNSSEC
82 + if (flags & F_DNSKEY)
83 + {
84 + if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) ||
85 + !(addr.addr.key.keydata = blockdata_read(fd, addr.addr.key.keylen)))
86 + return 0;
87 + }
88 + else if (flags & F_DS)
89 + {
90 + if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) ||
91 + (flags & F_NEG) ||
92 + !(addr.addr.key.keydata = blockdata_read(fd, addr.addr.key.keylen)))
93 + return 0;
94 + }
95 +#endif
96 +
97 + crecp = really_insert(daemon->namebuff, &addr, class, now, ttl, flags);
98 }
99 else if (flags & F_CNAME)
100 {
101 @@ -764,58 +772,6 @@ int cache_recv_insert(time_t now, int fd
102 }
103 }
104 }
105 -#ifdef HAVE_DNSSEC
106 - else if (flags & (F_DNSKEY | F_DS))
107 - {
108 - unsigned short class, keylen, keyflags, keytag;
109 - unsigned char algo, digest;
110 - struct blockdata *keydata;
111 -
112 - if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1))
113 - return 0;
114 -
115 - crecp = really_insert(daemon->namebuff, NULL, class, now, ttl, flags);
116 -
117 - if (flags & F_DNSKEY)
118 - {
119 - if (!read_write(fd, (unsigned char *)&algo, sizeof(algo), 1) ||
120 - !read_write(fd, (unsigned char *)&keytag, sizeof(keytag), 1) ||
121 - !read_write(fd, (unsigned char *)&keyflags, sizeof(keyflags), 1) ||
122 - !read_write(fd, (unsigned char *)&keylen, sizeof(keylen), 1) ||
123 - !(keydata = blockdata_read(fd, keylen)))
124 - return 0;
125 - }
126 - else if (!(flags & F_NEG))
127 - {
128 - if (!read_write(fd, (unsigned char *)&algo, sizeof(algo), 1) ||
129 - !read_write(fd, (unsigned char *)&keytag, sizeof(keytag), 1) ||
130 - !read_write(fd, (unsigned char *)&digest, sizeof(digest), 1) ||
131 - !read_write(fd, (unsigned char *)&keylen, sizeof(keylen), 1) ||
132 - !(keydata = blockdata_read(fd, keylen)))
133 - return 0;
134 - }
135 -
136 - if (crecp)
137 - {
138 - if (flags & F_DNSKEY)
139 - {
140 - crecp->addr.key.algo = algo;
141 - crecp->addr.key.keytag = keytag;
142 - crecp->addr.key.flags = flags;
143 - crecp->addr.key.keylen = keylen;
144 - crecp->addr.key.keydata = keydata;
145 - }
146 - else if (!(flags & F_NEG))
147 - {
148 - crecp->addr.ds.algo = algo;
149 - crecp->addr.ds.keytag = keytag;
150 - crecp->addr.ds.digest = digest;
151 - crecp->addr.ds.keylen = keylen;
152 - crecp->addr.ds.keydata = keydata;
153 - }
154 - }
155 - }
156 -#endif
157 }
158 }
159
160 @@ -1290,15 +1246,15 @@ void cache_reload(void)
161 #ifdef HAVE_DNSSEC
162 for (ds = daemon->ds; ds; ds = ds->next)
163 if ((cache = whine_malloc(SIZEOF_POINTER_CREC)) &&
164 - (cache->addr.ds.keydata = blockdata_alloc(ds->digest, ds->digestlen)))
165 + (cache->addr.addr.addr.ds.keydata = blockdata_alloc(ds->digest, ds->digestlen)))
166 {
167 cache->flags = F_FORWARD | F_IMMORTAL | F_DS | F_CONFIG | F_NAMEP;
168 cache->ttd = daemon->local_ttl;
169 cache->name.namep = ds->name;
170 - cache->addr.ds.keylen = ds->digestlen;
171 - cache->addr.ds.algo = ds->algo;
172 - cache->addr.ds.keytag = ds->keytag;
173 - cache->addr.ds.digest = ds->digest_type;
174 + cache->addr.addr.addr.ds.keylen = ds->digestlen;
175 + cache->addr.addr.addr.ds.algo = ds->algo;
176 + cache->addr.addr.addr.ds.keytag = ds->keytag;
177 + cache->addr.addr.addr.ds.digest = ds->digest_type;
178 cache->uid = ds->class;
179 cache_hash(cache);
180 make_non_terminals(cache);
181 @@ -1775,12 +1731,12 @@ void dump_cache(time_t now)
182 else if (cache->flags & F_DS)
183 {
184 if (!(cache->flags & F_NEG))
185 - sprintf(a, "%5u %3u %3u", cache->addr.ds.keytag,
186 - cache->addr.ds.algo, cache->addr.ds.digest);
187 + sprintf(a, "%5u %3u %3u", cache->addr.addr.addr.ds.keytag,
188 + cache->addr.addr.addr.ds.algo, cache->addr.addr.addr.ds.digest);
189 }
190 else if (cache->flags & F_DNSKEY)
191 - sprintf(a, "%5u %3u %3u", cache->addr.key.keytag,
192 - cache->addr.key.algo, cache->addr.key.flags);
193 + sprintf(a, "%5u %3u %3u", cache->addr.addr.addr.key.keytag,
194 + cache->addr.addr.addr.key.algo, cache->addr.addr.addr.key.flags);
195 #endif
196 else if (!(cache->flags & F_NEG) || !(cache->flags & F_FORWARD))
197 {
198 --- a/src/dnsmasq.h
199 +++ b/src/dnsmasq.h
200 @@ -277,14 +277,21 @@ struct all_addr {
201 union {
202 struct in_addr addr4;
203 struct in6_addr addr6;
204 + struct {
205 + struct blockdata *keydata;
206 + unsigned short keylen, flags, keytag;
207 + unsigned char algo;
208 + } key;
209 + struct {
210 + struct blockdata *keydata;
211 + unsigned short keylen, keytag;
212 + unsigned char algo;
213 + unsigned char digest;
214 + } ds;
215 /* for log_query */
216 struct {
217 unsigned short keytag, algo, digest, rcode;
218 } log;
219 - /* for cache_insert of DNSKEY, DS */
220 - struct {
221 - unsigned short class, type;
222 - } dnssec;
223 } addr;
224 };
225
226 @@ -414,17 +421,6 @@ struct crec {
227 } target;
228 unsigned int uid; /* 0 if union is interface-name */
229 } cname;
230 - struct {
231 - struct blockdata *keydata;
232 - unsigned short keylen, flags, keytag;
233 - unsigned char algo;
234 - } key;
235 - struct {
236 - struct blockdata *keydata;
237 - unsigned short keylen, keytag;
238 - unsigned char algo;
239 - unsigned char digest;
240 - } ds;
241 } addr;
242 time_t ttd; /* time to die */
243 /* used as class if DNSKEY/DS, index to source for F_HOSTS */
244 --- a/src/dnssec.c
245 +++ b/src/dnssec.c
246 @@ -628,10 +628,10 @@ static int validate_rrset(time_t now, st
247 {
248 /* iterate through all possible keys 4035 5.3.1 */
249 for (; crecp; crecp = cache_find_by_name(crecp, keyname, now, F_DNSKEY))
250 - if (crecp->addr.key.algo == algo &&
251 - crecp->addr.key.keytag == key_tag &&
252 + if (crecp->addr.addr.addr.key.algo == algo &&
253 + crecp->addr.addr.addr.key.keytag == key_tag &&
254 crecp->uid == (unsigned int)class &&
255 - verify(crecp->addr.key.keydata, crecp->addr.key.keylen, sig, sig_len, digest, hash->digest_size, algo))
256 + verify(crecp->addr.addr.addr.key.keydata, crecp->addr.addr.addr.key.keylen, sig, sig_len, digest, hash->digest_size, algo))
257 return (labels < name_labels) ? STAT_SECURE_WILDCARD : STAT_SECURE;
258 }
259 }
260 @@ -728,10 +728,10 @@ int dnssec_validate_by_ds(time_t now, st
261 const struct nettle_hash *hash;
262 int sigcnt, rrcnt;
263
264 - if (recp1->addr.ds.algo == algo &&
265 - recp1->addr.ds.keytag == keytag &&
266 + if (recp1->addr.addr.addr.ds.algo == algo &&
267 + recp1->addr.addr.addr.ds.keytag == keytag &&
268 recp1->uid == (unsigned int)class &&
269 - (hash = hash_find(ds_digest_name(recp1->addr.ds.digest))) &&
270 + (hash = hash_find(ds_digest_name(recp1->addr.addr.addr.ds.digest))) &&
271 hash_init(hash, &ctx, &digest))
272
273 {
274 @@ -746,9 +746,9 @@ int dnssec_validate_by_ds(time_t now, st
275 from_wire(name);
276
277 if (!(recp1->flags & F_NEG) &&
278 - recp1->addr.ds.keylen == (int)hash->digest_size &&
279 - (ds_digest = blockdata_retrieve(recp1->addr.key.keydata, recp1->addr.ds.keylen, NULL)) &&
280 - memcmp(ds_digest, digest, recp1->addr.ds.keylen) == 0 &&
281 + recp1->addr.addr.addr.ds.keylen == (int)hash->digest_size &&
282 + (ds_digest = blockdata_retrieve(recp1->addr.addr.addr.ds.keydata, recp1->addr.addr.addr.ds.keylen, NULL)) &&
283 + memcmp(ds_digest, digest, recp1->addr.addr.addr.ds.keylen) == 0 &&
284 explore_rrset(header, plen, class, T_DNSKEY, name, keyname, &sigcnt, &rrcnt) &&
285 sigcnt != 0 && rrcnt != 0 &&
286 validate_rrset(now, header, plen, class, T_DNSKEY, sigcnt, rrcnt, name, keyname,
287 @@ -800,7 +800,13 @@ int dnssec_validate_by_ds(time_t now, st
288
289 if ((key = blockdata_alloc((char*)p, rdlen - 4)))
290 {
291 - if (!(recp1 = cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK)))
292 + a.addr.key.keylen = rdlen - 4;
293 + a.addr.key.keydata = key;
294 + a.addr.key.algo = algo;
295 + a.addr.key.keytag = keytag;
296 + a.addr.key.flags = flags;
297 +
298 + if (!cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK))
299 {
300 blockdata_free(key);
301 return STAT_BOGUS;
302 @@ -813,12 +819,6 @@ int dnssec_validate_by_ds(time_t now, st
303 log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu");
304 else
305 log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu (not supported)");
306 -
307 - recp1->addr.key.keylen = rdlen - 4;
308 - recp1->addr.key.keydata = key;
309 - recp1->addr.key.algo = algo;
310 - recp1->addr.key.keytag = keytag;
311 - recp1->addr.key.flags = flags;
312 }
313 }
314 }
315 @@ -915,8 +915,7 @@ int dnssec_validate_ds(time_t now, struc
316 int algo, digest, keytag;
317 unsigned char *psave = p;
318 struct blockdata *key;
319 - struct crec *crecp;
320 -
321 +
322 if (rdlen < 4)
323 return STAT_BOGUS; /* bad packet */
324
325 @@ -926,7 +925,13 @@ int dnssec_validate_ds(time_t now, struc
326
327 if ((key = blockdata_alloc((char*)p, rdlen - 4)))
328 {
329 - if (!(crecp = cache_insert(name, NULL, class, now, ttl, F_FORWARD | F_DS | F_DNSSECOK)))
330 + a.addr.ds.digest = digest;
331 + a.addr.ds.keydata = key;
332 + a.addr.ds.algo = algo;
333 + a.addr.ds.keytag = keytag;
334 + a.addr.ds.keylen = rdlen - 4;
335 +
336 + if (!cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DS | F_DNSSECOK))
337 {
338 blockdata_free(key);
339 return STAT_BOGUS;
340 @@ -940,12 +945,6 @@ int dnssec_validate_ds(time_t now, struc
341 log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu");
342 else
343 log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu (not supported)");
344 -
345 - crecp->addr.ds.digest = digest;
346 - crecp->addr.ds.keydata = key;
347 - crecp->addr.ds.algo = algo;
348 - crecp->addr.ds.keytag = keytag;
349 - crecp->addr.ds.keylen = rdlen - 4;
350 }
351 }
352
353 @@ -1711,8 +1710,8 @@ static int zone_status(char *name, int c
354 do
355 {
356 if (crecp->uid == (unsigned int)class &&
357 - ds_digest_name(crecp->addr.ds.digest) &&
358 - algo_digest_name(crecp->addr.ds.algo))
359 + ds_digest_name(crecp->addr.addr.addr.ds.digest) &&
360 + algo_digest_name(crecp->addr.addr.addr.ds.algo))
361 break;
362 }
363 while ((crecp = cache_find_by_name(crecp, keyname, now, F_DS)));