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