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