File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / forward.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 09:57:01 2016 UTC (7 years, 10 months ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v2_76p1, HEAD
dnsmasq 2.76

    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: 
   19: static struct frec *lookup_frec(unsigned short id, void *hash);
   20: static struct frec *lookup_frec_by_sender(unsigned short id,
   21: 					  union mysockaddr *addr,
   22: 					  void *hash);
   23: static unsigned short get_id(void);
   24: static 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 */
   28: int 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:           
  109: static 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: 
  230: static 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: 
  556: static 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 */
  729: void 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 || RCODE(header) != REFUSED)
  857:     {
  858:       int check_rebind = 0, no_cache_dnssec = 0, cache_secure = 0, bogusanswer = 0;
  859: 
  860:       if (option_bool(OPT_NO_REBIND))
  861: 	check_rebind = !(forward->flags & FREC_NOREBIND);
  862:       
  863:       /*   Don't cache replies where DNSSEC validation was turned off, either
  864: 	   the upstream server told us so, or the original query specified it.  */
  865:       if ((header->hb4 & HB4_CD) || (forward->flags & FREC_CHECKING_DISABLED))
  866: 	no_cache_dnssec = 1;
  867:       
  868: #ifdef HAVE_DNSSEC
  869:       if (server && (server->flags & SERV_DO_DNSSEC) && 
  870: 	  option_bool(OPT_DNSSEC_VALID) && !(forward->flags & FREC_CHECKING_DISABLED))
  871: 	{
  872: 	  int status = 0;
  873: 
  874: 	  /* We've had a reply already, which we're validating. Ignore this duplicate */
  875: 	  if (forward->blocking_query)
  876: 	    return;
  877: 	  
  878: 	   /* Truncated answer can't be validated.
  879: 		 If this is an answer to a DNSSEC-generated query, we still
  880: 		 need to get the client to retry over TCP, so return
  881: 		 an answer with the TC bit set, even if the actual answer fits.
  882: 	      */
  883: 	  if (header->hb3 & HB3_TC)
  884: 	    status = STAT_TRUNCATED;
  885: 	  
  886: 	  while (1)
  887: 	    {
  888: 	      /* As soon as anything returns BOGUS, we stop and unwind, to do otherwise
  889: 		 would invite infinite loops, since the answers to DNSKEY and DS queries
  890: 		 will not be cached, so they'll be repeated. */
  891: 	      if (status != STAT_BOGUS && status != STAT_TRUNCATED && status != STAT_ABANDONED)
  892: 		{
  893: 		  if (forward->flags & FREC_DNSKEY_QUERY)
  894: 		    status = dnssec_validate_by_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
  895: 		  else if (forward->flags & FREC_DS_QUERY)
  896: 		    status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
  897: 		  else
  898: 		    status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class, 
  899: 						   option_bool(OPT_DNSSEC_NO_SIGN), NULL, NULL);
  900: 		}
  901: 	      
  902: 	      /* Can't validate, as we're missing key data. Put this
  903: 		 answer aside, whilst we get that. */     
  904: 	      if (status == STAT_NEED_DS || status == STAT_NEED_KEY)
  905: 		{
  906: 		  struct frec *new, *orig;
  907: 		  
  908: 		  /* Free any saved query */
  909: 		  if (forward->stash)
  910: 		    blockdata_free(forward->stash);
  911: 		  
  912: 		  /* Now save reply pending receipt of key data */
  913: 		  if (!(forward->stash = blockdata_alloc((char *)header, n)))
  914: 		    return;
  915: 		  forward->stash_len = n;
  916: 		  
  917: 		  /* Find the original query that started it all.... */
  918: 		  for (orig = forward; orig->dependent; orig = orig->dependent);
  919: 		  
  920: 		  if (--orig->work_counter == 0 || !(new = get_new_frec(now, NULL, 1)))
  921: 		    status = STAT_ABANDONED;
  922: 		  else
  923: 		    {
  924: 		      int fd, type = SERV_DO_DNSSEC;
  925: 		      struct frec *next = new->next;
  926: 		      char *domain;
  927: 		      
  928: 		      *new = *forward; /* copy everything, then overwrite */
  929: 		      new->next = next;
  930: 		      new->blocking_query = NULL;
  931: 
  932: 		      /* Find server to forward to. This will normally be the 
  933: 			 same as for the original query, but may be another if
  934: 			 servers for domains are involved. */		      
  935: 		      if (search_servers(now, NULL, F_QUERY, daemon->keyname, &type, &domain, NULL) == 0)
  936: 			{
  937: 			  struct server *start = server, *new_server = NULL;
  938: 			   type &= ~SERV_DO_DNSSEC;
  939: 			   
  940: 			   while (1)
  941: 			     {
  942: 			       if (type == (start->flags & SERV_TYPE) &&
  943: 				   (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
  944: 				   !(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
  945: 				 {
  946: 				   new_server = start;
  947: 				   if (server == start)
  948: 				     {
  949: 				       new_server = NULL;
  950: 				       break;
  951: 				     }
  952: 				 }
  953: 			       
  954: 			       if (!(start = start->next))
  955: 				 start = daemon->servers;
  956: 			       if (start == server)
  957: 				 break;
  958: 			     }
  959: 			
  960: 			   if (new_server)
  961: 			     server = new_server;
  962: 			}
  963: 
  964: 		      new->sentto = server;
  965: 
  966: 		      new->rfd4 = NULL;
  967: #ifdef HAVE_IPV6
  968: 		      new->rfd6 = NULL;
  969: #endif
  970: 		      new->flags &= ~(FREC_DNSKEY_QUERY | FREC_DS_QUERY);
  971: 		      
  972: 		      new->dependent = forward; /* to find query awaiting new one. */
  973: 		      forward->blocking_query = new; /* for garbage cleaning */
  974: 		      /* validate routines leave name of required record in daemon->keyname */
  975: 		      if (status == STAT_NEED_KEY)
  976: 			{
  977: 			  new->flags |= FREC_DNSKEY_QUERY; 
  978: 			  nn = dnssec_generate_query(header, ((unsigned char *) header) + server->edns_pktsz,
  979: 						     daemon->keyname, forward->class, T_DNSKEY, &server->addr, server->edns_pktsz);
  980: 			}
  981: 		      else 
  982: 			{
  983: 			  new->flags |= FREC_DS_QUERY;
  984: 			  nn = dnssec_generate_query(header,((unsigned char *) header) + server->edns_pktsz,
  985: 						     daemon->keyname, forward->class, T_DS, &server->addr, server->edns_pktsz);
  986: 			}
  987: 		      if ((hash = hash_questions(header, nn, daemon->namebuff)))
  988: 			memcpy(new->hash, hash, HASH_SIZE);
  989: 		      new->new_id = get_id();
  990: 		      header->id = htons(new->new_id);
  991: 		      /* Save query for retransmission */
  992: 		      new->stash = blockdata_alloc((char *)header, nn);
  993: 		      new->stash_len = nn;
  994: 		      
  995: 		      /* Don't resend this. */
  996: 		      daemon->srv_save = NULL;
  997: 		      
  998: 		      if (server->sfd)
  999: 			fd = server->sfd->fd;
 1000: 		      else
 1001: 			{
 1002: 			  fd = -1;
 1003: #ifdef HAVE_IPV6
 1004: 			  if (server->addr.sa.sa_family == AF_INET6)
 1005: 			    {
 1006: 			      if (new->rfd6 || (new->rfd6 = allocate_rfd(AF_INET6)))
 1007: 				fd = new->rfd6->fd;
 1008: 			    }
 1009: 			  else
 1010: #endif
 1011: 			    {
 1012: 			      if (new->rfd4 || (new->rfd4 = allocate_rfd(AF_INET)))
 1013: 				fd = new->rfd4->fd;
 1014: 			    }
 1015: 			}
 1016: 		      
 1017: 		      if (fd != -1)
 1018: 			{
 1019: #ifdef HAVE_CONNTRACK
 1020: 			  /* Copy connection mark of incoming query to outgoing connection. */
 1021: 			  if (option_bool(OPT_CONNTRACK))
 1022: 			    {
 1023: 			      unsigned int mark;
 1024: 			      if (get_incoming_mark(&orig->source, &orig->dest, 0, &mark))
 1025: 				setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
 1026: 			    }
 1027: #endif
 1028: 			  while (retry_send(sendto(fd, (char *)header, nn, 0, 
 1029: 						   &server->addr.sa, 
 1030: 						   sa_len(&server->addr)))); 
 1031: 			  server->queries++;
 1032: 			}
 1033: 		    }		  
 1034: 		  return;
 1035: 		}
 1036: 	  
 1037: 	      /* Validated original answer, all done. */
 1038: 	      if (!forward->dependent)
 1039: 		break;
 1040: 	      
 1041: 	      /* validated subsdiary query, (and cached result)
 1042: 		 pop that and return to the previous query we were working on. */
 1043: 	      struct frec *prev = forward->dependent;
 1044: 	      free_frec(forward);
 1045: 	      forward = prev;
 1046: 	      forward->blocking_query = NULL; /* already gone */
 1047: 	      blockdata_retrieve(forward->stash, forward->stash_len, (void *)header);
 1048: 	      n = forward->stash_len;
 1049: 	    }
 1050: 	
 1051: 	  
 1052: 	  no_cache_dnssec = 0;
 1053: 	  
 1054: 	  if (status == STAT_TRUNCATED)
 1055: 	    header->hb3 |= HB3_TC;
 1056: 	  else
 1057: 	    {
 1058: 	      char *result, *domain = "result";
 1059: 	      
 1060: 	      if (status == STAT_ABANDONED)
 1061: 		{
 1062: 		  result = "ABANDONED";
 1063: 		  status = STAT_BOGUS;
 1064: 		}
 1065: 	      else
 1066: 		result = (status == STAT_SECURE ? "SECURE" : (status == STAT_INSECURE ? "INSECURE" : "BOGUS"));
 1067: 	      
 1068: 	      if (status == STAT_BOGUS && extract_request(header, n, daemon->namebuff, NULL))
 1069: 		domain = daemon->namebuff;
 1070: 	      
 1071: 	      log_query(F_KEYTAG | F_SECSTAT, domain, NULL, result);
 1072: 	    }
 1073: 	  
 1074: 	  if (status == STAT_SECURE)
 1075: 	    cache_secure = 1;
 1076: 	  else if (status == STAT_BOGUS)
 1077: 	    {
 1078: 	      no_cache_dnssec = 1;
 1079: 	      bogusanswer = 1;
 1080: 	    }
 1081: 	}
 1082: #endif     
 1083:       
 1084:       /* restore CD bit to the value in the query */
 1085:       if (forward->flags & FREC_CHECKING_DISABLED)
 1086: 	header->hb4 |= HB4_CD;
 1087:       else
 1088: 	header->hb4 &= ~HB4_CD;
 1089:       
 1090:       if ((nn = process_reply(header, now, forward->sentto, (size_t)n, check_rebind, no_cache_dnssec, cache_secure, bogusanswer, 
 1091: 			      forward->flags & FREC_AD_QUESTION, forward->flags & FREC_DO_QUESTION, 
 1092: 			      forward->flags & FREC_ADDED_PHEADER, forward->flags & FREC_HAS_SUBNET, &forward->source)))
 1093: 	{
 1094: 	  header->id = htons(forward->orig_id);
 1095: 	  header->hb4 |= HB4_RA; /* recursion if available */
 1096: #ifdef HAVE_DNSSEC
 1097: 	  /* We added an EDNSO header for the purpose of getting DNSSEC RRs, and set the value of the UDP payload size
 1098: 	     greater than the no-EDNS0-implied 512 to have if space for the RRSIGS. If, having stripped them and the EDNS0
 1099:              header, the answer is still bigger than 512, truncate it and mark it so. The client then retries with TCP. */
 1100: 	  if (option_bool(OPT_DNSSEC_VALID) && (forward->flags & FREC_ADDED_PHEADER) && (nn > PACKETSZ))
 1101: 	    {
 1102: 	      header->ancount = htons(0);
 1103: 	      header->nscount = htons(0);
 1104: 	      header->arcount = htons(0);
 1105: 	      header->hb3 |= HB3_TC;
 1106: 	      nn = resize_packet(header, nn, NULL, 0);
 1107: 	    }
 1108: #endif
 1109: 	  send_from(forward->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn, 
 1110: 		    &forward->source, &forward->dest, forward->iface);
 1111: 	}
 1112:       free_frec(forward); /* cancel */
 1113:     }
 1114: }
 1115: 
 1116: 
 1117: void receive_query(struct listener *listen, time_t now)
 1118: {
 1119:   struct dns_header *header = (struct dns_header *)daemon->packet;
 1120:   union mysockaddr source_addr;
 1121:   unsigned char *pheader;
 1122:   unsigned short type, udp_size = PACKETSZ; /* default if no EDNS0 */
 1123:   struct all_addr dst_addr;
 1124:   struct in_addr netmask, dst_addr_4;
 1125:   size_t m;
 1126:   ssize_t n;
 1127:   int if_index = 0, auth_dns = 0, do_bit = 0, have_pseudoheader = 0;
 1128: #ifdef HAVE_AUTH
 1129:   int local_auth = 0;
 1130: #endif
 1131:   struct iovec iov[1];
 1132:   struct msghdr msg;
 1133:   struct cmsghdr *cmptr;
 1134:   union {
 1135:     struct cmsghdr align; /* this ensures alignment */
 1136: #ifdef HAVE_IPV6
 1137:     char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
 1138: #endif
 1139: #if defined(HAVE_LINUX_NETWORK)
 1140:     char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
 1141: #elif defined(IP_RECVDSTADDR) && defined(HAVE_SOLARIS_NETWORK)
 1142:     char control[CMSG_SPACE(sizeof(struct in_addr)) +
 1143: 		 CMSG_SPACE(sizeof(unsigned int))];
 1144: #elif defined(IP_RECVDSTADDR)
 1145:     char control[CMSG_SPACE(sizeof(struct in_addr)) +
 1146: 		 CMSG_SPACE(sizeof(struct sockaddr_dl))];
 1147: #endif
 1148:   } control_u;
 1149: #ifdef HAVE_IPV6
 1150:    /* Can always get recvd interface for IPv6 */
 1151:   int check_dst = !option_bool(OPT_NOWILD) || listen->family == AF_INET6;
 1152: #else
 1153:   int check_dst = !option_bool(OPT_NOWILD);
 1154: #endif
 1155: 
 1156:   /* packet buffer overwritten */
 1157:   daemon->srv_save = NULL;
 1158:   
 1159:   dst_addr_4.s_addr = dst_addr.addr.addr4.s_addr = 0;
 1160:   netmask.s_addr = 0;
 1161:   
 1162:   if (option_bool(OPT_NOWILD) && listen->iface)
 1163:     {
 1164:       auth_dns = listen->iface->dns_auth;
 1165:      
 1166:       if (listen->family == AF_INET)
 1167: 	{
 1168: 	  dst_addr_4 = dst_addr.addr.addr4 = listen->iface->addr.in.sin_addr;
 1169: 	  netmask = listen->iface->netmask;
 1170: 	}
 1171:     }
 1172:   
 1173:   iov[0].iov_base = daemon->packet;
 1174:   iov[0].iov_len = daemon->edns_pktsz;
 1175:     
 1176:   msg.msg_control = control_u.control;
 1177:   msg.msg_controllen = sizeof(control_u);
 1178:   msg.msg_flags = 0;
 1179:   msg.msg_name = &source_addr;
 1180:   msg.msg_namelen = sizeof(source_addr);
 1181:   msg.msg_iov = iov;
 1182:   msg.msg_iovlen = 1;
 1183:   
 1184:   if ((n = recvmsg(listen->fd, &msg, 0)) == -1)
 1185:     return;
 1186:   
 1187:   if (n < (int)sizeof(struct dns_header) || 
 1188:       (msg.msg_flags & MSG_TRUNC) ||
 1189:       (header->hb3 & HB3_QR))
 1190:     return;
 1191:   
 1192:   source_addr.sa.sa_family = listen->family;
 1193:   
 1194:   if (listen->family == AF_INET)
 1195:     {
 1196:        /* Source-port == 0 is an error, we can't send back to that. 
 1197: 	  http://www.ietf.org/mail-archive/web/dnsop/current/msg11441.html */
 1198:       if (source_addr.in.sin_port == 0)
 1199: 	return;
 1200:     }
 1201: #ifdef HAVE_IPV6
 1202:   else
 1203:     {
 1204:       /* Source-port == 0 is an error, we can't send back to that. */
 1205:       if (source_addr.in6.sin6_port == 0)
 1206: 	return;
 1207:       source_addr.in6.sin6_flowinfo = 0;
 1208:     }
 1209: #endif
 1210:   
 1211:   /* We can be configured to only accept queries from at-most-one-hop-away addresses. */
 1212:   if (option_bool(OPT_LOCAL_SERVICE))
 1213:     {
 1214:       struct addrlist *addr;
 1215: #ifdef HAVE_IPV6
 1216:       if (listen->family == AF_INET6) 
 1217: 	{
 1218: 	  for (addr = daemon->interface_addrs; addr; addr = addr->next)
 1219: 	    if ((addr->flags & ADDRLIST_IPV6) &&
 1220: 		is_same_net6(&addr->addr.addr.addr6, &source_addr.in6.sin6_addr, addr->prefixlen))
 1221: 	      break;
 1222: 	}
 1223:       else
 1224: #endif
 1225: 	{
 1226: 	  struct in_addr netmask;
 1227: 	  for (addr = daemon->interface_addrs; addr; addr = addr->next)
 1228: 	    {
 1229: 	      netmask.s_addr = htonl(~(in_addr_t)0 << (32 - addr->prefixlen));
 1230: 	      if (!(addr->flags & ADDRLIST_IPV6) &&
 1231: 		  is_same_net(addr->addr.addr.addr4, source_addr.in.sin_addr, netmask))
 1232: 		break;
 1233: 	    }
 1234: 	}
 1235:       if (!addr)
 1236: 	{
 1237: 	  static int warned = 0;
 1238: 	  if (!warned)
 1239: 	    {
 1240: 	      my_syslog(LOG_WARNING, _("Ignoring query from non-local network"));
 1241: 	      warned = 1;
 1242: 	    }
 1243: 	  return;
 1244: 	}
 1245:     }
 1246: 		
 1247:   if (check_dst)
 1248:     {
 1249:       struct ifreq ifr;
 1250: 
 1251:       if (msg.msg_controllen < sizeof(struct cmsghdr))
 1252: 	return;
 1253: 
 1254: #if defined(HAVE_LINUX_NETWORK)
 1255:       if (listen->family == AF_INET)
 1256: 	for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
 1257: 	  if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
 1258: 	    {
 1259: 	      union {
 1260: 		unsigned char *c;
 1261: 		struct in_pktinfo *p;
 1262: 	      } p;
 1263: 	      p.c = CMSG_DATA(cmptr);
 1264: 	      dst_addr_4 = dst_addr.addr.addr4 = p.p->ipi_spec_dst;
 1265: 	      if_index = p.p->ipi_ifindex;
 1266: 	    }
 1267: #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
 1268:       if (listen->family == AF_INET)
 1269: 	{
 1270: 	  for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
 1271: 	    {
 1272: 	      union {
 1273: 		unsigned char *c;
 1274: 		unsigned int *i;
 1275: 		struct in_addr *a;
 1276: #ifndef HAVE_SOLARIS_NETWORK
 1277: 		struct sockaddr_dl *s;
 1278: #endif
 1279: 	      } p;
 1280: 	       p.c = CMSG_DATA(cmptr);
 1281: 	       if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
 1282: 		 dst_addr_4 = dst_addr.addr.addr4 = *(p.a);
 1283: 	       else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
 1284: #ifdef HAVE_SOLARIS_NETWORK
 1285: 		 if_index = *(p.i);
 1286: #else
 1287:   	         if_index = p.s->sdl_index;
 1288: #endif
 1289: 	    }
 1290: 	}
 1291: #endif
 1292:       
 1293: #ifdef HAVE_IPV6
 1294:       if (listen->family == AF_INET6)
 1295: 	{
 1296: 	  for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
 1297: 	    if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
 1298: 	      {
 1299: 		union {
 1300: 		  unsigned char *c;
 1301: 		  struct in6_pktinfo *p;
 1302: 		} p;
 1303: 		p.c = CMSG_DATA(cmptr);
 1304: 		  
 1305: 		dst_addr.addr.addr6 = p.p->ipi6_addr;
 1306: 		if_index = p.p->ipi6_ifindex;
 1307: 	      }
 1308: 	}
 1309: #endif
 1310:       
 1311:       /* enforce available interface configuration */
 1312:       
 1313:       if (!indextoname(listen->fd, if_index, ifr.ifr_name))
 1314: 	return;
 1315:       
 1316:       if (!iface_check(listen->family, &dst_addr, ifr.ifr_name, &auth_dns))
 1317: 	{
 1318: 	   if (!option_bool(OPT_CLEVERBIND))
 1319: 	     enumerate_interfaces(0); 
 1320: 	   if (!loopback_exception(listen->fd, listen->family, &dst_addr, ifr.ifr_name) &&
 1321: 	       !label_exception(if_index, listen->family, &dst_addr))
 1322: 	     return;
 1323: 	}
 1324: 
 1325:       if (listen->family == AF_INET && option_bool(OPT_LOCALISE))
 1326: 	{
 1327: 	  struct irec *iface;
 1328: 	  
 1329: 	  /* get the netmask of the interface whch has the address we were sent to.
 1330: 	     This is no neccessarily the interface we arrived on. */
 1331: 	  
 1332: 	  for (iface = daemon->interfaces; iface; iface = iface->next)
 1333: 	    if (iface->addr.sa.sa_family == AF_INET &&
 1334: 		iface->addr.in.sin_addr.s_addr == dst_addr_4.s_addr)
 1335: 	      break;
 1336: 	  
 1337: 	  /* interface may be new */
 1338: 	  if (!iface && !option_bool(OPT_CLEVERBIND))
 1339: 	    enumerate_interfaces(0); 
 1340: 	  
 1341: 	  for (iface = daemon->interfaces; iface; iface = iface->next)
 1342: 	    if (iface->addr.sa.sa_family == AF_INET &&
 1343: 		iface->addr.in.sin_addr.s_addr == dst_addr_4.s_addr)
 1344: 	      break;
 1345: 	  
 1346: 	  /* If we failed, abandon localisation */
 1347: 	  if (iface)
 1348: 	    netmask = iface->netmask;
 1349: 	  else
 1350: 	    dst_addr_4.s_addr = 0;
 1351: 	}
 1352:     }
 1353:    
 1354:   /* log_query gets called indirectly all over the place, so 
 1355:      pass these in global variables - sorry. */
 1356:   daemon->log_display_id = ++daemon->log_id;
 1357:   daemon->log_source_addr = &source_addr;
 1358:   
 1359:   if (extract_request(header, (size_t)n, daemon->namebuff, &type))
 1360:     {
 1361: #ifdef HAVE_AUTH
 1362:       struct auth_zone *zone;
 1363: #endif
 1364:       char *types = querystr(auth_dns ? "auth" : "query", type);
 1365:       
 1366:       if (listen->family == AF_INET) 
 1367: 	log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, 
 1368: 		  (struct all_addr *)&source_addr.in.sin_addr, types);
 1369: #ifdef HAVE_IPV6
 1370:       else
 1371: 	log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, 
 1372: 		  (struct all_addr *)&source_addr.in6.sin6_addr, types);
 1373: #endif
 1374: 
 1375: #ifdef HAVE_AUTH
 1376:       /* find queries for zones we're authoritative for, and answer them directly */
 1377:       if (!auth_dns && !option_bool(OPT_LOCALISE))
 1378: 	for (zone = daemon->auth_zones; zone; zone = zone->next)
 1379: 	  if (in_zone(zone, daemon->namebuff, NULL))
 1380: 	    {
 1381: 	      auth_dns = 1;
 1382: 	      local_auth = 1;
 1383: 	      break;
 1384: 	    }
 1385: #endif
 1386:       
 1387: #ifdef HAVE_LOOP
 1388:       /* Check for forwarding loop */
 1389:       if (detect_loop(daemon->namebuff, type))
 1390: 	return;
 1391: #endif
 1392:     }
 1393:   
 1394:   if (find_pseudoheader(header, (size_t)n, NULL, &pheader, NULL, NULL))
 1395:     { 
 1396:       unsigned short flags;
 1397:       
 1398:       have_pseudoheader = 1;
 1399:       GETSHORT(udp_size, pheader);
 1400:       pheader += 2; /* ext_rcode */
 1401:       GETSHORT(flags, pheader);
 1402:       
 1403:       if (flags & 0x8000)
 1404: 	do_bit = 1;/* do bit */ 
 1405: 	
 1406:       /* If the client provides an EDNS0 UDP size, use that to limit our reply.
 1407: 	 (bounded by the maximum configured). If no EDNS0, then it
 1408: 	 defaults to 512 */
 1409:       if (udp_size > daemon->edns_pktsz)
 1410: 	udp_size = daemon->edns_pktsz;
 1411:     }
 1412: 
 1413: #ifdef HAVE_AUTH
 1414:   if (auth_dns)
 1415:     {
 1416:       m = answer_auth(header, ((char *) header) + udp_size, (size_t)n, now, &source_addr, 
 1417: 		      local_auth, do_bit, have_pseudoheader);
 1418:       if (m >= 1)
 1419: 	{
 1420: 	  send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
 1421: 		    (char *)header, m, &source_addr, &dst_addr, if_index);
 1422: 	  daemon->auth_answer++;
 1423: 	}
 1424:     }
 1425:   else
 1426: #endif
 1427:     {
 1428:       int ad_reqd = do_bit;
 1429:        /* RFC 6840 5.7 */
 1430:       if (header->hb4 & HB4_AD)
 1431: 	ad_reqd = 1;
 1432: 
 1433:       m = answer_request(header, ((char *) header) + udp_size, (size_t)n, 
 1434: 			 dst_addr_4, netmask, now, ad_reqd, do_bit, have_pseudoheader);
 1435:       
 1436:       if (m >= 1)
 1437: 	{
 1438: 	  send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
 1439: 		    (char *)header, m, &source_addr, &dst_addr, if_index);
 1440: 	  daemon->local_answer++;
 1441: 	}
 1442:       else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
 1443: 			     header, (size_t)n, now, NULL, ad_reqd, do_bit))
 1444: 	daemon->queries_forwarded++;
 1445:       else
 1446: 	daemon->local_answer++;
 1447:     }
 1448: }
 1449: 
 1450: #ifdef HAVE_DNSSEC
 1451: /* Recurse up the key heirarchy */
 1452: static int tcp_key_recurse(time_t now, int status, struct dns_header *header, size_t n, 
 1453: 			   int class, char *name, char *keyname, struct server *server, 
 1454: 			   int have_mark, unsigned int mark, int *keycount)
 1455: {
 1456:   int new_status;
 1457:   unsigned char *packet = NULL;
 1458:   unsigned char *payload = NULL;
 1459:   struct dns_header *new_header = NULL;
 1460:   u16 *length = NULL;
 1461: 
 1462:   while (1)
 1463:     {
 1464:       int type = SERV_DO_DNSSEC;
 1465:       char *domain;
 1466:       size_t m; 
 1467:       unsigned char c1, c2;
 1468:             
 1469:       /* limit the amount of work we do, to avoid cycling forever on loops in the DNS */
 1470:       if (--(*keycount) == 0)
 1471: 	new_status = STAT_ABANDONED;
 1472:       else if (status == STAT_NEED_KEY)
 1473: 	new_status = dnssec_validate_by_ds(now, header, n, name, keyname, class);
 1474:       else if (status == STAT_NEED_DS)
 1475: 	new_status = dnssec_validate_ds(now, header, n, name, keyname, class);
 1476:       else 
 1477: 	new_status = dnssec_validate_reply(now, header, n, name, keyname, &class, option_bool(OPT_DNSSEC_NO_SIGN), NULL, NULL);
 1478:       
 1479:       if (new_status != STAT_NEED_DS && new_status != STAT_NEED_KEY)
 1480: 	break;
 1481: 
 1482:       /* Can't validate because we need a key/DS whose name now in keyname.
 1483: 	 Make query for same, and recurse to validate */
 1484:       if (!packet)
 1485: 	{
 1486: 	  packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ + sizeof(u16));
 1487: 	  payload = &packet[2];
 1488: 	  new_header = (struct dns_header *)payload;
 1489: 	  length = (u16 *)packet;
 1490: 	}
 1491:       
 1492:       if (!packet)
 1493: 	{
 1494: 	  new_status = STAT_ABANDONED;
 1495: 	  break;
 1496: 	}
 1497: 	 
 1498:       m = dnssec_generate_query(new_header, ((unsigned char *) new_header) + 65536, keyname, class, 
 1499: 				new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS, &server->addr, server->edns_pktsz);
 1500:       
 1501:       *length = htons(m);
 1502: 
 1503:       /* Find server to forward to. This will normally be the 
 1504: 	 same as for the original query, but may be another if
 1505: 	 servers for domains are involved. */		      
 1506:       if (search_servers(now, NULL, F_QUERY, keyname, &type, &domain, NULL) == 0)
 1507: 	{
 1508: 	  struct server *start = server, *new_server = NULL;
 1509: 	  type &= ~SERV_DO_DNSSEC;
 1510: 			   
 1511: 	  while (1)
 1512: 	    {
 1513: 	      if (type == (start->flags & SERV_TYPE) &&
 1514: 		  (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
 1515: 		  !(start->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
 1516: 		{
 1517: 		  new_server = start;
 1518: 		  if (server == start)
 1519: 		    {
 1520: 		      new_server = NULL;
 1521: 		      break;
 1522: 		    }
 1523: 		}
 1524: 			       
 1525: 	      if (!(start = start->next))
 1526: 		start = daemon->servers;
 1527: 	      if (start == server)
 1528: 		break;
 1529: 	    }
 1530:        
 1531: 
 1532: 	  if (new_server)
 1533: 	    {
 1534: 	      server = new_server;
 1535: 	      /* may need to make new connection. */
 1536: 	      if (server->tcpfd == -1)
 1537: 		{
 1538: 		  if ((server->tcpfd = socket(server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
 1539: 		    {
 1540: 		      new_status = STAT_ABANDONED;
 1541: 		      break;
 1542: 		    }
 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: 		      new_status = STAT_ABANDONED;
 1556: 		      break;
 1557: 		    }
 1558: 
 1559: 		}
 1560: 	    }
 1561: 	}
 1562: 
 1563:       
 1564:       if (!read_write(server->tcpfd, packet, m + sizeof(u16), 0) ||
 1565: 	  !read_write(server->tcpfd, &c1, 1, 1) ||
 1566: 	  !read_write(server->tcpfd, &c2, 1, 1) ||
 1567: 	  !read_write(server->tcpfd, payload, (c1 << 8) | c2, 1))
 1568: 	{
 1569: 	  new_status = STAT_ABANDONED;
 1570: 	  break;
 1571: 	}
 1572: 
 1573:       m = (c1 << 8) | c2;
 1574:       
 1575:       new_status = tcp_key_recurse(now, new_status, new_header, m, class, name, keyname, server, have_mark, mark, keycount);
 1576:       
 1577:       if (new_status != STAT_OK)
 1578: 	break;
 1579:     }
 1580: 
 1581:   if (packet)
 1582:     free(packet);
 1583:     
 1584:   return new_status;
 1585: }
 1586: #endif
 1587: 
 1588: 
 1589: /* The daemon forks before calling this: it should deal with one connection,
 1590:    blocking as neccessary, and then return. Note, need to be a bit careful
 1591:    about resources for debug mode, when the fork is suppressed: that's
 1592:    done by the caller. */
 1593: unsigned char *tcp_request(int confd, time_t now,
 1594: 			   union mysockaddr *local_addr, struct in_addr netmask, int auth_dns)
 1595: {
 1596:   size_t size = 0;
 1597:   int norebind = 0;
 1598: #ifdef HAVE_AUTH
 1599:   int local_auth = 0;
 1600: #endif
 1601:   int checking_disabled, do_bit, added_pheader = 0, have_pseudoheader = 0;
 1602:   int check_subnet, no_cache_dnssec = 0, cache_secure = 0, bogusanswer = 0;
 1603:   size_t m;
 1604:   unsigned short qtype;
 1605:   unsigned int gotname;
 1606:   unsigned char c1, c2;
 1607:   /* Max TCP packet + slop + size */
 1608:   unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ + sizeof(u16));
 1609:   unsigned char *payload = &packet[2];
 1610:   /* largest field in header is 16-bits, so this is still sufficiently aligned */
 1611:   struct dns_header *header = (struct dns_header *)payload;
 1612:   u16 *length = (u16 *)packet;
 1613:   struct server *last_server;
 1614:   struct in_addr dst_addr_4;
 1615:   union mysockaddr peer_addr;
 1616:   socklen_t peer_len = sizeof(union mysockaddr);
 1617:   int query_count = 0;
 1618:   unsigned char *pheader;
 1619:   unsigned int mark = 0;
 1620:   int have_mark = 0;
 1621: 
 1622:   (void)mark;
 1623:   (void)have_mark;
 1624: 
 1625:   if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) == -1)
 1626:     return packet;
 1627: 
 1628: #ifdef HAVE_CONNTRACK
 1629:   /* Get connection mark of incoming query to set on outgoing connections. */
 1630:   if (option_bool(OPT_CONNTRACK))
 1631:     {
 1632:       struct all_addr local;
 1633: #ifdef HAVE_IPV6		      
 1634:       if (local_addr->sa.sa_family == AF_INET6)
 1635: 	local.addr.addr6 = local_addr->in6.sin6_addr;
 1636:       else
 1637: #endif
 1638: 	local.addr.addr4 = local_addr->in.sin_addr;
 1639:       
 1640:       have_mark = get_incoming_mark(&peer_addr, &local, 1, &mark);
 1641:     }
 1642: #endif	
 1643: 
 1644:   /* We can be configured to only accept queries from at-most-one-hop-away addresses. */
 1645:   if (option_bool(OPT_LOCAL_SERVICE))
 1646:     {
 1647:       struct addrlist *addr;
 1648: #ifdef HAVE_IPV6
 1649:       if (peer_addr.sa.sa_family == AF_INET6) 
 1650: 	{
 1651: 	  for (addr = daemon->interface_addrs; addr; addr = addr->next)
 1652: 	    if ((addr->flags & ADDRLIST_IPV6) &&
 1653: 		is_same_net6(&addr->addr.addr.addr6, &peer_addr.in6.sin6_addr, addr->prefixlen))
 1654: 	      break;
 1655: 	}
 1656:       else
 1657: #endif
 1658: 	{
 1659: 	  struct in_addr netmask;
 1660: 	  for (addr = daemon->interface_addrs; addr; addr = addr->next)
 1661: 	    {
 1662: 	      netmask.s_addr = htonl(~(in_addr_t)0 << (32 - addr->prefixlen));
 1663: 	      if (!(addr->flags & ADDRLIST_IPV6) && 
 1664: 		  is_same_net(addr->addr.addr.addr4, peer_addr.in.sin_addr, netmask))
 1665: 		break;
 1666: 	    }
 1667: 	}
 1668:       if (!addr)
 1669: 	{
 1670: 	  my_syslog(LOG_WARNING, _("Ignoring query from non-local network"));
 1671: 	  return packet;
 1672: 	}
 1673:     }
 1674: 
 1675:   while (1)
 1676:     {
 1677:       if (query_count == TCP_MAX_QUERIES ||
 1678: 	  !packet ||
 1679: 	  !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) ||
 1680: 	  !(size = c1 << 8 | c2) ||
 1681: 	  !read_write(confd, payload, size, 1))
 1682:        	return packet; 
 1683:   
 1684:       if (size < (int)sizeof(struct dns_header))
 1685: 	continue;
 1686:       
 1687:       query_count++;
 1688: 
 1689:       /* log_query gets called indirectly all over the place, so 
 1690: 	 pass these in global variables - sorry. */
 1691:       daemon->log_display_id = ++daemon->log_id;
 1692:       daemon->log_source_addr = &peer_addr;
 1693:       
 1694:       /* save state of "cd" flag in query */
 1695:       if ((checking_disabled = header->hb4 & HB4_CD))
 1696: 	no_cache_dnssec = 1;
 1697:        
 1698:       if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
 1699: 	{
 1700: #ifdef HAVE_AUTH
 1701: 	  struct auth_zone *zone;
 1702: #endif
 1703: 	  char *types = querystr(auth_dns ? "auth" : "query", qtype);
 1704: 	  
 1705: 	  if (peer_addr.sa.sa_family == AF_INET) 
 1706: 	    log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, 
 1707: 		      (struct all_addr *)&peer_addr.in.sin_addr, types);
 1708: #ifdef HAVE_IPV6
 1709: 	  else
 1710: 	    log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, 
 1711: 		      (struct all_addr *)&peer_addr.in6.sin6_addr, types);
 1712: #endif
 1713: 	  
 1714: #ifdef HAVE_AUTH
 1715: 	  /* find queries for zones we're authoritative for, and answer them directly */
 1716: 	  if (!auth_dns && !option_bool(OPT_LOCALISE))
 1717: 	    for (zone = daemon->auth_zones; zone; zone = zone->next)
 1718: 	      if (in_zone(zone, daemon->namebuff, NULL))
 1719: 		{
 1720: 		  auth_dns = 1;
 1721: 		  local_auth = 1;
 1722: 		  break;
 1723: 		}
 1724: #endif
 1725: 	}
 1726:       
 1727:       if (local_addr->sa.sa_family == AF_INET)
 1728: 	dst_addr_4 = local_addr->in.sin_addr;
 1729:       else
 1730: 	dst_addr_4.s_addr = 0;
 1731:       
 1732:       do_bit = 0;
 1733: 
 1734:       if (find_pseudoheader(header, (size_t)size, NULL, &pheader, NULL, NULL))
 1735: 	{ 
 1736: 	  unsigned short flags;
 1737: 	  
 1738: 	  have_pseudoheader = 1;
 1739: 	  pheader += 4; /* udp_size, ext_rcode */
 1740: 	  GETSHORT(flags, pheader);
 1741:       
 1742: 	  if (flags & 0x8000)
 1743: 	    do_bit = 1; /* do bit */ 
 1744: 	}
 1745: 
 1746: #ifdef HAVE_AUTH
 1747:       if (auth_dns)
 1748: 	m = answer_auth(header, ((char *) header) + 65536, (size_t)size, now, &peer_addr, 
 1749: 			local_auth, do_bit, have_pseudoheader);
 1750:       else
 1751: #endif
 1752: 	{
 1753: 	   int ad_reqd = do_bit;
 1754: 	   /* RFC 6840 5.7 */
 1755: 	   if (header->hb4 & HB4_AD)
 1756: 	     ad_reqd = 1;
 1757: 	   
 1758: 	   /* m > 0 if answered from cache */
 1759: 	   m = answer_request(header, ((char *) header) + 65536, (size_t)size, 
 1760: 			      dst_addr_4, netmask, now, ad_reqd, do_bit, have_pseudoheader);
 1761: 	  
 1762: 	  /* Do this by steam now we're not in the select() loop */
 1763: 	  check_log_writer(1); 
 1764: 	  
 1765: 	  if (m == 0)
 1766: 	    {
 1767: 	      unsigned int flags = 0;
 1768: 	      struct all_addr *addrp = NULL;
 1769: 	      int type = SERV_DO_DNSSEC;
 1770: 	      char *domain = NULL;
 1771: 	      size_t new_size = add_edns0_config(header, size, ((unsigned char *) header) + 65536, &peer_addr, now, &check_subnet);
 1772: 
 1773: 	      if (size != new_size)
 1774: 		{
 1775: 		  added_pheader = 1;
 1776: 		  size = new_size;
 1777: 		}
 1778: 	      
 1779: 	      if (gotname)
 1780: 		flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
 1781: 	      
 1782: 	      type &= ~SERV_DO_DNSSEC;
 1783: 	      
 1784: 	      if (type != 0  || option_bool(OPT_ORDER) || !daemon->last_server)
 1785: 		last_server = daemon->servers;
 1786: 	      else
 1787: 		last_server = daemon->last_server;
 1788: 	      
 1789: 	      if (!flags && last_server)
 1790: 		{
 1791: 		  struct server *firstsendto = NULL;
 1792: #ifdef HAVE_DNSSEC
 1793: 		  unsigned char *newhash, hash[HASH_SIZE];
 1794: 		  if ((newhash = hash_questions(header, (unsigned int)size, daemon->namebuff)))
 1795: 		    memcpy(hash, newhash, HASH_SIZE);
 1796: 		  else
 1797: 		    memset(hash, 0, HASH_SIZE);
 1798: #else
 1799: 		  unsigned int crc = questions_crc(header, (unsigned int)size, daemon->namebuff);
 1800: #endif		  
 1801: 		  /* Loop round available servers until we succeed in connecting to one.
 1802: 		     Note that this code subtley ensures that consecutive queries on this connection
 1803: 		     which can go to the same server, do so. */
 1804: 		  while (1) 
 1805: 		    {
 1806: 		      if (!firstsendto)
 1807: 			firstsendto = last_server;
 1808: 		      else
 1809: 			{
 1810: 			  if (!(last_server = last_server->next))
 1811: 			    last_server = daemon->servers;
 1812: 			  
 1813: 			  if (last_server == firstsendto)
 1814: 			    break;
 1815: 			}
 1816: 		      
 1817: 		      /* server for wrong domain */
 1818: 		      if (type != (last_server->flags & SERV_TYPE) ||
 1819: 			  (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, last_server->domain)) ||
 1820: 			  (last_server->flags & (SERV_LITERAL_ADDRESS | SERV_LOOP)))
 1821: 			continue;
 1822: 		      
 1823: 		      if (last_server->tcpfd == -1)
 1824: 			{
 1825: 			  if ((last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
 1826: 			    continue;
 1827: 			  
 1828: #ifdef HAVE_CONNTRACK
 1829: 			  /* Copy connection mark of incoming query to outgoing connection. */
 1830: 			  if (have_mark)
 1831: 			    setsockopt(last_server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
 1832: #endif	
 1833: 		      
 1834: 			  if ((!local_bind(last_server->tcpfd,  &last_server->source_addr, last_server->interface, 1) ||
 1835: 			       connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1))
 1836: 			    {
 1837: 			      close(last_server->tcpfd);
 1838: 			      last_server->tcpfd = -1;
 1839: 			      continue;
 1840: 			    }
 1841: 			  
 1842: #ifdef HAVE_DNSSEC
 1843: 			  if (option_bool(OPT_DNSSEC_VALID) && (last_server->flags & SERV_DO_DNSSEC))
 1844: 			    {
 1845: 			      new_size = add_do_bit(header, size, ((unsigned char *) header) + 65536);
 1846: 			      
 1847: 			      if (size != new_size)
 1848: 				{
 1849: 				  added_pheader = 1;
 1850: 				  size = new_size;
 1851: 				}
 1852: 			      
 1853: 			      /* For debugging, set Checking Disabled, otherwise, have the upstream check too,
 1854: 				 this allows it to select auth servers when one is returning bad data. */
 1855: 			      if (option_bool(OPT_DNSSEC_DEBUG))
 1856: 				header->hb4 |= HB4_CD;
 1857: 			    }
 1858: #endif
 1859: 			}
 1860: 		      
 1861: 		      *length = htons(size);
 1862: 
 1863: 		      /* get query name again for logging - may have been overwritten */
 1864: 		      if (!(gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
 1865: 			strcpy(daemon->namebuff, "query");
 1866: 		      
 1867: 		      if (!read_write(last_server->tcpfd, packet, size + sizeof(u16), 0) ||
 1868: 			  !read_write(last_server->tcpfd, &c1, 1, 1) ||
 1869: 			  !read_write(last_server->tcpfd, &c2, 1, 1) ||
 1870: 			  !read_write(last_server->tcpfd, payload, (c1 << 8) | c2, 1))
 1871: 			{
 1872: 			  close(last_server->tcpfd);
 1873: 			  last_server->tcpfd = -1;
 1874: 			  continue;
 1875: 			} 
 1876: 		      
 1877: 		      m = (c1 << 8) | c2;
 1878: 		      
 1879: 		      if (last_server->addr.sa.sa_family == AF_INET)
 1880: 			log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, 
 1881: 				  (struct all_addr *)&last_server->addr.in.sin_addr, NULL); 
 1882: #ifdef HAVE_IPV6
 1883: 		      else
 1884: 			log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, 
 1885: 				  (struct all_addr *)&last_server->addr.in6.sin6_addr, NULL);
 1886: #endif 
 1887: 
 1888: #ifdef HAVE_DNSSEC
 1889: 		      if (option_bool(OPT_DNSSEC_VALID) && !checking_disabled && (last_server->flags & SERV_DO_DNSSEC))
 1890: 			{
 1891: 			  int keycount = DNSSEC_WORK; /* Limit to number of DNSSEC questions, to catch loops and avoid filling cache. */
 1892: 			  int status = tcp_key_recurse(now, STAT_OK, header, m, 0, daemon->namebuff, daemon->keyname, 
 1893: 						       last_server, have_mark, mark, &keycount);
 1894: 			  char *result, *domain = "result";
 1895: 			  
 1896: 			  if (status == STAT_ABANDONED)
 1897: 			    {
 1898: 			      result = "ABANDONED";
 1899: 			      status = STAT_BOGUS;
 1900: 			    }
 1901: 			  else
 1902: 			    result = (status == STAT_SECURE ? "SECURE" : (status == STAT_INSECURE ? "INSECURE" : "BOGUS"));
 1903: 			  
 1904: 			  if (status == STAT_BOGUS && extract_request(header, m, daemon->namebuff, NULL))
 1905: 			    domain = daemon->namebuff;
 1906: 
 1907: 			  log_query(F_KEYTAG | F_SECSTAT, domain, NULL, result);
 1908: 			  
 1909: 			  if (status == STAT_BOGUS)
 1910: 			    {
 1911: 			      no_cache_dnssec = 1;
 1912: 			      bogusanswer = 1;
 1913: 			    }
 1914: 
 1915: 			  if (status == STAT_SECURE)
 1916: 			    cache_secure = 1;
 1917: 			}
 1918: #endif
 1919: 
 1920: 		      /* restore CD bit to the value in the query */
 1921: 		      if (checking_disabled)
 1922: 			header->hb4 |= HB4_CD;
 1923: 		      else
 1924: 			header->hb4 &= ~HB4_CD;
 1925: 		      
 1926: 		      /* There's no point in updating the cache, since this process will exit and
 1927: 			 lose the information after a few queries. We make this call for the alias and 
 1928: 			 bogus-nxdomain side-effects. */
 1929: 		      /* If the crc of the question section doesn't match the crc we sent, then
 1930: 			 someone might be attempting to insert bogus values into the cache by 
 1931: 			 sending replies containing questions and bogus answers. */
 1932: #ifdef HAVE_DNSSEC
 1933: 		      newhash = hash_questions(header, (unsigned int)m, daemon->namebuff);
 1934: 		      if (!newhash || memcmp(hash, newhash, HASH_SIZE) != 0)
 1935: 			{ 
 1936: 			  m = 0;
 1937: 			  break;
 1938: 			}
 1939: #else			  
 1940: 		      if (crc != questions_crc(header, (unsigned int)m, daemon->namebuff))
 1941: 			{
 1942: 			  m = 0;
 1943: 			  break;
 1944: 			}
 1945: #endif
 1946: 
 1947: 		      m = process_reply(header, now, last_server, (unsigned int)m, 
 1948: 					option_bool(OPT_NO_REBIND) && !norebind, no_cache_dnssec, cache_secure, bogusanswer,
 1949: 					ad_reqd, do_bit, added_pheader, check_subnet, &peer_addr); 
 1950: 		      
 1951: 		      break;
 1952: 		    }
 1953: 		}
 1954: 	
 1955: 	      /* In case of local answer or no connections made. */
 1956: 	      if (m == 0)
 1957: 		m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
 1958: 	    }
 1959: 	}
 1960: 	  
 1961:       check_log_writer(1);
 1962:       
 1963:       *length = htons(m);
 1964:            
 1965:       if (m == 0 || !read_write(confd, packet, m + sizeof(u16), 0))
 1966: 	return packet;
 1967:     }
 1968: }
 1969: 
 1970: static struct frec *allocate_frec(time_t now)
 1971: {
 1972:   struct frec *f;
 1973:   
 1974:   if ((f = (struct frec *)whine_malloc(sizeof(struct frec))))
 1975:     {
 1976:       f->next = daemon->frec_list;
 1977:       f->time = now;
 1978:       f->sentto = NULL;
 1979:       f->rfd4 = NULL;
 1980:       f->flags = 0;
 1981: #ifdef HAVE_IPV6
 1982:       f->rfd6 = NULL;
 1983: #endif
 1984: #ifdef HAVE_DNSSEC
 1985:       f->dependent = NULL;
 1986:       f->blocking_query = NULL;
 1987:       f->stash = NULL;
 1988: #endif
 1989:       daemon->frec_list = f;
 1990:     }
 1991: 
 1992:   return f;
 1993: }
 1994: 
 1995: struct randfd *allocate_rfd(int family)
 1996: {
 1997:   static int finger = 0;
 1998:   int i;
 1999: 
 2000:   /* limit the number of sockets we have open to avoid starvation of 
 2001:      (eg) TFTP. Once we have a reasonable number, randomness should be OK */
 2002: 
 2003:   for (i = 0; i < RANDOM_SOCKS; i++)
 2004:     if (daemon->randomsocks[i].refcount == 0)
 2005:       {
 2006: 	if ((daemon->randomsocks[i].fd = random_sock(family)) == -1)
 2007: 	  break;
 2008:       
 2009: 	daemon->randomsocks[i].refcount = 1;
 2010: 	daemon->randomsocks[i].family = family;
 2011: 	return &daemon->randomsocks[i];
 2012:       }
 2013: 
 2014:   /* No free ones or cannot get new socket, grab an existing one */
 2015:   for (i = 0; i < RANDOM_SOCKS; i++)
 2016:     {
 2017:       int j = (i+finger) % RANDOM_SOCKS;
 2018:       if (daemon->randomsocks[j].refcount != 0 &&
 2019: 	  daemon->randomsocks[j].family == family && 
 2020: 	  daemon->randomsocks[j].refcount != 0xffff)
 2021: 	{
 2022: 	  finger = j;
 2023: 	  daemon->randomsocks[j].refcount++;
 2024: 	  return &daemon->randomsocks[j];
 2025: 	}
 2026:     }
 2027: 
 2028:   return NULL; /* doom */
 2029: }
 2030: 
 2031: void free_rfd(struct randfd *rfd)
 2032: {
 2033:   if (rfd && --(rfd->refcount) == 0)
 2034:     close(rfd->fd);
 2035: }
 2036: 
 2037: static void free_frec(struct frec *f)
 2038: {
 2039:   free_rfd(f->rfd4);
 2040:   f->rfd4 = NULL;
 2041:   f->sentto = NULL;
 2042:   f->flags = 0;
 2043:   
 2044: #ifdef HAVE_IPV6
 2045:   free_rfd(f->rfd6);
 2046:   f->rfd6 = NULL;
 2047: #endif
 2048: 
 2049: #ifdef HAVE_DNSSEC
 2050:   if (f->stash)
 2051:     {
 2052:       blockdata_free(f->stash);
 2053:       f->stash = NULL;
 2054:     }
 2055: 
 2056:   /* Anything we're waiting on is pointless now, too */
 2057:   if (f->blocking_query)
 2058:     free_frec(f->blocking_query);
 2059:   f->blocking_query = NULL;
 2060:   f->dependent = NULL;
 2061: #endif
 2062: }
 2063: 
 2064: /* if wait==NULL return a free or older than TIMEOUT record.
 2065:    else return *wait zero if one available, or *wait is delay to
 2066:    when the oldest in-use record will expire. Impose an absolute
 2067:    limit of 4*TIMEOUT before we wipe things (for random sockets).
 2068:    If force is set, always return a result, even if we have
 2069:    to allocate above the limit. */
 2070: struct frec *get_new_frec(time_t now, int *wait, int force)
 2071: {
 2072:   struct frec *f, *oldest, *target;
 2073:   int count;
 2074:   
 2075:   if (wait)
 2076:     *wait = 0;
 2077: 
 2078:   for (f = daemon->frec_list, oldest = NULL, target =  NULL, count = 0; f; f = f->next, count++)
 2079:     if (!f->sentto)
 2080:       target = f;
 2081:     else 
 2082:       {
 2083: #ifdef HAVE_DNSSEC
 2084: 	    /* Don't free DNSSEC sub-queries here, as we may end up with
 2085: 	       dangling references to them. They'll go when their "real" query 
 2086: 	       is freed. */
 2087: 	    if (!f->dependent)
 2088: #endif
 2089: 	      {
 2090: 		if (difftime(now, f->time) >= 4*TIMEOUT)
 2091: 		  {
 2092: 		    free_frec(f);
 2093: 		    target = f;
 2094: 		  }
 2095: 	     
 2096: 	    
 2097: 		if (!oldest || difftime(f->time, oldest->time) <= 0)
 2098: 		  oldest = f;
 2099: 	      }
 2100:       }
 2101: 
 2102:   if (target)
 2103:     {
 2104:       target->time = now;
 2105:       return target;
 2106:     }
 2107:   
 2108:   /* can't find empty one, use oldest if there is one
 2109:      and it's older than timeout */
 2110:   if (oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
 2111:     { 
 2112:       /* keep stuff for twice timeout if we can by allocating a new
 2113: 	 record instead */
 2114:       if (difftime(now, oldest->time) < 2*TIMEOUT && 
 2115: 	  count <= daemon->ftabsize &&
 2116: 	  (f = allocate_frec(now)))
 2117: 	return f;
 2118: 
 2119:       if (!wait)
 2120: 	{
 2121: 	  free_frec(oldest);
 2122: 	  oldest->time = now;
 2123: 	}
 2124:       return oldest;
 2125:     }
 2126:   
 2127:   /* none available, calculate time 'till oldest record expires */
 2128:   if (!force && count > daemon->ftabsize)
 2129:     {
 2130:       static time_t last_log = 0;
 2131:       
 2132:       if (oldest && wait)
 2133: 	*wait = oldest->time + (time_t)TIMEOUT - now;
 2134:       
 2135:       if ((int)difftime(now, last_log) > 5)
 2136: 	{
 2137: 	  last_log = now;
 2138: 	  my_syslog(LOG_WARNING, _("Maximum number of concurrent DNS queries reached (max: %d)"), daemon->ftabsize);
 2139: 	}
 2140: 
 2141:       return NULL;
 2142:     }
 2143:   
 2144:   if (!(f = allocate_frec(now)) && wait)
 2145:     /* wait one second on malloc failure */
 2146:     *wait = 1;
 2147: 
 2148:   return f; /* OK if malloc fails and this is NULL */
 2149: }
 2150:  
 2151: /* crc is all-ones if not known. */
 2152: static struct frec *lookup_frec(unsigned short id, void *hash)
 2153: {
 2154:   struct frec *f;
 2155: 
 2156:   for(f = daemon->frec_list; f; f = f->next)
 2157:     if (f->sentto && f->new_id == id && 
 2158: 	(!hash || memcmp(hash, f->hash, HASH_SIZE) == 0))
 2159:       return f;
 2160:       
 2161:   return NULL;
 2162: }
 2163: 
 2164: static struct frec *lookup_frec_by_sender(unsigned short id,
 2165: 					  union mysockaddr *addr,
 2166: 					  void *hash)
 2167: {
 2168:   struct frec *f;
 2169:   
 2170:   for(f = daemon->frec_list; f; f = f->next)
 2171:     if (f->sentto &&
 2172: 	f->orig_id == id && 
 2173: 	memcmp(hash, f->hash, HASH_SIZE) == 0 &&
 2174: 	sockaddr_isequal(&f->source, addr))
 2175:       return f;
 2176:    
 2177:   return NULL;
 2178: }
 2179:  
 2180: /* Send query packet again, if we can. */
 2181: void resend_query()
 2182: {
 2183:   if (daemon->srv_save)
 2184:     {
 2185:       int fd;
 2186:       
 2187:       if (daemon->srv_save->sfd)
 2188: 	fd = daemon->srv_save->sfd->fd;
 2189:       else if (daemon->rfd_save && daemon->rfd_save->refcount != 0)
 2190: 	fd = daemon->rfd_save->fd;
 2191:       else
 2192: 	return;
 2193:       
 2194:       while(retry_send(sendto(fd, daemon->packet, daemon->packet_len, 0,
 2195: 			      &daemon->srv_save->addr.sa, 
 2196: 			      sa_len(&daemon->srv_save->addr)))); 
 2197:     }
 2198: }
 2199: 
 2200: /* A server record is going away, remove references to it */
 2201: void server_gone(struct server *server)
 2202: {
 2203:   struct frec *f;
 2204:   
 2205:   for (f = daemon->frec_list; f; f = f->next)
 2206:     if (f->sentto && f->sentto == server)
 2207:       free_frec(f);
 2208:   
 2209:   if (daemon->last_server == server)
 2210:     daemon->last_server = NULL;
 2211: 
 2212:   if (daemon->srv_save == server)
 2213:     daemon->srv_save = NULL;
 2214: }
 2215: 
 2216: /* return unique random ids. */
 2217: static unsigned short get_id(void)
 2218: {
 2219:   unsigned short ret = 0;
 2220:   
 2221:   do 
 2222:     ret = rand16();
 2223:   while (lookup_frec(ret, NULL));
 2224:   
 2225:   return ret;
 2226: }
 2227: 
 2228: 
 2229: 
 2230: 
 2231: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>