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