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