OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From 5b99eae59d59a8e34a7e512059b98bbd803312f2 Mon Sep 17 00:00:00 2001 |
2 | From: Simon Kelley <simon@thekelleys.org.uk> |
||
3 | Date: Sun, 6 Jan 2019 23:09:50 +0000 |
||
4 | Subject: [PATCH 24/32] Cache SRV records. |
||
5 | |||
6 | Inpsired by a patch from Jeremy Allison, but completely re-rolled |
||
7 | by srk. All bugs are mine. |
||
8 | |||
9 | Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> |
||
10 | --- |
||
11 | src/auth.c | 2 +- |
||
12 | src/blockdata.c | 12 ++--- |
||
13 | src/cache.c | 64 ++++++++++++++-------- |
||
14 | src/dnsmasq.c | 2 - |
||
15 | src/dnsmasq.h | 11 ++-- |
||
16 | src/rfc1035.c | 141 ++++++++++++++++++++++++++++++++++++++---------- |
||
17 | 6 files changed, 166 insertions(+), 66 deletions(-) |
||
18 | |||
19 | --- a/src/auth.c |
||
20 | +++ b/src/auth.c |
||
21 | @@ -129,7 +129,7 @@ size_t answer_auth(struct dns_header *he |
||
22 | |||
23 | for (q = ntohs(header->qdcount); q != 0; q--) |
||
24 | { |
||
25 | - unsigned short flag = 0; |
||
26 | + unsigned int flag = 0; |
||
27 | int found = 0; |
||
28 | int cname_wildcard = 0; |
||
29 | |||
30 | --- a/src/blockdata.c |
||
31 | +++ b/src/blockdata.c |
||
32 | @@ -16,8 +16,6 @@ |
||
33 | |||
34 | #include "dnsmasq.h" |
||
35 | |||
36 | -#ifdef HAVE_DNSSEC |
||
37 | - |
||
38 | static struct blockdata *keyblock_free; |
||
39 | static unsigned int blockdata_count, blockdata_hwm, blockdata_alloced; |
||
40 | |||
41 | @@ -54,11 +52,10 @@ void blockdata_init(void) |
||
42 | |||
43 | void blockdata_report(void) |
||
44 | { |
||
45 | - if (option_bool(OPT_DNSSEC_VALID)) |
||
46 | - my_syslog(LOG_INFO, _("DNSSEC memory in use %u, max %u, allocated %u"), |
||
47 | - blockdata_count * sizeof(struct blockdata), |
||
48 | - blockdata_hwm * sizeof(struct blockdata), |
||
49 | - blockdata_alloced * sizeof(struct blockdata)); |
||
50 | + my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"), |
||
51 | + blockdata_count * sizeof(struct blockdata), |
||
52 | + blockdata_hwm * sizeof(struct blockdata), |
||
53 | + blockdata_alloced * sizeof(struct blockdata)); |
||
54 | } |
||
55 | |||
56 | static struct blockdata *blockdata_alloc_real(int fd, char *data, size_t len) |
||
57 | @@ -178,4 +175,3 @@ struct blockdata *blockdata_read(int fd, |
||
58 | return blockdata_alloc_real(fd, NULL, len); |
||
59 | } |
||
60 | |||
61 | -#endif |
||
62 | --- a/src/cache.c |
||
63 | +++ b/src/cache.c |
||
64 | @@ -27,7 +27,7 @@ static int bignames_left, hash_size; |
||
65 | |||
66 | static void make_non_terminals(struct crec *source); |
||
67 | static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class, |
||
68 | - time_t now, unsigned long ttl, unsigned short flags); |
||
69 | + time_t now, unsigned long ttl, unsigned int flags); |
||
70 | |||
71 | /* type->string mapping: this is also used by the name-hash function as a mixing table. */ |
||
72 | static const struct { |
||
73 | @@ -198,15 +198,17 @@ static void cache_hash(struct crec *crec |
||
74 | *up = crecp; |
||
75 | } |
||
76 | |||
77 | -#ifdef HAVE_DNSSEC |
||
78 | static void cache_blockdata_free(struct crec *crecp) |
||
79 | { |
||
80 | - if (crecp->flags & F_DNSKEY) |
||
81 | + if (crecp->flags & F_SRV) |
||
82 | + blockdata_free(crecp->addr.srv.target); |
||
83 | +#ifdef HAVE_DNSSEC |
||
84 | + else if (crecp->flags & F_DNSKEY) |
||
85 | blockdata_free(crecp->addr.key.keydata); |
||
86 | else if ((crecp->flags & F_DS) && !(crecp->flags & F_NEG)) |
||
87 | blockdata_free(crecp->addr.ds.keydata); |
||
88 | -} |
||
89 | #endif |
||
90 | +} |
||
91 | |||
92 | static void cache_free(struct crec *crecp) |
||
93 | { |
||
94 | @@ -230,9 +232,7 @@ static void cache_free(struct crec *crec |
||
95 | crecp->flags &= ~F_BIGNAME; |
||
96 | } |
||
97 | |||
98 | -#ifdef HAVE_DNSSEC |
||
99 | cache_blockdata_free(crecp); |
||
100 | -#endif |
||
101 | } |
||
102 | |||
103 | /* insert a new cache entry at the head of the list (youngest entry) */ |
||
104 | @@ -331,7 +331,7 @@ static int is_expired(time_t now, struct |
||
105 | } |
||
106 | |||
107 | static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned short class, time_t now, |
||
108 | - unsigned short flags, struct crec **target_crec, unsigned int *target_uid) |
||
109 | + unsigned int flags, struct crec **target_crec, unsigned int *target_uid) |
||
110 | { |
||
111 | /* Scan and remove old entries. |
||
112 | If (flags & F_FORWARD) then remove any forward entries for name and any expired |
||
113 | @@ -360,7 +360,7 @@ static struct crec *cache_scan_free(char |
||
114 | if ((crecp->flags & F_FORWARD) && hostname_isequal(cache_get_name(crecp), name)) |
||
115 | { |
||
116 | /* Don't delete DNSSEC in favour of a CNAME, they can co-exist */ |
||
117 | - if ((flags & crecp->flags & (F_IPV4 | F_IPV6)) || |
||
118 | + if ((flags & crecp->flags & (F_IPV4 | F_IPV6 | F_SRV)) || |
||
119 | (((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS)))) |
||
120 | { |
||
121 | if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) |
||
122 | @@ -467,10 +467,10 @@ void cache_start_insert(void) |
||
123 | } |
||
124 | |||
125 | struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class, |
||
126 | - time_t now, unsigned long ttl, unsigned short flags) |
||
127 | + time_t now, unsigned long ttl, unsigned int flags) |
||
128 | { |
||
129 | /* Don't log DNSSEC records here, done elsewhere */ |
||
130 | - if (flags & (F_IPV4 | F_IPV6 | F_CNAME)) |
||
131 | + if (flags & (F_IPV4 | F_IPV6 | F_CNAME | F_SRV)) |
||
132 | { |
||
133 | log_query(flags | F_UPSTREAM, name, addr, NULL); |
||
134 | /* Don't mess with TTL for DNSSEC records. */ |
||
135 | @@ -485,7 +485,7 @@ struct crec *cache_insert(char *name, un |
||
136 | |||
137 | |||
138 | static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class, |
||
139 | - time_t now, unsigned long ttl, unsigned short flags) |
||
140 | + time_t now, unsigned long ttl, unsigned int flags) |
||
141 | { |
||
142 | struct crec *new, *target_crec = NULL; |
||
143 | union bigname *big_name = NULL; |
||
144 | @@ -649,7 +649,7 @@ void cache_end_insert(void) |
||
145 | { |
||
146 | char *name = cache_get_name(new_chain); |
||
147 | ssize_t m = strlen(name); |
||
148 | - unsigned short flags = new_chain->flags; |
||
149 | + unsigned int flags = new_chain->flags; |
||
150 | #ifdef HAVE_DNSSEC |
||
151 | u16 class = new_chain->uid; |
||
152 | #endif |
||
153 | @@ -659,8 +659,10 @@ void cache_end_insert(void) |
||
154 | read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->ttd, sizeof(new_chain->ttd), 0); |
||
155 | read_write(daemon->pipe_to_parent, (unsigned char *)&flags, sizeof(flags), 0); |
||
156 | |||
157 | - if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS)) |
||
158 | + if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_SRV)) |
||
159 | read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr, sizeof(new_chain->addr), 0); |
||
160 | + if (flags & F_SRV) |
||
161 | + blockdata_write(new_chain->addr.srv.target, new_chain->addr.srv.targetlen, daemon->pipe_to_parent); |
||
162 | #ifdef HAVE_DNSSEC |
||
163 | if (flags & F_DNSKEY) |
||
164 | { |
||
165 | @@ -699,7 +701,7 @@ int cache_recv_insert(time_t now, int fd |
||
166 | union all_addr addr; |
||
167 | unsigned long ttl; |
||
168 | time_t ttd; |
||
169 | - unsigned short flags; |
||
170 | + unsigned int flags; |
||
171 | struct crec *crecp = NULL; |
||
172 | |||
173 | cache_start_insert(); |
||
174 | @@ -725,13 +727,16 @@ int cache_recv_insert(time_t now, int fd |
||
175 | |||
176 | ttl = difftime(ttd, now); |
||
177 | |||
178 | - if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS)) |
||
179 | + if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_SRV)) |
||
180 | { |
||
181 | unsigned short class = C_IN; |
||
182 | |||
183 | if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1)) |
||
184 | return 0; |
||
185 | - |
||
186 | + |
||
187 | + if (flags & F_SRV && !(addr.srv.target = blockdata_read(fd, addr.srv.targetlen))) |
||
188 | + return 0; |
||
189 | + |
||
190 | #ifdef HAVE_DNSSEC |
||
191 | if (flags & F_DNSKEY) |
||
192 | { |
||
193 | @@ -802,7 +807,7 @@ struct crec *cache_find_by_name(struct c |
||
194 | /* first search, look for relevant entries and push to top of list |
||
195 | also free anything which has expired */ |
||
196 | struct crec *next, **up, **insert = NULL, **chainp = &ans; |
||
197 | - unsigned short ins_flags = 0; |
||
198 | + unsigned int ins_flags = 0; |
||
199 | |||
200 | for (up = hash_bucket(name), crecp = *up; crecp; crecp = next) |
||
201 | { |
||
202 | @@ -1086,7 +1091,7 @@ int read_hostsfile(char *filename, unsig |
||
203 | FILE *f = fopen(filename, "r"); |
||
204 | char *token = daemon->namebuff, *domain_suffix = NULL; |
||
205 | int addr_count = 0, name_count = cache_size, lineno = 0; |
||
206 | - unsigned short flags = 0; |
||
207 | + unsigned int flags = 0; |
||
208 | union all_addr addr; |
||
209 | int atnl, addrlen = 0; |
||
210 | |||
211 | @@ -1201,9 +1206,8 @@ void cache_reload(void) |
||
212 | for (i=0; i<hash_size; i++) |
||
213 | for (cache = hash_table[i], up = &hash_table[i]; cache; cache = tmp) |
||
214 | { |
||
215 | -#ifdef HAVE_DNSSEC |
||
216 | cache_blockdata_free(cache); |
||
217 | -#endif |
||
218 | + |
||
219 | tmp = cache->hash_next; |
||
220 | if (cache->flags & (F_HOSTS | F_CONFIG)) |
||
221 | { |
||
222 | @@ -1381,7 +1385,7 @@ void cache_add_dhcp_entry(char *host_nam |
||
223 | union all_addr *host_address, time_t ttd) |
||
224 | { |
||
225 | struct crec *crec = NULL, *fail_crec = NULL; |
||
226 | - unsigned short flags = F_IPV4; |
||
227 | + unsigned int flags = F_IPV4; |
||
228 | int in_hosts = 0; |
||
229 | size_t addrlen = sizeof(struct in_addr); |
||
230 | |||
231 | @@ -1682,9 +1686,8 @@ void dump_cache(time_t now) |
||
232 | #ifdef HAVE_AUTH |
||
233 | my_syslog(LOG_INFO, _("queries for authoritative zones %u"), daemon->metrics[METRIC_DNS_AUTH_ANSWERED]); |
||
234 | #endif |
||
235 | -#ifdef HAVE_DNSSEC |
||
236 | + |
||
237 | blockdata_report(); |
||
238 | -#endif |
||
239 | |||
240 | /* sum counts from different records for same server */ |
||
241 | for (serv = daemon->servers; serv; serv = serv->next) |
||
242 | @@ -1726,6 +1729,17 @@ void dump_cache(time_t now) |
||
243 | p += sprintf(p, "%-30.30s ", sanitise(n)); |
||
244 | if ((cache->flags & F_CNAME) && !is_outdated_cname_pointer(cache)) |
||
245 | a = sanitise(cache_get_cname_target(cache)); |
||
246 | + else if ((cache->flags & F_SRV) && !(cache->flags & F_NEG)) |
||
247 | + { |
||
248 | + int targetlen = cache->addr.srv.targetlen; |
||
249 | + ssize_t len = sprintf(a, "%u %u %u ", cache->addr.srv.priority, |
||
250 | + cache->addr.srv.weight, cache->addr.srv.srvport); |
||
251 | + |
||
252 | + if (targetlen > (40 - len)) |
||
253 | + targetlen = 40 - len; |
||
254 | + blockdata_retrieve(cache->addr.srv.target, targetlen, a + len); |
||
255 | + a[len + targetlen] = 0; |
||
256 | + } |
||
257 | #ifdef HAVE_DNSSEC |
||
258 | else if (cache->flags & F_DS) |
||
259 | { |
||
260 | @@ -1752,6 +1766,8 @@ void dump_cache(time_t now) |
||
261 | t = "6"; |
||
262 | else if (cache->flags & F_CNAME) |
||
263 | t = "C"; |
||
264 | + else if (cache->flags & F_SRV) |
||
265 | + t = "V"; |
||
266 | #ifdef HAVE_DNSSEC |
||
267 | else if (cache->flags & F_DS) |
||
268 | t = "S"; |
||
269 | @@ -1913,6 +1929,8 @@ void log_query(unsigned int flags, char |
||
270 | } |
||
271 | else if (flags & F_CNAME) |
||
272 | dest = "<CNAME>"; |
||
273 | + else if (flags & F_SRV) |
||
274 | + dest = "<SRV>"; |
||
275 | else if (flags & F_RRNAME) |
||
276 | dest = arg; |
||
277 | |||
278 | --- a/src/dnsmasq.c |
||
279 | +++ b/src/dnsmasq.c |
||
280 | @@ -366,9 +366,7 @@ int main (int argc, char **argv) |
||
281 | { |
||
282 | cache_init(); |
||
283 | |||
284 | -#ifdef HAVE_DNSSEC |
||
285 | blockdata_init(); |
||
286 | -#endif |
||
287 | } |
||
288 | |||
289 | #ifdef HAVE_INOTIFY |
||
290 | --- a/src/dnsmasq.h |
||
291 | +++ b/src/dnsmasq.h |
||
292 | @@ -299,6 +299,10 @@ union all_addr { |
||
293 | unsigned char algo; |
||
294 | unsigned char digest; |
||
295 | } ds; |
||
296 | + struct { |
||
297 | + struct blockdata *target; |
||
298 | + unsigned short targetlen, srvport, priority, weight; |
||
299 | + } srv; |
||
300 | /* for log_query */ |
||
301 | struct { |
||
302 | unsigned short keytag, algo, digest, rcode; |
||
303 | @@ -426,7 +430,7 @@ struct crec { |
||
304 | time_t ttd; /* time to die */ |
||
305 | /* used as class if DNSKEY/DS, index to source for F_HOSTS */ |
||
306 | unsigned int uid; |
||
307 | - unsigned short flags; |
||
308 | + unsigned int flags; |
||
309 | union { |
||
310 | char sname[SMALLDNAME]; |
||
311 | union bigname *bname; |
||
312 | @@ -470,6 +474,7 @@ struct crec { |
||
313 | #define F_NOEXTRA (1u<<27) |
||
314 | #define F_SERVFAIL (1u<<28) |
||
315 | #define F_RCODE (1u<<29) |
||
316 | +#define F_SRV (1u<<30) |
||
317 | |||
318 | #define UID_NONE 0 |
||
319 | /* Values of uid in crecs with F_CONFIG bit set. */ |
||
320 | @@ -1142,7 +1147,7 @@ void cache_end_insert(void); |
||
321 | void cache_start_insert(void); |
||
322 | int cache_recv_insert(time_t now, int fd); |
||
323 | struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class, |
||
324 | - time_t now, unsigned long ttl, unsigned short flags); |
||
325 | + time_t now, unsigned long ttl, unsigned int flags); |
||
326 | void cache_reload(void); |
||
327 | void cache_add_dhcp_entry(char *host_name, int prot, union all_addr *host_address, time_t ttd); |
||
328 | struct in_addr a_record_from_hosts(char *name, time_t now); |
||
329 | @@ -1158,7 +1163,6 @@ int read_hostsfile(char *filename, unsig |
||
330 | struct crec **rhash, int hashsz); |
||
331 | |||
332 | /* blockdata.c */ |
||
333 | -#ifdef HAVE_DNSSEC |
||
334 | void blockdata_init(void); |
||
335 | void blockdata_report(void); |
||
336 | struct blockdata *blockdata_alloc(char *data, size_t len); |
||
337 | @@ -1166,7 +1170,6 @@ void *blockdata_retrieve(struct blockdat |
||
338 | struct blockdata *blockdata_read(int fd, size_t len); |
||
339 | void blockdata_write(struct blockdata *block, size_t len, int fd); |
||
340 | void blockdata_free(struct blockdata *blocks); |
||
341 | -#endif |
||
342 | |||
343 | /* domain.c */ |
||
344 | char *get_domain(struct in_addr addr); |
||
345 | --- a/src/rfc1035.c |
||
346 | +++ b/src/rfc1035.c |
||
347 | @@ -726,7 +726,7 @@ int extract_addresses(struct dns_header |
||
348 | { |
||
349 | /* everything other than PTR */ |
||
350 | struct crec *newc; |
||
351 | - int addrlen; |
||
352 | + int addrlen = 0; |
||
353 | |||
354 | if (qtype == T_A) |
||
355 | { |
||
356 | @@ -738,7 +738,9 @@ int extract_addresses(struct dns_header |
||
357 | addrlen = IN6ADDRSZ; |
||
358 | flags |= F_IPV6; |
||
359 | } |
||
360 | - else |
||
361 | + else if (qtype == T_SRV) |
||
362 | + flags |= F_SRV; |
||
363 | + else |
||
364 | continue; |
||
365 | |||
366 | cname_loop1: |
||
367 | @@ -799,39 +801,61 @@ int extract_addresses(struct dns_header |
||
368 | { |
||
369 | found = 1; |
||
370 | |||
371 | - /* copy address into aligned storage */ |
||
372 | - if (!CHECK_LEN(header, p1, qlen, addrlen)) |
||
373 | - return 0; /* bad packet */ |
||
374 | - memcpy(&addr, p1, addrlen); |
||
375 | - |
||
376 | - /* check for returned address in private space */ |
||
377 | - if (check_rebind) |
||
378 | + if (flags & F_SRV) |
||
379 | { |
||
380 | - if ((flags & F_IPV4) && |
||
381 | - private_net(addr.addr4, !option_bool(OPT_LOCAL_REBIND))) |
||
382 | - return 1; |
||
383 | - |
||
384 | - if ((flags & F_IPV6) && |
||
385 | - IN6_IS_ADDR_V4MAPPED(&addr.addr6)) |
||
386 | + unsigned char *tmp = namep; |
||
387 | + |
||
388 | + if (!CHECK_LEN(header, p1, qlen, 6)) |
||
389 | + return 0; /* bad packet */ |
||
390 | + GETSHORT(addr.srv.priority, p1); |
||
391 | + GETSHORT(addr.srv.weight, p1); |
||
392 | + GETSHORT(addr.srv.srvport, p1); |
||
393 | + if (!extract_name(header, qlen, &p1, name, 1, 0)) |
||
394 | + return 0; |
||
395 | + addr.srv.targetlen = strlen(name) + 1; /* include terminating zero */ |
||
396 | + if (!(addr.srv.target = blockdata_alloc(name, addr.srv.targetlen))) |
||
397 | + return 0; |
||
398 | + |
||
399 | + /* we overwrote the original name, so get it back here. */ |
||
400 | + if (!extract_name(header, qlen, &tmp, name, 1, 0)) |
||
401 | + return 0; |
||
402 | + } |
||
403 | + else |
||
404 | + { |
||
405 | + /* copy address into aligned storage */ |
||
406 | + if (!CHECK_LEN(header, p1, qlen, addrlen)) |
||
407 | + return 0; /* bad packet */ |
||
408 | + memcpy(&addr, p1, addrlen); |
||
409 | + |
||
410 | + /* check for returned address in private space */ |
||
411 | + if (check_rebind) |
||
412 | { |
||
413 | - struct in_addr v4; |
||
414 | - v4.s_addr = ((const uint32_t *) (&addr.addr6))[3]; |
||
415 | - if (private_net(v4, !option_bool(OPT_LOCAL_REBIND))) |
||
416 | + if ((flags & F_IPV4) && |
||
417 | + private_net(addr.addr4, !option_bool(OPT_LOCAL_REBIND))) |
||
418 | return 1; |
||
419 | + |
||
420 | + if ((flags & F_IPV6) && |
||
421 | + IN6_IS_ADDR_V4MAPPED(&addr.addr6)) |
||
422 | + { |
||
423 | + struct in_addr v4; |
||
424 | + v4.s_addr = ((const uint32_t *) (&addr.addr6))[3]; |
||
425 | + if (private_net(v4, !option_bool(OPT_LOCAL_REBIND))) |
||
426 | + return 1; |
||
427 | + } |
||
428 | } |
||
429 | - } |
||
430 | - |
||
431 | + |
||
432 | #ifdef HAVE_IPSET |
||
433 | - if (ipsets && (flags & (F_IPV4 | F_IPV6))) |
||
434 | - { |
||
435 | - ipsets_cur = ipsets; |
||
436 | - while (*ipsets_cur) |
||
437 | + if (ipsets && (flags & (F_IPV4 | F_IPV6))) |
||
438 | { |
||
439 | - log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur); |
||
440 | - add_to_ipset(*ipsets_cur++, &addr, flags, 0); |
||
441 | + ipsets_cur = ipsets; |
||
442 | + while (*ipsets_cur) |
||
443 | + { |
||
444 | + log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur); |
||
445 | + add_to_ipset(*ipsets_cur++, &addr, flags, 0); |
||
446 | + } |
||
447 | } |
||
448 | - } |
||
449 | #endif |
||
450 | + } |
||
451 | |||
452 | newc = cache_insert(name, &addr, C_IN, now, attl, flags | F_FORWARD | secflag); |
||
453 | if (newc && cpp) |
||
454 | @@ -1844,7 +1868,68 @@ size_t answer_request(struct dns_header |
||
455 | *up = move; |
||
456 | move->next = NULL; |
||
457 | } |
||
458 | - |
||
459 | + |
||
460 | + if (!found) |
||
461 | + { |
||
462 | + cname_srv_restart: |
||
463 | + if ((crecp = cache_find_by_name(NULL, name, now, F_CNAME | F_SRV | (dryrun ? F_NO_RR : 0))) && |
||
464 | + (!do_bit || (option_bool(OPT_DNSSEC_VALID) && !(crecp->flags & F_DNSSECOK)))) |
||
465 | + { |
||
466 | + if (!(crecp->flags & F_DNSSECOK)) |
||
467 | + sec_data = 0; |
||
468 | + |
||
469 | + auth = 0; |
||
470 | + found = ans = 1; |
||
471 | + |
||
472 | + do { |
||
473 | + if (crecp->flags & F_CNAME) |
||
474 | + { |
||
475 | + char *cname_target = cache_get_cname_target(crecp); |
||
476 | + |
||
477 | + if (!dryrun) |
||
478 | + { |
||
479 | + log_query(crecp->flags, name, NULL, record_source(crecp->uid)); |
||
480 | + if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
||
481 | + crec_ttl(crecp, now), &nameoffset, |
||
482 | + T_CNAME, C_IN, "d", cname_target)) |
||
483 | + anscount++; |
||
484 | + } |
||
485 | + |
||
486 | + strcpy(name, cname_target); |
||
487 | + goto cname_srv_restart; |
||
488 | + } |
||
489 | + else if (crecp->flags & F_NEG) |
||
490 | + { |
||
491 | + if (crecp->flags & F_NXDOMAIN) |
||
492 | + nxdomain = 1; |
||
493 | + if (!dryrun) |
||
494 | + log_query(crecp->flags, name, NULL, NULL); |
||
495 | + } |
||
496 | + else |
||
497 | + { |
||
498 | + unsigned char *p1 = ((unsigned char *)header) + nameoffset; |
||
499 | + |
||
500 | + if (!dryrun) |
||
501 | + { |
||
502 | + log_query(crecp->flags, name, NULL, 0); |
||
503 | + |
||
504 | + blockdata_retrieve(crecp->addr.srv.target, crecp->addr.srv.targetlen, name); |
||
505 | + if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, |
||
506 | + crec_ttl(crecp, now), NULL, T_SRV, C_IN, "sssd", |
||
507 | + crecp->addr.srv.priority, crecp->addr.srv.weight, crecp->addr.srv.srvport, |
||
508 | + name)) |
||
509 | + anscount++; |
||
510 | + |
||
511 | + |
||
512 | + /* restore name we overwrote */ |
||
513 | + if (!extract_name(header, qlen, &p1, name, 1, 0)) |
||
514 | + return 0; /* bad packet */ |
||
515 | + } |
||
516 | + } |
||
517 | + } while ((crecp = cache_find_by_name(crecp, name, now, F_SRV | F_CNAME))); |
||
518 | + } |
||
519 | + } |
||
520 | + |
||
521 | if (!found && option_bool(OPT_FILTER) && (qtype == T_SRV || (qtype == T_ANY && strchr(name, '_')))) |
||
522 | { |
||
523 | ans = 1; |