]>
git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/forward.c
1 /* dnsmasq is Copyright (c) 2000 - 2003 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.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
13 /* Author's email: simon@thekelleys.org.uk */
17 static struct frec
*frec_list
;
19 static struct frec
*get_new_frec(time_t now
);
20 static struct frec
*lookup_frec(unsigned short id
);
21 static struct frec
*lookup_frec_by_sender(unsigned short id
,
22 union mysockaddr
*addr
,
24 static unsigned short get_id(void);
26 /* May be called more than once. */
27 void forward_init(int first
)
33 for (f
= frec_list
; f
; f
= f
->next
)
37 /* Send a UDP packet with it's source address set as "source"
38 unless nowild is true, when we just send it with the kernel default */
39 static void send_from(int fd
, int nowild
, char *packet
, int len
,
40 union mysockaddr
*to
, struct all_addr
*source
,
46 struct cmsghdr align
; /* this ensures alignment */
47 #if defined(IP_PKTINFO)
48 char control
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
49 #elif defined(IP_SENDSRCADDR)
50 char control
[CMSG_SPACE(sizeof(struct in_addr
))];
53 char control6
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
57 iov
[0].iov_base
= packet
;
60 msg
.msg_control
= NULL
;
61 msg
.msg_controllen
= 0;
64 msg
.msg_namelen
= sa_len(to
);
70 struct cmsghdr
*cmptr
;
71 msg
.msg_control
= &control_u
;
72 msg
.msg_controllen
= sizeof(control_u
);
73 cmptr
= CMSG_FIRSTHDR(&msg
);
75 if (to
->sa
.sa_family
== AF_INET
)
77 #if defined(IP_PKTINFO)
78 struct in_pktinfo
*pkt
= (struct in_pktinfo
*)CMSG_DATA(cmptr
);
80 pkt
->ipi_spec_dst
= source
->addr
.addr4
;
81 msg
.msg_controllen
= cmptr
->cmsg_len
= CMSG_LEN(sizeof(struct in_pktinfo
));
82 cmptr
->cmsg_level
= SOL_IP
;
83 cmptr
->cmsg_type
= IP_PKTINFO
;
84 #elif defined(IP_SENDSRCADDR)
85 struct in_addr
*a
= (struct in_addr
*)CMSG_DATA(cmptr
);
86 *a
= source
->addr
.addr4
;
87 msg
.msg_controllen
= cmptr
->cmsg_len
= CMSG_LEN(sizeof(struct in_addr
));
88 cmptr
->cmsg_level
= IPPROTO_IP
;
89 cmptr
->cmsg_type
= IP_SENDSRCADDR
;
96 struct in6_pktinfo
*pkt
= (struct in6_pktinfo
*)CMSG_DATA(cmptr
);
97 pkt
->ipi6_ifindex
= iface
; /* Need iface for IPv6 to handle link-local addrs */
98 pkt
->ipi6_addr
= source
->addr
.addr6
;
99 msg
.msg_controllen
= cmptr
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
100 cmptr
->cmsg_type
= IPV6_PKTINFO
;
101 cmptr
->cmsg_level
= IPV6_LEVEL
;
107 if (sendmsg(fd
, &msg
, 0) == -1)
109 /* certain Linux kernels seem to object to setting the source address in the IPv6 stack
110 by returning EINVAL from sendmsg. In that case, try again without setting the
111 source address, since it will nearly alway be correct anyway. IPv6 stinks. */
112 if (errno
== EINVAL
&& msg
.msg_controllen
)
114 msg
.msg_controllen
= 0;
122 static unsigned short search_servers(struct daemon
*daemon
, time_t now
, struct all_addr
**addrpp
,
123 unsigned short qtype
, char *qdomain
, int *type
, char **domain
)
126 /* If the query ends in the domain in one of our servers, set
127 domain to point to that name. We find the largest match to allow both
128 domain.org and sub.domain.org to exist. */
130 unsigned int namelen
= strlen(qdomain
);
131 unsigned int matchlen
= 0;
133 unsigned short flags
= 0;
135 for (serv
= daemon
->servers
; serv
; serv
=serv
->next
)
136 /* domain matches take priority over NODOTS matches */
137 if ((serv
->flags
& SERV_FOR_NODOTS
) && *type
!= SERV_HAS_DOMAIN
&& !strchr(qdomain
, '.'))
139 unsigned short sflag
= serv
->addr
.sa
.sa_family
== AF_INET
? F_IPV4
: F_IPV6
;
140 *type
= SERV_FOR_NODOTS
;
141 if (serv
->flags
& SERV_NO_ADDR
)
143 else if (serv
->flags
& SERV_LITERAL_ADDRESS
)
148 if (serv
->addr
.sa
.sa_family
== AF_INET
)
149 *addrpp
= (struct all_addr
*)&serv
->addr
.in
.sin_addr
;
152 *addrpp
= (struct all_addr
*)&serv
->addr
.in6
.sin6_addr
;
159 else if (serv
->flags
& SERV_HAS_DOMAIN
)
161 unsigned int domainlen
= strlen(serv
->domain
);
162 if (namelen
>= domainlen
&&
163 hostname_isequal(qdomain
+ namelen
- domainlen
, serv
->domain
) &&
164 domainlen
>= matchlen
)
166 unsigned short sflag
= serv
->addr
.sa
.sa_family
== AF_INET
? F_IPV4
: F_IPV6
;
167 *type
= SERV_HAS_DOMAIN
;
168 *domain
= serv
->domain
;
169 matchlen
= domainlen
;
170 if (serv
->flags
& SERV_NO_ADDR
)
172 else if (serv
->flags
& SERV_LITERAL_ADDRESS
)
174 if ((sflag
| F_QUERY
) & qtype
)
177 if (serv
->addr
.sa
.sa_family
== AF_INET
)
178 *addrpp
= (struct all_addr
*)&serv
->addr
.in
.sin_addr
;
181 *addrpp
= (struct all_addr
*)&serv
->addr
.in6
.sin6_addr
;
190 if (flags
& ~(F_NOERR
| F_NXDOMAIN
)) /* flags set here means a literal found */
193 log_query(F_CONFIG
| F_FORWARD
| F_NEG
, qdomain
, NULL
, 0, NULL
, 0);
195 log_query(F_CONFIG
| F_FORWARD
| flags
, qdomain
, *addrpp
, 0, NULL
, 0);
197 else if (qtype
&& (daemon
->options
& OPT_NODOTS_LOCAL
) && !strchr(qdomain
, '.'))
200 if (flags
== F_NXDOMAIN
&& check_for_local_domain(qdomain
, now
, daemon
->mxnames
))
203 if (flags
== F_NXDOMAIN
|| flags
== F_NOERR
)
204 log_query(F_CONFIG
| F_FORWARD
| F_NEG
| qtype
| (flags
& F_NXDOMAIN
), qdomain
, NULL
, 0, NULL
, 0);
209 /* returns new last_server */
210 static void forward_query(struct daemon
*daemon
, int udpfd
, union mysockaddr
*udpaddr
,
211 struct all_addr
*dst_addr
, unsigned int dst_iface
,
212 HEADER
*header
, int plen
, time_t now
)
214 struct frec
*forward
;
216 int forwardall
= 0, type
= 0;
217 struct all_addr
*addrp
= NULL
;
218 unsigned short flags
= 0;
219 unsigned short gotname
= extract_request(header
, (unsigned int)plen
, daemon
->namebuff
, NULL
);
220 struct server
*start
= NULL
;
221 unsigned int crc
= questions_crc(header
,(unsigned int)plen
);
223 /* may be recursion not speced or no servers available. */
224 if (!header
->rd
|| !daemon
->servers
)
226 else if ((forward
= lookup_frec_by_sender(ntohs(header
->id
), udpaddr
, crc
)))
228 /* retry on existing query, send to all available servers */
229 domain
= forward
->sentto
->domain
;
230 if (!(daemon
->options
& OPT_ORDER
))
233 daemon
->last_server
= NULL
;
235 type
= forward
->sentto
->flags
& SERV_TYPE
;
236 if (!(start
= forward
->sentto
->next
))
237 start
= daemon
->servers
; /* at end of list, recycle */
238 header
->id
= htons(forward
->new_id
);
243 flags
= search_servers(daemon
, now
, &addrp
, gotname
, daemon
->namebuff
, &type
, &domain
);
245 if (!flags
&& !(forward
= get_new_frec(now
)))
246 /* table full - server failure. */
251 /* In strict_order mode, or when using domain specific servers
252 always try servers in the order specified in resolv.conf,
253 otherwise, use the one last known to work. */
255 if (type
!= 0 || (daemon
->options
& OPT_ORDER
))
256 start
= daemon
->servers
;
257 else if (!(start
= daemon
->last_server
))
259 start
= daemon
->servers
;
263 forward
->source
= *udpaddr
;
264 forward
->dest
= *dst_addr
;
265 forward
->iface
= dst_iface
;
266 forward
->new_id
= get_id();
268 forward
->orig_id
= ntohs(header
->id
);
270 header
->id
= htons(forward
->new_id
);
274 /* check for send errors here (no route to host)
275 if we fail to send to all nameservers, send back an error
276 packet straight away (helps modem users when offline) */
278 if (!flags
&& forward
)
280 struct server
*firstsentto
= start
;
285 /* only send to servers dealing with our domain.
286 domain may be NULL, in which case server->domain
287 must be NULL also. */
289 if (type
== (start
->flags
& SERV_TYPE
) &&
290 (type
!= SERV_HAS_DOMAIN
|| hostname_isequal(domain
, start
->domain
)) &&
291 !(start
->flags
& SERV_LITERAL_ADDRESS
))
293 if (sendto(start
->sfd
->fd
, (char *)header
, plen
, 0,
295 sa_len(&start
->addr
)) == -1)
303 strcpy(daemon
->namebuff
, "query");
304 if (start
->addr
.sa
.sa_family
== AF_INET
)
305 log_query(F_SERVER
| F_IPV4
| F_FORWARD
, daemon
->namebuff
,
306 (struct all_addr
*)&start
->addr
.in
.sin_addr
, 0,
310 log_query(F_SERVER
| F_IPV6
| F_FORWARD
, daemon
->namebuff
,
311 (struct all_addr
*)&start
->addr
.in6
.sin6_addr
, 0,
315 forward
->sentto
= start
;
321 if (!(start
= start
->next
))
322 start
= daemon
->servers
;
324 if (start
== firstsentto
)
331 /* could not send on, prepare to return */
332 header
->id
= htons(forward
->orig_id
);
333 forward
->new_id
= 0; /* cancel */
336 /* could not send on, return empty answer or address if known for whole domain */
337 plen
= setup_reply(header
, (unsigned int)plen
, addrp
, flags
, daemon
->local_ttl
);
338 send_from(udpfd
, daemon
->options
& OPT_NOWILD
, (char *)header
, plen
, udpaddr
, dst_addr
, dst_iface
);
343 static int process_reply(struct daemon
*daemon
, HEADER
*header
, time_t now
,
344 union mysockaddr
*serveraddr
, unsigned int n
)
346 unsigned char *pheader
, *sizep
;
347 unsigned int plen
, munged
= 0;
349 /* If upstream is advertising a larger UDP packet size
350 than we allow, trim it so that we don't get overlarge
351 requests for the client. */
353 if ((pheader
= find_pseudoheader(header
, n
, &plen
, &sizep
)))
355 unsigned short udpsz
;
356 unsigned char *psave
= sizep
;
358 GETSHORT(udpsz
, sizep
);
359 if (udpsz
> daemon
->edns_pktsz
)
360 PUTSHORT(daemon
->edns_pktsz
, psave
);
363 /* Complain loudly if the upstream server is non-recursive. */
364 if (!header
->ra
&& header
->rcode
== NOERROR
&& ntohs(header
->ancount
) == 0)
366 char addrbuff
[ADDRSTRLEN
];
368 if (serveraddr
->sa
.sa_family
== AF_INET
)
369 inet_ntop(AF_INET
, &serveraddr
->in
.sin_addr
, addrbuff
, ADDRSTRLEN
);
370 else if (serveraddr
->sa
.sa_family
== AF_INET6
)
371 inet_ntop(AF_INET6
, &serveraddr
->in6
.sin6_addr
, addrbuff
, ADDRSTRLEN
);
373 strcpy(addrbuff
, inet_ntoa(serveraddr
->in
.sin_addr
));
375 syslog(LOG_WARNING
, "nameserver %s refused to do a recursive query", addrbuff
);
379 if (header
->opcode
!= QUERY
|| (header
->rcode
!= NOERROR
&& header
->rcode
!= NXDOMAIN
))
382 if (daemon
->bogus_addr
&& header
->rcode
!= NXDOMAIN
&&
383 check_for_bogus_wildcard(header
, n
, daemon
->namebuff
, daemon
->bogus_addr
, now
))
386 header
->rcode
= NXDOMAIN
;
391 if (header
->rcode
== NXDOMAIN
&&
392 extract_request(header
, n
, daemon
->namebuff
, NULL
) &&
393 check_for_local_domain(daemon
->namebuff
, now
, daemon
->mxnames
))
395 /* if we forwarded a query for a locally known name (because it was for
396 an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
397 since we know that the domain exists, even if upstream doesn't */
400 header
->rcode
= NOERROR
;
403 extract_addresses(header
, n
, daemon
->namebuff
, now
, daemon
);
406 /* do this after extract_addresses. Ensure NODATA reply and remove
411 header
->ancount
= htons(0);
412 header
->nscount
= htons(0);
413 header
->arcount
= htons(0);
416 /* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
417 sections of the packet. Find the new length here and put back pseudoheader
418 if it was removed. */
419 return resize_packet(header
, n
, pheader
, plen
);
422 /* sets new last_server */
423 void reply_query(struct serverfd
*sfd
, struct daemon
*daemon
, time_t now
)
425 /* packet from peer server, extract data for cache, and send to
426 original requester */
427 struct frec
*forward
;
429 union mysockaddr serveraddr
;
430 socklen_t addrlen
= sizeof(serveraddr
);
431 int n
= recvfrom(sfd
->fd
, daemon
->packet
, daemon
->edns_pktsz
, 0, &serveraddr
.sa
, &addrlen
);
433 /* Determine the address of the server replying so that we can mark that as good */
434 serveraddr
.sa
.sa_family
= sfd
->source_addr
.sa
.sa_family
;
436 if (serveraddr
.sa
.sa_family
== AF_INET6
)
437 serveraddr
.in6
.sin6_flowinfo
= htonl(0);
440 header
= (HEADER
*)daemon
->packet
;
441 forward
= lookup_frec(ntohs(header
->id
));
443 if (n
>= (int)sizeof(HEADER
) && header
->qr
&& forward
)
445 /* find good server by address if possible, otherwise assume the last one we sent to */
446 if ((forward
->sentto
->flags
& SERV_TYPE
) == 0)
448 struct server
*last_server
;
449 daemon
->last_server
= forward
->sentto
;
450 for (last_server
= daemon
->servers
; last_server
; last_server
= last_server
->next
)
451 if (!(last_server
->flags
& (SERV_LITERAL_ADDRESS
| SERV_HAS_DOMAIN
| SERV_FOR_NODOTS
| SERV_NO_ADDR
)) &&
452 sockaddr_isequal(&last_server
->addr
, &serveraddr
))
454 daemon
->last_server
= last_server
;
459 if ((n
= process_reply(daemon
, header
, now
, &serveraddr
, (unsigned int)n
)))
461 header
->id
= htons(forward
->orig_id
);
462 header
->ra
= 1; /* recursion if available */
463 send_from(forward
->fd
, daemon
->options
& OPT_NOWILD
, daemon
->packet
, n
,
464 &forward
->source
, &forward
->dest
, forward
->iface
);
465 forward
->new_id
= 0; /* cancel */
470 void receive_query(struct listener
*listen
, struct daemon
*daemon
, time_t now
)
472 HEADER
*header
= (HEADER
*)daemon
->packet
;
473 union mysockaddr source_addr
;
476 struct all_addr dst_addr
;
477 int m
, n
, if_index
= 0;
480 struct cmsghdr
*cmptr
;
482 struct cmsghdr align
; /* this ensures alignment */
484 char control6
[CMSG_SPACE(sizeof(struct in6_pktinfo
))];
486 #if defined(IP_PKTINFO)
487 char control
[CMSG_SPACE(sizeof(struct in_pktinfo
))];
488 #elif defined(IP_RECVDSTADDR)
489 char control
[CMSG_SPACE(sizeof(struct in_addr
)) +
490 CMSG_SPACE(sizeof(struct sockaddr_dl
))];
494 iov
[0].iov_base
= daemon
->packet
;
495 iov
[0].iov_len
= daemon
->edns_pktsz
;
497 msg
.msg_control
= control_u
.control
;
498 msg
.msg_controllen
= sizeof(control_u
);
500 msg
.msg_name
= &source_addr
;
501 msg
.msg_namelen
= sizeof(source_addr
);
505 if ((n
= recvmsg(listen
->fd
, &msg
, 0)) == -1)
508 if (n
< (int)sizeof(HEADER
) || header
->qr
)
511 source_addr
.sa
.sa_family
= listen
->family
;
513 if (listen
->family
== AF_INET6
)
514 source_addr
.in6
.sin6_flowinfo
= htonl(0);
517 if (!(daemon
->options
& OPT_NOWILD
))
521 if (msg
.msg_controllen
< sizeof(struct cmsghdr
))
524 #if defined(IP_PKTINFO)
525 if (listen
->family
== AF_INET
)
526 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
527 if (cmptr
->cmsg_level
== SOL_IP
&& cmptr
->cmsg_type
== IP_PKTINFO
)
529 dst_addr
.addr
.addr4
= ((struct in_pktinfo
*)CMSG_DATA(cmptr
))->ipi_spec_dst
;
530 if_index
= ((struct in_pktinfo
*)CMSG_DATA(cmptr
))->ipi_ifindex
;
532 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
533 if (listen
->family
== AF_INET
)
535 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
536 if (cmptr
->cmsg_level
== IPPROTO_IP
&& cmptr
->cmsg_type
== IP_RECVDSTADDR
)
537 dst_addr
.addr
.addr4
= *((struct in_addr
*)CMSG_DATA(cmptr
));
538 else if (cmptr
->cmsg_level
== IPPROTO_IP
&& cmptr
->cmsg_type
== IP_RECVIF
)
539 if_index
= ((struct sockaddr_dl
*)CMSG_DATA(cmptr
))->sdl_index
;
544 if (listen
->family
== AF_INET6
)
546 for (cmptr
= CMSG_FIRSTHDR(&msg
); cmptr
; cmptr
= CMSG_NXTHDR(&msg
, cmptr
))
547 if (cmptr
->cmsg_level
== IPV6_LEVEL
&& cmptr
->cmsg_type
== IPV6_PKTINFO
)
549 dst_addr
.addr
.addr6
= ((struct in6_pktinfo
*)CMSG_DATA(cmptr
))->ipi6_addr
;
550 if_index
=((struct in6_pktinfo
*)CMSG_DATA(cmptr
))->ipi6_ifindex
;
555 /* enforce available interface configuration */
560 if (daemon
->if_except
|| daemon
->if_names
)
563 ifr
.ifr_ifindex
= if_index
;
564 if (ioctl(listen
->fd
, SIOCGIFNAME
, &ifr
) == -1)
567 if (!if_indextoname(if_index
, ifr
.ifr_name
))
572 for (tmp
= daemon
->if_except
; tmp
; tmp
= tmp
->next
)
573 if (tmp
->name
&& (strcmp(tmp
->name
, ifr
.ifr_name
) == 0))
576 if (daemon
->if_names
|| daemon
->if_addrs
)
578 for (tmp
= daemon
->if_names
; tmp
; tmp
= tmp
->next
)
579 if (tmp
->name
&& (strcmp(tmp
->name
, ifr
.ifr_name
) == 0))
582 for (tmp
= daemon
->if_addrs
; tmp
; tmp
= tmp
->next
)
583 if (tmp
->addr
.sa
.sa_family
== listen
->family
)
585 if (tmp
->addr
.sa
.sa_family
== AF_INET
&&
586 tmp
->addr
.in
.sin_addr
.s_addr
== dst_addr
.addr
.addr4
.s_addr
)
589 else if (tmp
->addr
.sa
.sa_family
== AF_INET6
&&
590 memcmp(&tmp
->addr
.in6
.sin6_addr
,
591 &dst_addr
.addr
.addr6
,
592 sizeof(struct in6_addr
)) == 0)
601 if (extract_request(header
, (unsigned int)n
, daemon
->namebuff
, &type
))
603 if (listen
->family
== AF_INET
)
604 log_query(F_QUERY
| F_IPV4
| F_FORWARD
, daemon
->namebuff
,
605 (struct all_addr
*)&source_addr
.in
.sin_addr
, type
, NULL
, 0);
608 log_query(F_QUERY
| F_IPV6
| F_FORWARD
, daemon
->namebuff
,
609 (struct all_addr
*)&source_addr
.in6
.sin6_addr
, type
, NULL
, 0);
613 m
= answer_request (header
, ((char *) header
) + PACKETSZ
, (unsigned int)n
, daemon
, now
);
615 send_from(listen
->fd
, daemon
->options
& OPT_NOWILD
, (char *)header
, m
, &source_addr
, &dst_addr
, if_index
);
617 forward_query(daemon
, listen
->fd
, &source_addr
, &dst_addr
, if_index
,
621 static int read_write(int fd
, char *packet
, int size
, int rw
)
625 for (done
= 0; done
< size
; done
+= n
)
629 n
= read(fd
, &packet
[done
], (size_t)(size
- done
));
631 n
= write(fd
, &packet
[done
], (size_t)(size
- done
));
646 /* The daemon forks before calling this: it should deal with one connection,
647 blocking as neccessary, and then return. Note, need to be a bit careful
648 about resources for debug mode, when the fork is suppressed: that's
649 done by the caller. */
650 char *tcp_request(struct daemon
*daemon
, int confd
, time_t now
)
653 unsigned short qtype
, gotname
;
654 unsigned char c1
, c2
;
655 /* Max TCP packet + slop */
656 char *packet
= malloc(65536 + MAXDNAME
+ RRFIXEDSZ
);
658 struct server
*last_server
;
663 !read_write(confd
, &c1
, 1, 1) || !read_write(confd
, &c2
, 1, 1) ||
664 !(size
= c1
<< 8 | c2
) ||
665 !read_write(confd
, packet
, size
, 1))
668 if (size
< (int)sizeof(HEADER
))
671 header
= (HEADER
*)packet
;
673 if ((gotname
= extract_request(header
, (unsigned int)size
, daemon
->namebuff
, &qtype
)))
675 union mysockaddr peer_addr
;
676 socklen_t peer_len
= sizeof(union mysockaddr
);
678 if (getpeername(confd
, (struct sockaddr
*)&peer_addr
, &peer_len
) != -1)
680 if (peer_addr
.sa
.sa_family
== AF_INET
)
681 log_query(F_QUERY
| F_IPV4
| F_FORWARD
, daemon
->namebuff
,
682 (struct all_addr
*)&peer_addr
.in
.sin_addr
, qtype
, NULL
, 0);
685 log_query(F_QUERY
| F_IPV6
| F_FORWARD
, daemon
->namebuff
,
686 (struct all_addr
*)&peer_addr
.in6
.sin6_addr
, qtype
, NULL
, 0);
691 /* m > 0 if answered from cache */
692 m
= answer_request(header
, ((char *) header
) + 65536, (unsigned int)size
, daemon
, now
);
696 unsigned short flags
= 0;
697 struct all_addr
*addrp
= NULL
;
702 flags
= search_servers(daemon
, now
, &addrp
, gotname
, daemon
->namebuff
, &type
, &domain
);
704 if (type
!= 0 || (daemon
->options
& OPT_ORDER
) || !daemon
->last_server
)
705 last_server
= daemon
->servers
;
707 last_server
= daemon
->last_server
;
709 if (!flags
&& last_server
)
711 struct server
*firstsendto
= NULL
;
713 /* Loop round available servers until we succeed in connecting to one.
714 Note that this code subtley ensures that consecutive queries on this connection
715 which can go to the same server, do so. */
719 firstsendto
= last_server
;
722 if (!(last_server
= last_server
->next
))
723 last_server
= daemon
->servers
;
725 if (last_server
== firstsendto
)
729 /* server for wrong domain */
730 if (type
!= (last_server
->flags
& SERV_TYPE
) ||
731 (type
== SERV_HAS_DOMAIN
&& !hostname_isequal(domain
, last_server
->domain
)))
734 if ((last_server
->tcpfd
== -1) &&
735 (last_server
->tcpfd
= socket(last_server
->addr
.sa
.sa_family
, SOCK_STREAM
, 0)) != -1 &&
736 connect(last_server
->tcpfd
, &last_server
->addr
.sa
, sa_len(&last_server
->addr
)) == -1)
738 close(last_server
->tcpfd
);
739 last_server
->tcpfd
= -1;
742 if (last_server
->tcpfd
== -1)
748 if (!read_write(last_server
->tcpfd
, &c1
, 1, 0) ||
749 !read_write(last_server
->tcpfd
, &c2
, 1, 0) ||
750 !read_write(last_server
->tcpfd
, packet
, size
, 0) ||
751 !read_write(last_server
->tcpfd
, &c1
, 1, 1) ||
752 !read_write(last_server
->tcpfd
, &c2
, 1, 1))
754 close(last_server
->tcpfd
);
755 last_server
->tcpfd
= -1;
760 if (!read_write(last_server
->tcpfd
, packet
, m
, 1))
764 strcpy(daemon
->namebuff
, "query");
765 if (last_server
->addr
.sa
.sa_family
== AF_INET
)
766 log_query(F_SERVER
| F_IPV4
| F_FORWARD
, daemon
->namebuff
,
767 (struct all_addr
*)&last_server
->addr
.in
.sin_addr
, 0, NULL
, 0);
770 log_query(F_SERVER
| F_IPV6
| F_FORWARD
, daemon
->namebuff
,
771 (struct all_addr
*)&last_server
->addr
.in6
.sin6_addr
, 0, NULL
, 0);
774 /* There's no point in updating the cache, since this process will exit and
775 lose the information after one query. We make this call for the alias and
776 bogus-nxdomain side-effects. */
777 m
= process_reply(daemon
, header
, now
, &last_server
->addr
, (unsigned int)m
);
783 /* In case of local answer or no connections made. */
785 m
= setup_reply(header
, (unsigned int)size
, addrp
, flags
, daemon
->local_ttl
);
790 if (!read_write(confd
, &c1
, 1, 0) ||
791 !read_write(confd
, &c2
, 1, 0) ||
792 !read_write(confd
, packet
, m
, 0))
797 static struct frec
*get_new_frec(time_t now
)
799 struct frec
*f
= frec_list
, *oldest
= NULL
;
800 time_t oldtime
= now
;
802 static time_t warntime
= 0;
812 if (difftime(f
->time
, oldtime
) <= 0)
822 /* can't find empty one, use oldest if there is one
823 and it's older than timeout */
824 if (oldest
&& difftime(now
, oldtime
) > TIMEOUT
)
831 { /* limit logging rate so syslog isn't DOSed either */
832 if (!warntime
|| difftime(now
, warntime
) > LOGRATE
)
835 syslog(LOG_WARNING
, "forwarding table overflow: check for server loops.");
840 if ((f
= (struct frec
*)malloc(sizeof(struct frec
))))
846 return f
; /* OK if malloc fails and this is NULL */
849 static struct frec
*lookup_frec(unsigned short id
)
853 for(f
= frec_list
; f
; f
= f
->next
)
860 static struct frec
*lookup_frec_by_sender(unsigned short id
,
861 union mysockaddr
*addr
,
866 for(f
= frec_list
; f
; f
= f
->next
)
870 sockaddr_isequal(&f
->source
, addr
))
877 /* return unique random ids between 1 and 65535 */
878 static unsigned short get_id(void)
880 unsigned short ret
= 0;
886 /* scrap ids already in use */
887 if ((ret
!= 0) && lookup_frec(ret
))