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