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