source: src/router/dnsmasq/src/forward.c @ 31543

Last change on this file since 31543 was 31543, checked in by brainslayer, 3 months ago

latest dnsmasq code

File size: 65.1 KB
Line 
1/* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
2
3   This program is free software; you can redistribute it and/or modify
4   it under the terms of the GNU General Public License as published by
5   the Free Software Foundation; version 2 dated June, 1991, or
6   (at your option) version 3 dated 29 June, 2007.
7 
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.
12     
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/>.
15*/
16
17#include "dnsmasq.h"
18
19static struct frec *lookup_frec(unsigned short id, void *hash);
20static struct frec *lookup_frec_by_sender(unsigned short id,
21                                          union mysockaddr *addr,
22                                          void *hash);
23static unsigned short get_id(void);
24static void free_frec(struct frec *f);
25
26/* Send a UDP packet with its source address set as "source"
27   unless nowild is true, when we just send it with the kernel default */
28int send_from(int fd, int nowild, char *packet, size_t len,
29              union mysockaddr *to, struct all_addr *source,
30              unsigned int iface)
31{
32  struct msghdr msg;
33  struct iovec iov[1];
34  union {
35    struct cmsghdr align; /* this ensures alignment */
36#if defined(HAVE_LINUX_NETWORK)
37    char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
38#elif defined(IP_SENDSRCADDR)
39    char control[CMSG_SPACE(sizeof(struct in_addr))];
40#endif
41#ifdef HAVE_IPV6
42    char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
43#endif
44  } control_u;
45 
46  iov[0].iov_base = packet;
47  iov[0].iov_len = len;
48
49  msg.msg_control = NULL;
50  msg.msg_controllen = 0;
51  msg.msg_flags = 0;
52  msg.msg_name = to;
53  msg.msg_namelen = sa_len(to);
54  msg.msg_iov = iov;
55  msg.msg_iovlen = 1;
56 
57  if (!nowild)
58    {
59      struct cmsghdr *cmptr;
60      msg.msg_control = &control_u;
61      msg.msg_controllen = sizeof(control_u);
62      cmptr = CMSG_FIRSTHDR(&msg);
63
64      if (to->sa.sa_family == AF_INET)
65        {
66#if defined(HAVE_LINUX_NETWORK)
67          struct in_pktinfo p;
68          p.ipi_ifindex = 0;
69          p.ipi_spec_dst = source->addr.addr4;
70          memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
71          msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
72          cmptr->cmsg_level = IPPROTO_IP;
73          cmptr->cmsg_type = IP_PKTINFO;
74#elif defined(IP_SENDSRCADDR)
75          memcpy(CMSG_DATA(cmptr), &(source->addr.addr4), sizeof(source->addr.addr4));
76          msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
77          cmptr->cmsg_level = IPPROTO_IP;
78          cmptr->cmsg_type = IP_SENDSRCADDR;
79#endif
80        }
81      else
82#ifdef HAVE_IPV6
83        {
84          struct in6_pktinfo p;
85          p.ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local addrs */
86          p.ipi6_addr = source->addr.addr6;
87          memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
88          msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
89          cmptr->cmsg_type = daemon->v6pktinfo;
90          cmptr->cmsg_level = IPPROTO_IPV6;
91        }
92#else
93      (void)iface; /* eliminate warning */
94#endif
95    }
96 
97  while (retry_send(sendmsg(fd, &msg, 0)));
98
99  /* If interface is still in DAD, EINVAL results - ignore that. */
100  if (errno != 0 && errno != EINVAL)
101    {
102      my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
103      return 0;
104    }
105 
106  return 1;
107}
108         
109static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigned int qtype,
110                                   char *qdomain, int *type, char **domain, int *norebind)
111                             
112{
113  /* If the query ends in the domain in one of our servers, set
114     domain to point to that name. We find the largest match to allow both
115     domain.org and sub.domain.org to exist. */
116 
117  unsigned int namelen = strlen(qdomain);
118  unsigned int matchlen = 0;
119  struct server *serv;
120  unsigned int flags = 0;
121 
122  for (serv = daemon->servers; serv; serv=serv->next)
123    /* domain matches take priority over NODOTS matches */
124    if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') && namelen != 0)
125      {
126        unsigned int sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
127        *type = SERV_FOR_NODOTS;
128        if (serv->flags & SERV_NO_ADDR)
129          flags = F_NXDOMAIN;
130        else if (serv->flags & SERV_LITERAL_ADDRESS)
131          {
132            if (sflag & qtype)
133              {
134                flags = sflag;
135                if (serv->addr.sa.sa_family == AF_INET)
136                  *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
137#ifdef HAVE_IPV6
138                else
139                  *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
140#endif
141              }
142            else if (!flags || (flags & F_NXDOMAIN))
143              flags = F_NOERR;
144          }
145      }
146    else if (serv->flags & SERV_HAS_DOMAIN)
147      {
148        unsigned int domainlen = strlen(serv->domain);
149        char *matchstart = qdomain + namelen - domainlen;
150        if (namelen >= domainlen &&
151            hostname_isequal(matchstart, serv->domain) &&
152            (domainlen == 0 || namelen == domainlen || *(matchstart-1) == '.' ))
153          {
154            if ((serv->flags & SERV_NO_REBIND) && norebind)     
155              *norebind = 1;
156            else
157              {
158                unsigned int sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
159                /* implement priority rules for --address and --server for same domain.
160                   --address wins if the address is for the correct AF
161                   --server wins otherwise. */
162                if (domainlen != 0 && domainlen == matchlen)
163                  {
164                    if ((serv->flags & SERV_LITERAL_ADDRESS))
165                      {
166                        if (!(sflag & qtype) && flags == 0)
167                          continue;
168                      }
169                    else
170                      {
171                        if (flags & (F_IPV4 | F_IPV6))
172                          continue;
173                      }
174                  }
175               
176                if (domainlen >= matchlen)
177                  {
178                    *type = serv->flags & (SERV_HAS_DOMAIN | SERV_USE_RESOLV | SERV_NO_REBIND | SERV_DO_DNSSEC);
179                    *domain = serv->domain;
180                    matchlen = domainlen;
181                    if (serv->flags & SERV_NO_ADDR)
182                      flags = F_NXDOMAIN;
183                    else if (serv->flags & SERV_LITERAL_ADDRESS)
184                      {
185                        if (sflag & qtype)
186                          {
187                            flags = sflag;
188                            if (serv->addr.sa.sa_family == AF_INET)
189                              *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
190#ifdef HAVE_IPV6
191                            else
192                              *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
193#endif
194                          }
195                        else if (!flags || (flags & F_NXDOMAIN))
196                          flags = F_NOERR;
197                      }
198                    else
199                      flags = 0;
200                  }
201              }
202          }
203      }
204 
205  if (flags == 0 && !(qtype & F_QUERY) &&
206      option_bool(OPT_NODOTS_LOCAL) && !strchr(qdomain, '.') && namelen != 0)
207    /* don't forward A or AAAA queries for simple names, except the empty name */
208    flags = F_NOERR;
209 
210  if (flags == F_NXDOMAIN && check_for_local_domain(qdomain, now))
211    flags = F_NOERR;
212
213  if (flags)
214    {
215      int logflags = 0;
216     
217      if (flags == F_NXDOMAIN || flags == F_NOERR)
218        logflags = F_NEG | qtype;
219 
220      log_query(logflags | flags | F_CONFIG | F_FORWARD, qdomain, *addrpp, NULL);
221    }
222  else if ((*type) & SERV_USE_RESOLV)
223    {
224      *type = 0; /* use normal servers for this domain */
225      *domain = NULL;
226    }
227  return  flags;
228}
229
230static int forward_query(int udpfd, union mysockaddr *udpaddr,
231                         struct all_addr *dst_addr, unsigned int dst_iface,
232                         struct dns_header *header, size_t plen, time_t now,
233                         struct frec *forward, int ad_reqd, int do_bit)
234{
235  char *domain = NULL;
236  int type = SERV_DO_DNSSEC, norebind = 0;
237  struct all_addr *addrp = NULL;
238  unsigned int flags = 0;
239  struct server *start = NULL;
240#ifdef HAVE_DNSSEC
241  void *hash = hash_questions(header, plen, daemon->namebuff);
242  int do_dnssec = 0;
243#else
244  unsigned int crc = questions_crc(header, plen, daemon->namebuff);
245  void *hash = &crc;
246#endif
247 unsigned int gotname = extract_request(header, plen, daemon->namebuff, NULL);
248
249 (void)do_bit;
250
251  /* may be no servers available. */
252  if (forward || (hash && (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, hash))))
253    {
254      /* If we didn't get an answer advertising a maximal packet in EDNS,
255         fall back to 1280, which should work everywhere on IPv6.
256         If that generates an answer, it will become the new default
257         for this server */
258      forward->flags |= FREC_TEST_PKTSZ;
259     
260#ifdef HAVE_DNSSEC
261      /* If we've already got an answer to this query, but we're awaiting keys for validation,
262         there's no point retrying the query, retry the key query instead...... */
263      if (forward->blocking_query)
264        {
265          int fd, is_sign;
266          unsigned char *pheader;
267         
268          forward->flags &= ~FREC_TEST_PKTSZ;
269         
270          while (forward->blocking_query)
271            forward = forward->blocking_query;
272           
273          forward->flags |= FREC_TEST_PKTSZ;
274         
275          blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
276          plen = forward->stash_len;
277         
278          if (find_pseudoheader(header, plen, NULL, &pheader, &is_sign, NULL) && !is_sign)
279            PUTSHORT(SAFE_PKTSZ, pheader);
280
281          if (forward->sentto->addr.sa.sa_family == AF_INET)
282            log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (struct all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec");
283#ifdef HAVE_IPV6
284          else
285            log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (struct all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec");
286#endif
287 
288          if (forward->sentto->sfd)
289            fd = forward->sentto->sfd->fd;
290          else
291            {
292#ifdef HAVE_IPV6
293              if (forward->sentto->addr.sa.sa_family == AF_INET6)
294                fd = forward->rfd6->fd;
295              else
296#endif
297                fd = forward->rfd4->fd;
298            }
299         
300          while (retry_send( sendto(fd, (char *)header, plen, 0,
301                                    &forward->sentto->addr.sa,
302                                    sa_len(&forward->sentto->addr))));
303         
304          return 1;
305        }
306#endif
307
308      /* retry on existing query, send to all available servers  */
309      domain = forward->sentto->domain;
310      forward->sentto->failed_queries++;
311      if (!option_bool(OPT_ORDER))
312        {
313          forward->forwardall = 1;
314          daemon->last_server = NULL;
315        }
316      type = forward->sentto->flags & SERV_TYPE;
317#ifdef HAVE_DNSSEC
318      do_dnssec = forward->sentto->flags & SERV_DO_DNSSEC;
319#endif
320
321      if (!(start = forward->sentto->next))
322        start = daemon->servers; /* at end of list, recycle */
323      header->id = htons(forward->new_id);
324    }
325  else
326    {
327      if (gotname)
328        flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
329     
330#ifdef HAVE_DNSSEC
331      do_dnssec = type & SERV_DO_DNSSEC;
332#endif
333      type &= ~SERV_DO_DNSSEC;     
334
335      if (daemon->servers && !flags)
336        forward = get_new_frec(now, NULL, 0);
337      /* table full - flags == 0, return REFUSED */
338     
339      if (forward)
340        {
341          forward->source = *udpaddr;
342          forward->dest = *dst_addr;
343          forward->iface = dst_iface;
344          forward->orig_id = ntohs(header->id);
345          forward->new_id = get_id();
346          forward->fd = udpfd;
347          memcpy(forward->hash, hash, HASH_SIZE);
348          forward->forwardall = 0;
349          forward->flags = 0;
350          if (norebind)
351            forward->flags |= FREC_NOREBIND;
352          if (header->hb4 & HB4_CD)
353            forward->flags |= FREC_CHECKING_DISABLED;
354          if (ad_reqd)
355            forward->flags |= FREC_AD_QUESTION;
356#ifdef HAVE_DNSSEC
357          forward->work_counter = DNSSEC_WORK;
358          if (do_bit)
359            forward->flags |= FREC_DO_QUESTION;
360#endif
361         
362          header->id = htons(forward->new_id);
363         
364          /* In strict_order mode, always try servers in the order
365             specified in resolv.conf, if a domain is given
366             always try all the available servers,
367             otherwise, use the one last known to work. */
368         
369          if (type == 0)
370            {
371              if (option_bool(OPT_ORDER))
372                start = daemon->servers;
373              else if (!(start = daemon->last_server) ||
374                       daemon->forwardcount++ > FORWARD_TEST ||
375                       difftime(now, daemon->forwardtime) > FORWARD_TIME)
376                {
377                  start = daemon->servers;
378                  forward->forwardall = 1;
379                  daemon->forwardcount = 0;
380                  daemon->forwardtime = now;
381                }
382            }
383          else
384            {
385              start = daemon->servers;
386              if (!option_bool(OPT_ORDER))
387                forward->forwardall = 1;
388            }
389        }
390    }
391
392  /* check for send errors here (no route to host)
393     if we fail to send to all nameservers, send back an error
394     packet straight away (helps modem users when offline)  */
395 
396  if (!flags && forward)
397    {
398      struct server *firstsentto = start;
399      int subnet, forwarded = 0;
400      size_t edns0_len;
401
402      /* If a query is retried, use the log_id for the retry when logging the answer. */
403      forward->log_id = daemon->log_id;
404     
405      edns0_len  = add_edns0_config(header, plen, ((unsigned char *)header) + PACKETSZ, &forward->source, now, &subnet);
406     
407      if (edns0_len != plen)
408        {
409          plen = edns0_len;
410          forward->flags |= FREC_ADDED_PHEADER;
411         
412          if (subnet)
413            forward->flags |= FREC_HAS_SUBNET;
414        }
415     
416#ifdef HAVE_DNSSEC
417      if (option_bool(OPT_DNSSEC_VALID) && do_dnssec)
418        {
419          size_t new = add_do_bit(header, plen, ((unsigned char *) header) + PACKETSZ);
420         
421          if (new != plen)
422            forward->flags |= FREC_ADDED_PHEADER;
423
424          plen = new;
425             
426          /* For debugging, set Checking Disabled, otherwise, have the upstream check too,
427             this allows it to select auth servers when one is returning bad data. */
428          if (option_bool(OPT_DNSSEC_DEBUG))
429            header->hb4 |= HB4_CD;
430
431        }
432#endif
433
434      /* If we're sending an EDNS0 with any options, we can't recreate the query from a reply. */
435      if (find_pseudoheader(header, plen, &edns0_len, NULL, NULL, NULL) && edns0_len > 11)
436        forward->flags |= FREC_HAS_EXTRADATA;
437     
438      while (1)
439        {
440          /* only send to servers dealing with our domain.
441             domain may be NULL, in which case server->domain
442             must be NULL also. */
443         
444          if (type == (start->flags & SERV_TYPE) &&
445              (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
446              !(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
447            {
448              int fd;
449
450              /* find server socket to use, may need to get random one. */
451              if (start->sfd)
452                fd = start->sfd->fd;
453              else
454                {
455#ifdef HAVE_IPV6
456                  if (start->addr.sa.sa_family == AF_INET6)
457                    {
458                      if (!forward->rfd6 &&
459                          !(forward->rfd6 = allocate_rfd(AF_INET6)))
460                        break;
461                      daemon->rfd_save = forward->rfd6;
462                      fd = forward->rfd6->fd;
463                    }
464                  else
465#endif
466                    {
467                      if (!forward->rfd4 &&
468                          !(forward->rfd4 = allocate_rfd(AF_INET)))
469                        break;
470                      daemon->rfd_save = forward->rfd4;
471                      fd = forward->rfd4->fd;
472                    }
473
474#ifdef HAVE_CONNTRACK
475                  /* Copy connection mark of incoming query to outgoing connection. */
476                  if (option_bool(OPT_CONNTRACK))
477                    {
478                      unsigned int mark;
479                      if (get_incoming_mark(&forward->source, &forward->dest, 0, &mark))
480                        setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
481                    }
482#endif
483                }
484             
485#ifdef HAVE_DNSSEC
486              if (option_bool(OPT_DNSSEC_VALID) && (forward->flags & FREC_ADDED_PHEADER))
487                {
488                  /* Difficult one here. If our client didn't send EDNS0, we will have set the UDP
489                     packet size to 512. But that won't provide space for the RRSIGS in many cases.
490                     The RRSIGS will be stripped out before the answer goes back, so the packet should
491                     shrink again. So, if we added a do-bit, bump the udp packet size to the value
492                     known to be OK for this server. We check returned size after stripping and set
493                     the truncated bit if it's still too big. */                 
494                  unsigned char *pheader;
495                  int is_sign;
496                  if (find_pseudoheader(header, plen, NULL, &pheader, &is_sign, NULL) && !is_sign)
497                    PUTSHORT(start->edns_pktsz, pheader);
498                }
499#endif
500
501              if (retry_send(sendto(fd, (char *)header, plen, 0,
502                                    &start->addr.sa,
503                                    sa_len(&start->addr))))
504                continue;
505           
506              if (errno == 0)
507                {
508                  /* Keep info in case we want to re-send this packet */
509                  daemon->srv_save = start;
510                  daemon->packet_len = plen;
511                 
512                  if (!gotname)
513                    strcpy(daemon->namebuff, "query");
514                  if (start->addr.sa.sa_family == AF_INET)
515                    log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
516                              (struct all_addr *)&start->addr.in.sin_addr, NULL);
517#ifdef HAVE_IPV6
518                  else
519                    log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
520                              (struct all_addr *)&start->addr.in6.sin6_addr, NULL);
521#endif
522                  start->queries++;
523                  forwarded = 1;
524                  forward->sentto = start;
525                  if (!forward->forwardall)
526                    break;
527                  forward->forwardall++;
528                }
529            }
530         
531          if (!(start = start->next))
532            start = daemon->servers;
533         
534          if (start == firstsentto)
535            break;
536        }
537     
538      if (forwarded)
539        return 1;
540     
541      /* could not send on, prepare to return */
542      header->id = htons(forward->orig_id);
543      free_frec(forward); /* cancel */
544    }     
545 
546  /* could not send on, return empty answer or address if known for whole domain */
547  if (udpfd != -1)
548    {
549      plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl);
550      send_from(udpfd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND), (char *)header, plen, udpaddr, dst_addr, dst_iface);
551    }
552
553  return 0;
554}
555
556static size_t process_reply(struct dns_header *header, time_t now, struct server *server, size_t n, int check_rebind,
557                            int no_cache, int cache_secure, int bogusanswer, int ad_reqd, int do_bit, int added_pheader,
558                            int check_subnet, union mysockaddr *query_source)
559{
560  unsigned char *pheader, *sizep;
561  char **sets = 0;
562  int munged = 0, is_sign;
563  size_t plen;
564
565  (void)ad_reqd;
566  (void)do_bit;
567  (void)bogusanswer;
568
569#ifdef HAVE_IPSET
570  if (daemon->ipsets && extract_request(header, n, daemon->namebuff, NULL))
571    {
572      /* Similar algorithm to search_servers. */
573      struct ipsets *ipset_pos;
574      unsigned int namelen = strlen(daemon->namebuff);
575      unsigned int matchlen = 0;
576      for (ipset_pos = daemon->ipsets; ipset_pos; ipset_pos = ipset_pos->next)
577        {
578          unsigned int domainlen = strlen(ipset_pos->domain);
579          char *matchstart = daemon->namebuff + namelen - domainlen;
580          if (namelen >= domainlen && hostname_isequal(matchstart, ipset_pos->domain) &&
581              (domainlen == 0 || namelen == domainlen || *(matchstart - 1) == '.' ) &&
582              domainlen >= matchlen)
583            {
584              matchlen = domainlen;
585              sets = ipset_pos->sets;
586            }
587        }
588    }
589#endif
590 
591  if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign, NULL)))
592    {
593      if (check_subnet && !check_source(header, plen, pheader, query_source))
594        {
595          my_syslog(LOG_WARNING, _("discarding DNS reply: subnet option mismatch"));
596          return 0;
597        }
598     
599      if (!is_sign)
600        {
601          if (added_pheader)
602            {
603              /* client didn't send EDNS0, we added one, strip it off before returning answer. */
604              n = rrfilter(header, n, 0);
605              pheader = NULL;
606            }
607          else
608            {
609              unsigned short udpsz;
610
611              /* If upstream is advertising a larger UDP packet size
612                 than we allow, trim it so that we don't get overlarge
613                 requests for the client. We can't do this for signed packets. */
614              GETSHORT(udpsz, sizep);
615              if (udpsz > daemon->edns_pktsz)
616                {
617                  sizep -= 2;
618                  PUTSHORT(daemon->edns_pktsz, sizep);
619                }
620
621#ifdef HAVE_DNSSEC
622              /* If the client didn't set the do bit, but we did, reset it. */
623              if (option_bool(OPT_DNSSEC_VALID) && !do_bit)
624                {
625                  unsigned short flags;
626                  sizep += 2; /* skip RCODE */
627                  GETSHORT(flags, sizep);
628                  flags &= ~0x8000;
629                  sizep -= 2;
630                  PUTSHORT(flags, sizep);
631                }
632#endif
633            }
634        }
635    }
636 
637  /* RFC 4035 sect 4.6 para 3 */
638  if (!is_sign && !option_bool(OPT_DNSSEC_PROXY))
639     header->hb4 &= ~HB4_AD;
640 
641  if (OPCODE(header) != QUERY || (RCODE(header) != NOERROR && RCODE(header) != NXDOMAIN))
642    return resize_packet(header, n, pheader, plen);
643 
644  /* Complain loudly if the upstream server is non-recursive. */
645  if (!(header->hb4 & HB4_RA) && RCODE(header) == NOERROR &&
646      server && !(server->flags & SERV_WARNED_RECURSIVE))
647    {
648      prettyprint_addr(&server->addr, daemon->namebuff);
649      my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
650      if (!option_bool(OPT_LOG))
651        server->flags |= SERV_WARNED_RECURSIVE;
652    } 
653
654  if (daemon->bogus_addr && RCODE(header) != NXDOMAIN &&
655      check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now))
656    {
657      munged = 1;
658      SET_RCODE(header, NXDOMAIN);
659      header->hb3 &= ~HB3_AA;
660      cache_secure = 0;
661    }
662  else
663    {
664      int doctored = 0;
665     
666      if (RCODE(header) == NXDOMAIN &&
667          extract_request(header, n, daemon->namebuff, NULL) &&
668          check_for_local_domain(daemon->namebuff, now))
669        {
670          /* if we forwarded a query for a locally known name (because it was for
671             an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
672             since we know that the domain exists, even if upstream doesn't */
673          munged = 1;
674          header->hb3 |= HB3_AA;
675          SET_RCODE(header, NOERROR);
676          cache_secure = 0;
677        }
678     
679      if (extract_addresses(header, n, daemon->namebuff, now, sets, is_sign, check_rebind, no_cache, cache_secure, &doctored))
680        {
681          my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected: %s"), daemon->namebuff);
682          munged = 1;
683          cache_secure = 0;
684        }
685
686      if (doctored)
687        cache_secure = 0;
688    }
689 
690#ifdef HAVE_DNSSEC
691  if (bogusanswer && !(header->hb4 & HB4_CD) && !option_bool(OPT_DNSSEC_DEBUG))
692    {
693      /* Bogus reply, turn into SERVFAIL */
694      SET_RCODE(header, SERVFAIL);
695      munged = 1;
696    }
697
698  if (option_bool(OPT_DNSSEC_VALID))
699    {
700      header->hb4 &= ~HB4_AD;
701     
702      if (!(header->hb4 & HB4_CD) && ad_reqd && cache_secure)
703        header->hb4 |= HB4_AD;
704     
705      /* If the requestor didn't set the DO bit, don't return DNSSEC info. */
706      if (!do_bit)
707        n = rrfilter(header, n, 1);
708    }
709#endif
710
711  /* do this after extract_addresses. Ensure NODATA reply and remove
712     nameserver info. */
713 
714  if (munged)
715    {
716      header->ancount = htons(0);
717      header->nscount = htons(0);
718      header->arcount = htons(0);
719      header->hb3 &= ~HB3_TC;
720    }
721 
722  /* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
723     sections of the packet. Find the new length here and put back pseudoheader
724     if it was removed. */
725  return resize_packet(header, n, pheader, plen);
726}
727
728/* sets new last_server */
729void reply_query(int fd, int family, time_t now)
730{
731  /* packet from peer server, extract data for cache, and send to
732     original requester */
733  struct dns_header *header;
734  union mysockaddr serveraddr;
735  struct frec *forward;
736  socklen_t addrlen = sizeof(serveraddr);
737  ssize_t n = recvfrom(fd, daemon->packet, daemon->packet_buff_sz, 0, &serveraddr.sa, &addrlen);
738  size_t nn;
739  struct server *server;
740  void *hash;
741#ifndef HAVE_DNSSEC
742  unsigned int crc;
743#endif
744
745  /* packet buffer overwritten */
746  daemon->srv_save = NULL;
747 
748  /* Determine the address of the server replying  so that we can mark that as good */
749  serveraddr.sa.sa_family = family;
750#ifdef HAVE_IPV6
751  if (serveraddr.sa.sa_family == AF_INET6)
752    serveraddr.in6.sin6_flowinfo = 0;
753#endif
754 
755  header = (struct dns_header *)daemon->packet;
756 
757  if (n < (int)sizeof(struct dns_header) || !(header->hb3 & HB3_QR))
758    return;
759 
760  /* spoof check: answer must come from known server, */
761  for (server = daemon->servers; server; server = server->next)
762    if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
763        sockaddr_isequal(&server->addr, &serveraddr))
764      break;
765 
766  if (!server)
767    return;
768 
769#ifdef HAVE_DNSSEC
770  hash = hash_questions(header, n, daemon->namebuff);
771#else
772  hash = &crc;
773  crc = questions_crc(header, n, daemon->namebuff);
774#endif
775 
776  if (!(forward = lookup_frec(ntohs(header->id), hash)))
777    return;
778 
779  /* log_query gets called indirectly all over the place, so
780     pass these in global variables - sorry. */
781  daemon->log_display_id = forward->log_id;
782  daemon->log_source_addr = &forward->source;
783 
784  if (daemon->ignore_addr && RCODE(header) == NOERROR &&
785      check_for_ignored_address(header, n, daemon->ignore_addr))
786    return;
787
788  /* Note: if we send extra options in the EDNS0 header, we can't recreate
789     the query from the reply. */
790  if (RCODE(header) == REFUSED &&
791      !option_bool(OPT_ORDER) &&
792      forward->forwardall == 0 &&
793      !(forward->flags & FREC_HAS_EXTRADATA))
794    /* for broken servers, attempt to send to another one. */
795    {
796      unsigned char *pheader;
797      size_t plen;
798      int is_sign;
799     
800      /* recreate query from reply */
801      pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign, NULL);
802      if (!is_sign)
803        {
804          header->ancount = htons(0);
805          header->nscount = htons(0);
806          header->arcount = htons(0);
807          if ((nn = resize_packet(header, (size_t)n, pheader, plen)))
808            {
809              header->hb3 &= ~(HB3_QR | HB3_AA | HB3_TC);
810              header->hb4 &= ~(HB4_RA | HB4_RCODE | HB4_CD | HB4_AD);
811              if (forward->flags & FREC_CHECKING_DISABLED)
812                header->hb4 |= HB4_CD;
813              if (forward->flags & FREC_AD_QUESTION)
814                header->hb4 |= HB4_AD;
815              if (forward->flags & FREC_DO_QUESTION)
816                add_do_bit(header, nn,  (unsigned char *)pheader + plen);
817              forward_query(-1, NULL, NULL, 0, header, nn, now, forward, forward->flags & FREC_AD_QUESTION, forward->flags & FREC_DO_QUESTION);
818              return;
819            }
820        }
821    }   
822   
823  server = forward->sentto;
824  if ((forward->sentto->flags & SERV_TYPE) == 0)
825    {
826      if (RCODE(header) == REFUSED)
827        server = NULL;
828      else
829        {
830          struct server *last_server;
831         
832          /* find good server by address if possible, otherwise assume the last one we sent to */
833          for (last_server = daemon->servers; last_server; last_server = last_server->next)
834            if (!(last_server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR)) &&
835                sockaddr_isequal(&last_server->addr, &serveraddr))
836              {
837                server = last_server;
838                break;
839              }
840        }
841      if (!option_bool(OPT_ALL_SERVERS))
842        daemon->last_server = server;
843    }
844 
845  /* We tried resending to this server with a smaller maximum size and got an answer.
846     Make that permanent. To avoid reduxing the packet size for an single dropped packet,
847     only do this when we get a truncated answer, or one larger than the safe size. */
848  if (server && (forward->flags & FREC_TEST_PKTSZ) &&
849      ((header->hb3 & HB3_TC) || n >= SAFE_PKTSZ))
850    server->edns_pktsz = SAFE_PKTSZ;
851 
852  /* If the answer is an error, keep the forward record in place in case
853     we get a good reply from another server. Kill it when we've
854     had replies from all to avoid filling the forwarding table when
855     everything is broken */
856  if (forward->forwardall == 0 || --forward->forwardall == 1 ||
857      (RCODE(header) != REFUSED && RCODE(header) != SERVFAIL))
858    {
859      int check_rebind = 0, no_cache_dnssec = 0, cache_secure = 0, bogusanswer = 0;
860
861      if (option_bool(OPT_NO_REBIND))
862        check_rebind = !(forward->flags & FREC_NOREBIND);
863     
864      /*   Don't cache replies where DNSSEC validation was turned off, either
865           the upstream server told us so, or the original query specified it.  */
866      if ((header->hb4 & HB4_CD) || (forward->flags & FREC_CHECKING_DISABLED))
867        no_cache_dnssec = 1;
868     
869#ifdef HAVE_DNSSEC
870      if (server && (server->flags & SERV_DO_DNSSEC) &&
871          option_bool(OPT_DNSSEC_VALID) && !(forward->flags & FREC_CHECKING_DISABLED))
872        {
873          int status = 0;
874
875          /* We've had a reply already, which we're validating. Ignore this duplicate */
876          if (forward->blocking_query)
877            return;
878         
879           /* Truncated answer can't be validated.
880                 If this is an answer to a DNSSEC-generated query, we still
881                 need to get the client to retry over TCP, so return
882                 an answer with the TC bit set, even if the actual answer fits.
883              */
884          if (header->hb3 & HB3_TC)
885            status = STAT_TRUNCATED;
886         
887          while (1)
888            {
889              /* As soon as anything returns BOGUS, we stop and unwind, to do otherwise
890                 would invite infinite loops, since the answers to DNSKEY and DS queries
891                 will not be cached, so they'll be repeated. */
892              if (status != STAT_BOGUS && status != STAT_TRUNCATED && status != STAT_ABANDONED)
893                {
894                  if (forward->flags & FREC_DNSKEY_QUERY)
895                    status = dnssec_validate_by_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
896                  else if (forward->flags & FREC_DS_QUERY)
897                    status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
898                  else
899                    status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class,
900                                                   option_bool(OPT_DNSSEC_NO_SIGN), NULL, NULL);
901                }
902             
903              /* Can't validate, as we're missing key data. Put this
904                 answer aside, whilst we get that. */     
905              if (status == STAT_NEED_DS || status == STAT_NEED_KEY)
906                {
907                  struct frec *new, *orig;
908                 
909                  /* Free any saved query */
910                  if (forward->stash)
911                    blockdata_free(forward->stash);
912                 
913                  /* Now save reply pending receipt of key data */
914                  if (!(forward->stash = blockdata_alloc((char *)header, n)))
915                    return;
916                  forward->stash_len = n;
917                 
918                  /* Find the original query that started it all.... */
919                  for (orig = forward; orig->dependent; orig = orig->dependent);
920                 
921                  if (--orig->work_counter == 0 || !(new = get_new_frec(now, NULL, 1)))
922                    status = STAT_ABANDONED;
923                  else
924                    {
925                      int fd, type = SERV_DO_DNSSEC;
926                      struct frec *next = new->next;
927                      char *domain;
928                     
929                      *new = *forward; /* copy everything, then overwrite */
930                      new->next = next;
931                      new->blocking_query = NULL;
932
933                      /* Find server to forward to. This will normally be the
934                         same as for the original query, but may be another if
935                         servers for domains are involved. */                 
936                      if (search_servers(now, NULL, F_QUERY, daemon->keyname, &type, &domain, NULL) == 0)
937                        {
938                          struct server *start = server, *new_server = NULL;
939                           type &= ~SERV_DO_DNSSEC;
940                           
941                           while (1)
942                             {
943                               if (type == (start->flags & SERV_TYPE) &&
944                                   (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
945                                   !(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
946                                 {
947                                   new_server = start;
948                                   if (server == start)
949                                     {
950                                       new_server = NULL;
951                                       break;
952                                     }
953                                 }
954                               
955                               if (!(start = start->next))
956                                 start = daemon->servers;
957                               if (start == server)
958                                 break;
959                             }
960                       
961                           if (new_server)
962                             server = new_server;
963                        }
964
965                      new->sentto = server;
966
967                      new->rfd4 = NULL;
968#ifdef HAVE_IPV6
969                      new->rfd6 = NULL;
970#endif
971                      new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY);
972                     
973                      new->dependent = forward; /* to find query awaiting new one. */
974                      forward->blocking_query = new; /* for garbage cleaning */
975                      /* validate routines leave name of required record in daemon->keyname */
976                      if (status == STAT_NEED_KEY)
977                        {
978                          new->flags |= FREC_DNSKEY_QUERY;
979                          nn = dnssec_generate_query(header, ((unsigned char *) header) + server->edns_pktsz,
980                                                     daemon->keyname, forward->class, T_DNSKEY, &server->addr, server->edns_pktsz);
981                        }
982                      else
983                        {
984                          new->flags |= FREC_DS_QUERY;
985                          nn = dnssec_generate_query(header,((unsigned char *) header) + server->edns_pktsz,
986                                                     daemon->keyname, forward->class, T_DS, &server->addr, server->edns_pktsz);
987                        }
988                      if ((hash = hash_questions(header, nn, daemon->namebuff)))
989                        memcpy(new->hash, hash, HASH_SIZE);
990                      new->new_id = get_id();
991                      header->id = htons(new->new_id);
992                      /* Save query for retransmission */
993                      new->stash = blockdata_alloc((char *)header, nn);
994                      new->stash_len = nn;
995                     
996                      /* Don't resend this. */
997                      daemon->srv_save = NULL;
998                     
999                      if (server->sfd)
1000                        fd = server->sfd->fd;
1001                      else
1002                        {
1003                          fd = -1;
1004#ifdef HAVE_IPV6
1005                          if (server->addr.sa.sa_family == AF_INET6)
1006                            {
1007                              if (new->rfd6 || (new->rfd6 = allocate_rfd(AF_INET6)))
1008                                fd = new->rfd6->fd;
1009                            }
1010                          else
1011#endif
1012                            {
1013                              if (new->rfd4 || (new->rfd4 = allocate_rfd(AF_INET)))
1014                                fd = new->rfd4->fd;
1015                            }
1016                        }
1017                     
1018                      if (fd != -1)
1019                        {
1020#ifdef HAVE_CONNTRACK
1021                          /* Copy connection mark of incoming query to outgoing connection. */
1022                          if (option_bool(OPT_CONNTRACK))
1023                            {
1024                              unsigned int mark;
1025                              if (get_incoming_mark(&orig->source, &orig->dest, 0, &mark))
1026                                setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
1027                            }
1028#endif
1029                          while (retry_send(sendto(fd, (char *)header, nn, 0,
1030                                                   &server->addr.sa,
1031                                                   sa_len(&server->addr))));
1032                          server->queries++;
1033                        }
1034                    }             
1035                  return;
1036                }
1037         
1038              /* Validated original answer, all done. */
1039              if (!forward->dependent)
1040                break;
1041             
1042              /* validated subsidiary query, (and cached result)
1043                 pop that and return to the previous query we were working on. */
1044              struct frec *prev = forward->dependent;
1045              free_frec(forward);
1046              forward = prev;
1047              forward->blocking_query = NULL; /* already gone */
1048              blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
1049              n = forward->stash_len;
1050            }
1051       
1052         
1053          no_cache_dnssec = 0;
1054         
1055          if (status == STAT_TRUNCATED)
1056            header->hb3 |= HB3_TC;
1057          else
1058            {
1059              char *result, *domain = "result";
1060             
1061              if (status == STAT_ABANDONED)
1062                {
1063                  result = "ABANDONED";
1064                  status = STAT_BOGUS;
1065                }
1066              else
1067                result = (status == STAT_SECURE ? "SECURE" : (status == STAT_INSECURE ? "INSECURE" : "BOGUS"));
1068             
1069              if (status == STAT_BOGUS && extract_request(header, n, daemon->namebuff, NULL))
1070                domain = daemon->namebuff;
1071             
1072              log_query(F_KEYTAG | F_SECSTAT, domain, NULL, result);
1073            }
1074         
1075          if (status == STAT_SECURE)
1076            cache_secure = 1;
1077          else if (status == STAT_BOGUS)
1078            {
1079              no_cache_dnssec = 1;
1080              bogusanswer = 1;
1081            }
1082        }
1083#endif     
1084     
1085      /* restore CD bit to the value in the query */
1086      if (forward->flags & FREC_CHECKING_DISABLED)
1087        header->hb4 |= HB4_CD;
1088      else
1089        header->hb4 &= ~HB4_CD;
1090     
1091      if ((nn = process_reply(header, now, forward->sentto, (size_t)n, check_rebind, no_cache_dnssec, cache_secure, bogusanswer,
1092                              forward->flags & FREC_AD_QUESTION, forward->flags & FREC_DO_QUESTION,
1093                              forward->flags & FREC_ADDED_PHEADER, forward->flags & FREC_HAS_SUBNET, &forward->source)))
1094        {
1095          header->id = htons(forward->orig_id);
1096          header->hb4 |= HB4_RA; /* recursion if available */
1097#ifdef HAVE_DNSSEC
1098          /* We added an EDNSO header for the purpose of getting DNSSEC RRs, and set the value of the UDP payload size
1099             greater than the no-EDNS0-implied 512 to have if space for the RRSIGS. If, having stripped them and the EDNS0
1100             header, the answer is still bigger than 512, truncate it and mark it so. The client then retries with TCP. */
1101          if (option_bool(OPT_DNSSEC_VALID) && (forward->flags & FREC_ADDED_PHEADER) && (nn > PACKETSZ))
1102            {
1103              header->ancount = htons(0);
1104              header->nscount = htons(0);
1105              header->arcount = htons(0);
1106              header->hb3 |= HB3_TC;
1107              nn = resize_packet(header, nn, NULL, 0);
1108            }
1109#endif
1110          send_from(forward->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn,
1111                    &forward->source, &forward->dest, forward->iface);
1112        }
1113      free_frec(forward); /* cancel */
1114    }
1115}
1116
1117
1118void receive_query(struct listener *listen, time_t now)
1119{
1120  struct dns_header *header = (struct dns_header *)daemon->packet;
1121  union mysockaddr source_addr;
1122  unsigned char *pheader;
1123  unsigned short type, udp_size = PACKETSZ; /* default if no EDNS0 */
1124  struct all_addr dst_addr;
1125  struct in_addr netmask, dst_addr_4;
1126  size_t m;
1127  ssize_t n;
1128  int if_index = 0, auth_dns = 0, do_bit = 0, have_pseudoheader = 0;
1129#ifdef HAVE_AUTH
1130  int local_auth = 0;
1131#endif
1132  struct iovec iov[1];
1133  struct msghdr msg;
1134  struct cmsghdr *cmptr;
1135  union {
1136    struct cmsghdr align; /* this ensures alignment */
1137#ifdef HAVE_IPV6
1138    char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
1139#endif
1140#if defined(HAVE_LINUX_NETWORK)
1141    char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
1142#elif defined(IP_RECVDSTADDR) && defined(HAVE_SOLARIS_NETWORK)
1143    char control[CMSG_SPACE(sizeof(struct in_addr)) +
1144                 CMSG_SPACE(sizeof(unsigned int))];
1145#elif defined(IP_RECVDSTADDR)
1146    char control[CMSG_SPACE(sizeof(struct in_addr)) +
1147                 CMSG_SPACE(sizeof(struct sockaddr_dl))];
1148#endif
1149  } control_u;
1150#ifdef HAVE_IPV6
1151   /* Can always get recvd interface for IPv6 */
1152  int check_dst = !option_bool(OPT_NOWILD) || listen->family == AF_INET6;
1153#else
1154  int check_dst = !option_bool(OPT_NOWILD);
1155#endif
1156
1157  /* packet buffer overwritten */
1158  daemon->srv_save = NULL;
1159 
1160  dst_addr_4.s_addr = dst_addr.addr.addr4.s_addr = 0;
1161  netmask.s_addr = 0;
1162 
1163  if (option_bool(OPT_NOWILD) && listen->iface)
1164    {
1165      auth_dns = listen->iface->dns_auth;
1166     
1167      if (listen->family == AF_INET)
1168        {
1169          dst_addr_4 = dst_addr.addr.addr4 = listen->iface->addr.in.sin_addr;
1170          netmask = listen->iface->netmask;
1171        }
1172    }
1173 
1174  iov[0].iov_base = daemon->packet;
1175  iov[0].iov_len = daemon->edns_pktsz;
1176   
1177  msg.msg_control = control_u.control;
1178  msg.msg_controllen = sizeof(control_u);
1179  msg.msg_flags = 0;
1180  msg.msg_name = &source_addr;
1181  msg.msg_namelen = sizeof(source_addr);
1182  msg.msg_iov = iov;
1183  msg.msg_iovlen = 1;
1184 
1185  if ((n = recvmsg(listen->fd, &msg, 0)) == -1)
1186    return;
1187 
1188  if (n < (int)sizeof(struct dns_header) ||
1189      (msg.msg_flags & MSG_TRUNC) ||
1190      (header->hb3 & HB3_QR))
1191    return;
1192 
1193  source_addr.sa.sa_family = listen->family;
1194 
1195  if (listen->family == AF_INET)
1196    {
1197       /* Source-port == 0 is an error, we can't send back to that.
1198          http://www.ietf.org/mail-archive/web/dnsop/current/msg11441.html */
1199      if (source_addr.in.sin_port == 0)
1200        return;
1201    }
1202#ifdef HAVE_IPV6
1203  else
1204    {
1205      /* Source-port == 0 is an error, we can't send back to that. */
1206      if (source_addr.in6.sin6_port == 0)
1207        return;
1208      source_addr.in6.sin6_flowinfo = 0;
1209    }
1210#endif
1211 
1212  /* We can be configured to only accept queries from at-most-one-hop-away addresses. */
1213  if (option_bool(OPT_LOCAL_SERVICE))
1214    {
1215      struct addrlist *addr;
1216#ifdef HAVE_IPV6
1217      if (listen->family == AF_INET6)
1218        {
1219          for (addr = daemon->interface_addrs; addr; addr = addr->next)
1220            if ((addr->flags & ADDRLIST_IPV6) &&
1221                is_same_net6(&addr->addr.addr.addr6, &source_addr.in6.sin6_addr, addr->prefixlen))
1222              break;
1223        }
1224      else
1225#endif
1226        {
1227          struct in_addr netmask;
1228          for (addr = daemon->interface_addrs; addr; addr = addr->next)
1229            {
1230              netmask.s_addr = htonl(~(in_addr_t)0 << (32 - addr->prefixlen));
1231              if (!(addr->flags & ADDRLIST_IPV6) &&
1232                  is_same_net(addr->addr.addr.addr4, source_addr.in.sin_addr, netmask))
1233                break;
1234            }
1235        }
1236      if (!addr)
1237        {
1238          static int warned = 0;
1239          if (!warned)
1240            {
1241              my_syslog(LOG_WARNING, _("Ignoring query from non-local network"));
1242              warned = 1;
1243            }
1244          return;
1245        }
1246    }
1247               
1248  if (check_dst)
1249    {
1250      struct ifreq ifr;
1251
1252      if (msg.msg_controllen < sizeof(struct cmsghdr))
1253        return;
1254
1255#if defined(HAVE_LINUX_NETWORK)
1256      if (listen->family == AF_INET)
1257        for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
1258          if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
1259            {
1260              union {
1261                unsigned char *c;
1262                struct in_pktinfo *p;
1263              } p;
1264              p.c = CMSG_DATA(cmptr);
1265              dst_addr_4 = dst_addr.addr.addr4 = p.p->ipi_spec_dst;
1266              if_index = p.p->ipi_ifindex;
1267            }
1268#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
1269      if (listen->family == AF_INET)
1270        {
1271          for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
1272            {
1273              union {
1274                unsigned char *c;
1275                unsigned int *i;
1276                struct in_addr *a;
1277#ifndef HAVE_SOLARIS_NETWORK
1278                struct sockaddr_dl *s;
1279#endif
1280              } p;
1281               p.c = CMSG_DATA(cmptr);
1282               if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
1283                 dst_addr_4 = dst_addr.addr.addr4 = *(p.a);
1284               else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
1285#ifdef HAVE_SOLARIS_NETWORK
1286                 if_index = *(p.i);
1287#else
1288                 if_index = p.s->sdl_index;
1289#endif
1290            }
1291        }
1292#endif
1293     
1294#ifdef HAVE_IPV6
1295      if (listen->family == AF_INET6)
1296        {
1297          for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
1298            if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
1299              {
1300                union {
1301                  unsigned char *c;
1302                  struct in6_pktinfo *p;
1303                } p;
1304                p.c = CMSG_DATA(cmptr);
1305                 
1306                dst_addr.addr.addr6 = p.p->ipi6_addr;
1307                if_index = p.p->ipi6_ifindex;
1308              }
1309        }
1310#endif
1311     
1312      /* enforce available interface configuration */
1313     
1314      if (!indextoname(listen->fd, if_index, ifr.ifr_name))
1315        return;
1316     
1317      if (!iface_check(listen->family, &dst_addr, ifr.ifr_name, &auth_dns))
1318        {
1319           if (!option_bool(OPT_CLEVERBIND))
1320             enumerate_interfaces(0);
1321           if (!loopback_exception(listen->fd, listen->family, &dst_addr, ifr.ifr_name) &&
1322               !label_exception(if_index, listen->family, &dst_addr))
1323             return;
1324        }
1325
1326      if (listen->family == AF_INET && option_bool(OPT_LOCALISE))
1327        {
1328          struct irec *iface;
1329         
1330          /* get the netmask of the interface which has the address we were sent to.
1331             This is no necessarily the interface we arrived on. */
1332         
1333          for (iface = daemon->interfaces; iface; iface = iface->next)
1334            if (iface->addr.sa.sa_family == AF_INET &&
1335                iface->addr.in.sin_addr.s_addr == dst_addr_4.s_addr)
1336              break;
1337         
1338          /* interface may be new */
1339          if (!iface && !option_bool(OPT_CLEVERBIND))
1340            enumerate_interfaces(0);
1341         
1342          for (iface = daemon->interfaces; iface; iface = iface->next)
1343            if (iface->addr.sa.sa_family == AF_INET &&
1344                iface->addr.in.sin_addr.s_addr == dst_addr_4.s_addr)
1345              break;
1346         
1347          /* If we failed, abandon localisation */
1348          if (iface)
1349            netmask = iface->netmask;
1350          else
1351            dst_addr_4.s_addr = 0;
1352        }
1353    }
1354   
1355  /* log_query gets called indirectly all over the place, so
1356     pass these in global variables - sorry. */
1357  daemon->log_display_id = ++daemon->log_id;
1358  daemon->log_source_addr = &source_addr;
1359 
1360  if (extract_request(header, (size_t)n, daemon->namebuff, &type))
1361    {
1362#ifdef HAVE_AUTH
1363      struct auth_zone *zone;
1364#endif
1365      char *types = querystr(auth_dns ? "auth" : "query", type);
1366     
1367      if (listen->family == AF_INET)
1368        log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
1369                  (struct all_addr *)&source_addr.in.sin_addr, types);
1370#ifdef HAVE_IPV6
1371      else
1372        log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
1373                  (struct all_addr *)&source_addr.in6.sin6_addr, types);
1374#endif
1375
1376#ifdef HAVE_AUTH
1377      /* find queries for zones we're authoritative for, and answer them directly */
1378      if (!auth_dns && !option_bool(OPT_LOCALISE))
1379        for (zone = daemon->auth_zones; zone; zone = zone->next)
1380          if (in_zone(zone, daemon->namebuff, NULL))
1381            {
1382              auth_dns = 1;
1383              local_auth = 1;
1384              break;
1385            }
1386#endif
1387     
1388#ifdef HAVE_LOOP
1389      /* Check for forwarding loop */
1390      if (detect_loop(daemon->namebuff, type))
1391        return;
1392#endif
1393    }
1394 
1395  if (find_pseudoheader(header, (size_t)n, NULL, &pheader, NULL, NULL))
1396    {
1397      unsigned short flags;
1398     
1399      have_pseudoheader = 1;
1400      GETSHORT(udp_size, pheader);
1401      pheader += 2; /* ext_rcode */
1402      GETSHORT(flags, pheader);
1403     
1404      if (flags & 0x8000)
1405        do_bit = 1;/* do bit */
1406       
1407      /* If the client provides an EDNS0 UDP size, use that to limit our reply.
1408         (bounded by the maximum configured). If no EDNS0, then it
1409         defaults to 512 */
1410      if (udp_size > daemon->edns_pktsz)
1411        udp_size = daemon->edns_pktsz;
1412    }
1413
1414#ifdef HAVE_AUTH
1415  if (auth_dns)
1416    {
1417      m = answer_auth(header, ((char *) header) + udp_size, (size_t)n, now, &source_addr,
1418                      local_auth, do_bit, have_pseudoheader);
1419      if (m >= 1)
1420        {
1421          send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
1422                    (char *)header, m, &source_addr, &dst_addr, if_index);
1423          daemon->auth_answer++;
1424        }
1425    }
1426  else
1427#endif
1428    {
1429      int ad_reqd = do_bit;
1430       /* RFC 6840 5.7 */
1431      if (header->hb4 & HB4_AD)
1432        ad_reqd = 1;
1433
1434      m = answer_request(header, ((char *) header) + udp_size, (size_t)n,
1435                         dst_addr_4, netmask, now, ad_reqd, do_bit, have_pseudoheader);
1436     
1437      if (m >= 1)
1438        {
1439          send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
1440                    (char *)header, m, &source_addr, &dst_addr, if_index);
1441          daemon->local_answer++;
1442        }
1443      else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
1444                             header, (size_t)n, now, NULL, ad_reqd, do_bit))
1445        daemon->queries_forwarded++;
1446      else
1447        daemon->local_answer++;
1448    }
1449}
1450
1451#ifdef HAVE_DNSSEC
1452/* Recurse up the key hierarchy */
1453static int tcp_key_recurse(time_t now, int status, struct dns_header *header, size_t n,
1454                           int class, char *name, char *keyname, struct server *server,
1455                           int have_mark, unsigned int mark, int *keycount)
1456{
1457  int new_status;
1458  unsigned char *packet = NULL;
1459  unsigned char *payload = NULL;
1460  struct dns_header *new_header = NULL;
1461  u16 *length = NULL;
1462 
1463  while (1)
1464    {
1465      int type = SERV_DO_DNSSEC;
1466      char *domain;
1467      size_t m;
1468      unsigned char c1, c2;
1469      struct server *firstsendto = NULL;
1470     
1471      /* limit the amount of work we do, to avoid cycling forever on loops in the DNS */
1472      if (--(*keycount) == 0)
1473        new_status = STAT_ABANDONED;
1474      else if (status == STAT_NEED_KEY)
1475        new_status = dnssec_validate_by_ds(now, header, n, name, keyname, class);
1476      else if (status == STAT_NEED_DS)
1477        new_status = dnssec_validate_ds(now, header, n, name, keyname, class);
1478      else
1479        new_status = dnssec_validate_reply(now, header, n, name, keyname, &class, option_bool(OPT_DNSSEC_NO_SIGN), NULL, NULL);
1480     
1481      if (new_status != STAT_NEED_DS && new_status != STAT_NEED_KEY)
1482        break;
1483
1484      /* Can't validate because we need a key/DS whose name now in keyname.
1485         Make query for same, and recurse to validate */
1486      if (!packet)
1487        {
1488          packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ + sizeof(u16));
1489          payload = &packet[2];
1490          new_header = (struct dns_header *)payload;
1491          length = (u16 *)packet;
1492        }
1493     
1494      if (!packet)
1495        {
1496          new_status = STAT_ABANDONED;
1497          break;
1498        }
1499         
1500      m = dnssec_generate_query(new_header, ((unsigned char *) new_header) + 65536, keyname, class,
1501                                new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS, &server->addr, server->edns_pktsz);
1502     
1503      *length = htons(m);
1504
1505      /* Find server to forward to. This will normally be the
1506         same as for the original query, but may be another if
1507         servers for domains are involved. */                 
1508      if (search_servers(now, NULL, F_QUERY, keyname, &type, &domain, NULL) != 0)
1509        {
1510          new_status = STAT_ABANDONED;
1511          break;
1512        }
1513       
1514      type &= ~SERV_DO_DNSSEC;
1515     
1516      while (1)
1517        {
1518          if (!firstsendto)
1519            firstsendto = server;
1520          else
1521            {
1522              if (!(server = server->next))
1523                server = daemon->servers;
1524              if (server == firstsendto)
1525                {
1526                  /* can't find server to accept our query. */
1527                  new_status = STAT_ABANDONED;
1528                  break;
1529                }
1530            }
1531         
1532          if (type != (server->flags & SERV_TYPE) ||
1533              (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, server->domain)) ||
1534              (server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
1535            continue;
1536         
1537        retry:
1538          /* may need to make new connection. */
1539          if (server->tcpfd == -1)
1540            {
1541              if ((server->tcpfd = socket(server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
1542                continue; /* No good, next server */
1543             
1544#ifdef HAVE_CONNTRACK
1545              /* Copy connection mark of incoming query to outgoing connection. */
1546              if (have_mark)
1547                setsockopt(server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
1548#endif 
1549             
1550              if (!local_bind(server->tcpfd,  &server->source_addr, server->interface, 1) ||
1551                  connect(server->tcpfd, &server->addr.sa, sa_len(&server->addr)) == -1)
1552                {
1553                  close(server->tcpfd);
1554                  server->tcpfd = -1;
1555                  continue; /* No good, next server */
1556                }
1557
1558              server->flags &= ~SERV_GOT_TCP;
1559            }
1560         
1561          if (!read_write(server->tcpfd, packet, m + sizeof(u16), 0) ||
1562              !read_write(server->tcpfd, &c1, 1, 1) ||
1563              !read_write(server->tcpfd, &c2, 1, 1) ||
1564              !read_write(server->tcpfd, payload, (c1 << 8) | c2, 1))
1565            {
1566              close(server->tcpfd);
1567              server->tcpfd = -1;
1568              /* We get data then EOF, reopen connection to same server,
1569                 else try next. This avoids DoS from a server which accepts
1570                 connections and then closes them. */
1571              if (server->flags & SERV_GOT_TCP)
1572                goto retry;
1573              else
1574                continue;
1575            }
1576         
1577          server->flags |= SERV_GOT_TCP;
1578         
1579          m = (c1 << 8) | c2;
1580          new_status = tcp_key_recurse(now, new_status, new_header, m, class, name, keyname, server, have_mark, mark, keycount);
1581          break;
1582        }
1583     
1584      if (new_status != STAT_OK)
1585        break;
1586    }
1587   
1588  if (packet)
1589    free(packet);
1590   
1591  return new_status;
1592}
1593#endif
1594
1595
1596/* The daemon forks before calling this: it should deal with one connection,
1597   blocking as necessary, and then return. Note, need to be a bit careful
1598   about resources for debug mode, when the fork is suppressed: that's
1599   done by the caller. */
1600unsigned char *tcp_request(int confd, time_t now,
1601                           union mysockaddr *local_addr, struct in_addr netmask, int auth_dns)
1602{
1603  size_t size = 0;
1604  int norebind = 0;
1605#ifdef HAVE_AUTH
1606  int local_auth = 0;
1607#endif
1608  int checking_disabled, do_bit, added_pheader = 0, have_pseudoheader = 0;
1609  int check_subnet, no_cache_dnssec = 0, cache_secure = 0, bogusanswer = 0;
1610  size_t m;
1611  unsigned short qtype;
1612  unsigned int gotname;
1613  unsigned char c1, c2;
1614  /* Max TCP packet + slop + size */
1615  unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ + sizeof(u16));
1616  unsigned char *payload = &packet[2];
1617  /* largest field in header is 16-bits, so this is still sufficiently aligned */
1618  struct dns_header *header = (struct dns_header *)payload;
1619  u16 *length = (u16 *)packet;
1620  struct server *last_server;
1621  struct in_addr dst_addr_4;
1622  union mysockaddr peer_addr;
1623  socklen_t peer_len = sizeof(union mysockaddr);
1624  int query_count = 0;
1625  unsigned char *pheader;
1626  unsigned int mark = 0;
1627  int have_mark = 0;
1628
1629  (void)mark;
1630  (void)have_mark;
1631
1632  if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) == -1)
1633    return packet;
1634
1635#ifdef HAVE_CONNTRACK
1636  /* Get connection mark of incoming query to set on outgoing connections. */
1637  if (option_bool(OPT_CONNTRACK))
1638    {
1639      struct all_addr local;
1640#ifdef HAVE_IPV6                     
1641      if (local_addr->sa.sa_family == AF_INET6)
1642        local.addr.addr6 = local_addr->in6.sin6_addr;
1643      else
1644#endif
1645        local.addr.addr4 = local_addr->in.sin_addr;
1646     
1647      have_mark = get_incoming_mark(&peer_addr, &local, 1, &mark);
1648    }
1649#endif 
1650
1651  /* We can be configured to only accept queries from at-most-one-hop-away addresses. */
1652  if (option_bool(OPT_LOCAL_SERVICE))
1653    {
1654      struct addrlist *addr;
1655#ifdef HAVE_IPV6
1656      if (peer_addr.sa.sa_family == AF_INET6)
1657        {
1658          for (addr = daemon->interface_addrs; addr; addr = addr->next)
1659            if ((addr->flags & ADDRLIST_IPV6) &&
1660                is_same_net6(&addr->addr.addr.addr6, &peer_addr.in6.sin6_addr, addr->prefixlen))
1661              break;
1662        }
1663      else
1664#endif
1665        {
1666          struct in_addr netmask;
1667          for (addr = daemon->interface_addrs; addr; addr = addr->next)
1668            {
1669              netmask.s_addr = htonl(~(in_addr_t)0 << (32 - addr->prefixlen));
1670              if (!(addr->flags & ADDRLIST_IPV6) &&
1671                  is_same_net(addr->addr.addr.addr4, peer_addr.in.sin_addr, netmask))
1672                break;
1673            }
1674        }
1675      if (!addr)
1676        {
1677          my_syslog(LOG_WARNING, _("Ignoring query from non-local network"));
1678          return packet;
1679        }
1680    }
1681
1682  while (1)
1683    {
1684      if (query_count == TCP_MAX_QUERIES ||
1685          !packet ||
1686          !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) ||
1687          !(size = c1 << 8 | c2) ||
1688          !read_write(confd, payload, size, 1))
1689        return packet;
1690 
1691      if (size < (int)sizeof(struct dns_header))
1692        continue;
1693     
1694      query_count++;
1695
1696      /* log_query gets called indirectly all over the place, so
1697         pass these in global variables - sorry. */
1698      daemon->log_display_id = ++daemon->log_id;
1699      daemon->log_source_addr = &peer_addr;
1700     
1701      /* save state of "cd" flag in query */
1702      if ((checking_disabled = header->hb4 & HB4_CD))
1703        no_cache_dnssec = 1;
1704       
1705      if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
1706        {
1707#ifdef HAVE_AUTH
1708          struct auth_zone *zone;
1709#endif
1710          char *types = querystr(auth_dns ? "auth" : "query", qtype);
1711         
1712          if (peer_addr.sa.sa_family == AF_INET)
1713            log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
1714                      (struct all_addr *)&peer_addr.in.sin_addr, types);
1715#ifdef HAVE_IPV6
1716          else
1717            log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
1718                      (struct all_addr *)&peer_addr.in6.sin6_addr, types);
1719#endif
1720         
1721#ifdef HAVE_AUTH
1722          /* find queries for zones we're authoritative for, and answer them directly */
1723          if (!auth_dns && !option_bool(OPT_LOCALISE))
1724            for (zone = daemon->auth_zones; zone; zone = zone->next)
1725              if (in_zone(zone, daemon->namebuff, NULL))
1726                {
1727                  auth_dns = 1;
1728                  local_auth = 1;
1729                  break;
1730                }
1731#endif
1732        }
1733     
1734      if (local_addr->sa.sa_family == AF_INET)
1735        dst_addr_4 = local_addr->in.sin_addr;
1736      else
1737        dst_addr_4.s_addr = 0;
1738     
1739      do_bit = 0;
1740
1741      if (find_pseudoheader(header, (size_t)size, NULL, &pheader, NULL, NULL))
1742        {
1743          unsigned short flags;
1744         
1745          have_pseudoheader = 1;
1746          pheader += 4; /* udp_size, ext_rcode */
1747          GETSHORT(flags, pheader);
1748     
1749          if (flags & 0x8000)
1750            do_bit = 1; /* do bit */
1751        }
1752
1753#ifdef HAVE_AUTH
1754      if (auth_dns)
1755        m = answer_auth(header, ((char *) header) + 65536, (size_t)size, now, &peer_addr,
1756                        local_auth, do_bit, have_pseudoheader);
1757      else
1758#endif
1759        {
1760           int ad_reqd = do_bit;
1761           /* RFC 6840 5.7 */
1762           if (header->hb4 & HB4_AD)
1763             ad_reqd = 1;
1764           
1765           /* m > 0 if answered from cache */
1766           m = answer_request(header, ((char *) header) + 65536, (size_t)size,
1767                              dst_addr_4, netmask, now, ad_reqd, do_bit, have_pseudoheader);
1768         
1769          /* Do this by steam now we're not in the select() loop */
1770          check_log_writer(1);
1771         
1772          if (m == 0)
1773            {
1774              unsigned int flags = 0;
1775              struct all_addr *addrp = NULL;
1776              int type = SERV_DO_DNSSEC;
1777              char *domain = NULL;
1778              size_t new_size = add_edns0_config(header, size, ((unsigned char *) header) + 65536, &peer_addr, now, &check_subnet);
1779
1780              if (size != new_size)
1781                {
1782                  added_pheader = 1;
1783                  size = new_size;
1784                }
1785             
1786              if (gotname)
1787                flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
1788             
1789              type &= ~SERV_DO_DNSSEC;
1790             
1791              if (type != 0  || option_bool(OPT_ORDER) || !daemon->last_server)
1792                last_server = daemon->servers;
1793              else
1794                last_server = daemon->last_server;
1795             
1796              if (!flags && last_server)
1797                {
1798                  struct server *firstsendto = NULL;
1799#ifdef HAVE_DNSSEC
1800                  unsigned char *newhash, hash[HASH_SIZE];
1801                  if ((newhash = hash_questions(header, (unsigned int)size, daemon->namebuff)))
1802                    memcpy(hash, newhash, HASH_SIZE);
1803                  else
1804                    memset(hash, 0, HASH_SIZE);
1805#else
1806                  unsigned int crc = questions_crc(header, (unsigned int)size, daemon->namebuff);
1807#endif           
1808                  /* Loop round available servers until we succeed in connecting to one.
1809                     Note that this code subtly ensures that consecutive queries on this connection
1810                     which can go to the same server, do so. */
1811                  while (1)
1812                    {
1813                      if (!firstsendto)
1814                        firstsendto = last_server;
1815                      else
1816                        {
1817                          if (!(last_server = last_server->next))
1818                            last_server = daemon->servers;
1819                         
1820                          if (last_server == firstsendto)
1821                            break;
1822                        }
1823                     
1824                      /* server for wrong domain */
1825                      if (type != (last_server->flags & SERV_TYPE) ||
1826                          (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, last_server->domain)) ||
1827                          (last_server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
1828                        continue;
1829
1830                    retry:
1831                      if (last_server->tcpfd == -1)
1832                        {
1833                          if ((last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
1834                            continue;
1835                         
1836#ifdef HAVE_CONNTRACK
1837                          /* Copy connection mark of incoming query to outgoing connection. */
1838                          if (have_mark)
1839                            setsockopt(last_server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
1840#endif 
1841                     
1842                          if ((!local_bind(last_server->tcpfd,  &last_server->source_addr, last_server->interface, 1) ||
1843                               connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1))
1844                            {
1845                              close(last_server->tcpfd);
1846                              last_server->tcpfd = -1;
1847                              continue;
1848                            }
1849                         
1850                          last_server->flags &= ~SERV_GOT_TCP;
1851                        }
1852                     
1853#ifdef HAVE_DNSSEC
1854                      if (option_bool(OPT_DNSSEC_VALID) && (last_server->flags & SERV_DO_DNSSEC))
1855                        {
1856                          new_size = add_do_bit(header, size, ((unsigned char *) header) + 65536);
1857                         
1858                          if (size != new_size)
1859                            {
1860                              added_pheader = 1;
1861                              size = new_size;
1862                            }
1863                         
1864                          /* For debugging, set Checking Disabled, otherwise, have the upstream check too,
1865                             this allows it to select auth servers when one is returning bad data. */
1866                          if (option_bool(OPT_DNSSEC_DEBUG))
1867                            header->hb4 |= HB4_CD;
1868                        }
1869#endif
1870                                             
1871                      *length = htons(size);
1872
1873                      /* get query name again for logging - may have been overwritten */
1874                      if (!(gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
1875                        strcpy(daemon->namebuff, "query");
1876                     
1877                      if (!read_write(last_server->tcpfd, packet, size + sizeof(u16), 0) ||
1878                          !read_write(last_server->tcpfd, &c1, 1, 1) ||
1879                          !read_write(last_server->tcpfd, &c2, 1, 1) ||
1880                          !read_write(last_server->tcpfd, payload, (c1 << 8) | c2, 1))
1881                        {
1882                          close(last_server->tcpfd);
1883                          last_server->tcpfd = -1;
1884                          /* We get data then EOF, reopen connection to same server,
1885                             else try next. This avoids DoS from a server which accepts
1886                             connections and then closes them. */
1887                          if (last_server->flags & SERV_GOT_TCP)
1888                            goto retry;
1889                          else
1890                            continue;
1891                        }
1892                     
1893                      last_server->flags |= SERV_GOT_TCP;
1894
1895                      m = (c1 << 8) | c2;
1896                     
1897                      if (last_server->addr.sa.sa_family == AF_INET)
1898                        log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
1899                                  (struct all_addr *)&last_server->addr.in.sin_addr, NULL);
1900#ifdef HAVE_IPV6
1901                      else
1902                        log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
1903                                  (struct all_addr *)&last_server->addr.in6.sin6_addr, NULL);
1904#endif
1905
1906#ifdef HAVE_DNSSEC
1907                      if (option_bool(OPT_DNSSEC_VALID) && !checking_disabled && (last_server->flags & SERV_DO_DNSSEC))
1908                        {
1909                          int keycount = DNSSEC_WORK; /* Limit to number of DNSSEC questions, to catch loops and avoid filling cache. */
1910                          int status = tcp_key_recurse(now, STAT_OK, header, m, 0, daemon->namebuff, daemon->keyname,
1911                                                       last_server, have_mark, mark, &keycount);
1912                          char *result, *domain = "result";
1913                         
1914                          if (status == STAT_ABANDONED)
1915                            {
1916                              result = "ABANDONED";
1917                              status = STAT_BOGUS;
1918                            }
1919                          else
1920                            result = (status == STAT_SECURE ? "SECURE" : (status == STAT_INSECURE ? "INSECURE" : "BOGUS"));
1921                         
1922                          if (status == STAT_BOGUS && extract_request(header, m, daemon->namebuff, NULL))
1923                            domain = daemon->namebuff;
1924
1925                          log_query(F_KEYTAG | F_SECSTAT, domain, NULL, result);
1926                         
1927                          if (status == STAT_BOGUS)
1928                            {
1929                              no_cache_dnssec = 1;
1930                              bogusanswer = 1;
1931                            }
1932
1933                          if (status == STAT_SECURE)
1934                            cache_secure = 1;
1935                        }
1936#endif
1937
1938                      /* restore CD bit to the value in the query */
1939                      if (checking_disabled)
1940                        header->hb4 |= HB4_CD;
1941                      else
1942                        header->hb4 &= ~HB4_CD;
1943                     
1944                      /* There's no point in updating the cache, since this process will exit and
1945                         lose the information after a few queries. We make this call for the alias and
1946                         bogus-nxdomain side-effects. */
1947                      /* If the crc of the question section doesn't match the crc we sent, then
1948                         someone might be attempting to insert bogus values into the cache by
1949                         sending replies containing questions and bogus answers. */
1950#ifdef HAVE_DNSSEC
1951                      newhash = hash_questions(header, (unsigned int)m, daemon->namebuff);
1952                      if (!newhash || memcmp(hash, newhash, HASH_SIZE) != 0)
1953                        {
1954                          m = 0;
1955                          break;
1956                        }
1957#else                     
1958                      if (crc != questions_crc(header, (unsigned int)m, daemon->namebuff))
1959                        {
1960                          m = 0;
1961                          break;
1962                        }
1963#endif
1964
1965                      m = process_reply(header, now, last_server, (unsigned int)m,
1966                                        option_bool(OPT_NO_REBIND) && !norebind, no_cache_dnssec, cache_secure, bogusanswer,
1967                                        ad_reqd, do_bit, added_pheader, check_subnet, &peer_addr);
1968                     
1969                      break;
1970                    }
1971                }
1972       
1973              /* In case of local answer or no connections made. */
1974              if (m == 0)
1975                m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
1976            }
1977        }
1978         
1979      check_log_writer(1);
1980     
1981      *length = htons(m);
1982           
1983      if (m == 0 || !read_write(confd, packet, m + sizeof(u16), 0))
1984        return packet;
1985    }
1986}
1987
1988static struct frec *allocate_frec(time_t now)
1989{
1990  struct frec *f;
1991 
1992  if ((f = (struct frec *)whine_malloc(sizeof(struct frec))))
1993    {
1994      f->next = daemon->frec_list;
1995      f->time = now;
1996      f->sentto = NULL;
1997      f->rfd4 = NULL;
1998      f->flags = 0;
1999#ifdef HAVE_IPV6
2000      f->rfd6 = NULL;
2001#endif
2002#ifdef HAVE_DNSSEC
2003      f->dependent = NULL;
2004      f->blocking_query = NULL;
2005      f->stash = NULL;
2006#endif
2007      daemon->frec_list = f;
2008    }
2009
2010  return f;
2011}
2012
2013struct randfd *allocate_rfd(int family)
2014{
2015  static int finger = 0;
2016  int i;
2017
2018  /* limit the number of sockets we have open to avoid starvation of
2019     (eg) TFTP. Once we have a reasonable number, randomness should be OK */
2020
2021  for (i = 0; i < RANDOM_SOCKS; i++)
2022    if (daemon->randomsocks[i].refcount == 0)
2023      {
2024        if ((daemon->randomsocks[i].fd = random_sock(family)) == -1)
2025          break;
2026     
2027        daemon->randomsocks[i].refcount = 1;
2028        daemon->randomsocks[i].family = family;
2029        return &daemon->randomsocks[i];
2030      }
2031
2032  /* No free ones or cannot get new socket, grab an existing one */
2033  for (i = 0; i < RANDOM_SOCKS; i++)
2034    {
2035      int j = (i+finger) % RANDOM_SOCKS;
2036      if (daemon->randomsocks[j].refcount != 0 &&
2037          daemon->randomsocks[j].family == family &&
2038          daemon->randomsocks[j].refcount != 0xffff)
2039        {
2040          finger = j;
2041          daemon->randomsocks[j].refcount++;
2042          return &daemon->randomsocks[j];
2043        }
2044    }
2045
2046  return NULL; /* doom */
2047}
2048
2049void free_rfd(struct randfd *rfd)
2050{
2051  if (rfd && --(rfd->refcount) == 0)
2052    close(rfd->fd);
2053}
2054
2055static void free_frec(struct frec *f)
2056{
2057  free_rfd(f->rfd4);
2058  f->rfd4 = NULL;
2059  f->sentto = NULL;
2060  f->flags = 0;
2061 
2062#ifdef HAVE_IPV6
2063  free_rfd(f->rfd6);
2064  f->rfd6 = NULL;
2065#endif
2066
2067#ifdef HAVE_DNSSEC
2068  if (f->stash)
2069    {
2070      blockdata_free(f->stash);
2071      f->stash = NULL;
2072    }
2073
2074  /* Anything we're waiting on is pointless now, too */
2075  if (f->blocking_query)
2076    free_frec(f->blocking_query);
2077  f->blocking_query = NULL;
2078  f->dependent = NULL;
2079#endif
2080}
2081
2082/* if wait==NULL return a free or older than TIMEOUT record.
2083   else return *wait zero if one available, or *wait is delay to
2084   when the oldest in-use record will expire. Impose an absolute
2085   limit of 4*TIMEOUT before we wipe things (for random sockets).
2086   If force is set, always return a result, even if we have
2087   to allocate above the limit. */
2088struct frec *get_new_frec(time_t now, int *wait, int force)
2089{
2090  struct frec *f, *oldest, *target;
2091  int count;
2092 
2093  if (wait)
2094    *wait = 0;
2095
2096  for (f = daemon->frec_list, oldest = NULL, target =  NULL, count = 0; f; f = f->next, count++)
2097    if (!f->sentto)
2098      target = f;
2099    else
2100      {
2101#ifdef HAVE_DNSSEC
2102            /* Don't free DNSSEC sub-queries here, as we may end up with
2103               dangling references to them. They'll go when their "real" query
2104               is freed. */
2105            if (!f->dependent)
2106#endif
2107              {
2108                if (difftime(now, f->time) >= 4*TIMEOUT)
2109                  {
2110                    free_frec(f);
2111                    target = f;
2112                  }
2113             
2114           
2115                if (!oldest || difftime(f->time, oldest->time) <= 0)
2116                  oldest = f;
2117              }
2118      }
2119
2120  if (target)
2121    {
2122      target->time = now;
2123      return target;
2124    }
2125 
2126  /* can't find empty one, use oldest if there is one
2127     and it's older than timeout */
2128  if (oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
2129    {
2130      /* keep stuff for twice timeout if we can by allocating a new
2131         record instead */
2132      if (difftime(now, oldest->time) < 2*TIMEOUT &&
2133          count <= daemon->ftabsize &&
2134          (f = allocate_frec(now)))
2135        return f;
2136
2137      if (!wait)
2138        {
2139          free_frec(oldest);
2140          oldest->time = now;
2141        }
2142      return oldest;
2143    }
2144 
2145  /* none available, calculate time 'till oldest record expires */
2146  if (!force && count > daemon->ftabsize)
2147    {
2148      static time_t last_log = 0;
2149     
2150      if (oldest && wait)
2151        *wait = oldest->time + (time_t)TIMEOUT - now;
2152     
2153      if ((int)difftime(now, last_log) > 5)
2154        {
2155          last_log = now;
2156          my_syslog(LOG_WARNING, _("Maximum number of concurrent DNS queries reached (max: %d)"), daemon->ftabsize);
2157        }
2158
2159      return NULL;
2160    }
2161 
2162  if (!(f = allocate_frec(now)) && wait)
2163    /* wait one second on malloc failure */
2164    *wait = 1;
2165
2166  return f; /* OK if malloc fails and this is NULL */
2167}
2168 
2169/* crc is all-ones if not known. */
2170static struct frec *lookup_frec(unsigned short id, void *hash)
2171{
2172  struct frec *f;
2173
2174  for(f = daemon->frec_list; f; f = f->next)
2175    if (f->sentto && f->new_id == id &&
2176        (!hash || memcmp(hash, f->hash, HASH_SIZE) == 0))
2177      return f;
2178     
2179  return NULL;
2180}
2181
2182static struct frec *lookup_frec_by_sender(unsigned short id,
2183                                          union mysockaddr *addr,
2184                                          void *hash)
2185{
2186  struct frec *f;
2187 
2188  for(f = daemon->frec_list; f; f = f->next)
2189    if (f->sentto &&
2190        f->orig_id == id &&
2191        memcmp(hash, f->hash, HASH_SIZE) == 0 &&
2192        sockaddr_isequal(&f->source, addr))
2193      return f;
2194   
2195  return NULL;
2196}
2197 
2198/* Send query packet again, if we can. */
2199void resend_query()
2200{
2201  if (daemon->srv_save)
2202    {
2203      int fd;
2204     
2205      if (daemon->srv_save->sfd)
2206        fd = daemon->srv_save->sfd->fd;
2207      else if (daemon->rfd_save && daemon->rfd_save->refcount != 0)
2208        fd = daemon->rfd_save->fd;
2209      else
2210        return;
2211     
2212      while(retry_send(sendto(fd, daemon->packet, daemon->packet_len, 0,
2213                              &daemon->srv_save->addr.sa,
2214                              sa_len(&daemon->srv_save->addr))));
2215    }
2216}
2217
2218/* A server record is going away, remove references to it */
2219void server_gone(struct server *server)
2220{
2221  struct frec *f;
2222 
2223  for (f = daemon->frec_list; f; f = f->next)
2224    if (f->sentto && f->sentto == server)
2225      free_frec(f);
2226 
2227  if (daemon->last_server == server)
2228    daemon->last_server = NULL;
2229
2230  if (daemon->srv_save == server)
2231    daemon->srv_save = NULL;
2232}
2233
2234/* return unique random ids. */
2235static unsigned short get_id(void)
2236{
2237  unsigned short ret = 0;
2238 
2239  do
2240    ret = rand16();
2241  while (lookup_frec(ret, NULL));
2242 
2243  return ret;
2244}
2245
2246
2247
2248
2249
Note: See TracBrowser for help on using the repository browser.