Tomato 1.28
[tomato.git] / release / src / router / dnsmasq / src / forward.c
blobe086db722ff06edfa69bf98c3dd11fd3215aa219
1 /* dnsmasq is Copyright (c) 2000-2010 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/>.
17 #include "dnsmasq.h"
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,
22 unsigned int crc);
23 static unsigned short get_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,
31 unsigned int iface)
33 struct msghdr msg;
34 struct iovec iov[1];
35 union {
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))];
41 #endif
42 #ifdef HAVE_IPV6
43 char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
44 #endif
45 } control_u;
47 iov[0].iov_base = packet;
48 iov[0].iov_len = len;
50 msg.msg_control = NULL;
51 msg.msg_controllen = 0;
52 msg.msg_flags = 0;
53 msg.msg_name = to;
54 msg.msg_namelen = sa_len(to);
55 msg.msg_iov = iov;
56 msg.msg_iovlen = 1;
58 if (!nowild)
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 p;
69 p.ipi_ifindex = 0;
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 = SOL_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;
80 #endif
82 else
83 #ifdef HAVE_IPV6
85 struct in6_pktinfo p;
86 p.ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local addrs */
87 p.ipi6_addr = source->addr.addr6;
88 memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
89 msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
90 cmptr->cmsg_type = daemon->v6pktinfo;
91 cmptr->cmsg_level = IPV6_LEVEL;
93 #else
94 iface = 0; /* eliminate warning */
95 #endif
98 retry:
99 if (sendmsg(fd, &msg, 0) == -1)
101 /* certain Linux kernels seem to object to setting the source address in the IPv6 stack
102 by returning EINVAL from sendmsg. In that case, try again without setting the
103 source address, since it will nearly alway be correct anyway. IPv6 stinks. */
104 if (errno == EINVAL && msg.msg_controllen)
106 msg.msg_controllen = 0;
107 goto retry;
109 if (retry_send())
110 goto retry;
114 static unsigned short search_servers(time_t now, struct all_addr **addrpp,
115 unsigned short 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;
124 struct server *serv;
125 unsigned short 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 short sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
132 *type = SERV_FOR_NODOTS;
133 if (serv->flags & SERV_NO_ADDR)
134 flags = F_NXDOMAIN;
135 else if (serv->flags & SERV_LITERAL_ADDRESS)
137 if (sflag & qtype)
139 flags = sflag;
140 if (serv->addr.sa.sa_family == AF_INET)
141 *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
142 #ifdef HAVE_IPV6
143 else
144 *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
145 #endif
147 else if (!flags || (flags & F_NXDOMAIN))
148 flags = F_NOERR;
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)
160 *norebind = 1;
161 else if (domainlen >= matchlen)
163 unsigned short sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
164 *type = serv->flags & (SERV_HAS_DOMAIN | SERV_USE_RESOLV | SERV_NO_REBIND);
165 *domain = serv->domain;
166 matchlen = domainlen;
167 if (serv->flags & SERV_NO_ADDR)
168 flags = F_NXDOMAIN;
169 else if (serv->flags & SERV_LITERAL_ADDRESS)
171 if (sflag & qtype)
173 flags = sflag;
174 if (serv->addr.sa.sa_family == AF_INET)
175 *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
176 #ifdef HAVE_IPV6
177 else
178 *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
179 #endif
181 else if (!flags || (flags & F_NXDOMAIN))
182 flags = F_NOERR;
184 else
185 flags = 0;
190 if (flags == 0 && !(qtype & F_BIGNAME) &&
191 (daemon->options & OPT_NODOTS_LOCAL) && !strchr(qdomain, '.') && namelen != 0)
192 /* don't forward simple names, make exception for NS queries and empty name. */
193 flags = F_NXDOMAIN;
195 if (flags == F_NXDOMAIN && check_for_local_domain(qdomain, now))
196 flags = F_NOERR;
198 if (flags)
200 int logflags = 0;
202 if (flags == F_NXDOMAIN || flags == F_NOERR)
203 logflags = F_NEG | qtype;
205 log_query(logflags | flags | F_CONFIG | F_FORWARD, qdomain, *addrpp, NULL);
207 else if ((*type) & SERV_USE_RESOLV)
209 *type = 0; /* use normal servers for this domain */
210 *domain = NULL;
212 return flags;
215 static int forward_query(int udpfd, union mysockaddr *udpaddr,
216 struct all_addr *dst_addr, unsigned int dst_iface,
217 HEADER *header, size_t plen, time_t now, struct frec *forward)
219 char *domain = NULL;
220 int type = 0, norebind = 0;
221 struct all_addr *addrp = NULL;
222 unsigned int crc = questions_crc(header, plen, daemon->namebuff);
223 unsigned short flags = 0;
224 unsigned short gotname = extract_request(header, plen, daemon->namebuff, NULL);
225 struct server *start = NULL;
227 /* may be no servers available. */
228 if (!daemon->servers)
229 forward = NULL;
230 else if (forward || (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, crc)))
232 /* retry on existing query, send to all available servers */
233 domain = forward->sentto->domain;
234 forward->sentto->failed_queries++;
235 if (!(daemon->options & OPT_ORDER))
237 forward->forwardall = 1;
238 daemon->last_server = NULL;
240 type = forward->sentto->flags & SERV_TYPE;
241 if (!(start = forward->sentto->next))
242 start = daemon->servers; /* at end of list, recycle */
243 header->id = htons(forward->new_id);
245 else
247 if (gotname)
248 flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
250 if (!flags && !(forward = get_new_frec(now, NULL)))
251 /* table full - server failure. */
252 flags = F_NEG;
254 if (forward)
256 forward->source = *udpaddr;
257 forward->dest = *dst_addr;
258 forward->iface = dst_iface;
259 forward->orig_id = ntohs(header->id);
260 forward->new_id = get_id(crc);
261 forward->fd = udpfd;
262 forward->crc = crc;
263 forward->forwardall = 0;
264 forward->norebind = norebind;
265 header->id = htons(forward->new_id);
267 /* In strict_order mode, always try servers in the order
268 specified in resolv.conf, if a domain is given
269 always try all the available servers,
270 otherwise, use the one last known to work. */
272 if (type == 0)
274 if (daemon->options & OPT_ORDER)
275 start = daemon->servers;
276 else if (!(start = daemon->last_server) ||
277 daemon->forwardcount++ > FORWARD_TEST ||
278 difftime(now, daemon->forwardtime) > FORWARD_TIME)
280 start = daemon->servers;
281 forward->forwardall = 1;
282 daemon->forwardcount = 0;
283 daemon->forwardtime = now;
286 else
288 start = daemon->servers;
289 if (!(daemon->options & OPT_ORDER))
290 forward->forwardall = 1;
295 /* check for send errors here (no route to host)
296 if we fail to send to all nameservers, send back an error
297 packet straight away (helps modem users when offline) */
299 if (!flags && forward)
301 struct server *firstsentto = start;
302 int forwarded = 0;
304 while (1)
306 /* only send to servers dealing with our domain.
307 domain may be NULL, in which case server->domain
308 must be NULL also. */
310 if (type == (start->flags & SERV_TYPE) &&
311 (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
312 !(start->flags & SERV_LITERAL_ADDRESS))
314 int fd;
316 /* find server socket to use, may need to get random one. */
317 if (start->sfd)
318 fd = start->sfd->fd;
319 else
321 #ifdef HAVE_IPV6
322 if (start->addr.sa.sa_family == AF_INET6)
324 if (!forward->rfd6 &&
325 !(forward->rfd6 = allocate_rfd(AF_INET6)))
326 break;
327 daemon->rfd_save = forward->rfd6;
328 fd = forward->rfd6->fd;
330 else
331 #endif
333 if (!forward->rfd4 &&
334 !(forward->rfd4 = allocate_rfd(AF_INET)))
335 break;
336 daemon->rfd_save = forward->rfd4;
337 fd = forward->rfd4->fd;
341 if (sendto(fd, (char *)header, plen, 0,
342 &start->addr.sa,
343 sa_len(&start->addr)) == -1)
345 if (retry_send())
346 continue;
348 else
350 /* Keep info in case we want to re-send this packet */
351 daemon->srv_save = start;
352 daemon->packet_len = plen;
354 if (!gotname)
355 strcpy(daemon->namebuff, "query");
356 if (start->addr.sa.sa_family == AF_INET)
357 log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
358 (struct all_addr *)&start->addr.in.sin_addr, NULL);
359 #ifdef HAVE_IPV6
360 else
361 log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
362 (struct all_addr *)&start->addr.in6.sin6_addr, NULL);
363 #endif
364 start->queries++;
365 forwarded = 1;
366 forward->sentto = start;
367 if (!forward->forwardall)
368 break;
369 forward->forwardall++;
373 if (!(start = start->next))
374 start = daemon->servers;
376 if (start == firstsentto)
377 break;
380 if (forwarded)
381 return 1;
383 /* could not send on, prepare to return */
384 header->id = htons(forward->orig_id);
385 free_frec(forward); /* cancel */
388 /* could not send on, return empty answer or address if known for whole domain */
389 if (udpfd != -1)
391 plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl);
392 send_from(udpfd, daemon->options & OPT_NOWILD, (char *)header, plen, udpaddr, dst_addr, dst_iface);
395 return 0;
398 static size_t process_reply(HEADER *header, time_t now,
399 struct server *server, size_t n, int check_rebind)
401 unsigned char *pheader, *sizep;
402 int munged = 0, is_sign;
403 size_t plen;
405 /* If upstream is advertising a larger UDP packet size
406 than we allow, trim it so that we don't get overlarge
407 requests for the client. We can't do this for signed packets. */
409 if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign)) && !is_sign)
411 unsigned short udpsz;
412 unsigned char *psave = sizep;
414 GETSHORT(udpsz, sizep);
415 if (udpsz > daemon->edns_pktsz)
416 PUTSHORT(daemon->edns_pktsz, psave);
419 if (header->opcode != QUERY || (header->rcode != NOERROR && header->rcode != NXDOMAIN))
420 return n;
422 /* Complain loudly if the upstream server is non-recursive. */
423 if (!header->ra && header->rcode == NOERROR && ntohs(header->ancount) == 0 &&
424 server && !(server->flags & SERV_WARNED_RECURSIVE))
426 prettyprint_addr(&server->addr, daemon->namebuff);
427 my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
428 if (!(daemon->options & OPT_LOG))
429 server->flags |= SERV_WARNED_RECURSIVE;
432 if (daemon->bogus_addr && header->rcode != NXDOMAIN &&
433 check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now))
435 munged = 1;
436 header->rcode = NXDOMAIN;
437 header->aa = 0;
439 else
441 if (header->rcode == NXDOMAIN &&
442 extract_request(header, n, daemon->namebuff, NULL) &&
443 check_for_local_domain(daemon->namebuff, now))
445 /* if we forwarded a query for a locally known name (because it was for
446 an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
447 since we know that the domain exists, even if upstream doesn't */
448 munged = 1;
449 header->aa = 1;
450 header->rcode = NOERROR;
453 if (extract_addresses(header, n, daemon->namebuff, now, is_sign, check_rebind))
455 my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected: %s"), daemon->namebuff);
456 munged = 1;
460 /* do this after extract_addresses. Ensure NODATA reply and remove
461 nameserver info. */
463 if (munged)
465 header->ancount = htons(0);
466 header->nscount = htons(0);
467 header->arcount = htons(0);
470 /* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
471 sections of the packet. Find the new length here and put back pseudoheader
472 if it was removed. */
473 return resize_packet(header, n, pheader, plen);
476 /* sets new last_server */
477 void reply_query(int fd, int family, time_t now)
479 /* packet from peer server, extract data for cache, and send to
480 original requester */
481 HEADER *header;
482 union mysockaddr serveraddr;
483 struct frec *forward;
484 socklen_t addrlen = sizeof(serveraddr);
485 ssize_t n = recvfrom(fd, daemon->packet, daemon->edns_pktsz, 0, &serveraddr.sa, &addrlen);
486 size_t nn;
487 struct server *server;
489 /* packet buffer overwritten */
490 daemon->srv_save = NULL;
492 /* Determine the address of the server replying so that we can mark that as good */
493 serveraddr.sa.sa_family = family;
494 #ifdef HAVE_IPV6
495 if (serveraddr.sa.sa_family == AF_INET6)
496 serveraddr.in6.sin6_flowinfo = 0;
497 #endif
499 /* spoof check: answer must come from known server, */
500 for (server = daemon->servers; server; server = server->next)
501 if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
502 sockaddr_isequal(&server->addr, &serveraddr))
503 break;
505 header = (HEADER *)daemon->packet;
507 if (!server ||
508 n < (int)sizeof(HEADER) || !header->qr ||
509 !(forward = lookup_frec(ntohs(header->id), questions_crc(header, n, daemon->namebuff))))
510 return;
512 server = forward->sentto;
514 if ((header->rcode == SERVFAIL || header->rcode == REFUSED) &&
515 !(daemon->options & OPT_ORDER) &&
516 forward->forwardall == 0)
517 /* for broken servers, attempt to send to another one. */
519 unsigned char *pheader;
520 size_t plen;
521 int is_sign;
523 /* recreate query from reply */
524 pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign);
525 if (!is_sign)
527 header->ancount = htons(0);
528 header->nscount = htons(0);
529 header->arcount = htons(0);
530 if ((nn = resize_packet(header, (size_t)n, pheader, plen)))
532 header->qr = 0;
533 header->tc = 0;
534 forward_query(-1, NULL, NULL, 0, header, nn, now, forward);
535 return;
540 if ((forward->sentto->flags & SERV_TYPE) == 0)
542 if (header->rcode == SERVFAIL || header->rcode == REFUSED)
543 server = NULL;
544 else
546 struct server *last_server;
548 /* find good server by address if possible, otherwise assume the last one we sent to */
549 for (last_server = daemon->servers; last_server; last_server = last_server->next)
550 if (!(last_server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR)) &&
551 sockaddr_isequal(&last_server->addr, &serveraddr))
553 server = last_server;
554 break;
557 if (!(daemon->options & OPT_ALL_SERVERS))
558 daemon->last_server = server;
561 /* If the answer is an error, keep the forward record in place in case
562 we get a good reply from another server. Kill it when we've
563 had replies from all to avoid filling the forwarding table when
564 everything is broken */
565 if (forward->forwardall == 0 || --forward->forwardall == 1 ||
566 (header->rcode != REFUSED && header->rcode != SERVFAIL))
568 int check_rebind = !forward->norebind;
570 if (!(daemon->options & OPT_NO_REBIND))
571 check_rebind = 0;
573 if ((nn = process_reply(header, now, server, (size_t)n, check_rebind)))
575 header->id = htons(forward->orig_id);
576 header->ra = 1; /* recursion if available */
577 send_from(forward->fd, daemon->options & OPT_NOWILD, daemon->packet, nn,
578 &forward->source, &forward->dest, forward->iface);
580 free_frec(forward); /* cancel */
585 void receive_query(struct listener *listen, time_t now)
587 HEADER *header = (HEADER *)daemon->packet;
588 union mysockaddr source_addr;
589 unsigned short type;
590 struct all_addr dst_addr;
591 struct in_addr netmask, dst_addr_4;
592 size_t m;
593 ssize_t n;
594 int if_index = 0;
595 struct iovec iov[1];
596 struct msghdr msg;
597 struct cmsghdr *cmptr;
598 union {
599 struct cmsghdr align; /* this ensures alignment */
600 #ifdef HAVE_IPV6
601 char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
602 #endif
603 #if defined(HAVE_LINUX_NETWORK)
604 char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
605 #elif defined(IP_RECVDSTADDR) && defined(HAVE_SOLARIS_NETWORK)
606 char control[CMSG_SPACE(sizeof(struct in_addr)) +
607 CMSG_SPACE(sizeof(unsigned int))];
608 #elif defined(IP_RECVDSTADDR)
609 char control[CMSG_SPACE(sizeof(struct in_addr)) +
610 CMSG_SPACE(sizeof(struct sockaddr_dl))];
611 #endif
612 } control_u;
614 /* packet buffer overwritten */
615 daemon->srv_save = NULL;
617 if (listen->family == AF_INET && (daemon->options & OPT_NOWILD))
619 dst_addr_4 = listen->iface->addr.in.sin_addr;
620 netmask = listen->iface->netmask;
622 else
624 dst_addr_4.s_addr = 0;
625 netmask.s_addr = 0;
628 iov[0].iov_base = daemon->packet;
629 iov[0].iov_len = daemon->edns_pktsz;
631 msg.msg_control = control_u.control;
632 msg.msg_controllen = sizeof(control_u);
633 msg.msg_flags = 0;
634 msg.msg_name = &source_addr;
635 msg.msg_namelen = sizeof(source_addr);
636 msg.msg_iov = iov;
637 msg.msg_iovlen = 1;
639 if ((n = recvmsg(listen->fd, &msg, 0)) == -1)
640 return;
642 if (n < (int)sizeof(HEADER) ||
643 (msg.msg_flags & MSG_TRUNC) ||
644 header->qr)
645 return;
647 source_addr.sa.sa_family = listen->family;
648 #ifdef HAVE_IPV6
649 if (listen->family == AF_INET6)
650 source_addr.in6.sin6_flowinfo = 0;
651 #endif
653 if (!(daemon->options & OPT_NOWILD))
655 struct ifreq ifr;
657 if (msg.msg_controllen < sizeof(struct cmsghdr))
658 return;
660 #if defined(HAVE_LINUX_NETWORK)
661 if (listen->family == AF_INET)
662 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
663 if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO)
665 union {
666 unsigned char *c;
667 struct in_pktinfo *p;
668 } p;
669 p.c = CMSG_DATA(cmptr);
670 dst_addr_4 = dst_addr.addr.addr4 = p.p->ipi_spec_dst;
671 if_index = p.p->ipi_ifindex;
673 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
674 if (listen->family == AF_INET)
676 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
678 union {
679 unsigned char *c;
680 unsigned int *i;
681 struct in_addr *a;
682 #ifndef HAVE_SOLARIS_NETWORK
683 struct sockaddr_dl *s;
684 #endif
685 } p;
686 p.c = CMSG_DATA(cmptr);
687 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
688 dst_addr_4 = dst_addr.addr.addr4 = *(p.a);
689 else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
690 #ifdef HAVE_SOLARIS_NETWORK
691 if_index = *(p.i);
692 #else
693 if_index = p.s->sdl_index;
694 #endif
697 #endif
699 #ifdef HAVE_IPV6
700 if (listen->family == AF_INET6)
702 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
703 if (cmptr->cmsg_level == IPV6_LEVEL && cmptr->cmsg_type == daemon->v6pktinfo)
705 union {
706 unsigned char *c;
707 struct in6_pktinfo *p;
708 } p;
709 p.c = CMSG_DATA(cmptr);
711 dst_addr.addr.addr6 = p.p->ipi6_addr;
712 if_index = p.p->ipi6_ifindex;
715 #endif
717 /* enforce available interface configuration */
719 if (!indextoname(listen->fd, if_index, ifr.ifr_name) ||
720 !iface_check(listen->family, &dst_addr, ifr.ifr_name, &if_index))
721 return;
723 if (listen->family == AF_INET &&
724 (daemon->options & OPT_LOCALISE) &&
725 ioctl(listen->fd, SIOCGIFNETMASK, &ifr) == -1)
726 return;
728 netmask = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
731 if (extract_request(header, (size_t)n, daemon->namebuff, &type))
733 char types[20];
735 querystr(types, type);
737 if (listen->family == AF_INET)
738 log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
739 (struct all_addr *)&source_addr.in.sin_addr, types);
740 #ifdef HAVE_IPV6
741 else
742 log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
743 (struct all_addr *)&source_addr.in6.sin6_addr, types);
744 #endif
747 m = answer_request (header, ((char *) header) + PACKETSZ, (size_t)n,
748 dst_addr_4, netmask, now);
749 if (m >= 1)
751 send_from(listen->fd, daemon->options & OPT_NOWILD, (char *)header,
752 m, &source_addr, &dst_addr, if_index);
753 daemon->local_answer++;
755 else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
756 header, (size_t)n, now, NULL))
757 daemon->queries_forwarded++;
758 else
759 daemon->local_answer++;
762 /* The daemon forks before calling this: it should deal with one connection,
763 blocking as neccessary, and then return. Note, need to be a bit careful
764 about resources for debug mode, when the fork is suppressed: that's
765 done by the caller. */
766 unsigned char *tcp_request(int confd, time_t now,
767 struct in_addr local_addr, struct in_addr netmask)
769 int size = 0, norebind = 0;
770 size_t m;
771 unsigned short qtype, gotname;
772 unsigned char c1, c2;
773 /* Max TCP packet + slop */
774 unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ);
775 HEADER *header;
776 struct server *last_server;
778 while (1)
780 if (!packet ||
781 !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) ||
782 !(size = c1 << 8 | c2) ||
783 !read_write(confd, packet, size, 1))
784 return packet;
786 if (size < (int)sizeof(HEADER))
787 continue;
789 header = (HEADER *)packet;
791 if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
793 union mysockaddr peer_addr;
794 socklen_t peer_len = sizeof(union mysockaddr);
796 if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) != -1)
798 char types[20];
800 querystr(types, qtype);
802 if (peer_addr.sa.sa_family == AF_INET)
803 log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
804 (struct all_addr *)&peer_addr.in.sin_addr, types);
805 #ifdef HAVE_IPV6
806 else
807 log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
808 (struct all_addr *)&peer_addr.in6.sin6_addr, types);
809 #endif
813 /* m > 0 if answered from cache */
814 m = answer_request(header, ((char *) header) + 65536, (unsigned int)size,
815 local_addr, netmask, now);
817 /* Do this by steam now we're not in the select() loop */
818 check_log_writer(NULL);
820 if (m == 0)
822 unsigned short flags = 0;
823 struct all_addr *addrp = NULL;
824 int type = 0;
825 char *domain = NULL;
827 if (gotname)
828 flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
830 if (type != 0 || (daemon->options & OPT_ORDER) || !daemon->last_server)
831 last_server = daemon->servers;
832 else
833 last_server = daemon->last_server;
835 if (!flags && last_server)
837 struct server *firstsendto = NULL;
838 unsigned int crc = questions_crc(header, (unsigned int)size, daemon->namebuff);
840 /* Loop round available servers until we succeed in connecting to one.
841 Note that this code subtley ensures that consecutive queries on this connection
842 which can go to the same server, do so. */
843 while (1)
845 if (!firstsendto)
846 firstsendto = last_server;
847 else
849 if (!(last_server = last_server->next))
850 last_server = daemon->servers;
852 if (last_server == firstsendto)
853 break;
856 /* server for wrong domain */
857 if (type != (last_server->flags & SERV_TYPE) ||
858 (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, last_server->domain)))
859 continue;
861 if ((last_server->tcpfd == -1) &&
862 (last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) != -1 &&
863 (!local_bind(last_server->tcpfd, &last_server->source_addr, last_server->interface, 1) ||
864 connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1))
866 close(last_server->tcpfd);
867 last_server->tcpfd = -1;
870 if (last_server->tcpfd == -1)
871 continue;
873 c1 = size >> 8;
874 c2 = size;
876 if (!read_write(last_server->tcpfd, &c1, 1, 0) ||
877 !read_write(last_server->tcpfd, &c2, 1, 0) ||
878 !read_write(last_server->tcpfd, packet, size, 0) ||
879 !read_write(last_server->tcpfd, &c1, 1, 1) ||
880 !read_write(last_server->tcpfd, &c2, 1, 1))
882 close(last_server->tcpfd);
883 last_server->tcpfd = -1;
884 continue;
887 m = (c1 << 8) | c2;
888 if (!read_write(last_server->tcpfd, packet, m, 1))
889 return packet;
891 if (!gotname)
892 strcpy(daemon->namebuff, "query");
893 if (last_server->addr.sa.sa_family == AF_INET)
894 log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
895 (struct all_addr *)&last_server->addr.in.sin_addr, NULL);
896 #ifdef HAVE_IPV6
897 else
898 log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
899 (struct all_addr *)&last_server->addr.in6.sin6_addr, NULL);
900 #endif
902 /* There's no point in updating the cache, since this process will exit and
903 lose the information after a few queries. We make this call for the alias and
904 bogus-nxdomain side-effects. */
905 /* If the crc of the question section doesn't match the crc we sent, then
906 someone might be attempting to insert bogus values into the cache by
907 sending replies containing questions and bogus answers. */
908 if (crc == questions_crc(header, (unsigned int)m, daemon->namebuff))
909 m = process_reply(header, now, last_server, (unsigned int)m, (daemon->options & OPT_NO_REBIND) && !norebind );
911 break;
915 /* In case of local answer or no connections made. */
916 if (m == 0)
917 m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
920 check_log_writer(NULL);
922 c1 = m>>8;
923 c2 = m;
924 if (!read_write(confd, &c1, 1, 0) ||
925 !read_write(confd, &c2, 1, 0) ||
926 !read_write(confd, packet, m, 0))
927 return packet;
931 static struct frec *allocate_frec(time_t now)
933 struct frec *f;
935 if ((f = (struct frec *)whine_malloc(sizeof(struct frec))))
937 f->next = daemon->frec_list;
938 f->time = now;
939 f->sentto = NULL;
940 f->rfd4 = NULL;
941 #ifdef HAVE_IPV6
942 f->rfd6 = NULL;
943 #endif
944 daemon->frec_list = f;
947 return f;
950 static struct randfd *allocate_rfd(int family)
952 static int finger = 0;
953 int i;
955 /* limit the number of sockets we have open to avoid starvation of
956 (eg) TFTP. Once we have a reasonable number, randomness should be OK */
958 for (i = 0; i < RANDOM_SOCKS; i++)
959 if (daemon->randomsocks[i].refcount == 0)
961 if ((daemon->randomsocks[i].fd = random_sock(family)) == -1)
962 break;
964 daemon->randomsocks[i].refcount = 1;
965 daemon->randomsocks[i].family = family;
966 return &daemon->randomsocks[i];
969 /* No free ones or cannot get new socket, grab an existing one */
970 for (i = 0; i < RANDOM_SOCKS; i++)
972 int j = (i+finger) % RANDOM_SOCKS;
973 if (daemon->randomsocks[j].refcount != 0 &&
974 daemon->randomsocks[j].family == family &&
975 daemon->randomsocks[j].refcount != 0xffff)
977 finger = j;
978 daemon->randomsocks[j].refcount++;
979 return &daemon->randomsocks[j];
983 return NULL; /* doom */
986 static void free_frec(struct frec *f)
988 if (f->rfd4 && --(f->rfd4->refcount) == 0)
989 close(f->rfd4->fd);
991 f->rfd4 = NULL;
992 f->sentto = NULL;
994 #ifdef HAVE_IPV6
995 if (f->rfd6 && --(f->rfd6->refcount) == 0)
996 close(f->rfd6->fd);
998 f->rfd6 = NULL;
999 #endif
1002 /* if wait==NULL return a free or older than TIMEOUT record.
1003 else return *wait zero if one available, or *wait is delay to
1004 when the oldest in-use record will expire. Impose an absolute
1005 limit of 4*TIMEOUT before we wipe things (for random sockets) */
1006 struct frec *get_new_frec(time_t now, int *wait)
1008 struct frec *f, *oldest, *target;
1009 int count;
1011 if (wait)
1012 *wait = 0;
1014 for (f = daemon->frec_list, oldest = NULL, target = NULL, count = 0; f; f = f->next, count++)
1015 if (!f->sentto)
1016 target = f;
1017 else
1019 if (difftime(now, f->time) >= 4*TIMEOUT)
1021 free_frec(f);
1022 target = f;
1025 if (!oldest || difftime(f->time, oldest->time) <= 0)
1026 oldest = f;
1029 if (target)
1031 target->time = now;
1032 return target;
1035 /* can't find empty one, use oldest if there is one
1036 and it's older than timeout */
1037 if (oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
1039 /* keep stuff for twice timeout if we can by allocating a new
1040 record instead */
1041 if (difftime(now, oldest->time) < 2*TIMEOUT &&
1042 count <= daemon->ftabsize &&
1043 (f = allocate_frec(now)))
1044 return f;
1046 if (!wait)
1048 free_frec(oldest);
1049 oldest->time = now;
1051 return oldest;
1054 /* none available, calculate time 'till oldest record expires */
1055 if (count > daemon->ftabsize)
1057 if (oldest && wait)
1058 *wait = oldest->time + (time_t)TIMEOUT - now;
1059 return NULL;
1062 if (!(f = allocate_frec(now)) && wait)
1063 /* wait one second on malloc failure */
1064 *wait = 1;
1066 return f; /* OK if malloc fails and this is NULL */
1069 /* crc is all-ones if not known. */
1070 static struct frec *lookup_frec(unsigned short id, unsigned int crc)
1072 struct frec *f;
1074 for(f = daemon->frec_list; f; f = f->next)
1075 if (f->sentto && f->new_id == id &&
1076 (f->crc == crc || crc == 0xffffffff))
1077 return f;
1079 return NULL;
1082 static struct frec *lookup_frec_by_sender(unsigned short id,
1083 union mysockaddr *addr,
1084 unsigned int crc)
1086 struct frec *f;
1088 for(f = daemon->frec_list; f; f = f->next)
1089 if (f->sentto &&
1090 f->orig_id == id &&
1091 f->crc == crc &&
1092 sockaddr_isequal(&f->source, addr))
1093 return f;
1095 return NULL;
1098 /* A server record is going away, remove references to it */
1099 void server_gone(struct server *server)
1101 struct frec *f;
1103 for (f = daemon->frec_list; f; f = f->next)
1104 if (f->sentto && f->sentto == server)
1105 free_frec(f);
1107 if (daemon->last_server == server)
1108 daemon->last_server = NULL;
1110 if (daemon->srv_save == server)
1111 daemon->srv_save = NULL;
1114 /* return unique random ids. */
1115 static unsigned short get_id(unsigned int crc)
1117 unsigned short ret = 0;
1120 ret = rand16();
1121 while (lookup_frec(ret, crc));
1123 return ret;