]>
git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/forward.c
1 /* dnsmasq is Copyright (c) 2000-2008 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
, unsigned int crc
);
20 static struct frec
*lookup_frec_by_sender(unsigned short id
,
21 union mysockaddr
*addr
,
23 static unsigned short get_id(int force
, unsigned short force_id
, unsigned int crc
);
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 static void 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)
68 struct in_pktinfo
*pkt
= (struct in_pktinfo
*)CMSG_DATA(cmptr
);
70 pkt
->ipi_spec_dst
= source
->addr
.addr4
;
71 msg
.msg_controllen
= cmptr
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
72 cmptr
->cmsg_level
= SOL_IP
;
73 cmptr
->cmsg_type
= IP_PKTINFO
;
74 #elif defined(IP_SENDSRCADDR)
75 struct in_addr
*a
= (struct in_addr
*)CMSG_DATA(cmptr
);
76 *a
= 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
;
85 struct in6_pktinfo
*pkt
= (struct in6_pktinfo
*)CMSG_DATA(cmptr
);
86 pkt
->ipi6_ifindex
= iface
; /* Need iface for IPv6 to handle link-local addrs */
87 pkt
->ipi6_addr
= source
->addr
.addr6
;
88 msg
.msg_controllen
= cmptr
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
89 cmptr
->cmsg_type
= IPV6_PKTINFO
;
90 cmptr
->cmsg_level
= IPV6_LEVEL
;
93 iface
= 0; /* eliminate warning */
98 if (sendmsg(fd
, &msg
, 0) == -1)
100 /* certain Linux kernels seem to object to setting the source address in the IPv6 stack
101 by returning EINVAL from sendmsg. In that case, try again without setting the
102 source address, since it will nearly alway be correct anyway. IPv6 stinks. */
103 if (errno
== EINVAL
&& msg
.msg_controllen
)
105 msg
.msg_controllen
= 0;
113 static unsigned short search_servers(time_t now
, struct all_addr
**addrpp
,
114 unsigned short qtype
, char *qdomain
, int *type
, char **domain
)
117 /* If the query ends in the domain in one of our servers, set
118 domain to point to that name. We find the largest match to allow both
119 domain.org and sub.domain.org to exist. */
121 unsigned int namelen
= strlen(qdomain
);
122 unsigned int matchlen
= 0;
124 unsigned short flags
= 0;
126 for (serv
= daemon
->servers
; serv
; serv
=serv
->next
)
127 /* domain matches take priority over NODOTS matches */
128 if ((serv
->flags
& SERV_FOR_NODOTS
) && *type
!= SERV_HAS_DOMAIN
&& !strchr(qdomain
, '.') && namelen
!= 0)
130 unsigned short sflag
= serv
->addr
.sa
.sa_family
== AF_INET
? F_IPV4
: F_IPV6
;
131 *type
= SERV_FOR_NODOTS
;
132 if (serv
->flags
& SERV_NO_ADDR
)
134 else if (serv
->flags
& SERV_LITERAL_ADDRESS
)
139 if (serv
->addr
.sa
.sa_family
== AF_INET
)
140 *addrpp
= (struct all_addr
*)&serv
->addr
.in
.sin_addr
;
143 *addrpp
= (struct all_addr
*)&serv
->addr
.in6
.sin6_addr
;
146 else if (!flags
|| (flags
& F_NXDOMAIN
))
150 else if (serv
->flags
& SERV_HAS_DOMAIN
)
152 unsigned int domainlen
= strlen(serv
->domain
);
153 char *matchstart
= qdomain
+ namelen
- domainlen
;
154 if (namelen
>= domainlen
&&
155 hostname_isequal(matchstart
, serv
->domain
) &&
156 domainlen
>= matchlen
&&
157 (domainlen
== 0 || namelen
== domainlen
|| *(serv
->domain
) == '.' || *(matchstart
-1) == '.' ))
159 unsigned short sflag
= serv
->addr
.sa
.sa_family
== AF_INET
? F_IPV4
: F_IPV6
;
160 *type
= SERV_HAS_DOMAIN
;
161 *domain
= serv
->domain
;
162 matchlen
= domainlen
;
163 if (serv
->flags
& SERV_NO_ADDR
)
165 else if (serv
->flags
& SERV_LITERAL_ADDRESS
)
170 if (serv
->addr
.sa
.sa_family
== AF_INET
)
171 *addrpp
= (struct all_addr
*)&serv
->addr
.in
.sin_addr
;
174 *addrpp
= (struct all_addr
*)&serv
->addr
.in6
.sin6_addr
;
177 else if (!flags
|| (flags
& F_NXDOMAIN
))
183 if (flags
== 0 && !(qtype
& F_BIGNAME
) &&
184 (daemon
->options
& OPT_NODOTS_LOCAL
) && !strchr(qdomain
, '.') && namelen
!= 0)
185 /* don't forward simple names, make exception for NS queries and empty name. */
188 if (flags
== F_NXDOMAIN
&& check_for_local_domain(qdomain
, now
))
195 if (flags
== F_NXDOMAIN
|| flags
== F_NOERR
)
196 logflags
= F_NEG
| qtype
;
198 log_query(logflags
| flags
| F_CONFIG
| F_FORWARD
, qdomain
, *addrpp
, NULL
);
204 static int forward_query(int udpfd
, union mysockaddr
*udpaddr
,
205 struct all_addr
*dst_addr
, unsigned int dst_iface
,
206 HEADER
*header
, size_t plen
, time_t now
, struct frec
*forward
)
210 struct all_addr
*addrp
= NULL
;
211 unsigned int crc
= questions_crc(header
, plen
, daemon
->namebuff
);
212 unsigned short flags
= 0;
213 unsigned short gotname
= extract_request(header
, plen
, daemon
->namebuff
, NULL
);
214 struct server
*start
= NULL
;
216 /* may be no servers available. */
217 if (!daemon
->servers
)
219 else if (forward
|| (forward
= lookup_frec_by_sender(ntohs(header
->id
), udpaddr
, crc
)))
221 /* retry on existing query, send to all available servers */
222 domain
= forward
->sentto
->domain
;
223 forward
->sentto
->failed_queries
++;
224 if (!(daemon
->options
& OPT_ORDER
))
226 forward
->forwardall
= 1;
227 daemon
->last_server
= NULL
;
229 type
= forward
->sentto
->flags
& SERV_TYPE
;
230 if (!(start
= forward
->sentto
->next
))
231 start
= daemon
->servers
; /* at end of list, recycle */
232 header
->id
= htons(forward
->new_id
);
237 flags
= search_servers(now
, &addrp
, gotname
, daemon
->namebuff
, &type
, &domain
);
239 if (!flags
&& !(forward
= get_new_frec(now
, NULL
)))
240 /* table full - server failure. */
245 /* force unchanging id for signed packets */
247 find_pseudoheader(header
, plen
, NULL
, NULL
, &is_sign
);
249 forward
->source
= *udpaddr
;
250 forward
->dest
= *dst_addr
;
251 forward
->iface
= dst_iface
;
252 forward
->orig_id
= ntohs(header
->id
);
253 forward
->new_id
= get_id(is_sign
, forward
->orig_id
, crc
);
256 forward
->forwardall
= 0;
257 header
->id
= htons(forward
->new_id
);
259 /* In strict_order mode, or when using domain specific servers
260 always try servers in the order specified in resolv.conf,
261 otherwise, use the one last known to work. */
263 if (type
!= 0 || (daemon
->options
& OPT_ORDER
))
264 start
= daemon
->servers
;
265 else if (!(start
= daemon
->last_server
))
267 start
= daemon
->servers
;
268 forward
->forwardall
= 1;
273 /* check for send errors here (no route to host)
274 if we fail to send to all nameservers, send back an error
275 packet straight away (helps modem users when offline) */
277 if (!flags
&& forward
)
279 struct server
*firstsentto
= start
;
284 /* only send to servers dealing with our domain.
285 domain may be NULL, in which case server->domain
286 must be NULL also. */
288 if (type
== (start
->flags
& SERV_TYPE
) &&
289 (type
!= SERV_HAS_DOMAIN
|| hostname_isequal(domain
, start
->domain
)) &&
290 !(start
->flags
& SERV_LITERAL_ADDRESS
))
294 /* find server socket to use, may need to get random one. */
300 if (start
->addr
.sa
.sa_family
== AF_INET6
)
302 if (!forward
->rfd6
&&
303 !(forward
->rfd6
= allocate_rfd(AF_INET6
)))
305 daemon
->rfd_save
= forward
->rfd6
;
306 fd
= forward
->rfd6
->fd
;
311 if (!forward
->rfd4
&&
312 !(forward
->rfd4
= allocate_rfd(AF_INET
)))
314 daemon
->rfd_save
= forward
->rfd4
;
315 fd
= forward
->rfd4
->fd
;
319 if (sendto(fd
, (char *)header
, plen
, 0,
321 sa_len(&start
->addr
)) == -1)
328 /* Keep info in case we want to re-send this packet */
329 daemon
->srv_save
= start
;
330 daemon
->packet_len
= plen
;
333 strcpy(daemon
->namebuff
, "query");
334 if (start
->addr
.sa
.sa_family
== AF_INET
)
335 log_query(F_SERVER
| F_IPV4
| F_FORWARD
, daemon
->namebuff
,
336 (struct all_addr
*)&start
->addr
.in
.sin_addr
, NULL
);
339 log_query(F_SERVER
| F_IPV6
| F_FORWARD
, daemon
->namebuff
,
340 (struct all_addr
*)&start
->addr
.in6
.sin6_addr
, NULL
);
344 forward
->sentto
= start
;
345 if (!forward
->forwardall
)
347 forward
->forwardall
++;
351 if (!(start
= start
->next
))
352 start
= daemon
->servers
;
354 if (start
== firstsentto
)
361 /* could not send on, prepare to return */
362 header
->id
= htons(forward
->orig_id
);
363 free_frec(forward
); /* cancel */
366 /* could not send on, return empty answer or address if known for whole domain */
369 plen
= setup_reply(header
, plen
, addrp
, flags
, daemon
->local_ttl
);
370 send_from(udpfd
, daemon
->options
& OPT_NOWILD
, (char *)header
, plen
, udpaddr
, dst_addr
, dst_iface
);
376 static size_t process_reply(HEADER
*header
, time_t now
,
377 struct server
*server
, size_t n
)
379 unsigned char *pheader
, *sizep
;
380 int munged
= 0, is_sign
;
383 /* If upstream is advertising a larger UDP packet size
384 than we allow, trim it so that we don't get overlarge
385 requests for the client. We can't do this for signed packets. */
387 if ((pheader
= find_pseudoheader(header
, n
, &plen
, &sizep
, &is_sign
)) && !is_sign
)
389 unsigned short udpsz
;
390 unsigned char *psave
= sizep
;
392 GETSHORT(udpsz
, sizep
);
393 if (udpsz
> daemon
->edns_pktsz
)
394 PUTSHORT(daemon
->edns_pktsz
, psave
);
397 if (header
->opcode
!= QUERY
|| (header
->rcode
!= NOERROR
&& header
->rcode
!= NXDOMAIN
))
400 /* Complain loudly if the upstream server is non-recursive. */
401 if (!header
->ra
&& header
->rcode
== NOERROR
&& ntohs(header
->ancount
) == 0 &&
402 server
&& !(server
->flags
& SERV_WARNED_RECURSIVE
))
404 prettyprint_addr(&server
->addr
, daemon
->namebuff
);
405 my_syslog(LOG_WARNING
, _("nameserver %s refused to do a recursive query"), daemon
->namebuff
);
406 if (!(daemon
->options
& OPT_LOG
))
407 server
->flags
|= SERV_WARNED_RECURSIVE
;
410 if (daemon
->bogus_addr
&& header
->rcode
!= NXDOMAIN
&&
411 check_for_bogus_wildcard(header
, n
, daemon
->namebuff
, daemon
->bogus_addr
, now
))
414 header
->rcode
= NXDOMAIN
;
419 if (header
->rcode
== NXDOMAIN
&&
420 extract_request(header
, n
, daemon
->namebuff
, NULL
) &&
421 check_for_local_domain(daemon
->namebuff
, now
))
423 /* if we forwarded a query for a locally known name (because it was for
424 an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
425 since we know that the domain exists, even if upstream doesn't */
428 header
->rcode
= NOERROR
;
431 if (extract_addresses(header
, n
, daemon
->namebuff
, now
))
433 my_syslog(LOG_WARNING
, _("possible DNS-rebind attack detected"));
438 /* do this after extract_addresses. Ensure NODATA reply and remove
443 header
->ancount
= htons(0);
444 header
->nscount
= htons(0);
445 header
->arcount
= htons(0);
448 /* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
449 sections of the packet. Find the new length here and put back pseudoheader
450 if it was removed. */
451 return resize_packet(header
, n
, pheader
, plen
);
454 /* sets new last_server */
455 void reply_query(int fd
, int family
, time_t now
)
457 /* packet from peer server, extract data for cache, and send to
458 original requester */
460 union mysockaddr serveraddr
;
461 struct frec
*forward
;
462 socklen_t addrlen
= sizeof(serveraddr
);
463 ssize_t n
= recvfrom(fd
, daemon
->packet
, daemon
->edns_pktsz
, 0, &serveraddr
.sa
, &addrlen
);
465 struct server
*server
;
467 /* packet buffer overwritten */
468 daemon
->srv_save
= NULL
;
470 /* Determine the address of the server replying so that we can mark that as good */
471 serveraddr
.sa
.sa_family
= family
;
473 if (serveraddr
.sa
.sa_family
== AF_INET6
)
474 serveraddr
.in6
.sin6_flowinfo
= 0;
477 /* spoof check: answer must come from known server, */
478 for (server
= daemon
->servers
; server
; server
= server
->next
)
479 if (!(server
->flags
& (SERV_LITERAL_ADDRESS
| SERV_NO_ADDR
)) &&
480 sockaddr_isequal(&server
->addr
, &serveraddr
))
483 header
= (HEADER
*)daemon
->packet
;
486 n
< (int)sizeof(HEADER
) || !header
->qr
||
487 !(forward
= lookup_frec(ntohs(header
->id
), questions_crc(header
, n
, daemon
->namebuff
))))
490 server
= forward
->sentto
;
492 if ((header
->rcode
== SERVFAIL
|| header
->rcode
== REFUSED
) &&
493 !(daemon
->options
& OPT_ORDER
) &&
494 forward
->forwardall
== 0)
495 /* for broken servers, attempt to send to another one. */
497 unsigned char *pheader
;
501 /* recreate query from reply */
502 pheader
= find_pseudoheader(header
, (size_t)n
, &plen
, NULL
, &is_sign
);
505 header
->ancount
= htons(0);
506 header
->nscount
= htons(0);
507 header
->arcount
= htons(0);
508 if ((nn
= resize_packet(header
, (size_t)n
, pheader
, plen
)))
512 forward_query(-1, NULL
, NULL
, 0, header
, nn
, now
, forward
);
518 if ((forward
->sentto
->flags
& SERV_TYPE
) == 0)
520 if (header
->rcode
== SERVFAIL
|| header
->rcode
== REFUSED
)
524 struct server
*last_server
;
526 /* find good server by address if possible, otherwise assume the last one we sent to */
527 for (last_server
= daemon
->servers
; last_server
; last_server
= last_server
->next
)
528 if (!(last_server
->flags
& (SERV_LITERAL_ADDRESS
| SERV_HAS_DOMAIN
| SERV_FOR_NODOTS
| SERV_NO_ADDR
)) &&
529 sockaddr_isequal(&last_server
->addr
, &serveraddr
))
531 server
= last_server
;
535 if (!(daemon
->options
& OPT_ALL_SERVERS
))
536 daemon
->last_server
= server
;
539 /* If the answer is an error, keep the forward record in place in case
540 we get a good reply from another server. Kill it when we've
541 had replies from all to avoid filling the forwarding table when
542 everything is broken */
543 if (forward
->forwardall
== 0 || --forward
->forwardall
== 1 ||
544 (header
->rcode
!= REFUSED
&& header
->rcode
!= SERVFAIL
))
546 if ((nn
= process_reply(header
, now
, server
, (size_t)n
)))
548 header
->id
= htons(forward
->orig_id
);
549 header
->ra
= 1; /* recursion if available */
550 send_from(forward
->fd
, daemon
->options
& OPT_NOWILD
, daemon
->packet
, nn
,
551 &forward
->source
, &forward
->dest
, forward
->iface
);
553 free_frec(forward
); /* cancel */
558 void receive_query(struct listener
*listen
, time_t now
)
560 HEADER
*header
= (HEADER
*)daemon
->packet
;
561 union mysockaddr source_addr
;
563 struct all_addr dst_addr
;
564 struct in_addr netmask
, dst_addr_4
;
570 struct cmsghdr
*cmptr
;
572 struct cmsghdr align
; /* this ensures alignment */
574 char control6
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
576 #if defined(HAVE_LINUX_NETWORK)
577 char control
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
578 #elif defined(IP_RECVDSTADDR) && defined(HAVE_SOLARIS_NETWORK)
579 char control
[CMSG_SPACE(sizeof(struct in_addr
)) +
580 CMSG_SPACE(sizeof(unsigned int))];
581 #elif defined(IP_RECVDSTADDR)
582 char control
[CMSG_SPACE(sizeof(struct in_addr
)) +
583 CMSG_SPACE(sizeof(struct sockaddr_dl
))];
587 /* packet buffer overwritten */
588 daemon
->srv_save
= NULL
;
590 if (listen
->family
== AF_INET
&& (daemon
->options
& OPT_NOWILD
))
592 dst_addr_4
= listen
->iface
->addr
.in
.sin_addr
;
593 netmask
= listen
->iface
->netmask
;
597 dst_addr_4
.s_addr
= 0;
601 iov
[0].iov_base
= daemon
->packet
;
602 iov
[0].iov_len
= daemon
->edns_pktsz
;
604 msg
.msg_control
= control_u
.control
;
605 msg
.msg_controllen
= sizeof(control_u
);
607 msg
.msg_name
= &source_addr
;
608 msg
.msg_namelen
= sizeof(source_addr
);
612 if ((n
= recvmsg(listen
->fd
, &msg
, 0)) == -1)
615 if (n
< (int)sizeof(HEADER
) ||
616 (msg
.msg_flags
& MSG_TRUNC
) ||
620 source_addr
.sa
.sa_family
= listen
->family
;
622 if (listen
->family
== AF_INET6
)
623 source_addr
.in6
.sin6_flowinfo
= 0;
626 if (!(daemon
->options
& OPT_NOWILD
))
630 if (msg
.msg_controllen
< sizeof(struct cmsghdr
))
633 #if defined(HAVE_LINUX_NETWORK)
634 if (listen
->family
== AF_INET
)
635 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
636 if (cmptr
->cmsg_level
== SOL_IP
&& cmptr
->cmsg_type
== IP_PKTINFO
)
638 dst_addr_4
= dst_addr
.addr
.addr4
= ((struct in_pktinfo
*)CMSG_DATA(cmptr
))->ipi_spec_dst
;
639 if_index
= ((struct in_pktinfo
*)CMSG_DATA(cmptr
))->ipi_ifindex
;
641 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
642 if (listen
->family
== AF_INET
)
644 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
645 if (cmptr
->cmsg_level
== IPPROTO_IP
&& cmptr
->cmsg_type
== IP_RECVDSTADDR
)
646 dst_addr_4
= dst_addr
.addr
.addr4
= *((struct in_addr
*)CMSG_DATA(cmptr
));
647 else if (cmptr
->cmsg_level
== IPPROTO_IP
&& cmptr
->cmsg_type
== IP_RECVIF
)
648 #ifdef HAVE_SOLARIS_NETWORK
649 if_index
= *((unsigned int *)CMSG_DATA(cmptr
));
651 if_index
= ((struct sockaddr_dl
*)CMSG_DATA(cmptr
))->sdl_index
;
657 if (listen
->family
== AF_INET6
)
659 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
660 if (cmptr
->cmsg_level
== IPV6_LEVEL
&& cmptr
->cmsg_type
== IPV6_PKTINFO
)
662 dst_addr
.addr
.addr6
= ((struct in6_pktinfo
*)CMSG_DATA(cmptr
))->ipi6_addr
;
663 if_index
=((struct in6_pktinfo
*)CMSG_DATA(cmptr
))->ipi6_ifindex
;
668 /* enforce available interface configuration */
674 ifr
.ifr_ifindex
= if_index
;
675 if (ioctl(listen
->fd
, SIOCGIFNAME
, &ifr
) == -1)
678 if (!if_indextoname(if_index
, ifr
.ifr_name
))
682 if (!iface_check(listen
->family
, &dst_addr
, &ifr
, &if_index
))
685 if (listen
->family
== AF_INET
&&
686 (daemon
->options
& OPT_LOCALISE
) &&
687 ioctl(listen
->fd
, SIOCGIFNETMASK
, &ifr
) == -1)
690 netmask
= ((struct sockaddr_in
*) &ifr
.ifr_addr
)->sin_addr
;
693 if (extract_request(header
, (size_t)n
, daemon
->namebuff
, &type
))
697 querystr(types
, type
);
699 if (listen
->family
== AF_INET
)
700 log_query(F_QUERY
| F_IPV4
| F_FORWARD
, daemon
->namebuff
,
701 (struct all_addr
*)&source_addr
.in
.sin_addr
, types
);
704 log_query(F_QUERY
| F_IPV6
| F_FORWARD
, daemon
->namebuff
,
705 (struct all_addr
*)&source_addr
.in6
.sin6_addr
, types
);
709 m
= answer_request (header
, ((char *) header
) + PACKETSZ
, (size_t)n
,
710 dst_addr_4
, netmask
, now
);
713 send_from(listen
->fd
, daemon
->options
& OPT_NOWILD
, (char *)header
,
714 m
, &source_addr
, &dst_addr
, if_index
);
715 daemon
->local_answer
++;
717 else if (forward_query(listen
->fd
, &source_addr
, &dst_addr
, if_index
,
718 header
, (size_t)n
, now
, NULL
))
719 daemon
->queries_forwarded
++;
721 daemon
->local_answer
++;
724 /* The daemon forks before calling this: it should deal with one connection,
725 blocking as neccessary, and then return. Note, need to be a bit careful
726 about resources for debug mode, when the fork is suppressed: that's
727 done by the caller. */
728 unsigned char *tcp_request(int confd
, time_t now
,
729 struct in_addr local_addr
, struct in_addr netmask
)
733 unsigned short qtype
, gotname
;
734 unsigned char c1
, c2
;
735 /* Max TCP packet + slop */
736 unsigned char *packet
= whine_malloc(65536 + MAXDNAME
+ RRFIXEDSZ
);
738 struct server
*last_server
;
743 !read_write(confd
, &c1
, 1, 1) || !read_write(confd
, &c2
, 1, 1) ||
744 !(size
= c1
<< 8 | c2
) ||
745 !read_write(confd
, packet
, size
, 1))
748 if (size
< (int)sizeof(HEADER
))
751 header
= (HEADER
*)packet
;
753 if ((gotname
= extract_request(header
, (unsigned int)size
, daemon
->namebuff
, &qtype
)))
755 union mysockaddr peer_addr
;
756 socklen_t peer_len
= sizeof(union mysockaddr
);
758 if (getpeername(confd
, (struct sockaddr
*)&peer_addr
, &peer_len
) != -1)
762 querystr(types
, qtype
);
764 if (peer_addr
.sa
.sa_family
== AF_INET
)
765 log_query(F_QUERY
| F_IPV4
| F_FORWARD
, daemon
->namebuff
,
766 (struct all_addr
*)&peer_addr
.in
.sin_addr
, types
);
769 log_query(F_QUERY
| F_IPV6
| F_FORWARD
, daemon
->namebuff
,
770 (struct all_addr
*)&peer_addr
.in6
.sin6_addr
, types
);
775 /* m > 0 if answered from cache */
776 m
= answer_request(header
, ((char *) header
) + 65536, (unsigned int)size
,
777 local_addr
, netmask
, now
);
779 /* Do this by steam now we're not in the select() loop */
780 check_log_writer(NULL
);
784 unsigned short flags
= 0;
785 struct all_addr
*addrp
= NULL
;
790 flags
= search_servers(now
, &addrp
, gotname
, daemon
->namebuff
, &type
, &domain
);
792 if (type
!= 0 || (daemon
->options
& OPT_ORDER
) || !daemon
->last_server
)
793 last_server
= daemon
->servers
;
795 last_server
= daemon
->last_server
;
797 if (!flags
&& last_server
)
799 struct server
*firstsendto
= NULL
;
800 unsigned int crc
= questions_crc(header
, (unsigned int)size
, daemon
->namebuff
);
802 /* Loop round available servers until we succeed in connecting to one.
803 Note that this code subtley ensures that consecutive queries on this connection
804 which can go to the same server, do so. */
808 firstsendto
= last_server
;
811 if (!(last_server
= last_server
->next
))
812 last_server
= daemon
->servers
;
814 if (last_server
== firstsendto
)
818 /* server for wrong domain */
819 if (type
!= (last_server
->flags
& SERV_TYPE
) ||
820 (type
== SERV_HAS_DOMAIN
&& !hostname_isequal(domain
, last_server
->domain
)))
823 if ((last_server
->tcpfd
== -1) &&
824 (last_server
->tcpfd
= socket(last_server
->addr
.sa
.sa_family
, SOCK_STREAM
, 0)) != -1 &&
825 (!local_bind(last_server
->tcpfd
, &last_server
->source_addr
, last_server
->interface
, 1) ||
826 connect(last_server
->tcpfd
, &last_server
->addr
.sa
, sa_len(&last_server
->addr
)) == -1))
828 close(last_server
->tcpfd
);
829 last_server
->tcpfd
= -1;
832 if (last_server
->tcpfd
== -1)
838 if (!read_write(last_server
->tcpfd
, &c1
, 1, 0) ||
839 !read_write(last_server
->tcpfd
, &c2
, 1, 0) ||
840 !read_write(last_server
->tcpfd
, packet
, size
, 0) ||
841 !read_write(last_server
->tcpfd
, &c1
, 1, 1) ||
842 !read_write(last_server
->tcpfd
, &c2
, 1, 1))
844 close(last_server
->tcpfd
);
845 last_server
->tcpfd
= -1;
850 if (!read_write(last_server
->tcpfd
, packet
, m
, 1))
854 strcpy(daemon
->namebuff
, "query");
855 if (last_server
->addr
.sa
.sa_family
== AF_INET
)
856 log_query(F_SERVER
| F_IPV4
| F_FORWARD
, daemon
->namebuff
,
857 (struct all_addr
*)&last_server
->addr
.in
.sin_addr
, NULL
);
860 log_query(F_SERVER
| F_IPV6
| F_FORWARD
, daemon
->namebuff
,
861 (struct all_addr
*)&last_server
->addr
.in6
.sin6_addr
, NULL
);
864 /* There's no point in updating the cache, since this process will exit and
865 lose the information after a few queries. We make this call for the alias and
866 bogus-nxdomain side-effects. */
867 /* If the crc of the question section doesn't match the crc we sent, then
868 someone might be attempting to insert bogus values into the cache by
869 sending replies containing questions and bogus answers. */
870 if (crc
== questions_crc(header
, (unsigned int)m
, daemon
->namebuff
))
871 m
= process_reply(header
, now
, last_server
, (unsigned int)m
);
877 /* In case of local answer or no connections made. */
879 m
= setup_reply(header
, (unsigned int)size
, addrp
, flags
, daemon
->local_ttl
);
882 check_log_writer(NULL
);
886 if (!read_write(confd
, &c1
, 1, 0) ||
887 !read_write(confd
, &c2
, 1, 0) ||
888 !read_write(confd
, packet
, m
, 0))
893 static struct frec
*allocate_frec(time_t now
)
897 if ((f
= (struct frec
*)whine_malloc(sizeof(struct frec
))))
899 f
->next
= daemon
->frec_list
;
906 daemon
->frec_list
= f
;
912 static struct randfd
*allocate_rfd(int family
)
914 static int finger
= 0;
917 /* limit the number of sockets we have open to avoid starvation of
918 (eg) TFTP. Once we have a reasonable number, randomness should be OK */
920 for (i
= 0; i
< RANDOM_SOCKS
; i
++)
921 if (daemon
->randomsocks
[i
].refcount
== 0)
923 if ((daemon
->randomsocks
[i
].fd
= random_sock(family
)) == -1)
926 daemon
->randomsocks
[i
].refcount
= 1;
927 daemon
->randomsocks
[i
].family
= family
;
928 return &daemon
->randomsocks
[i
];
931 /* No free ones or cannot get new socket, grab an existing one */
932 for (i
= 0; i
< RANDOM_SOCKS
; i
++)
934 int j
= (i
+finger
) % RANDOM_SOCKS
;
935 if (daemon
->randomsocks
[j
].refcount
!= 0 &&
936 daemon
->randomsocks
[j
].family
== family
&&
937 daemon
->randomsocks
[j
].refcount
!= 0xffff)
940 daemon
->randomsocks
[j
].refcount
++;
941 return &daemon
->randomsocks
[j
];
945 return NULL
; /* doom */
948 static void free_frec(struct frec
*f
)
950 if (f
->rfd4
&& --(f
->rfd4
->refcount
) == 0)
957 if (f
->rfd6
&& --(f
->rfd6
->refcount
) == 0)
964 /* if wait==NULL return a free or older than TIMEOUT record.
965 else return *wait zero if one available, or *wait is delay to
966 when the oldest in-use record will expire. Impose an absolute
967 limit of 4*TIMEOUT before we wipe things (for random sockets) */
968 struct frec
*get_new_frec(time_t now
, int *wait
)
970 struct frec
*f
, *oldest
, *target
;
976 for (f
= daemon
->frec_list
, oldest
= NULL
, target
= NULL
, count
= 0; f
; f
= f
->next
, count
++)
981 if (difftime(now
, f
->time
) >= 4*TIMEOUT
)
987 if (!oldest
|| difftime(f
->time
, oldest
->time
) <= 0)
997 /* can't find empty one, use oldest if there is one
998 and it's older than timeout */
999 if (oldest
&& ((int)difftime(now
, oldest
->time
)) >= TIMEOUT
)
1001 /* keep stuff for twice timeout if we can by allocating a new
1003 if (difftime(now
, oldest
->time
) < 2*TIMEOUT
&&
1004 count
<= daemon
->ftabsize
&&
1005 (f
= allocate_frec(now
)))
1016 /* none available, calculate time 'till oldest record expires */
1017 if (count
> daemon
->ftabsize
)
1020 *wait
= oldest
->time
+ (time_t)TIMEOUT
- now
;
1024 if (!(f
= allocate_frec(now
)) && wait
)
1025 /* wait one second on malloc failure */
1028 return f
; /* OK if malloc fails and this is NULL */
1031 /* crc is all-ones if not known. */
1032 static struct frec
*lookup_frec(unsigned short id
, unsigned int crc
)
1036 for(f
= daemon
->frec_list
; f
; f
= f
->next
)
1037 if (f
->sentto
&& f
->new_id
== id
&&
1038 (f
->crc
== crc
|| crc
== 0xffffffff))
1044 static struct frec
*lookup_frec_by_sender(unsigned short id
,
1045 union mysockaddr
*addr
,
1050 for(f
= daemon
->frec_list
; f
; f
= f
->next
)
1054 sockaddr_isequal(&f
->source
, addr
))
1060 /* A server record is going away, remove references to it */
1061 void server_gone(struct server
*server
)
1065 for (f
= daemon
->frec_list
; f
; f
= f
->next
)
1066 if (f
->sentto
&& f
->sentto
== server
)
1069 if (daemon
->last_server
== server
)
1070 daemon
->last_server
= NULL
;
1072 if (daemon
->srv_save
== server
)
1073 daemon
->srv_save
= NULL
;
1076 /* return unique random ids.
1077 For signed packets we can't change the ID without breaking the
1078 signing, so we keep the same one. In this case force is set, and this
1079 routine degenerates into killing any conflicting forward record. */
1080 static unsigned short get_id(int force
, unsigned short force_id
, unsigned int crc
)
1082 unsigned short ret
= 0;
1086 struct frec
*f
= lookup_frec(force_id
, crc
);
1088 free_frec(f
); /* free */
1093 while (lookup_frec(ret
, crc
));