]> git.ipfire.org Git - people/ms/dnsmasq.git/blame - src/forward.c
Handle validation when more one key is needed.
[people/ms/dnsmasq.git] / src / forward.c
CommitLineData
c47e3ba4 1/* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
9e4abcb5
SK
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
824af85b
SK
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
7
9e4abcb5
SK
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
824af85b 12
73a08a24
SK
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
9e4abcb5
SK
15*/
16
9e4abcb5
SK
17#include "dnsmasq.h"
18
8a9be9e4 19static struct frec *lookup_frec(unsigned short id, void *hash);
9e4abcb5 20static struct frec *lookup_frec_by_sender(unsigned short id,
fd9fa481 21 union mysockaddr *addr,
8a9be9e4
SK
22 void *hash);
23static unsigned short get_id(void);
1a6bca81
SK
24static void free_frec(struct frec *f);
25static struct randfd *allocate_rfd(int family);
9e4abcb5 26
824af85b 27/* Send a UDP packet with its source address set as "source"
44a2a316 28 unless nowild is true, when we just send it with the kernel default */
29689cfa
SK
29int send_from(int fd, int nowild, char *packet, size_t len,
30 union mysockaddr *to, struct all_addr *source,
50303b19 31 unsigned int iface)
9e4abcb5 32{
44a2a316
SK
33 struct msghdr msg;
34 struct iovec iov[1];
44a2a316
SK
35 union {
36 struct cmsghdr align; /* this ensures alignment */
5e9e0efb 37#if defined(HAVE_LINUX_NETWORK)
44a2a316
SK
38 char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
39#elif defined(IP_SENDSRCADDR)
40 char control[CMSG_SPACE(sizeof(struct in_addr))];
41#endif
42#ifdef HAVE_IPV6
43 char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
44#endif
45 } control_u;
feba5c1d 46
44a2a316
SK
47 iov[0].iov_base = packet;
48 iov[0].iov_len = len;
49
feba5c1d
SK
50 msg.msg_control = NULL;
51 msg.msg_controllen = 0;
44a2a316
SK
52 msg.msg_flags = 0;
53 msg.msg_name = to;
54 msg.msg_namelen = sa_len(to);
55 msg.msg_iov = iov;
56 msg.msg_iovlen = 1;
feba5c1d 57
26128d27 58 if (!nowild)
44a2a316 59 {
26128d27 60 struct cmsghdr *cmptr;
feba5c1d
SK
61 msg.msg_control = &control_u;
62 msg.msg_controllen = sizeof(control_u);
26128d27
SK
63 cmptr = CMSG_FIRSTHDR(&msg);
64
65 if (to->sa.sa_family == AF_INET)
66 {
5e9e0efb 67#if defined(HAVE_LINUX_NETWORK)
8ef5ada2
SK
68 struct in_pktinfo p;
69 p.ipi_ifindex = 0;
70 p.ipi_spec_dst = source->addr.addr4;
71 memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
26128d27 72 msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
c72daea8 73 cmptr->cmsg_level = IPPROTO_IP;
26128d27 74 cmptr->cmsg_type = IP_PKTINFO;
44a2a316 75#elif defined(IP_SENDSRCADDR)
8ef5ada2 76 memcpy(CMSG_DATA(cmptr), &(source->addr.addr4), sizeof(source->addr.addr4));
26128d27
SK
77 msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
78 cmptr->cmsg_level = IPPROTO_IP;
79 cmptr->cmsg_type = IP_SENDSRCADDR;
44a2a316 80#endif
26128d27 81 }
26128d27 82 else
b8187c80 83#ifdef HAVE_IPV6
26128d27 84 {
8ef5ada2
SK
85 struct in6_pktinfo p;
86 p.ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local addrs */
87 p.ipi6_addr = source->addr.addr6;
88 memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
26128d27 89 msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
316e2730 90 cmptr->cmsg_type = daemon->v6pktinfo;
c72daea8 91 cmptr->cmsg_level = IPPROTO_IPV6;
26128d27 92 }
3d8df260 93#else
c72daea8 94 (void)iface; /* eliminate warning */
44a2a316 95#endif
26128d27 96 }
feba5c1d 97
29d28dda 98 while (sendmsg(fd, &msg, 0) == -1)
feba5c1d 99 {
fd9fa481 100 if (retry_send())
29d28dda 101 continue;
22d904db 102
29d28dda
SK
103 /* If interface is still in DAD, EINVAL results - ignore that. */
104 if (errno == EINVAL)
105 break;
29689cfa 106
29d28dda 107 my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
29689cfa 108 return 0;
feba5c1d 109 }
29d28dda 110
29689cfa 111 return 1;
9e4abcb5 112}
44a2a316 113
28866e95
SK
114static unsigned int search_servers(time_t now, struct all_addr **addrpp,
115 unsigned int qtype, char *qdomain, int *type, char **domain, int *norebind)
feba5c1d
SK
116
117{
118 /* If the query ends in the domain in one of our servers, set
119 domain to point to that name. We find the largest match to allow both
120 domain.org and sub.domain.org to exist. */
121
122 unsigned int namelen = strlen(qdomain);
123 unsigned int matchlen = 0;
124 struct server *serv;
28866e95 125 unsigned int flags = 0;
feba5c1d 126
3be34541 127 for (serv = daemon->servers; serv; serv=serv->next)
feba5c1d 128 /* domain matches take priority over NODOTS matches */
3d8df260 129 if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') && namelen != 0)
feba5c1d 130 {
28866e95 131 unsigned int sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
feba5c1d 132 *type = SERV_FOR_NODOTS;
feba5c1d 133 if (serv->flags & SERV_NO_ADDR)
36717eee
SK
134 flags = F_NXDOMAIN;
135 else if (serv->flags & SERV_LITERAL_ADDRESS)
136 {
137 if (sflag & qtype)
138 {
139 flags = sflag;
140 if (serv->addr.sa.sa_family == AF_INET)
141 *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
feba5c1d 142#ifdef HAVE_IPV6
36717eee
SK
143 else
144 *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
feba5c1d 145#endif
36717eee 146 }
824af85b 147 else if (!flags || (flags & F_NXDOMAIN))
36717eee
SK
148 flags = F_NOERR;
149 }
feba5c1d
SK
150 }
151 else if (serv->flags & SERV_HAS_DOMAIN)
152 {
153 unsigned int domainlen = strlen(serv->domain);
b8187c80 154 char *matchstart = qdomain + namelen - domainlen;
feba5c1d 155 if (namelen >= domainlen &&
b8187c80 156 hostname_isequal(matchstart, serv->domain) &&
8ef5ada2 157 (domainlen == 0 || namelen == domainlen || *(matchstart-1) == '.' ))
feba5c1d 158 {
8ef5ada2
SK
159 if (serv->flags & SERV_NO_REBIND)
160 *norebind = 1;
28866e95 161 else
feba5c1d 162 {
28866e95
SK
163 unsigned int sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
164 /* implement priority rules for --address and --server for same domain.
165 --address wins if the address is for the correct AF
166 --server wins otherwise. */
167 if (domainlen != 0 && domainlen == matchlen)
36717eee 168 {
28866e95 169 if ((serv->flags & SERV_LITERAL_ADDRESS))
8ef5ada2 170 {
28866e95
SK
171 if (!(sflag & qtype) && flags == 0)
172 continue;
173 }
174 else
175 {
176 if (flags & (F_IPV4 | F_IPV6))
177 continue;
178 }
179 }
180
181 if (domainlen >= matchlen)
182 {
183 *type = serv->flags & (SERV_HAS_DOMAIN | SERV_USE_RESOLV | SERV_NO_REBIND);
184 *domain = serv->domain;
185 matchlen = domainlen;
186 if (serv->flags & SERV_NO_ADDR)
187 flags = F_NXDOMAIN;
188 else if (serv->flags & SERV_LITERAL_ADDRESS)
189 {
190 if (sflag & qtype)
191 {
192 flags = sflag;
193 if (serv->addr.sa.sa_family == AF_INET)
194 *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
feba5c1d 195#ifdef HAVE_IPV6
28866e95
SK
196 else
197 *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
feba5c1d 198#endif
28866e95
SK
199 }
200 else if (!flags || (flags & F_NXDOMAIN))
201 flags = F_NOERR;
8ef5ada2 202 }
28866e95
SK
203 else
204 flags = 0;
205 }
206 }
8ef5ada2 207 }
feba5c1d 208 }
8ef5ada2 209
7de060b0 210 if (flags == 0 && !(qtype & F_QUERY) &&
28866e95 211 option_bool(OPT_NODOTS_LOCAL) && !strchr(qdomain, '.') && namelen != 0)
7de060b0
SK
212 /* don't forward A or AAAA queries for simple names, except the empty name */
213 flags = F_NOERR;
8ef5ada2 214
5aabfc78 215 if (flags == F_NXDOMAIN && check_for_local_domain(qdomain, now))
c1bb8504 216 flags = F_NOERR;
feba5c1d 217
824af85b
SK
218 if (flags)
219 {
220 int logflags = 0;
221
222 if (flags == F_NXDOMAIN || flags == F_NOERR)
223 logflags = F_NEG | qtype;
224
1a6bca81 225 log_query(logflags | flags | F_CONFIG | F_FORWARD, qdomain, *addrpp, NULL);
824af85b 226 }
8ef5ada2
SK
227 else if ((*type) & SERV_USE_RESOLV)
228 {
229 *type = 0; /* use normal servers for this domain */
230 *domain = NULL;
231 }
feba5c1d
SK
232 return flags;
233}
44a2a316 234
824af85b
SK
235static int forward_query(int udpfd, union mysockaddr *udpaddr,
236 struct all_addr *dst_addr, unsigned int dst_iface,
572b41eb 237 struct dns_header *header, size_t plen, time_t now, struct frec *forward)
9e4abcb5 238{
9e4abcb5 239 char *domain = NULL;
8ef5ada2 240 int type = 0, norebind = 0;
9e4abcb5 241 struct all_addr *addrp = NULL;
28866e95 242 unsigned int flags = 0;
de37951c 243 struct server *start = NULL;
8a9be9e4
SK
244#ifdef HAVE_DNSSEC
245 void *hash = hash_questions(header, plen, daemon->namebuff);
246#else
247 unsigned int crc = questions_crc(header, plen, daemon->namebuff);
248 void *hash = &crc;
249#endif
250 unsigned int gotname = extract_request(header, plen, daemon->namebuff, NULL);
251
3d8df260
SK
252 /* may be no servers available. */
253 if (!daemon->servers)
9e4abcb5 254 forward = NULL;
8a9be9e4 255 else if (forward || (hash && (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, hash))))
9e4abcb5 256 {
e0c0ad3b
SK
257#ifdef HAVE_DNSSEC
258 /* If we've already got an answer to this query, but we're awaiting keys for vaildation,
259 there's no point retrying the query, retry the key query instead...... */
260 if (forward->blocking_query)
261 {
262 int fd;
263
264 while (forward->blocking_query)
265 forward = forward->blocking_query;
266
267 blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
268 plen = forward->stash_len;
269
270 if (forward->sentto->addr.sa.sa_family)
271 log_query(F_DNSSEC | F_IPV4, "retry", (struct all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec");
272#ifdef HAVE_IPV6
273 else
274 log_query(F_DNSSEC | F_IPV6, "retry", (struct all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec");
275#endif
276
277 if (forward->sentto->sfd)
278 fd = forward->sentto->sfd->fd;
279 else
280 {
281#ifdef HAVE_IPV6
282 if (forward->sentto->addr.sa.sa_family == AF_INET6)
283 fd = forward->rfd6->fd;
284 else
285#endif
286 fd = forward->rfd4->fd;
287 }
288
289 while (sendto(fd, (char *)header, plen, 0,
290 &forward->sentto->addr.sa,
291 sa_len(&forward->sentto->addr)) == -1 && retry_send());
292
293 return 1;
294 }
295#endif
296
de37951c 297 /* retry on existing query, send to all available servers */
9e4abcb5 298 domain = forward->sentto->domain;
824af85b 299 forward->sentto->failed_queries++;
28866e95 300 if (!option_bool(OPT_ORDER))
de37951c 301 {
0a852541 302 forward->forwardall = 1;
3be34541 303 daemon->last_server = NULL;
de37951c 304 }
9e4abcb5 305 type = forward->sentto->flags & SERV_TYPE;
de37951c 306 if (!(start = forward->sentto->next))
3be34541 307 start = daemon->servers; /* at end of list, recycle */
9e4abcb5
SK
308 header->id = htons(forward->new_id);
309 }
310 else
311 {
312 if (gotname)
8ef5ada2 313 flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
9e4abcb5 314
3a237152 315 if (!flags && !(forward = get_new_frec(now, NULL, 0)))
feba5c1d
SK
316 /* table full - server failure. */
317 flags = F_NEG;
9e4abcb5
SK
318
319 if (forward)
320 {
0a852541
SK
321 forward->source = *udpaddr;
322 forward->dest = *dst_addr;
323 forward->iface = dst_iface;
0a852541 324 forward->orig_id = ntohs(header->id);
8a9be9e4 325 forward->new_id = get_id();
832af0ba 326 forward->fd = udpfd;
8a9be9e4 327 memcpy(forward->hash, hash, HASH_SIZE);
0a852541 328 forward->forwardall = 0;
ed4c0767 329 forward->flags = 0;
28866e95
SK
330 if (norebind)
331 forward->flags |= FREC_NOREBIND;
572b41eb 332 if (header->hb4 & HB4_CD)
28866e95 333 forward->flags |= FREC_CHECKING_DISABLED;
7fa836e1
SK
334#ifdef HAVE_DNSSEC
335 forward->work_counter = DNSSEC_WORK;
336#endif
0a852541 337
28866e95
SK
338 header->id = htons(forward->new_id);
339
8ef5ada2
SK
340 /* In strict_order mode, always try servers in the order
341 specified in resolv.conf, if a domain is given
342 always try all the available servers,
9e4abcb5
SK
343 otherwise, use the one last known to work. */
344
8ef5ada2
SK
345 if (type == 0)
346 {
28866e95 347 if (option_bool(OPT_ORDER))
8ef5ada2
SK
348 start = daemon->servers;
349 else if (!(start = daemon->last_server) ||
350 daemon->forwardcount++ > FORWARD_TEST ||
351 difftime(now, daemon->forwardtime) > FORWARD_TIME)
352 {
353 start = daemon->servers;
354 forward->forwardall = 1;
355 daemon->forwardcount = 0;
356 daemon->forwardtime = now;
357 }
358 }
359 else
de37951c 360 {
3be34541 361 start = daemon->servers;
28866e95 362 if (!option_bool(OPT_ORDER))
8ef5ada2 363 forward->forwardall = 1;
de37951c 364 }
9e4abcb5
SK
365 }
366 }
feba5c1d 367
9e4abcb5
SK
368 /* check for send errors here (no route to host)
369 if we fail to send to all nameservers, send back an error
370 packet straight away (helps modem users when offline) */
371
372 if (!flags && forward)
373 {
de37951c
SK
374 struct server *firstsentto = start;
375 int forwarded = 0;
28866e95 376
797a7afb 377 if (option_bool(OPT_ADD_MAC))
60b68069 378 plen = add_mac(header, plen, ((char *) header) + daemon->packet_buff_sz, &forward->source);
28866e95 379
ed4c0767
SK
380 if (option_bool(OPT_CLIENT_SUBNET))
381 {
60b68069 382 size_t new = add_source_addr(header, plen, ((char *) header) + daemon->packet_buff_sz, &forward->source);
ed4c0767
SK
383 if (new != plen)
384 {
385 plen = new;
386 forward->flags |= FREC_HAS_SUBNET;
387 }
388 }
389
3a237152
SK
390#ifdef HAVE_DNSSEC
391 if (option_bool(OPT_DNSSEC_VALID))
0fc2f313 392 {
60b68069 393 plen = add_do_bit(header, plen, ((char *) header) + daemon->packet_buff_sz);
5b3bf921
SK
394 /* For debugging, set Checking Disabled, otherwise, have the upstream check too,
395 this allows it to select auth servers when one is returning bad data. */
396 if (option_bool(OPT_DNSSEC_DEBUG))
397 header->hb4 |= HB4_CD;
0fc2f313 398 }
3a237152
SK
399#endif
400
9e4abcb5
SK
401 while (1)
402 {
9e4abcb5
SK
403 /* only send to servers dealing with our domain.
404 domain may be NULL, in which case server->domain
405 must be NULL also. */
406
de37951c 407 if (type == (start->flags & SERV_TYPE) &&
fd9fa481
SK
408 (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
409 !(start->flags & SERV_LITERAL_ADDRESS))
9e4abcb5 410 {
1a6bca81
SK
411 int fd;
412
413 /* find server socket to use, may need to get random one. */
414 if (start->sfd)
415 fd = start->sfd->fd;
416 else
417 {
418#ifdef HAVE_IPV6
419 if (start->addr.sa.sa_family == AF_INET6)
420 {
421 if (!forward->rfd6 &&
422 !(forward->rfd6 = allocate_rfd(AF_INET6)))
423 break;
3927da46 424 daemon->rfd_save = forward->rfd6;
1a6bca81
SK
425 fd = forward->rfd6->fd;
426 }
427 else
428#endif
429 {
430 if (!forward->rfd4 &&
431 !(forward->rfd4 = allocate_rfd(AF_INET)))
432 break;
3927da46 433 daemon->rfd_save = forward->rfd4;
1a6bca81
SK
434 fd = forward->rfd4->fd;
435 }
7de060b0
SK
436
437#ifdef HAVE_CONNTRACK
438 /* Copy connection mark of incoming query to outgoing connection. */
439 if (option_bool(OPT_CONNTRACK))
440 {
441 unsigned int mark;
797a7afb 442 if (get_incoming_mark(&forward->source, &forward->dest, 0, &mark))
7de060b0
SK
443 setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
444 }
445#endif
1a6bca81
SK
446 }
447
448 if (sendto(fd, (char *)header, plen, 0,
feba5c1d 449 &start->addr.sa,
fd9fa481
SK
450 sa_len(&start->addr)) == -1)
451 {
452 if (retry_send())
453 continue;
454 }
455 else
9e4abcb5 456 {
cdeda28f
SK
457 /* Keep info in case we want to re-send this packet */
458 daemon->srv_save = start;
459 daemon->packet_len = plen;
460
de37951c 461 if (!gotname)
3be34541 462 strcpy(daemon->namebuff, "query");
de37951c 463 if (start->addr.sa.sa_family == AF_INET)
3be34541 464 log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
1a6bca81 465 (struct all_addr *)&start->addr.in.sin_addr, NULL);
de37951c
SK
466#ifdef HAVE_IPV6
467 else
3be34541 468 log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
1a6bca81 469 (struct all_addr *)&start->addr.in6.sin6_addr, NULL);
de37951c 470#endif
824af85b 471 start->queries++;
de37951c
SK
472 forwarded = 1;
473 forward->sentto = start;
0a852541 474 if (!forward->forwardall)
de37951c 475 break;
0a852541 476 forward->forwardall++;
9e4abcb5
SK
477 }
478 }
479
de37951c 480 if (!(start = start->next))
3be34541 481 start = daemon->servers;
9e4abcb5 482
de37951c 483 if (start == firstsentto)
9e4abcb5
SK
484 break;
485 }
486
de37951c 487 if (forwarded)
824af85b 488 return 1;
de37951c 489
9e4abcb5
SK
490 /* could not send on, prepare to return */
491 header->id = htons(forward->orig_id);
1a6bca81 492 free_frec(forward); /* cancel */
9e4abcb5
SK
493 }
494
495 /* could not send on, return empty answer or address if known for whole domain */
b8187c80
SK
496 if (udpfd != -1)
497 {
cdeda28f 498 plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl);
54dd393f 499 send_from(udpfd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND), (char *)header, plen, udpaddr, dst_addr, dst_iface);
b8187c80
SK
500 }
501
824af85b 502 return 0;
9e4abcb5
SK
503}
504
ed4c0767 505static size_t process_reply(struct dns_header *header, time_t now, struct server *server, size_t n, int check_rebind,
3a237152 506 int no_cache, int cache_secure, int check_subnet, union mysockaddr *query_source)
feba5c1d 507{
36717eee 508 unsigned char *pheader, *sizep;
13d86c73 509 char **sets = 0;
832af0ba 510 int munged = 0, is_sign;
cdeda28f
SK
511 size_t plen;
512
13d86c73
JD
513#ifdef HAVE_IPSET
514 /* Similar algorithm to search_servers. */
515 struct ipsets *ipset_pos;
516 unsigned int namelen = strlen(daemon->namebuff);
517 unsigned int matchlen = 0;
518 for (ipset_pos = daemon->ipsets; ipset_pos; ipset_pos = ipset_pos->next)
519 {
520 unsigned int domainlen = strlen(ipset_pos->domain);
521 char *matchstart = daemon->namebuff + namelen - domainlen;
522 if (namelen >= domainlen && hostname_isequal(matchstart, ipset_pos->domain) &&
523 (domainlen == 0 || namelen == domainlen || *(matchstart - 1) == '.' ) &&
6c0cb858
SK
524 domainlen >= matchlen)
525 {
526 matchlen = domainlen;
527 sets = ipset_pos->sets;
528 }
13d86c73
JD
529 }
530#endif
531
feba5c1d 532 /* If upstream is advertising a larger UDP packet size
9009d746
SK
533 than we allow, trim it so that we don't get overlarge
534 requests for the client. We can't do this for signed packets. */
feba5c1d 535
ed4c0767 536 if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign)))
feba5c1d 537 {
ed4c0767
SK
538 if (!is_sign)
539 {
540 unsigned short udpsz;
541 unsigned char *psave = sizep;
542
543 GETSHORT(udpsz, sizep);
544 if (udpsz > daemon->edns_pktsz)
545 PUTSHORT(daemon->edns_pktsz, psave);
546 }
feba5c1d 547
ed4c0767
SK
548 if (check_subnet && !check_source(header, plen, pheader, query_source))
549 {
550 my_syslog(LOG_WARNING, _("discarding DNS reply: subnet option mismatch"));
551 return 0;
552 }
feba5c1d 553 }
ed4c0767 554
28866e95 555 /* RFC 4035 sect 4.6 para 3 */
237724c0 556 if (!is_sign && !option_bool(OPT_DNSSEC_PROXY))
795501bc 557 header->hb4 &= ~HB4_AD;
3a237152 558
572b41eb 559 if (OPCODE(header) != QUERY || (RCODE(header) != NOERROR && RCODE(header) != NXDOMAIN))
0a852541
SK
560 return n;
561
feba5c1d 562 /* Complain loudly if the upstream server is non-recursive. */
572b41eb 563 if (!(header->hb4 & HB4_RA) && RCODE(header) == NOERROR && ntohs(header->ancount) == 0 &&
0a852541 564 server && !(server->flags & SERV_WARNED_RECURSIVE))
feba5c1d 565 {
3d8df260 566 prettyprint_addr(&server->addr, daemon->namebuff);
f2621c7f 567 my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
28866e95 568 if (!option_bool(OPT_LOG))
0a852541
SK
569 server->flags |= SERV_WARNED_RECURSIVE;
570 }
e292e93d 571
572b41eb 572 if (daemon->bogus_addr && RCODE(header) != NXDOMAIN &&
fd9fa481 573 check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now))
feba5c1d 574 {
fd9fa481 575 munged = 1;
572b41eb
SK
576 SET_RCODE(header, NXDOMAIN);
577 header->hb3 &= ~HB3_AA;
6938f347 578 cache_secure = 0;
36717eee 579 }
fd9fa481 580 else
36717eee 581 {
6938f347
SK
582 int doctored = 0;
583
572b41eb 584 if (RCODE(header) == NXDOMAIN &&
fd9fa481 585 extract_request(header, n, daemon->namebuff, NULL) &&
5aabfc78 586 check_for_local_domain(daemon->namebuff, now))
36717eee
SK
587 {
588 /* if we forwarded a query for a locally known name (because it was for
589 an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
590 since we know that the domain exists, even if upstream doesn't */
fd9fa481 591 munged = 1;
572b41eb
SK
592 header->hb3 |= HB3_AA;
593 SET_RCODE(header, NOERROR);
6938f347 594 cache_secure = 0;
feba5c1d 595 }
832af0ba 596
6938f347 597 if (extract_addresses(header, n, daemon->namebuff, now, sets, is_sign, check_rebind, no_cache, cache_secure, &doctored))
824af85b 598 {
8ef5ada2 599 my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected: %s"), daemon->namebuff);
824af85b 600 munged = 1;
6938f347 601 cache_secure = 0;
824af85b 602 }
6938f347
SK
603
604 if (doctored)
605 cache_secure = 0;
feba5c1d 606 }
fd9fa481 607
a25720a3
SK
608#ifdef HAVE_DNSSEC
609 if (no_cache && !(header->hb4 & HB4_CD))
610 {
7d23a66f 611 if (!option_bool(OPT_DNSSEC_DEBUG))
a25720a3
SK
612 {
613 /* Bogus reply, turn into SERVFAIL */
614 SET_RCODE(header, SERVFAIL);
615 munged = 1;
616 }
617 }
6938f347
SK
618
619 if (option_bool(OPT_DNSSEC_VALID))
620 header->hb4 &= ~HB4_AD;
621
622 if (!(header->hb4 & HB4_CD) && cache_secure)
623 header->hb4 |= HB4_AD;
a25720a3
SK
624#endif
625
fd9fa481
SK
626 /* do this after extract_addresses. Ensure NODATA reply and remove
627 nameserver info. */
628
629 if (munged)
630 {
631 header->ancount = htons(0);
632 header->nscount = htons(0);
633 header->arcount = htons(0);
634 }
635
36717eee
SK
636 /* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
637 sections of the packet. Find the new length here and put back pseudoheader
638 if it was removed. */
639 return resize_packet(header, n, pheader, plen);
feba5c1d
SK
640}
641
3be34541 642/* sets new last_server */
1a6bca81 643void reply_query(int fd, int family, time_t now)
9e4abcb5
SK
644{
645 /* packet from peer server, extract data for cache, and send to
646 original requester */
572b41eb 647 struct dns_header *header;
de37951c 648 union mysockaddr serveraddr;
832af0ba 649 struct frec *forward;
de37951c 650 socklen_t addrlen = sizeof(serveraddr);
60b68069 651 ssize_t n = recvfrom(fd, daemon->packet, daemon->packet_buff_sz, 0, &serveraddr.sa, &addrlen);
cdeda28f 652 size_t nn;
1a6bca81 653 struct server *server;
8a9be9e4
SK
654 void *hash;
655#ifndef HAVE_DNSSEC
656 unsigned int crc;
657#endif
658
cdeda28f
SK
659 /* packet buffer overwritten */
660 daemon->srv_save = NULL;
832af0ba 661
de37951c 662 /* Determine the address of the server replying so that we can mark that as good */
1a6bca81 663 serveraddr.sa.sa_family = family;
de37951c
SK
664#ifdef HAVE_IPV6
665 if (serveraddr.sa.sa_family == AF_INET6)
5e9e0efb 666 serveraddr.in6.sin6_flowinfo = 0;
de37951c 667#endif
9e4abcb5 668
1a6bca81
SK
669 /* spoof check: answer must come from known server, */
670 for (server = daemon->servers; server; server = server->next)
671 if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
672 sockaddr_isequal(&server->addr, &serveraddr))
673 break;
674
572b41eb 675 header = (struct dns_header *)daemon->packet;
8a9be9e4
SK
676
677#ifdef HAVE_DNSSEC
678 hash = hash_questions(header, n, daemon->namebuff);
679#else
680 hash = &crc;
681 crc = questions_crc(header, n, daemon->namebuff);
682#endif
fd9fa481 683
1a6bca81 684 if (!server ||
572b41eb 685 n < (int)sizeof(struct dns_header) || !(header->hb3 & HB3_QR) ||
8a9be9e4 686 !(forward = lookup_frec(ntohs(header->id), hash)))
1a6bca81 687 return;
3a237152 688
572b41eb 689 if ((RCODE(header) == SERVFAIL || RCODE(header) == REFUSED) &&
28866e95 690 !option_bool(OPT_ORDER) &&
1a6bca81
SK
691 forward->forwardall == 0)
692 /* for broken servers, attempt to send to another one. */
9e4abcb5 693 {
1a6bca81
SK
694 unsigned char *pheader;
695 size_t plen;
696 int is_sign;
832af0ba 697
1a6bca81
SK
698 /* recreate query from reply */
699 pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign);
700 if (!is_sign)
832af0ba 701 {
1a6bca81
SK
702 header->ancount = htons(0);
703 header->nscount = htons(0);
704 header->arcount = htons(0);
705 if ((nn = resize_packet(header, (size_t)n, pheader, plen)))
832af0ba 706 {
572b41eb 707 header->hb3 &= ~(HB3_QR | HB3_TC);
1a6bca81
SK
708 forward_query(-1, NULL, NULL, 0, header, nn, now, forward);
709 return;
832af0ba 710 }
832af0ba 711 }
1a6bca81 712 }
3a237152
SK
713
714 server = forward->sentto;
1a6bca81
SK
715
716 if ((forward->sentto->flags & SERV_TYPE) == 0)
717 {
572b41eb 718 if (RCODE(header) == SERVFAIL || RCODE(header) == REFUSED)
1a6bca81
SK
719 server = NULL;
720 else
b8187c80 721 {
1a6bca81
SK
722 struct server *last_server;
723
724 /* find good server by address if possible, otherwise assume the last one we sent to */
725 for (last_server = daemon->servers; last_server; last_server = last_server->next)
726 if (!(last_server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR)) &&
727 sockaddr_isequal(&last_server->addr, &serveraddr))
728 {
729 server = last_server;
730 break;
731 }
732 }
28866e95 733 if (!option_bool(OPT_ALL_SERVERS))
1a6bca81
SK
734 daemon->last_server = server;
735 }
3a237152 736
1a6bca81
SK
737 /* If the answer is an error, keep the forward record in place in case
738 we get a good reply from another server. Kill it when we've
739 had replies from all to avoid filling the forwarding table when
740 everything is broken */
741 if (forward->forwardall == 0 || --forward->forwardall == 1 ||
572b41eb 742 (RCODE(header) != REFUSED && RCODE(header) != SERVFAIL))
1a6bca81 743 {
3a237152
SK
744 int check_rebind = 0, no_cache_dnssec = 0, cache_secure = 0;
745
746 if (option_bool(OPT_NO_REBIND))
747 check_rebind = !(forward->flags & FREC_NOREBIND);
748
749 /* Don't cache replies where DNSSEC validation was turned off, either
750 the upstream server told us so, or the original query specified it. */
751 if ((header->hb4 & HB4_CD) || (forward->flags & FREC_CHECKING_DISABLED))
752 no_cache_dnssec = 1;
753
754#ifdef HAVE_DNSSEC
755 if (option_bool(OPT_DNSSEC_VALID) && !(forward->flags & FREC_CHECKING_DISABLED))
756 {
9d633048 757 int status;
0fc2f313
SK
758
759 /* We've had a reply already, which we're validating. Ignore this duplicate */
e0c0ad3b 760 if (forward->blocking_query)
0fc2f313 761 return;
9d633048 762
871417d4
SK
763 if (header->hb3 & HB3_TC)
764 {
765 /* Truncated answer can't be validated.
5d3b87a4
SK
766 If this is an answer to a DNSSEC-generated query, we still
767 need to get the client to retry over TCP, so return
768 an answer with the TC bit set, even if the actual answer fits.
769 */
770 status = STAT_TRUNCATED;
871417d4
SK
771 }
772 else if (forward->flags & FREC_DNSKEY_QUERY)
8d718cbb 773 status = dnssec_validate_by_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
c3e0b9b6
SK
774 else if (forward->flags & FREC_DS_QUERY)
775 status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
9d633048 776 else
0fc2f313 777 status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class);
7fa836e1 778
3a237152
SK
779 /* Can't validate, as we're missing key data. Put this
780 answer aside, whilst we get that. */
781 if (status == STAT_NEED_DS || status == STAT_NEED_KEY)
782 {
7fa836e1
SK
783 struct frec *new, *orig;
784
785 /* Free any saved query */
786 if (forward->stash)
787 blockdata_free(forward->stash);
788
789 /* Now save reply pending receipt of key data */
790 if (!(forward->stash = blockdata_alloc((char *)header, n)))
791 return;
792 forward->stash_len = n;
0fc2f313 793
7fa836e1
SK
794 anotherkey:
795 /* Find the original query that started it all.... */
796 for (orig = forward; orig->dependent; orig = orig->dependent);
797
798 if (--orig->work_counter == 0 || !(new = get_new_frec(now, NULL, 1)))
799 status = STAT_INSECURE;
800 else
3a237152 801 {
7fa836e1 802 int fd;
0fc2f313
SK
803 struct frec *next = new->next;
804 *new = *forward; /* copy everything, then overwrite */
805 new->next = next;
0fc2f313 806 new->blocking_query = NULL;
f1668d27
SK
807 new->rfd4 = NULL;
808#ifdef HAVE_IPV6
809 new->rfd6 = NULL;
810#endif
0fc2f313 811 new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY);
9d633048 812
7fa836e1
SK
813 new->dependent = forward; /* to find query awaiting new one. */
814 forward->blocking_query = new; /* for garbage cleaning */
815 /* validate routines leave name of required record in daemon->keyname */
816 if (status == STAT_NEED_KEY)
817 {
818 new->flags |= FREC_DNSKEY_QUERY;
819 nn = dnssec_generate_query(header, ((char *) header) + daemon->packet_buff_sz,
820 daemon->keyname, forward->class, T_DNSKEY, &server->addr);
821 }
822 else
823 {
824 new->flags |= FREC_DS_QUERY;
825 nn = dnssec_generate_query(header,((char *) header) + daemon->packet_buff_sz,
826 daemon->keyname, forward->class, T_DS, &server->addr);
827 }
828 if ((hash = hash_questions(header, nn, daemon->namebuff)))
829 memcpy(new->hash, hash, HASH_SIZE);
830 new->new_id = get_id();
831 header->id = htons(new->new_id);
832 /* Save query for retransmission */
833 new->stash = blockdata_alloc((char *)header, nn);
834 new->stash_len = nn;
835
836 /* Don't resend this. */
837 daemon->srv_save = NULL;
e0c0ad3b 838
7fa836e1
SK
839 if (server->sfd)
840 fd = server->sfd->fd;
e0c0ad3b 841 else
3a237152 842 {
7fa836e1
SK
843 fd = -1;
844#ifdef HAVE_IPV6
845 if (server->addr.sa.sa_family == AF_INET6)
9d633048 846 {
7fa836e1
SK
847 if (new->rfd6 || (new->rfd6 = allocate_rfd(AF_INET6)))
848 fd = new->rfd6->fd;
9d633048 849 }
3a237152 850 else
3a237152 851#endif
f1668d27 852 {
7fa836e1
SK
853 if (new->rfd4 || (new->rfd4 = allocate_rfd(AF_INET)))
854 fd = new->rfd4->fd;
f1668d27 855 }
3a237152 856 }
7fa836e1
SK
857
858 if (fd != -1)
859 {
860 while (sendto(fd, (char *)header, nn, 0, &server->addr.sa, sa_len(&server->addr)) == -1 && retry_send());
861 server->queries++;
862 }
863
864 return;
3a237152 865 }
3a237152
SK
866 }
867
868 /* Ok, we reached far enough up the chain-of-trust that we can validate something.
869 Now wind back down, pulling back answers which wouldn't previously validate
7fa836e1
SK
870 and validate them with the new data. Note that if an answer needs multiple
871 keys to validate, we may find another key is needed, in which case we set off
872 down another branch of the tree. Once we get to the original answer
873 (FREC_DNSSEC_QUERY not set) and it validates, return it to the original requestor. */
0744ca66 874 while (forward->dependent)
3a237152 875 {
0744ca66
SK
876 struct frec *prev = forward->dependent;
877 free_frec(forward);
878 forward = prev;
879 forward->blocking_query = NULL; /* already gone */
880 blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
881 n = forward->stash_len;
882
883 if (status == STAT_SECURE)
3a237152 884 {
0744ca66
SK
885 if (forward->flags & FREC_DNSKEY_QUERY)
886 status = dnssec_validate_by_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
887 else if (forward->flags & FREC_DS_QUERY)
888 status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
889 else
890 status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class);
c3e0b9b6 891
0744ca66 892 if (status == STAT_NEED_DS || status == STAT_NEED_KEY)
7fa836e1 893 goto anotherkey;
3a237152
SK
894 }
895 }
5d3b87a4
SK
896
897 if (status == STAT_TRUNCATED)
0744ca66 898 header->hb3 |= HB3_TC;
5d3b87a4 899 else
7fa836e1
SK
900 {
901 char *result;
902
903 if (forward->work_counter == 0)
904 result = "ABANDONED";
905 else
906 result = (status == STAT_SECURE ? "SECURE" : (status == STAT_INSECURE ? "INSECURE" : "BOGUS"));
907
908 log_query(F_KEYTAG | F_SECSTAT, "result", NULL, result);
909 }
5d3b87a4 910
0fc2f313 911 no_cache_dnssec = 0;
5d3b87a4 912
3a237152
SK
913 if (status == STAT_SECURE)
914 cache_secure = 1;
3a237152
SK
915 else if (status == STAT_BOGUS)
916 no_cache_dnssec = 1;
0fc2f313
SK
917
918 /* restore CD bit to the value in the query */
919 if (forward->flags & FREC_CHECKING_DISABLED)
920 header->hb4 |= HB4_CD;
921 else
922 header->hb4 &= ~HB4_CD;
3a237152
SK
923 }
924#endif
8ef5ada2 925
3a237152 926 if ((nn = process_reply(header, now, server, (size_t)n, check_rebind, no_cache_dnssec, cache_secure,
ed4c0767 927 forward->flags & FREC_HAS_SUBNET, &forward->source)))
1a6bca81
SK
928 {
929 header->id = htons(forward->orig_id);
572b41eb 930 header->hb4 |= HB4_RA; /* recursion if available */
54dd393f 931 send_from(forward->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn,
50303b19 932 &forward->source, &forward->dest, forward->iface);
b8187c80 933 }
1a6bca81 934 free_frec(forward); /* cancel */
9e4abcb5 935 }
9e4abcb5 936}
44a2a316 937
1a6bca81 938
5aabfc78 939void receive_query(struct listener *listen, time_t now)
44a2a316 940{
572b41eb 941 struct dns_header *header = (struct dns_header *)daemon->packet;
44a2a316 942 union mysockaddr source_addr;
c1bb8504 943 unsigned short type;
44a2a316 944 struct all_addr dst_addr;
f6b7dc47 945 struct in_addr netmask, dst_addr_4;
cdeda28f
SK
946 size_t m;
947 ssize_t n;
3b195961
VG
948 int if_index = 0, auth_dns = 0;
949#ifdef HAVE_AUTH
950 int local_auth = 0;
951#endif
44a2a316
SK
952 struct iovec iov[1];
953 struct msghdr msg;
954 struct cmsghdr *cmptr;
44a2a316
SK
955 union {
956 struct cmsghdr align; /* this ensures alignment */
957#ifdef HAVE_IPV6
958 char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
959#endif
5e9e0efb 960#if defined(HAVE_LINUX_NETWORK)
44a2a316 961 char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
824af85b
SK
962#elif defined(IP_RECVDSTADDR) && defined(HAVE_SOLARIS_NETWORK)
963 char control[CMSG_SPACE(sizeof(struct in_addr)) +
964 CMSG_SPACE(sizeof(unsigned int))];
44a2a316
SK
965#elif defined(IP_RECVDSTADDR)
966 char control[CMSG_SPACE(sizeof(struct in_addr)) +
967 CMSG_SPACE(sizeof(struct sockaddr_dl))];
968#endif
969 } control_u;
2329bef5
SK
970#ifdef HAVE_IPV6
971 /* Can always get recvd interface for IPv6 */
972 int check_dst = !option_bool(OPT_NOWILD) || listen->family == AF_INET6;
973#else
974 int check_dst = !option_bool(OPT_NOWILD);
975#endif
976
cdeda28f
SK
977 /* packet buffer overwritten */
978 daemon->srv_save = NULL;
979
4f7b304f
SK
980 dst_addr_4.s_addr = 0;
981 netmask.s_addr = 0;
982
7e5664bd 983 if (option_bool(OPT_NOWILD) && listen->iface)
3d8df260 984 {
4f7b304f
SK
985 auth_dns = listen->iface->dns_auth;
986
987 if (listen->family == AF_INET)
988 {
989 dst_addr_4 = listen->iface->addr.in.sin_addr;
990 netmask = listen->iface->netmask;
991 }
3d8df260 992 }
4f7b304f 993
3be34541
SK
994 iov[0].iov_base = daemon->packet;
995 iov[0].iov_len = daemon->edns_pktsz;
44a2a316
SK
996
997 msg.msg_control = control_u.control;
998 msg.msg_controllen = sizeof(control_u);
999 msg.msg_flags = 0;
1000 msg.msg_name = &source_addr;
1001 msg.msg_namelen = sizeof(source_addr);
1002 msg.msg_iov = iov;
1003 msg.msg_iovlen = 1;
1004
de37951c 1005 if ((n = recvmsg(listen->fd, &msg, 0)) == -1)
3be34541 1006 return;
44a2a316 1007
572b41eb 1008 if (n < (int)sizeof(struct dns_header) ||
5e9e0efb 1009 (msg.msg_flags & MSG_TRUNC) ||
572b41eb 1010 (header->hb3 & HB3_QR))
26128d27
SK
1011 return;
1012
44a2a316
SK
1013 source_addr.sa.sa_family = listen->family;
1014#ifdef HAVE_IPV6
1015 if (listen->family == AF_INET6)
5e9e0efb 1016 source_addr.in6.sin6_flowinfo = 0;
44a2a316 1017#endif
28866e95 1018
2329bef5 1019 if (check_dst)
26128d27
SK
1020 {
1021 struct ifreq ifr;
1022
1023 if (msg.msg_controllen < sizeof(struct cmsghdr))
1024 return;
44a2a316 1025
5e9e0efb 1026#if defined(HAVE_LINUX_NETWORK)
26128d27
SK
1027 if (listen->family == AF_INET)
1028 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
c72daea8 1029 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
26128d27 1030 {
8ef5ada2
SK
1031 union {
1032 unsigned char *c;
1033 struct in_pktinfo *p;
1034 } p;
1035 p.c = CMSG_DATA(cmptr);
1036 dst_addr_4 = dst_addr.addr.addr4 = p.p->ipi_spec_dst;
1037 if_index = p.p->ipi_ifindex;
26128d27
SK
1038 }
1039#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
1040 if (listen->family == AF_INET)
44a2a316 1041 {
26128d27 1042 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
8ef5ada2
SK
1043 {
1044 union {
1045 unsigned char *c;
1046 unsigned int *i;
1047 struct in_addr *a;
1048#ifndef HAVE_SOLARIS_NETWORK
1049 struct sockaddr_dl *s;
1050#endif
1051 } p;
1052 p.c = CMSG_DATA(cmptr);
1053 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
1054 dst_addr_4 = dst_addr.addr.addr4 = *(p.a);
1055 else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
824af85b 1056#ifdef HAVE_SOLARIS_NETWORK
8ef5ada2 1057 if_index = *(p.i);
824af85b 1058#else
8ef5ada2 1059 if_index = p.s->sdl_index;
824af85b 1060#endif
8ef5ada2 1061 }
44a2a316 1062 }
44a2a316 1063#endif
26128d27 1064
44a2a316 1065#ifdef HAVE_IPV6
26128d27
SK
1066 if (listen->family == AF_INET6)
1067 {
1068 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
c72daea8 1069 if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
26128d27 1070 {
8ef5ada2
SK
1071 union {
1072 unsigned char *c;
1073 struct in6_pktinfo *p;
1074 } p;
1075 p.c = CMSG_DATA(cmptr);
1076
1077 dst_addr.addr.addr6 = p.p->ipi6_addr;
1078 if_index = p.p->ipi6_ifindex;
26128d27
SK
1079 }
1080 }
44a2a316 1081#endif
26128d27
SK
1082
1083 /* enforce available interface configuration */
1084
e25db1f2 1085 if (!indextoname(listen->fd, if_index, ifr.ifr_name))
5e9e0efb 1086 return;
832af0ba 1087
e25db1f2
SK
1088 if (!iface_check(listen->family, &dst_addr, ifr.ifr_name, &auth_dns))
1089 {
1090 if (!option_bool(OPT_CLEVERBIND))
115ac3e4 1091 enumerate_interfaces(0);
3f2873d4
SK
1092 if (!loopback_exception(listen->fd, listen->family, &dst_addr, ifr.ifr_name) &&
1093 !label_exception(if_index, listen->family, &dst_addr))
e25db1f2
SK
1094 return;
1095 }
1096
552af8b9
SK
1097 if (listen->family == AF_INET && option_bool(OPT_LOCALISE))
1098 {
1099 struct irec *iface;
1100
1101 /* get the netmask of the interface whch has the address we were sent to.
1102 This is no neccessarily the interface we arrived on. */
1103
1104 for (iface = daemon->interfaces; iface; iface = iface->next)
1105 if (iface->addr.sa.sa_family == AF_INET &&
1106 iface->addr.in.sin_addr.s_addr == dst_addr_4.s_addr)
1107 break;
1108
1109 /* interface may be new */
e25db1f2 1110 if (!iface && !option_bool(OPT_CLEVERBIND))
115ac3e4 1111 enumerate_interfaces(0);
552af8b9
SK
1112
1113 for (iface = daemon->interfaces; iface; iface = iface->next)
1114 if (iface->addr.sa.sa_family == AF_INET &&
1115 iface->addr.in.sin_addr.s_addr == dst_addr_4.s_addr)
1116 break;
1117
1118 /* If we failed, abandon localisation */
1119 if (iface)
1120 netmask = iface->netmask;
1121 else
1122 dst_addr_4.s_addr = 0;
1123 }
44a2a316
SK
1124 }
1125
cdeda28f 1126 if (extract_request(header, (size_t)n, daemon->namebuff, &type))
44a2a316 1127 {
b485ed97
SK
1128#ifdef HAVE_AUTH
1129 struct auth_zone *zone;
1130#endif
610e782a
SK
1131 char *types = querystr(auth_dns ? "auth" : "query", type);
1132
44a2a316 1133 if (listen->family == AF_INET)
3be34541 1134 log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
1a6bca81 1135 (struct all_addr *)&source_addr.in.sin_addr, types);
44a2a316
SK
1136#ifdef HAVE_IPV6
1137 else
3be34541 1138 log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
1a6bca81 1139 (struct all_addr *)&source_addr.in6.sin6_addr, types);
44a2a316 1140#endif
44a2a316 1141
b485ed97
SK
1142#ifdef HAVE_AUTH
1143 /* find queries for zones we're authoritative for, and answer them directly */
6008bdbb
SK
1144 if (!auth_dns)
1145 for (zone = daemon->auth_zones; zone; zone = zone->next)
1146 if (in_zone(zone, daemon->namebuff, NULL))
1147 {
1148 auth_dns = 1;
1149 local_auth = 1;
1150 break;
1151 }
b485ed97
SK
1152#endif
1153 }
1154
4820dce9 1155#ifdef HAVE_AUTH
4f7b304f 1156 if (auth_dns)
824af85b 1157 {
60b68069 1158 m = answer_auth(header, ((char *) header) + daemon->packet_buff_sz, (size_t)n, now, &source_addr, local_auth);
4f7b304f 1159 if (m >= 1)
b485ed97
SK
1160 {
1161 send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
1162 (char *)header, m, &source_addr, &dst_addr, if_index);
1163 daemon->auth_answer++;
1164 }
824af85b 1165 }
44a2a316 1166 else
4820dce9 1167#endif
4f7b304f 1168 {
60b68069 1169 m = answer_request(header, ((char *) header) + daemon->packet_buff_sz, (size_t)n,
4f7b304f
SK
1170 dst_addr_4, netmask, now);
1171
1172 if (m >= 1)
1173 {
1174 send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
1175 (char *)header, m, &source_addr, &dst_addr, if_index);
1176 daemon->local_answer++;
1177 }
1178 else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
1179 header, (size_t)n, now, NULL))
1180 daemon->queries_forwarded++;
1181 else
1182 daemon->local_answer++;
1183 }
44a2a316
SK
1184}
1185
7d7b7b31 1186#ifdef HAVE_DNSSEC
7fa836e1
SK
1187static int tcp_key_recurse(time_t now, int status, struct dns_header *header, size_t n,
1188 int class, char *name, char *keyname, struct server *server, int *keycount)
7d7b7b31
SK
1189{
1190 /* Recurse up the key heirarchy */
7d7b7b31 1191 int new_status;
7d7b7b31 1192
7fa836e1
SK
1193 /* limit the amount of work we do, to avoid cycling forever on loops in the DNS */
1194 if (--(*keycount) == 0)
1195 return STAT_INSECURE;
7d7b7b31 1196
7fa836e1
SK
1197 if (status == STAT_NEED_KEY)
1198 new_status = dnssec_validate_by_ds(now, header, n, name, keyname, class);
1199 else if (status == STAT_NEED_DS)
1200 new_status = dnssec_validate_ds(now, header, n, name, keyname, class);
7d7b7b31 1201 else
7fa836e1
SK
1202 new_status = dnssec_validate_reply(now, header, n, name, keyname, &class);
1203
1204 /* Can't validate because we need a key/DS whose name now in keyname.
1205 Make query for same, and recurse to validate */
1206 if (new_status == STAT_NEED_DS || new_status == STAT_NEED_KEY)
7d7b7b31 1207 {
7fa836e1
SK
1208 size_t m;
1209 unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ + sizeof(u16));
1210 unsigned char *payload = &packet[2];
1211 struct dns_header *new_header = (struct dns_header *)payload;
1212 u16 *length = (u16 *)packet;
1213 unsigned char c1, c2;
1214
1215 if (!packet)
1216 return STAT_INSECURE;
1217
1218 another_tcp_key:
1219 m = dnssec_generate_query(new_header, ((char *) new_header) + 65536, keyname, class,
1220 new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS, &server->addr);
7d7b7b31 1221
7fa836e1 1222 *length = htons(m);
7d7b7b31 1223
7fa836e1
SK
1224 if (!read_write(server->tcpfd, packet, m + sizeof(u16), 0) ||
1225 !read_write(server->tcpfd, &c1, 1, 1) ||
1226 !read_write(server->tcpfd, &c2, 1, 1) ||
1227 !read_write(server->tcpfd, payload, (c1 << 8) | c2, 1))
1228 new_status = STAT_INSECURE;
1229 else
7d7b7b31 1230 {
7fa836e1
SK
1231 m = (c1 << 8) | c2;
1232
1233 if (tcp_key_recurse(now, new_status, new_header, m, class, name, keyname, server, keycount) == STAT_SECURE)
7d7b7b31 1234 {
7fa836e1
SK
1235 /* Reached a validated record, now try again at this level.
1236 Note that we may get ANOTHER NEED_* if an answer needs more than one key.
1237 If so, go round again. */
7d7b7b31 1238
7fa836e1
SK
1239 if (status == STAT_NEED_KEY)
1240 new_status = dnssec_validate_by_ds(now, header, n, name, keyname, class);
1241 else if (status == STAT_NEED_DS)
1242 new_status = dnssec_validate_ds(now, header, n, name, keyname, class);
1243 else
1244 new_status = dnssec_validate_reply(now, header, n, name, keyname, &class);
1245
7d7b7b31 1246 if (new_status == STAT_NEED_DS || new_status == STAT_NEED_KEY)
7fa836e1 1247 goto another_tcp_key;
7d7b7b31
SK
1248 }
1249 }
7d7b7b31 1250
7fa836e1
SK
1251 free(packet);
1252 }
1253
7d7b7b31
SK
1254 return new_status;
1255}
1256#endif
1257
1258
feba5c1d
SK
1259/* The daemon forks before calling this: it should deal with one connection,
1260 blocking as neccessary, and then return. Note, need to be a bit careful
1261 about resources for debug mode, when the fork is suppressed: that's
1262 done by the caller. */
5aabfc78 1263unsigned char *tcp_request(int confd, time_t now,
4f7b304f 1264 union mysockaddr *local_addr, struct in_addr netmask, int auth_dns)
feba5c1d 1265{
28866e95
SK
1266 size_t size = 0;
1267 int norebind = 0;
3b195961 1268#ifdef HAVE_AUTH
19b16891 1269 int local_auth = 0;
3b195961 1270#endif
7d7b7b31 1271 int checking_disabled, check_subnet, no_cache_dnssec = 0, cache_secure = 0;
cdeda28f 1272 size_t m;
ee86ce68
SK
1273 unsigned short qtype;
1274 unsigned int gotname;
feba5c1d 1275 unsigned char c1, c2;
4b5ea12e
SK
1276 /* Max TCP packet + slop + size */
1277 unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ + sizeof(u16));
1278 unsigned char *payload = &packet[2];
1279 /* largest field in header is 16-bits, so this is still sufficiently aligned */
1280 struct dns_header *header = (struct dns_header *)payload;
1281 u16 *length = (u16 *)packet;
3be34541 1282 struct server *last_server;
7de060b0
SK
1283 struct in_addr dst_addr_4;
1284 union mysockaddr peer_addr;
1285 socklen_t peer_len = sizeof(union mysockaddr);
3be34541 1286
7de060b0
SK
1287 if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) == -1)
1288 return packet;
1289
feba5c1d
SK
1290 while (1)
1291 {
1292 if (!packet ||
1293 !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) ||
1294 !(size = c1 << 8 | c2) ||
4b5ea12e 1295 !read_write(confd, payload, size, 1))
feba5c1d
SK
1296 return packet;
1297
572b41eb 1298 if (size < (int)sizeof(struct dns_header))
feba5c1d
SK
1299 continue;
1300
ed4c0767
SK
1301 check_subnet = 0;
1302
28866e95 1303 /* save state of "cd" flag in query */
7d7b7b31
SK
1304 if ((checking_disabled = header->hb4 & HB4_CD))
1305 no_cache_dnssec = 1;
28866e95 1306
3be34541 1307 if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
feba5c1d 1308 {
b485ed97
SK
1309#ifdef HAVE_AUTH
1310 struct auth_zone *zone;
1311#endif
610e782a 1312 char *types = querystr(auth_dns ? "auth" : "query", qtype);
7de060b0
SK
1313
1314 if (peer_addr.sa.sa_family == AF_INET)
1315 log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
1316 (struct all_addr *)&peer_addr.in.sin_addr, types);
feba5c1d 1317#ifdef HAVE_IPV6
7de060b0
SK
1318 else
1319 log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
1320 (struct all_addr *)&peer_addr.in6.sin6_addr, types);
feba5c1d 1321#endif
b485ed97
SK
1322
1323#ifdef HAVE_AUTH
1324 /* find queries for zones we're authoritative for, and answer them directly */
6008bdbb
SK
1325 if (!auth_dns)
1326 for (zone = daemon->auth_zones; zone; zone = zone->next)
1327 if (in_zone(zone, daemon->namebuff, NULL))
1328 {
1329 auth_dns = 1;
1330 local_auth = 1;
1331 break;
1332 }
b485ed97 1333#endif
feba5c1d
SK
1334 }
1335
7de060b0
SK
1336 if (local_addr->sa.sa_family == AF_INET)
1337 dst_addr_4 = local_addr->in.sin_addr;
1338 else
1339 dst_addr_4.s_addr = 0;
1340
4820dce9 1341#ifdef HAVE_AUTH
4f7b304f 1342 if (auth_dns)
19b16891 1343 m = answer_auth(header, ((char *) header) + 65536, (size_t)size, now, &peer_addr, local_auth);
4f7b304f 1344 else
4820dce9 1345#endif
feba5c1d 1346 {
4f7b304f
SK
1347 /* m > 0 if answered from cache */
1348 m = answer_request(header, ((char *) header) + 65536, (size_t)size,
1349 dst_addr_4, netmask, now);
feba5c1d 1350
4f7b304f
SK
1351 /* Do this by steam now we're not in the select() loop */
1352 check_log_writer(NULL);
1353
1354 if (m == 0)
feba5c1d 1355 {
4f7b304f
SK
1356 unsigned int flags = 0;
1357 struct all_addr *addrp = NULL;
1358 int type = 0;
1359 char *domain = NULL;
feba5c1d 1360
4f7b304f
SK
1361 if (option_bool(OPT_ADD_MAC))
1362 size = add_mac(header, size, ((char *) header) + 65536, &peer_addr);
ed4c0767
SK
1363
1364 if (option_bool(OPT_CLIENT_SUBNET))
1365 {
1366 size_t new = add_source_addr(header, size, ((char *) header) + 65536, &peer_addr);
1367 if (size != new)
1368 {
1369 size = new;
1370 check_subnet = 1;
1371 }
1372 }
1373
4f7b304f
SK
1374 if (gotname)
1375 flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
1376
1377 if (type != 0 || option_bool(OPT_ORDER) || !daemon->last_server)
1378 last_server = daemon->servers;
1379 else
1380 last_server = daemon->last_server;
1381
1382 if (!flags && last_server)
1383 {
1384 struct server *firstsendto = NULL;
8a9be9e4 1385#ifdef HAVE_DNSSEC
703c7ff4 1386 unsigned char *newhash, hash[HASH_SIZE];
8a9be9e4
SK
1387 if ((newhash = hash_questions(header, (unsigned int)size, daemon->keyname)))
1388 memcpy(hash, newhash, HASH_SIZE);
1389#else
4f7b304f 1390 unsigned int crc = questions_crc(header, (unsigned int)size, daemon->namebuff);
8a9be9e4 1391#endif
4f7b304f
SK
1392 /* Loop round available servers until we succeed in connecting to one.
1393 Note that this code subtley ensures that consecutive queries on this connection
1394 which can go to the same server, do so. */
1395 while (1)
feba5c1d 1396 {
4f7b304f
SK
1397 if (!firstsendto)
1398 firstsendto = last_server;
1399 else
1400 {
1401 if (!(last_server = last_server->next))
1402 last_server = daemon->servers;
1403
1404 if (last_server == firstsendto)
1405 break;
1406 }
1407
1408 /* server for wrong domain */
1409 if (type != (last_server->flags & SERV_TYPE) ||
1410 (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, last_server->domain)))
7de060b0
SK
1411 continue;
1412
4f7b304f 1413 if (last_server->tcpfd == -1)
7de060b0 1414 {
4f7b304f
SK
1415 if ((last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
1416 continue;
1417
1418 if ((!local_bind(last_server->tcpfd, &last_server->source_addr, last_server->interface, 1) ||
1419 connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1))
1420 {
1421 close(last_server->tcpfd);
1422 last_server->tcpfd = -1;
1423 continue;
1424 }
1425
7d7b7b31
SK
1426#ifdef HAVE_DNSSEC
1427 if (option_bool(OPT_DNSSEC_VALID))
1428 {
1429 size = add_do_bit(header, size, ((char *) header) + 65536);
1430 header->hb4 |= HB4_CD;
1431 }
1432#endif
1433
7de060b0 1434#ifdef HAVE_CONNTRACK
4f7b304f
SK
1435 /* Copy connection mark of incoming query to outgoing connection. */
1436 if (option_bool(OPT_CONNTRACK))
1437 {
1438 unsigned int mark;
1439 struct all_addr local;
7de060b0 1440#ifdef HAVE_IPV6
4f7b304f
SK
1441 if (local_addr->sa.sa_family == AF_INET6)
1442 local.addr.addr6 = local_addr->in6.sin6_addr;
1443 else
7de060b0 1444#endif
4f7b304f
SK
1445 local.addr.addr4 = local_addr->in.sin_addr;
1446
1447 if (get_incoming_mark(&peer_addr, &local, 1, &mark))
1448 setsockopt(last_server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
1449 }
7de060b0 1450#endif
4f7b304f
SK
1451 }
1452
4b5ea12e 1453 *length = htons(size);
4f7b304f 1454
4b5ea12e 1455 if (!read_write(last_server->tcpfd, packet, size + sizeof(u16), 0) ||
4f7b304f 1456 !read_write(last_server->tcpfd, &c1, 1, 1) ||
7d7b7b31
SK
1457 !read_write(last_server->tcpfd, &c2, 1, 1) ||
1458 !read_write(last_server->tcpfd, payload, (c1 << 8) | c2, 1))
4f7b304f
SK
1459 {
1460 close(last_server->tcpfd);
1461 last_server->tcpfd = -1;
1462 continue;
1463 }
1464
1465 m = (c1 << 8) | c2;
4f7b304f
SK
1466
1467 if (!gotname)
1468 strcpy(daemon->namebuff, "query");
1469 if (last_server->addr.sa.sa_family == AF_INET)
1470 log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
1471 (struct all_addr *)&last_server->addr.in.sin_addr, NULL);
feba5c1d 1472#ifdef HAVE_IPV6
4f7b304f
SK
1473 else
1474 log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
1475 (struct all_addr *)&last_server->addr.in6.sin6_addr, NULL);
feba5c1d 1476#endif
7d7b7b31
SK
1477
1478#ifdef HAVE_DNSSEC
1479 if (option_bool(OPT_DNSSEC_VALID) && !checking_disabled)
1480 {
7fa836e1
SK
1481 int keycount = DNSSEC_WORK; /* Limit to number of DNSSEC questions, to catch loops and avoid filling cache. */
1482 int status = tcp_key_recurse(now, STAT_TRUNCATED, header, m, 0, daemon->namebuff, daemon->keyname, last_server, &keycount);
1483 char *result;
1484
1485 if (keycount == 0)
1486 result = "ABANDONED";
1487 else
1488 result = (status == STAT_SECURE ? "SECURE" : (status == STAT_INSECURE ? "INSECURE" : "BOGUS"));
7d7b7b31 1489
7fa836e1 1490 log_query(F_KEYTAG | F_SECSTAT, "result", NULL, result);
7d7b7b31 1491
7d7b7b31
SK
1492 if (status == STAT_BOGUS)
1493 no_cache_dnssec = 1;
7fa836e1 1494
7d7b7b31
SK
1495 if (status == STAT_SECURE)
1496 cache_secure = 1;
1497 }
1498#endif
1499
1500 /* restore CD bit to the value in the query */
1501 if (checking_disabled)
1502 header->hb4 |= HB4_CD;
1503 else
1504 header->hb4 &= ~HB4_CD;
4f7b304f
SK
1505
1506 /* There's no point in updating the cache, since this process will exit and
1507 lose the information after a few queries. We make this call for the alias and
1508 bogus-nxdomain side-effects. */
1509 /* If the crc of the question section doesn't match the crc we sent, then
1510 someone might be attempting to insert bogus values into the cache by
1511 sending replies containing questions and bogus answers. */
8a9be9e4
SK
1512#ifdef HAVE_DNSSEC
1513 newhash = hash_questions(header, (unsigned int)m, daemon->namebuff);
1514 if (!newhash || memcmp(hash, newhash, HASH_SIZE) != 0)
703c7ff4
SK
1515 {
1516 m = 0;
1517 break;
1518 }
8a9be9e4
SK
1519#else
1520 if (crc != questions_crc(header, (unsigned int)m, daemon->namebuff))
703c7ff4
SK
1521 {
1522 m = 0;
1523 break;
1524 }
8a9be9e4
SK
1525#endif
1526
1527 m = process_reply(header, now, last_server, (unsigned int)m,
1528 option_bool(OPT_NO_REBIND) && !norebind, no_cache_dnssec,
1529 cache_secure, check_subnet, &peer_addr);
4f7b304f
SK
1530
1531 break;
1532 }
feba5c1d 1533 }
4f7b304f
SK
1534
1535 /* In case of local answer or no connections made. */
1536 if (m == 0)
1537 m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
feba5c1d 1538 }
feba5c1d 1539 }
4f7b304f 1540
5aabfc78 1541 check_log_writer(NULL);
feba5c1d 1542
4b5ea12e
SK
1543 *length = htons(m);
1544
1545 if (m == 0 || !read_write(confd, packet, m + sizeof(u16), 0))
feba5c1d
SK
1546 return packet;
1547 }
1548}
1549
1697269c 1550static struct frec *allocate_frec(time_t now)
9e4abcb5 1551{
1697269c
SK
1552 struct frec *f;
1553
5aabfc78 1554 if ((f = (struct frec *)whine_malloc(sizeof(struct frec))))
9e4abcb5 1555 {
1a6bca81 1556 f->next = daemon->frec_list;
1697269c 1557 f->time = now;
832af0ba 1558 f->sentto = NULL;
1a6bca81 1559 f->rfd4 = NULL;
28866e95 1560 f->flags = 0;
1a6bca81
SK
1561#ifdef HAVE_IPV6
1562 f->rfd6 = NULL;
3a237152
SK
1563#endif
1564#ifdef HAVE_DNSSEC
97bc798b 1565 f->dependent = NULL;
3a237152 1566 f->blocking_query = NULL;
4619d946 1567 f->stash = NULL;
1a6bca81
SK
1568#endif
1569 daemon->frec_list = f;
1697269c 1570 }
9e4abcb5 1571
1697269c
SK
1572 return f;
1573}
9e4abcb5 1574
1a6bca81
SK
1575static struct randfd *allocate_rfd(int family)
1576{
1577 static int finger = 0;
1578 int i;
1579
1580 /* limit the number of sockets we have open to avoid starvation of
1581 (eg) TFTP. Once we have a reasonable number, randomness should be OK */
1582
1583 for (i = 0; i < RANDOM_SOCKS; i++)
9009d746 1584 if (daemon->randomsocks[i].refcount == 0)
1a6bca81 1585 {
9009d746
SK
1586 if ((daemon->randomsocks[i].fd = random_sock(family)) == -1)
1587 break;
1588
1a6bca81
SK
1589 daemon->randomsocks[i].refcount = 1;
1590 daemon->randomsocks[i].family = family;
1591 return &daemon->randomsocks[i];
1592 }
1593
9009d746 1594 /* No free ones or cannot get new socket, grab an existing one */
1a6bca81
SK
1595 for (i = 0; i < RANDOM_SOCKS; i++)
1596 {
1597 int j = (i+finger) % RANDOM_SOCKS;
9009d746
SK
1598 if (daemon->randomsocks[j].refcount != 0 &&
1599 daemon->randomsocks[j].family == family &&
1600 daemon->randomsocks[j].refcount != 0xffff)
1a6bca81
SK
1601 {
1602 finger = j;
1603 daemon->randomsocks[j].refcount++;
1604 return &daemon->randomsocks[j];
1605 }
1606 }
1607
1608 return NULL; /* doom */
1609}
1a6bca81
SK
1610static void free_frec(struct frec *f)
1611{
1612 if (f->rfd4 && --(f->rfd4->refcount) == 0)
1613 close(f->rfd4->fd);
1614
1615 f->rfd4 = NULL;
1616 f->sentto = NULL;
28866e95 1617 f->flags = 0;
1a6bca81
SK
1618
1619#ifdef HAVE_IPV6
1620 if (f->rfd6 && --(f->rfd6->refcount) == 0)
1621 close(f->rfd6->fd);
1622
1623 f->rfd6 = NULL;
1624#endif
3a237152
SK
1625
1626#ifdef HAVE_DNSSEC
1627 if (f->stash)
0fc2f313
SK
1628 {
1629 blockdata_free(f->stash);
1630 f->stash = NULL;
1631 }
3a237152
SK
1632
1633 /* Anything we're waiting on is pointless now, too */
1634 if (f->blocking_query)
1635 free_frec(f->blocking_query);
1636 f->blocking_query = NULL;
39048ad1 1637 f->dependent = NULL;
3a237152 1638#endif
1a6bca81
SK
1639}
1640
1697269c
SK
1641/* if wait==NULL return a free or older than TIMEOUT record.
1642 else return *wait zero if one available, or *wait is delay to
1a6bca81 1643 when the oldest in-use record will expire. Impose an absolute
3a237152
SK
1644 limit of 4*TIMEOUT before we wipe things (for random sockets).
1645 If force is set, always return a result, even if we have
1646 to allocate above the limit. */
1647struct frec *get_new_frec(time_t now, int *wait, int force)
1697269c 1648{
1a6bca81 1649 struct frec *f, *oldest, *target;
1697269c
SK
1650 int count;
1651
1652 if (wait)
1653 *wait = 0;
1654
1a6bca81 1655 for (f = daemon->frec_list, oldest = NULL, target = NULL, count = 0; f; f = f->next, count++)
832af0ba 1656 if (!f->sentto)
1a6bca81
SK
1657 target = f;
1658 else
1697269c 1659 {
1a6bca81
SK
1660 if (difftime(now, f->time) >= 4*TIMEOUT)
1661 {
1662 free_frec(f);
1663 target = f;
1664 }
1665
1666 if (!oldest || difftime(f->time, oldest->time) <= 0)
1667 oldest = f;
1697269c 1668 }
1a6bca81
SK
1669
1670 if (target)
1671 {
1672 target->time = now;
1673 return target;
1674 }
9e4abcb5
SK
1675
1676 /* can't find empty one, use oldest if there is one
1677 and it's older than timeout */
1697269c 1678 if (oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
9e4abcb5 1679 {
1697269c
SK
1680 /* keep stuff for twice timeout if we can by allocating a new
1681 record instead */
1682 if (difftime(now, oldest->time) < 2*TIMEOUT &&
1683 count <= daemon->ftabsize &&
1684 (f = allocate_frec(now)))
1685 return f;
1686
1687 if (!wait)
1688 {
1a6bca81 1689 free_frec(oldest);
1697269c
SK
1690 oldest->time = now;
1691 }
9e4abcb5
SK
1692 return oldest;
1693 }
1694
1697269c 1695 /* none available, calculate time 'till oldest record expires */
3a237152 1696 if (!force && count > daemon->ftabsize)
1697269c 1697 {
0da5e897
MSB
1698 static time_t last_log = 0;
1699
1697269c
SK
1700 if (oldest && wait)
1701 *wait = oldest->time + (time_t)TIMEOUT - now;
0da5e897
MSB
1702
1703 if ((int)difftime(now, last_log) > 5)
1704 {
1705 last_log = now;
1706 my_syslog(LOG_WARNING, _("Maximum number of concurrent DNS queries reached (max: %d)"), daemon->ftabsize);
1707 }
1708
9e4abcb5
SK
1709 return NULL;
1710 }
1697269c
SK
1711
1712 if (!(f = allocate_frec(now)) && wait)
1713 /* wait one second on malloc failure */
1714 *wait = 1;
9e4abcb5 1715
9e4abcb5
SK
1716 return f; /* OK if malloc fails and this is NULL */
1717}
1718
832af0ba 1719/* crc is all-ones if not known. */
8a9be9e4 1720static struct frec *lookup_frec(unsigned short id, void *hash)
9e4abcb5
SK
1721{
1722 struct frec *f;
1723
1a6bca81 1724 for(f = daemon->frec_list; f; f = f->next)
832af0ba 1725 if (f->sentto && f->new_id == id &&
8a9be9e4 1726 (!hash || memcmp(hash, f->hash, HASH_SIZE) == 0))
9e4abcb5
SK
1727 return f;
1728
1729 return NULL;
1730}
1731
1732static struct frec *lookup_frec_by_sender(unsigned short id,
fd9fa481 1733 union mysockaddr *addr,
8a9be9e4 1734 void *hash)
9e4abcb5 1735{
feba5c1d
SK
1736 struct frec *f;
1737
1a6bca81 1738 for(f = daemon->frec_list; f; f = f->next)
832af0ba 1739 if (f->sentto &&
9e4abcb5 1740 f->orig_id == id &&
8a9be9e4 1741 memcmp(hash, f->hash, HASH_SIZE) == 0 &&
9e4abcb5
SK
1742 sockaddr_isequal(&f->source, addr))
1743 return f;
1744
1745 return NULL;
1746}
1747
849a8357 1748/* A server record is going away, remove references to it */
5aabfc78 1749void server_gone(struct server *server)
849a8357
SK
1750{
1751 struct frec *f;
1752
1a6bca81 1753 for (f = daemon->frec_list; f; f = f->next)
832af0ba 1754 if (f->sentto && f->sentto == server)
1a6bca81 1755 free_frec(f);
849a8357
SK
1756
1757 if (daemon->last_server == server)
1758 daemon->last_server = NULL;
1759
1760 if (daemon->srv_save == server)
1761 daemon->srv_save = NULL;
1762}
9e4abcb5 1763
316e2730 1764/* return unique random ids. */
8a9be9e4 1765static unsigned short get_id(void)
9e4abcb5
SK
1766{
1767 unsigned short ret = 0;
832af0ba 1768
316e2730 1769 do
832af0ba 1770 ret = rand16();
8a9be9e4 1771 while (lookup_frec(ret, NULL));
832af0ba 1772
9e4abcb5
SK
1773 return ret;
1774}
1775
1776
1777
1778
1779