]>
git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/forward.c
1 /* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
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
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
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.
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/>.
19 static struct frec
*lookup_frec(unsigned short id
, void *hash
);
20 static struct frec
*lookup_frec_by_sender(unsigned short id
,
21 union mysockaddr
*addr
,
23 static unsigned short get_id(void);
24 static void free_frec(struct frec
*f
);
25 static struct randfd
*allocate_rfd(int family
);
27 /* Send a UDP packet with its source address set as "source"
28 unless nowild is true, when we just send it with the kernel default */
29 int send_from(int fd
, int nowild
, char *packet
, size_t len
,
30 union mysockaddr
*to
, struct all_addr
*source
,
36 struct cmsghdr align
; /* this ensures alignment */
37 #if defined(HAVE_LINUX_NETWORK)
38 char control
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
39 #elif defined(IP_SENDSRCADDR)
40 char control
[CMSG_SPACE(sizeof(struct in_addr
))];
43 char control6
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
47 iov
[0].iov_base
= packet
;
50 msg
.msg_control
= NULL
;
51 msg
.msg_controllen
= 0;
54 msg
.msg_namelen
= sa_len(to
);
60 struct cmsghdr
*cmptr
;
61 msg
.msg_control
= &control_u
;
62 msg
.msg_controllen
= sizeof(control_u
);
63 cmptr
= CMSG_FIRSTHDR(&msg
);
65 if (to
->sa
.sa_family
== AF_INET
)
67 #if defined(HAVE_LINUX_NETWORK)
70 p
.ipi_spec_dst
= source
->addr
.addr4
;
71 memcpy(CMSG_DATA(cmptr
), &p
, sizeof(p
));
72 msg
.msg_controllen
= cmptr
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
73 cmptr
->cmsg_level
= IPPROTO_IP
;
74 cmptr
->cmsg_type
= IP_PKTINFO
;
75 #elif defined(IP_SENDSRCADDR)
76 memcpy(CMSG_DATA(cmptr
), &(source
->addr
.addr4
), sizeof(source
->addr
.addr4
));
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
;
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
));
89 msg
.msg_controllen
= cmptr
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
90 cmptr
->cmsg_type
= daemon
->v6pktinfo
;
91 cmptr
->cmsg_level
= IPPROTO_IPV6
;
94 (void)iface
; /* eliminate warning */
98 while (sendmsg(fd
, &msg
, 0) == -1)
103 /* If interface is still in DAD, EINVAL results - ignore that. */
107 my_syslog(LOG_ERR
, _("failed to send packet: %s"), strerror(errno
));
114 static unsigned int search_servers(time_t now
, struct all_addr
**addrpp
,
115 unsigned int qtype
, char *qdomain
, int *type
, char **domain
, int *norebind
)
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. */
122 unsigned int namelen
= strlen(qdomain
);
123 unsigned int matchlen
= 0;
125 unsigned int flags
= 0;
127 for (serv
= daemon
->servers
; serv
; serv
=serv
->next
)
128 /* domain matches take priority over NODOTS matches */
129 if ((serv
->flags
& SERV_FOR_NODOTS
) && *type
!= SERV_HAS_DOMAIN
&& !strchr(qdomain
, '.') && namelen
!= 0)
131 unsigned int sflag
= serv
->addr
.sa
.sa_family
== AF_INET
? F_IPV4
: F_IPV6
;
132 *type
= SERV_FOR_NODOTS
;
133 if (serv
->flags
& SERV_NO_ADDR
)
135 else if (serv
->flags
& SERV_LITERAL_ADDRESS
)
140 if (serv
->addr
.sa
.sa_family
== AF_INET
)
141 *addrpp
= (struct all_addr
*)&serv
->addr
.in
.sin_addr
;
144 *addrpp
= (struct all_addr
*)&serv
->addr
.in6
.sin6_addr
;
147 else if (!flags
|| (flags
& F_NXDOMAIN
))
151 else if (serv
->flags
& SERV_HAS_DOMAIN
)
153 unsigned int domainlen
= strlen(serv
->domain
);
154 char *matchstart
= qdomain
+ namelen
- domainlen
;
155 if (namelen
>= domainlen
&&
156 hostname_isequal(matchstart
, serv
->domain
) &&
157 (domainlen
== 0 || namelen
== domainlen
|| *(matchstart
-1) == '.' ))
159 if (serv
->flags
& SERV_NO_REBIND
)
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
)
169 if ((serv
->flags
& SERV_LITERAL_ADDRESS
))
171 if (!(sflag
& qtype
) && flags
== 0)
176 if (flags
& (F_IPV4
| F_IPV6
))
181 if (domainlen
>= matchlen
)
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
)
188 else if (serv
->flags
& SERV_LITERAL_ADDRESS
)
193 if (serv
->addr
.sa
.sa_family
== AF_INET
)
194 *addrpp
= (struct all_addr
*)&serv
->addr
.in
.sin_addr
;
197 *addrpp
= (struct all_addr
*)&serv
->addr
.in6
.sin6_addr
;
200 else if (!flags
|| (flags
& F_NXDOMAIN
))
210 if (flags
== 0 && !(qtype
& F_QUERY
) &&
211 option_bool(OPT_NODOTS_LOCAL
) && !strchr(qdomain
, '.') && namelen
!= 0)
212 /* don't forward A or AAAA queries for simple names, except the empty name */
215 if (flags
== F_NXDOMAIN
&& check_for_local_domain(qdomain
, now
))
222 if (flags
== F_NXDOMAIN
|| flags
== F_NOERR
)
223 logflags
= F_NEG
| qtype
;
225 log_query(logflags
| flags
| F_CONFIG
| F_FORWARD
, qdomain
, *addrpp
, NULL
);
227 else if ((*type
) & SERV_USE_RESOLV
)
229 *type
= 0; /* use normal servers for this domain */
235 static int forward_query(int udpfd
, union mysockaddr
*udpaddr
,
236 struct all_addr
*dst_addr
, unsigned int dst_iface
,
237 struct dns_header
*header
, size_t plen
, time_t now
, struct frec
*forward
)
240 int type
= 0, norebind
= 0;
241 struct all_addr
*addrp
= NULL
;
242 unsigned int flags
= 0;
243 struct server
*start
= NULL
;
245 void *hash
= hash_questions(header
, plen
, daemon
->namebuff
);
247 unsigned int crc
= questions_crc(header
, plen
, daemon
->namebuff
);
250 unsigned int gotname
= extract_request(header
, plen
, daemon
->namebuff
, NULL
);
252 /* may be no servers available. */
253 if (!daemon
->servers
)
255 else if (forward
|| (hash
&& (forward
= lookup_frec_by_sender(ntohs(header
->id
), udpaddr
, hash
))))
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
)
264 while (forward
->blocking_query
)
265 forward
= forward
->blocking_query
;
267 blockdata_retrieve(forward
->stash
, forward
->stash_len
, (void *)header
);
268 plen
= forward
->stash_len
;
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");
274 log_query(F_DNSSEC
| F_IPV6
, "retry", (struct all_addr
*)&forward
->sentto
->addr
.in6
.sin6_addr
, "dnssec");
277 if (forward
->sentto
->sfd
)
278 fd
= forward
->sentto
->sfd
->fd
;
282 if (forward
->sentto
->addr
.sa
.sa_family
== AF_INET6
)
283 fd
= forward
->rfd6
->fd
;
286 fd
= forward
->rfd4
->fd
;
289 while (sendto(fd
, (char *)header
, plen
, 0,
290 &forward
->sentto
->addr
.sa
,
291 sa_len(&forward
->sentto
->addr
)) == -1 && retry_send());
297 /* retry on existing query, send to all available servers */
298 domain
= forward
->sentto
->domain
;
299 forward
->sentto
->failed_queries
++;
300 if (!option_bool(OPT_ORDER
))
302 forward
->forwardall
= 1;
303 daemon
->last_server
= NULL
;
305 type
= forward
->sentto
->flags
& SERV_TYPE
;
306 if (!(start
= forward
->sentto
->next
))
307 start
= daemon
->servers
; /* at end of list, recycle */
308 header
->id
= htons(forward
->new_id
);
313 flags
= search_servers(now
, &addrp
, gotname
, daemon
->namebuff
, &type
, &domain
, &norebind
);
315 if (!flags
&& !(forward
= get_new_frec(now
, NULL
, 0)))
316 /* table full - server failure. */
321 forward
->source
= *udpaddr
;
322 forward
->dest
= *dst_addr
;
323 forward
->iface
= dst_iface
;
324 forward
->orig_id
= ntohs(header
->id
);
325 forward
->new_id
= get_id();
327 memcpy(forward
->hash
, hash
, HASH_SIZE
);
328 forward
->forwardall
= 0;
331 forward
->flags
|= FREC_NOREBIND
;
332 if (header
->hb4
& HB4_CD
)
333 forward
->flags
|= FREC_CHECKING_DISABLED
;
335 header
->id
= htons(forward
->new_id
);
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,
340 otherwise, use the one last known to work. */
344 if (option_bool(OPT_ORDER
))
345 start
= daemon
->servers
;
346 else if (!(start
= daemon
->last_server
) ||
347 daemon
->forwardcount
++ > FORWARD_TEST
||
348 difftime(now
, daemon
->forwardtime
) > FORWARD_TIME
)
350 start
= daemon
->servers
;
351 forward
->forwardall
= 1;
352 daemon
->forwardcount
= 0;
353 daemon
->forwardtime
= now
;
358 start
= daemon
->servers
;
359 if (!option_bool(OPT_ORDER
))
360 forward
->forwardall
= 1;
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) */
369 if (!flags
&& forward
)
371 struct server
*firstsentto
= start
;
374 if (option_bool(OPT_ADD_MAC
))
375 plen
= add_mac(header
, plen
, ((char *) header
) + daemon
->packet_buff_sz
, &forward
->source
);
377 if (option_bool(OPT_CLIENT_SUBNET
))
379 size_t new = add_source_addr(header
, plen
, ((char *) header
) + daemon
->packet_buff_sz
, &forward
->source
);
383 forward
->flags
|= FREC_HAS_SUBNET
;
388 if (option_bool(OPT_DNSSEC_VALID
))
390 plen
= add_do_bit(header
, plen
, ((char *) header
) + daemon
->packet_buff_sz
);
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
;
400 /* only send to servers dealing with our domain.
401 domain may be NULL, in which case server->domain
402 must be NULL also. */
404 if (type
== (start
->flags
& SERV_TYPE
) &&
405 (type
!= SERV_HAS_DOMAIN
|| hostname_isequal(domain
, start
->domain
)) &&
406 !(start
->flags
& SERV_LITERAL_ADDRESS
))
410 /* find server socket to use, may need to get random one. */
416 if (start
->addr
.sa
.sa_family
== AF_INET6
)
418 if (!forward
->rfd6
&&
419 !(forward
->rfd6
= allocate_rfd(AF_INET6
)))
421 daemon
->rfd_save
= forward
->rfd6
;
422 fd
= forward
->rfd6
->fd
;
427 if (!forward
->rfd4
&&
428 !(forward
->rfd4
= allocate_rfd(AF_INET
)))
430 daemon
->rfd_save
= forward
->rfd4
;
431 fd
= forward
->rfd4
->fd
;
434 #ifdef HAVE_CONNTRACK
435 /* Copy connection mark of incoming query to outgoing connection. */
436 if (option_bool(OPT_CONNTRACK
))
439 if (get_incoming_mark(&forward
->source
, &forward
->dest
, 0, &mark
))
440 setsockopt(fd
, SOL_SOCKET
, SO_MARK
, &mark
, sizeof(unsigned int));
445 if (sendto(fd
, (char *)header
, plen
, 0,
447 sa_len(&start
->addr
)) == -1)
454 /* Keep info in case we want to re-send this packet */
455 daemon
->srv_save
= start
;
456 daemon
->packet_len
= plen
;
459 strcpy(daemon
->namebuff
, "query");
460 if (start
->addr
.sa
.sa_family
== AF_INET
)
461 log_query(F_SERVER
| F_IPV4
| F_FORWARD
, daemon
->namebuff
,
462 (struct all_addr
*)&start
->addr
.in
.sin_addr
, NULL
);
465 log_query(F_SERVER
| F_IPV6
| F_FORWARD
, daemon
->namebuff
,
466 (struct all_addr
*)&start
->addr
.in6
.sin6_addr
, NULL
);
470 forward
->sentto
= start
;
471 if (!forward
->forwardall
)
473 forward
->forwardall
++;
477 if (!(start
= start
->next
))
478 start
= daemon
->servers
;
480 if (start
== firstsentto
)
487 /* could not send on, prepare to return */
488 header
->id
= htons(forward
->orig_id
);
489 free_frec(forward
); /* cancel */
492 /* could not send on, return empty answer or address if known for whole domain */
495 plen
= setup_reply(header
, plen
, addrp
, flags
, daemon
->local_ttl
);
496 send_from(udpfd
, option_bool(OPT_NOWILD
) || option_bool(OPT_CLEVERBIND
), (char *)header
, plen
, udpaddr
, dst_addr
, dst_iface
);
502 static size_t process_reply(struct dns_header
*header
, time_t now
, struct server
*server
, size_t n
, int check_rebind
,
503 int no_cache
, int cache_secure
, int check_subnet
, union mysockaddr
*query_source
)
505 unsigned char *pheader
, *sizep
;
507 int munged
= 0, is_sign
;
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
)
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) == '.' ) &&
521 domainlen
>= matchlen
)
523 matchlen
= domainlen
;
524 sets
= ipset_pos
->sets
;
529 /* If upstream is advertising a larger UDP packet size
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. */
533 if ((pheader
= find_pseudoheader(header
, n
, &plen
, &sizep
, &is_sign
)))
537 unsigned short udpsz
;
538 unsigned char *psave
= sizep
;
540 GETSHORT(udpsz
, sizep
);
541 if (udpsz
> daemon
->edns_pktsz
)
542 PUTSHORT(daemon
->edns_pktsz
, psave
);
545 if (check_subnet
&& !check_source(header
, plen
, pheader
, query_source
))
547 my_syslog(LOG_WARNING
, _("discarding DNS reply: subnet option mismatch"));
552 /* RFC 4035 sect 4.6 para 3 */
553 if (!is_sign
&& !option_bool(OPT_DNSSEC_PROXY
))
554 header
->hb4
&= ~HB4_AD
;
556 if (OPCODE(header
) != QUERY
|| (RCODE(header
) != NOERROR
&& RCODE(header
) != NXDOMAIN
))
559 /* Complain loudly if the upstream server is non-recursive. */
560 if (!(header
->hb4
& HB4_RA
) && RCODE(header
) == NOERROR
&& ntohs(header
->ancount
) == 0 &&
561 server
&& !(server
->flags
& SERV_WARNED_RECURSIVE
))
563 prettyprint_addr(&server
->addr
, daemon
->namebuff
);
564 my_syslog(LOG_WARNING
, _("nameserver %s refused to do a recursive query"), daemon
->namebuff
);
565 if (!option_bool(OPT_LOG
))
566 server
->flags
|= SERV_WARNED_RECURSIVE
;
569 if (daemon
->bogus_addr
&& RCODE(header
) != NXDOMAIN
&&
570 check_for_bogus_wildcard(header
, n
, daemon
->namebuff
, daemon
->bogus_addr
, now
))
573 SET_RCODE(header
, NXDOMAIN
);
574 header
->hb3
&= ~HB3_AA
;
581 if (RCODE(header
) == NXDOMAIN
&&
582 extract_request(header
, n
, daemon
->namebuff
, NULL
) &&
583 check_for_local_domain(daemon
->namebuff
, now
))
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 */
589 header
->hb3
|= HB3_AA
;
590 SET_RCODE(header
, NOERROR
);
594 if (extract_addresses(header
, n
, daemon
->namebuff
, now
, sets
, is_sign
, check_rebind
, no_cache
, cache_secure
, &doctored
))
596 my_syslog(LOG_WARNING
, _("possible DNS-rebind attack detected: %s"), daemon
->namebuff
);
606 if (no_cache
&& !(header
->hb4
& HB4_CD
))
608 if (!option_bool(OPT_DNSSEC_DEBUG
))
610 /* Bogus reply, turn into SERVFAIL */
611 SET_RCODE(header
, SERVFAIL
);
616 if (option_bool(OPT_DNSSEC_VALID
))
617 header
->hb4
&= ~HB4_AD
;
619 if (!(header
->hb4
& HB4_CD
) && cache_secure
)
620 header
->hb4
|= HB4_AD
;
623 /* do this after extract_addresses. Ensure NODATA reply and remove
628 header
->ancount
= htons(0);
629 header
->nscount
= htons(0);
630 header
->arcount
= htons(0);
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
);
639 /* sets new last_server */
640 void reply_query(int fd
, int family
, time_t now
)
642 /* packet from peer server, extract data for cache, and send to
643 original requester */
644 struct dns_header
*header
;
645 union mysockaddr serveraddr
;
646 struct frec
*forward
;
647 socklen_t addrlen
= sizeof(serveraddr
);
648 ssize_t n
= recvfrom(fd
, daemon
->packet
, daemon
->packet_buff_sz
, 0, &serveraddr
.sa
, &addrlen
);
650 struct server
*server
;
656 /* packet buffer overwritten */
657 daemon
->srv_save
= NULL
;
659 /* Determine the address of the server replying so that we can mark that as good */
660 serveraddr
.sa
.sa_family
= family
;
662 if (serveraddr
.sa
.sa_family
== AF_INET6
)
663 serveraddr
.in6
.sin6_flowinfo
= 0;
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
))
672 header
= (struct dns_header
*)daemon
->packet
;
675 hash
= hash_questions(header
, n
, daemon
->namebuff
);
678 crc
= questions_crc(header
, n
, daemon
->namebuff
);
682 n
< (int)sizeof(struct dns_header
) || !(header
->hb3
& HB3_QR
) ||
683 !(forward
= lookup_frec(ntohs(header
->id
), hash
)))
686 if ((RCODE(header
) == SERVFAIL
|| RCODE(header
) == REFUSED
) &&
687 !option_bool(OPT_ORDER
) &&
688 forward
->forwardall
== 0)
689 /* for broken servers, attempt to send to another one. */
691 unsigned char *pheader
;
695 /* recreate query from reply */
696 pheader
= find_pseudoheader(header
, (size_t)n
, &plen
, NULL
, &is_sign
);
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
)))
704 header
->hb3
&= ~(HB3_QR
| HB3_TC
);
705 forward_query(-1, NULL
, NULL
, 0, header
, nn
, now
, forward
);
711 server
= forward
->sentto
;
713 if ((forward
->sentto
->flags
& SERV_TYPE
) == 0)
715 if (RCODE(header
) == SERVFAIL
|| RCODE(header
) == REFUSED
)
719 struct server
*last_server
;
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
))
726 server
= last_server
;
730 if (!option_bool(OPT_ALL_SERVERS
))
731 daemon
->last_server
= server
;
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 ||
739 (RCODE(header
) != REFUSED
&& RCODE(header
) != SERVFAIL
))
741 int check_rebind
= 0, no_cache_dnssec
= 0, cache_secure
= 0;
743 if (option_bool(OPT_NO_REBIND
))
744 check_rebind
= !(forward
->flags
& FREC_NOREBIND
);
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
))
752 if (option_bool(OPT_DNSSEC_VALID
) && !(forward
->flags
& FREC_CHECKING_DISABLED
))
756 /* We've had a reply already, which we're validating. Ignore this duplicate */
757 if (forward
->blocking_query
)
760 if (header
->hb3
& HB3_TC
)
762 /* Truncated answer can't be validated.
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.
767 status
= STAT_TRUNCATED
;
769 else if (forward
->flags
& FREC_DNSKEY_QUERY
)
770 status
= dnssec_validate_by_ds(now
, header
, n
, daemon
->namebuff
, daemon
->keyname
, forward
->class);
771 else if (forward
->flags
& FREC_DS_QUERY
)
772 status
= dnssec_validate_ds(now
, header
, n
, daemon
->namebuff
, daemon
->keyname
, forward
->class);
774 status
= dnssec_validate_reply(now
, header
, n
, daemon
->namebuff
, daemon
->keyname
, &forward
->class);
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
)
782 if ((new = get_new_frec(now
, NULL
, 1)))
784 struct frec
*next
= new->next
;
785 *new = *forward
; /* copy everything, then overwrite */
787 new->blocking_query
= NULL
;
792 new->flags
&= ~(FREC_DNSKEY_QUERY
| FREC_DS_QUERY
);
794 /* Free any saved query */
796 blockdata_free(forward
->stash
);
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 */
805 forward
->stash_len
= n
;
807 new->dependent
= forward
; /* to find query awaiting new one. */
808 forward
->blocking_query
= new; /* for garbage cleaning */
809 /* validate routines leave name of required record in daemon->keyname */
810 if (status
== STAT_NEED_KEY
)
812 new->flags
|= FREC_DNSKEY_QUERY
;
813 nn
= dnssec_generate_query(header
, ((char *) header
) + daemon
->packet_buff_sz
,
814 daemon
->keyname
, forward
->class, T_DNSKEY
, &server
->addr
);
818 new->flags
|= FREC_DS_QUERY
;
819 nn
= dnssec_generate_query(header
,((char *) header
) + daemon
->packet_buff_sz
,
820 daemon
->keyname
, forward
->class, T_DS
, &server
->addr
);
822 if ((hash
= hash_questions(header
, nn
, daemon
->namebuff
)))
823 memcpy(new->hash
, hash
, HASH_SIZE
);
824 new->new_id
= get_id();
825 header
->id
= htons(new->new_id
);
826 /* Save query for retransmission */
827 new->stash
= blockdata_alloc((char *)header
, nn
);
830 /* Don't resend this. */
831 daemon
->srv_save
= NULL
;
834 fd
= server
->sfd
->fd
;
839 if (server
->addr
.sa
.sa_family
== AF_INET6
)
841 if (new->rfd6
|| (new->rfd6
= allocate_rfd(AF_INET6
)))
847 if (new->rfd4
|| (new->rfd4
= allocate_rfd(AF_INET
)))
854 while (sendto(fd
, (char *)header
, nn
, 0, &server
->addr
.sa
, sa_len(&server
->addr
)) == -1 && retry_send());
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. */
868 while (forward
->dependent
)
870 struct frec
*prev
= forward
->dependent
;
873 forward
->blocking_query
= NULL
; /* already gone */
874 blockdata_retrieve(forward
->stash
, forward
->stash_len
, (void *)header
);
875 n
= forward
->stash_len
;
877 if (status
== STAT_SECURE
)
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);
884 status
= dnssec_validate_reply(now
, header
, n
, daemon
->namebuff
, daemon
->keyname
, &forward
->class);
886 if (status
== STAT_NEED_DS
|| status
== STAT_NEED_KEY
)
888 my_syslog(LOG_ERR
, _("Unexpected missing data for DNSSEC validation"));
889 status
= STAT_INSECURE
;
894 if (status
== STAT_TRUNCATED
)
895 header
->hb3
|= HB3_TC
;
897 log_query(F_KEYTAG
| F_SECSTAT
, "result", NULL
,
898 status
== STAT_SECURE
? "SECURE" : (status
== STAT_INSECURE
? "INSECURE" : "BOGUS"));
902 if (status
== STAT_SECURE
)
904 else if (status
== STAT_BOGUS
)
907 /* restore CD bit to the value in the query */
908 if (forward
->flags
& FREC_CHECKING_DISABLED
)
909 header
->hb4
|= HB4_CD
;
911 header
->hb4
&= ~HB4_CD
;
915 if ((nn
= process_reply(header
, now
, server
, (size_t)n
, check_rebind
, no_cache_dnssec
, cache_secure
,
916 forward
->flags
& FREC_HAS_SUBNET
, &forward
->source
)))
918 header
->id
= htons(forward
->orig_id
);
919 header
->hb4
|= HB4_RA
; /* recursion if available */
920 send_from(forward
->fd
, option_bool(OPT_NOWILD
) || option_bool (OPT_CLEVERBIND
), daemon
->packet
, nn
,
921 &forward
->source
, &forward
->dest
, forward
->iface
);
923 free_frec(forward
); /* cancel */
928 void receive_query(struct listener
*listen
, time_t now
)
930 struct dns_header
*header
= (struct dns_header
*)daemon
->packet
;
931 union mysockaddr source_addr
;
933 struct all_addr dst_addr
;
934 struct in_addr netmask
, dst_addr_4
;
937 int if_index
= 0, auth_dns
= 0;
943 struct cmsghdr
*cmptr
;
945 struct cmsghdr align
; /* this ensures alignment */
947 char control6
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
949 #if defined(HAVE_LINUX_NETWORK)
950 char control
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
951 #elif defined(IP_RECVDSTADDR) && defined(HAVE_SOLARIS_NETWORK)
952 char control
[CMSG_SPACE(sizeof(struct in_addr
)) +
953 CMSG_SPACE(sizeof(unsigned int))];
954 #elif defined(IP_RECVDSTADDR)
955 char control
[CMSG_SPACE(sizeof(struct in_addr
)) +
956 CMSG_SPACE(sizeof(struct sockaddr_dl
))];
960 /* Can always get recvd interface for IPv6 */
961 int check_dst
= !option_bool(OPT_NOWILD
) || listen
->family
== AF_INET6
;
963 int check_dst
= !option_bool(OPT_NOWILD
);
966 /* packet buffer overwritten */
967 daemon
->srv_save
= NULL
;
969 dst_addr_4
.s_addr
= 0;
972 if (option_bool(OPT_NOWILD
) && listen
->iface
)
974 auth_dns
= listen
->iface
->dns_auth
;
976 if (listen
->family
== AF_INET
)
978 dst_addr_4
= listen
->iface
->addr
.in
.sin_addr
;
979 netmask
= listen
->iface
->netmask
;
983 iov
[0].iov_base
= daemon
->packet
;
984 iov
[0].iov_len
= daemon
->edns_pktsz
;
986 msg
.msg_control
= control_u
.control
;
987 msg
.msg_controllen
= sizeof(control_u
);
989 msg
.msg_name
= &source_addr
;
990 msg
.msg_namelen
= sizeof(source_addr
);
994 if ((n
= recvmsg(listen
->fd
, &msg
, 0)) == -1)
997 if (n
< (int)sizeof(struct dns_header
) ||
998 (msg
.msg_flags
& MSG_TRUNC
) ||
999 (header
->hb3
& HB3_QR
))
1002 source_addr
.sa
.sa_family
= listen
->family
;
1004 if (listen
->family
== AF_INET6
)
1005 source_addr
.in6
.sin6_flowinfo
= 0;
1012 if (msg
.msg_controllen
< sizeof(struct cmsghdr
))
1015 #if defined(HAVE_LINUX_NETWORK)
1016 if (listen
->family
== AF_INET
)
1017 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
1018 if (cmptr
->cmsg_level
== IPPROTO_IP
&& cmptr
->cmsg_type
== IP_PKTINFO
)
1022 struct in_pktinfo
*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
;
1028 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
1029 if (listen
->family
== AF_INET
)
1031 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
1037 #ifndef HAVE_SOLARIS_NETWORK
1038 struct sockaddr_dl
*s
;
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
)
1045 #ifdef HAVE_SOLARIS_NETWORK
1048 if_index
= p
.s
->sdl_index
;
1055 if (listen
->family
== AF_INET6
)
1057 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
1058 if (cmptr
->cmsg_level
== IPPROTO_IPV6
&& cmptr
->cmsg_type
== daemon
->v6pktinfo
)
1062 struct in6_pktinfo
*p
;
1064 p
.c
= CMSG_DATA(cmptr
);
1066 dst_addr
.addr
.addr6
= p
.p
->ipi6_addr
;
1067 if_index
= p
.p
->ipi6_ifindex
;
1072 /* enforce available interface configuration */
1074 if (!indextoname(listen
->fd
, if_index
, ifr
.ifr_name
))
1077 if (!iface_check(listen
->family
, &dst_addr
, ifr
.ifr_name
, &auth_dns
))
1079 if (!option_bool(OPT_CLEVERBIND
))
1080 enumerate_interfaces(0);
1081 if (!loopback_exception(listen
->fd
, listen
->family
, &dst_addr
, ifr
.ifr_name
) &&
1082 !label_exception(if_index
, listen
->family
, &dst_addr
))
1086 if (listen
->family
== AF_INET
&& option_bool(OPT_LOCALISE
))
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. */
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
)
1098 /* interface may be new */
1099 if (!iface
&& !option_bool(OPT_CLEVERBIND
))
1100 enumerate_interfaces(0);
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
)
1107 /* If we failed, abandon localisation */
1109 netmask
= iface
->netmask
;
1111 dst_addr_4
.s_addr
= 0;
1115 if (extract_request(header
, (size_t)n
, daemon
->namebuff
, &type
))
1118 struct auth_zone
*zone
;
1120 char *types
= querystr(auth_dns
? "auth" : "query", type
);
1122 if (listen
->family
== AF_INET
)
1123 log_query(F_QUERY
| F_IPV4
| F_FORWARD
, daemon
->namebuff
,
1124 (struct all_addr
*)&source_addr
.in
.sin_addr
, types
);
1127 log_query(F_QUERY
| F_IPV6
| F_FORWARD
, daemon
->namebuff
,
1128 (struct all_addr
*)&source_addr
.in6
.sin6_addr
, types
);
1132 /* find queries for zones we're authoritative for, and answer them directly */
1134 for (zone
= daemon
->auth_zones
; zone
; zone
= zone
->next
)
1135 if (in_zone(zone
, daemon
->namebuff
, NULL
))
1147 m
= answer_auth(header
, ((char *) header
) + daemon
->packet_buff_sz
, (size_t)n
, now
, &source_addr
, local_auth
);
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
++;
1158 m
= answer_request(header
, ((char *) header
) + daemon
->packet_buff_sz
, (size_t)n
,
1159 dst_addr_4
, netmask
, now
);
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
++;
1167 else if (forward_query(listen
->fd
, &source_addr
, &dst_addr
, if_index
,
1168 header
, (size_t)n
, now
, NULL
))
1169 daemon
->queries_forwarded
++;
1171 daemon
->local_answer
++;
1176 static int tcp_key_recurse(time_t now
, int status
, int class, char *keyname
, struct server
*server
)
1178 /* Recurse up the key heirarchy */
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
;
1185 unsigned char c1
, c2
;
1187 n
= dnssec_generate_query(header
, ((char *) header
) + 65536, keyname
, class,
1188 status
== STAT_NEED_KEY
? T_DNSKEY
: T_DS
, &server
->addr
);
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))
1197 close(server
->tcpfd
);
1199 new_status
= STAT_INSECURE
;
1205 if (status
== STAT_NEED_KEY
)
1206 new_status
= dnssec_validate_by_ds(now
, header
, n
, daemon
->namebuff
, daemon
->keyname
, class);
1208 new_status
= dnssec_validate_ds(now
, header
, n
, daemon
->namebuff
, daemon
->keyname
, class);
1210 if (new_status
== STAT_NEED_DS
|| new_status
== STAT_NEED_KEY
)
1212 if ((new_status
= tcp_key_recurse(now
, new_status
, class, daemon
->keyname
, server
) == STAT_SECURE
))
1214 if (status
== STAT_NEED_KEY
)
1215 new_status
= dnssec_validate_by_ds(now
, header
, n
, daemon
->namebuff
, daemon
->keyname
, class);
1217 new_status
= dnssec_validate_ds(now
, header
, n
, daemon
->namebuff
, daemon
->keyname
, class);
1219 if (new_status
== STAT_NEED_DS
|| new_status
== STAT_NEED_KEY
)
1221 my_syslog(LOG_ERR
, _("Unexpected missing data for DNSSEC validation"));
1222 status
= STAT_INSECURE
;
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. */
1239 unsigned char *tcp_request(int confd
, time_t now
,
1240 union mysockaddr
*local_addr
, struct in_addr netmask
, int auth_dns
)
1247 int checking_disabled
, check_subnet
, no_cache_dnssec
= 0, cache_secure
= 0;
1249 unsigned short qtype
;
1250 unsigned int gotname
;
1251 unsigned char c1
, c2
;
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
;
1258 struct server
*last_server
;
1259 struct in_addr dst_addr_4
;
1260 union mysockaddr peer_addr
;
1261 socklen_t peer_len
= sizeof(union mysockaddr
);
1263 if (getpeername(confd
, (struct sockaddr
*)&peer_addr
, &peer_len
) == -1)
1269 !read_write(confd
, &c1
, 1, 1) || !read_write(confd
, &c2
, 1, 1) ||
1270 !(size
= c1
<< 8 | c2
) ||
1271 !read_write(confd
, payload
, size
, 1))
1274 if (size
< (int)sizeof(struct dns_header
))
1279 /* save state of "cd" flag in query */
1280 if ((checking_disabled
= header
->hb4
& HB4_CD
))
1281 no_cache_dnssec
= 1;
1283 if ((gotname
= extract_request(header
, (unsigned int)size
, daemon
->namebuff
, &qtype
)))
1286 struct auth_zone
*zone
;
1288 char *types
= querystr(auth_dns
? "auth" : "query", qtype
);
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
);
1295 log_query(F_QUERY
| F_IPV6
| F_FORWARD
, daemon
->namebuff
,
1296 (struct all_addr
*)&peer_addr
.in6
.sin6_addr
, types
);
1300 /* find queries for zones we're authoritative for, and answer them directly */
1302 for (zone
= daemon
->auth_zones
; zone
; zone
= zone
->next
)
1303 if (in_zone(zone
, daemon
->namebuff
, NULL
))
1312 if (local_addr
->sa
.sa_family
== AF_INET
)
1313 dst_addr_4
= local_addr
->in
.sin_addr
;
1315 dst_addr_4
.s_addr
= 0;
1319 m
= answer_auth(header
, ((char *) header
) + 65536, (size_t)size
, now
, &peer_addr
, local_auth
);
1323 /* m > 0 if answered from cache */
1324 m
= answer_request(header
, ((char *) header
) + 65536, (size_t)size
,
1325 dst_addr_4
, netmask
, now
);
1327 /* Do this by steam now we're not in the select() loop */
1328 check_log_writer(NULL
);
1332 unsigned int flags
= 0;
1333 struct all_addr
*addrp
= NULL
;
1335 char *domain
= NULL
;
1337 if (option_bool(OPT_ADD_MAC
))
1338 size
= add_mac(header
, size
, ((char *) header
) + 65536, &peer_addr
);
1340 if (option_bool(OPT_CLIENT_SUBNET
))
1342 size_t new = add_source_addr(header
, size
, ((char *) header
) + 65536, &peer_addr
);
1351 flags
= search_servers(now
, &addrp
, gotname
, daemon
->namebuff
, &type
, &domain
, &norebind
);
1353 if (type
!= 0 || option_bool(OPT_ORDER
) || !daemon
->last_server
)
1354 last_server
= daemon
->servers
;
1356 last_server
= daemon
->last_server
;
1358 if (!flags
&& last_server
)
1360 struct server
*firstsendto
= NULL
;
1362 unsigned char *newhash
, hash
[HASH_SIZE
];
1363 if ((newhash
= hash_questions(header
, (unsigned int)size
, daemon
->keyname
)))
1364 memcpy(hash
, newhash
, HASH_SIZE
);
1366 unsigned int crc
= questions_crc(header
, (unsigned int)size
, daemon
->namebuff
);
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. */
1374 firstsendto
= last_server
;
1377 if (!(last_server
= last_server
->next
))
1378 last_server
= daemon
->servers
;
1380 if (last_server
== firstsendto
)
1384 /* server for wrong domain */
1385 if (type
!= (last_server
->flags
& SERV_TYPE
) ||
1386 (type
== SERV_HAS_DOMAIN
&& !hostname_isequal(domain
, last_server
->domain
)))
1389 if (last_server
->tcpfd
== -1)
1391 if ((last_server
->tcpfd
= socket(last_server
->addr
.sa
.sa_family
, SOCK_STREAM
, 0)) == -1)
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))
1397 close(last_server
->tcpfd
);
1398 last_server
->tcpfd
= -1;
1403 if (option_bool(OPT_DNSSEC_VALID
))
1405 size
= add_do_bit(header
, size
, ((char *) header
) + 65536);
1406 header
->hb4
|= HB4_CD
;
1410 #ifdef HAVE_CONNTRACK
1411 /* Copy connection mark of incoming query to outgoing connection. */
1412 if (option_bool(OPT_CONNTRACK
))
1415 struct all_addr local
;
1417 if (local_addr
->sa
.sa_family
== AF_INET6
)
1418 local
.addr
.addr6
= local_addr
->in6
.sin6_addr
;
1421 local
.addr
.addr4
= local_addr
->in
.sin_addr
;
1423 if (get_incoming_mark(&peer_addr
, &local
, 1, &mark
))
1424 setsockopt(last_server
->tcpfd
, SOL_SOCKET
, SO_MARK
, &mark
, sizeof(unsigned int));
1429 *length
= htons(size
);
1431 if (!read_write(last_server
->tcpfd
, packet
, size
+ sizeof(u16
), 0) ||
1432 !read_write(last_server
->tcpfd
, &c1
, 1, 1) ||
1433 !read_write(last_server
->tcpfd
, &c2
, 1, 1) ||
1434 !read_write(last_server
->tcpfd
, payload
, (c1
<< 8) | c2
, 1))
1436 close(last_server
->tcpfd
);
1437 last_server
->tcpfd
= -1;
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
);
1450 log_query(F_SERVER
| F_IPV6
| F_FORWARD
, daemon
->namebuff
,
1451 (struct all_addr
*)&last_server
->addr
.in6
.sin6_addr
, NULL
);
1455 if (option_bool(OPT_DNSSEC_VALID
) && !checking_disabled
)
1459 status
= dnssec_validate_reply(now
, header
, m
, daemon
->namebuff
, daemon
->keyname
, &class);
1461 if (status
== STAT_NEED_DS
|| status
== STAT_NEED_KEY
)
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);
1467 log_query(F_KEYTAG
| F_SECSTAT
, "result", NULL
,
1468 status
== STAT_SECURE
? "SECURE" : (status
== STAT_INSECURE
? "INSECURE" : "BOGUS"));
1470 if (status
== STAT_BOGUS
)
1471 no_cache_dnssec
= 1;
1473 if (status
== STAT_SECURE
)
1478 /* restore CD bit to the value in the query */
1479 if (checking_disabled
)
1480 header
->hb4
|= HB4_CD
;
1482 header
->hb4
&= ~HB4_CD
;
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. */
1491 newhash
= hash_questions(header
, (unsigned int)m
, daemon
->namebuff
);
1492 if (!newhash
|| memcmp(hash
, newhash
, HASH_SIZE
) != 0)
1498 if (crc
!= questions_crc(header
, (unsigned int)m
, daemon
->namebuff
))
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
);
1513 /* In case of local answer or no connections made. */
1515 m
= setup_reply(header
, (unsigned int)size
, addrp
, flags
, daemon
->local_ttl
);
1519 check_log_writer(NULL
);
1523 if (m
== 0 || !read_write(confd
, packet
, m
+ sizeof(u16
), 0))
1528 static struct frec
*allocate_frec(time_t now
)
1532 if ((f
= (struct frec
*)whine_malloc(sizeof(struct frec
))))
1534 f
->next
= daemon
->frec_list
;
1543 f
->dependent
= NULL
;
1544 f
->blocking_query
= NULL
;
1547 daemon
->frec_list
= f
;
1553 static struct randfd
*allocate_rfd(int family
)
1555 static int finger
= 0;
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 */
1561 for (i
= 0; i
< RANDOM_SOCKS
; i
++)
1562 if (daemon
->randomsocks
[i
].refcount
== 0)
1564 if ((daemon
->randomsocks
[i
].fd
= random_sock(family
)) == -1)
1567 daemon
->randomsocks
[i
].refcount
= 1;
1568 daemon
->randomsocks
[i
].family
= family
;
1569 return &daemon
->randomsocks
[i
];
1572 /* No free ones or cannot get new socket, grab an existing one */
1573 for (i
= 0; i
< RANDOM_SOCKS
; i
++)
1575 int j
= (i
+finger
) % RANDOM_SOCKS
;
1576 if (daemon
->randomsocks
[j
].refcount
!= 0 &&
1577 daemon
->randomsocks
[j
].family
== family
&&
1578 daemon
->randomsocks
[j
].refcount
!= 0xffff)
1581 daemon
->randomsocks
[j
].refcount
++;
1582 return &daemon
->randomsocks
[j
];
1586 return NULL
; /* doom */
1588 static void free_frec(struct frec
*f
)
1590 if (f
->rfd4
&& --(f
->rfd4
->refcount
) == 0)
1598 if (f
->rfd6
&& --(f
->rfd6
->refcount
) == 0)
1607 blockdata_free(f
->stash
);
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
;
1615 f
->dependent
= NULL
;
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
1621 when the oldest in-use record will expire. Impose an absolute
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. */
1625 struct frec
*get_new_frec(time_t now
, int *wait
, int force
)
1627 struct frec
*f
, *oldest
, *target
;
1633 for (f
= daemon
->frec_list
, oldest
= NULL
, target
= NULL
, count
= 0; f
; f
= f
->next
, count
++)
1638 if (difftime(now
, f
->time
) >= 4*TIMEOUT
)
1644 if (!oldest
|| difftime(f
->time
, oldest
->time
) <= 0)
1654 /* can't find empty one, use oldest if there is one
1655 and it's older than timeout */
1656 if (oldest
&& ((int)difftime(now
, oldest
->time
)) >= TIMEOUT
)
1658 /* keep stuff for twice timeout if we can by allocating a new
1660 if (difftime(now
, oldest
->time
) < 2*TIMEOUT
&&
1661 count
<= daemon
->ftabsize
&&
1662 (f
= allocate_frec(now
)))
1673 /* none available, calculate time 'till oldest record expires */
1674 if (!force
&& count
> daemon
->ftabsize
)
1676 static time_t last_log
= 0;
1679 *wait
= oldest
->time
+ (time_t)TIMEOUT
- now
;
1681 if ((int)difftime(now
, last_log
) > 5)
1684 my_syslog(LOG_WARNING
, _("Maximum number of concurrent DNS queries reached (max: %d)"), daemon
->ftabsize
);
1690 if (!(f
= allocate_frec(now
)) && wait
)
1691 /* wait one second on malloc failure */
1694 return f
; /* OK if malloc fails and this is NULL */
1697 /* crc is all-ones if not known. */
1698 static struct frec
*lookup_frec(unsigned short id
, void *hash
)
1702 for(f
= daemon
->frec_list
; f
; f
= f
->next
)
1703 if (f
->sentto
&& f
->new_id
== id
&&
1704 (!hash
|| memcmp(hash
, f
->hash
, HASH_SIZE
) == 0))
1710 static struct frec
*lookup_frec_by_sender(unsigned short id
,
1711 union mysockaddr
*addr
,
1716 for(f
= daemon
->frec_list
; f
; f
= f
->next
)
1719 memcmp(hash
, f
->hash
, HASH_SIZE
) == 0 &&
1720 sockaddr_isequal(&f
->source
, addr
))
1726 /* A server record is going away, remove references to it */
1727 void server_gone(struct server
*server
)
1731 for (f
= daemon
->frec_list
; f
; f
= f
->next
)
1732 if (f
->sentto
&& f
->sentto
== server
)
1735 if (daemon
->last_server
== server
)
1736 daemon
->last_server
= NULL
;
1738 if (daemon
->srv_save
== server
)
1739 daemon
->srv_save
= NULL
;
1742 /* return unique random ids. */
1743 static unsigned short get_id(void)
1745 unsigned short ret
= 0;
1749 while (lookup_frec(ret
, NULL
));