• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* dnsmasq is Copyright (c) 2000-2009 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, unsigned int crc);
20 static struct frec *lookup_frec_by_sender(unsigned short id,
21 					  union mysockaddr *addr,
22 					  unsigned int crc);
23 static unsigned short get_id(int force, unsigned short force_id, unsigned int crc);
24 static void free_frec(struct frec *f);
25 static struct randfd *allocate_rfd(int family);
26 
27 /* Send a UDP packet with its source address set as "source"
28    unless nowild is true, when we just send it with the kernel default */
send_from(int fd,int nowild,char * packet,size_t len,union mysockaddr * to,struct all_addr * source,unsigned int iface)29 static void send_from(int fd, int nowild, char *packet, size_t len,
30 		      union mysockaddr *to, struct all_addr *source,
31 		      unsigned int iface)
32 {
33   struct msghdr msg;
34   struct iovec iov[1];
35   union {
36     struct cmsghdr align; /* this ensures alignment */
37 #if defined(HAVE_LINUX_NETWORK)
38     char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
39 #elif defined(IP_SENDSRCADDR)
40     char control[CMSG_SPACE(sizeof(struct in_addr))];
41 #endif
42 #ifdef HAVE_IPV6
43     char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
44 #endif
45   } control_u;
46 
47   iov[0].iov_base = packet;
48   iov[0].iov_len = len;
49 
50   msg.msg_control = NULL;
51   msg.msg_controllen = 0;
52   msg.msg_flags = 0;
53   msg.msg_name = to;
54   msg.msg_namelen = sa_len(to);
55   msg.msg_iov = iov;
56   msg.msg_iovlen = 1;
57 
58   if (!nowild)
59     {
60       struct cmsghdr *cmptr;
61       msg.msg_control = &control_u;
62       msg.msg_controllen = sizeof(control_u);
63       cmptr = CMSG_FIRSTHDR(&msg);
64 
65       if (to->sa.sa_family == AF_INET)
66 	{
67 #if defined(HAVE_LINUX_NETWORK)
68 	  struct in_pktinfo *pkt = (struct in_pktinfo *)CMSG_DATA(cmptr);
69 	  pkt->ipi_ifindex = 0;
70 	  pkt->ipi_spec_dst = source->addr.addr4;
71 	  msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
72 	  cmptr->cmsg_level = SOL_IP;
73 	  cmptr->cmsg_type = IP_PKTINFO;
74 #elif defined(IP_SENDSRCADDR)
75 	  struct in_addr *a = (struct in_addr *)CMSG_DATA(cmptr);
76 	  *a = source->addr.addr4;
77 	  msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
78 	  cmptr->cmsg_level = IPPROTO_IP;
79 	  cmptr->cmsg_type = IP_SENDSRCADDR;
80 #endif
81 	}
82       else
83 #ifdef HAVE_IPV6
84 	{
85 	  struct in6_pktinfo *pkt = (struct in6_pktinfo *)CMSG_DATA(cmptr);
86 	  pkt->ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local addrs */
87 	  pkt->ipi6_addr = source->addr.addr6;
88 	  msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
89 	  cmptr->cmsg_type = IPV6_PKTINFO;
90 	  cmptr->cmsg_level = IPV6_LEVEL;
91 	}
92 #else
93       iface = 0; /* eliminate warning */
94 #endif
95     }
96 
97  retry:
98   if (sendmsg(fd, &msg, 0) == -1)
99     {
100       /* certain Linux kernels seem to object to setting the source address in the IPv6 stack
101 	 by returning EINVAL from sendmsg. In that case, try again without setting the
102 	 source address, since it will nearly alway be correct anyway.  IPv6 stinks. */
103       if (errno == EINVAL && msg.msg_controllen)
104 	{
105 	  msg.msg_controllen = 0;
106 	  goto retry;
107 	}
108       if (retry_send())
109 	goto retry;
110     }
111 }
112 
search_servers(time_t now,struct all_addr ** addrpp,unsigned short qtype,char * qdomain,int * type,char ** domain)113 static unsigned short search_servers(time_t now, struct all_addr **addrpp,
114 				     unsigned short qtype, char *qdomain, int *type, char **domain)
115 
116 {
117   /* If the query ends in the domain in one of our servers, set
118      domain to point to that name. We find the largest match to allow both
119      domain.org and sub.domain.org to exist. */
120 
121   unsigned int namelen = strlen(qdomain);
122   unsigned int matchlen = 0;
123   struct server *serv;
124   unsigned short flags = 0;
125 
126   for (serv = daemon->servers; serv; serv=serv->next)
127     /* domain matches take priority over NODOTS matches */
128     if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') && namelen != 0)
129       {
130 	unsigned short sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
131 	*type = SERV_FOR_NODOTS;
132 	if (serv->flags & SERV_NO_ADDR)
133 	  flags = F_NXDOMAIN;
134 	else if (serv->flags & SERV_LITERAL_ADDRESS)
135 	  {
136 	    if (sflag & qtype)
137 	      {
138 		flags = sflag;
139 		if (serv->addr.sa.sa_family == AF_INET)
140 		  *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
141 #ifdef HAVE_IPV6
142 		else
143 		  *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
144 #endif
145 	      }
146 	    else if (!flags || (flags & F_NXDOMAIN))
147 	      flags = F_NOERR;
148 	  }
149       }
150     else if (serv->flags & SERV_HAS_DOMAIN)
151       {
152 	unsigned int domainlen = strlen(serv->domain);
153 	char *matchstart = qdomain + namelen - domainlen;
154 	if (namelen >= domainlen &&
155 	    hostname_isequal(matchstart, serv->domain) &&
156 	    domainlen >= matchlen &&
157 	    (domainlen == 0 || namelen == domainlen || *(serv->domain) == '.' || *(matchstart-1) == '.' ))
158 	  {
159 	    unsigned short sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
160 	    *type = SERV_HAS_DOMAIN;
161 	    *domain = serv->domain;
162 	    matchlen = domainlen;
163 	    if (serv->flags & SERV_NO_ADDR)
164 	      flags = F_NXDOMAIN;
165 	    else if (serv->flags & SERV_LITERAL_ADDRESS)
166 	      {
167 		if (sflag & qtype)
168 		  {
169 		    flags = sflag;
170 		    if (serv->addr.sa.sa_family == AF_INET)
171 		      *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
172 #ifdef HAVE_IPV6
173 		    else
174 		      *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
175 #endif
176 		  }
177 		else if (!flags || (flags & F_NXDOMAIN))
178 		  flags = F_NOERR;
179 	      }
180 	  }
181       }
182 
183   if (flags == 0 && !(qtype & F_BIGNAME) &&
184       (daemon->options & OPT_NODOTS_LOCAL) && !strchr(qdomain, '.') && namelen != 0)
185     /* don't forward simple names, make exception for NS queries and empty name. */
186     flags = F_NXDOMAIN;
187 
188   if (flags == F_NXDOMAIN && check_for_local_domain(qdomain, now))
189     flags = F_NOERR;
190 
191   if (flags)
192     {
193       int logflags = 0;
194 
195       if (flags == F_NXDOMAIN || flags == F_NOERR)
196 	logflags = F_NEG | qtype;
197 
198       log_query(logflags | flags | F_CONFIG | F_FORWARD, qdomain, *addrpp, NULL);
199     }
200 
201   return  flags;
202 }
203 
forward_query(int udpfd,union mysockaddr * udpaddr,struct all_addr * dst_addr,unsigned int dst_iface,HEADER * header,size_t plen,time_t now,struct frec * forward)204 static int forward_query(int udpfd, union mysockaddr *udpaddr,
205 			 struct all_addr *dst_addr, unsigned int dst_iface,
206 			 HEADER *header, size_t plen, time_t now, struct frec *forward)
207 {
208   char *domain = NULL;
209   int type = 0;
210   struct all_addr *addrp = NULL;
211   unsigned int crc = questions_crc(header, plen, daemon->namebuff);
212   unsigned short flags = 0;
213   unsigned short gotname = extract_request(header, plen, daemon->namebuff, NULL);
214   struct server *start = NULL;
215 
216   /* may be no servers available. */
217   if (!daemon->servers)
218     forward = NULL;
219   else if (forward || (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, crc)))
220     {
221       /* retry on existing query, send to all available servers  */
222       domain = forward->sentto->domain;
223       forward->sentto->failed_queries++;
224       if (!(daemon->options & OPT_ORDER))
225 	{
226 	  forward->forwardall = 1;
227 	  daemon->last_server = NULL;
228 	}
229       type = forward->sentto->flags & SERV_TYPE;
230       if (!(start = forward->sentto->next))
231 	start = daemon->servers; /* at end of list, recycle */
232       header->id = htons(forward->new_id);
233     }
234   else
235     {
236       if (gotname)
237 	flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain);
238 
239       if (!flags && !(forward = get_new_frec(now, NULL)))
240 	/* table full - server failure. */
241 	flags = F_NEG;
242 
243       if (forward)
244 	{
245 	  /* force unchanging id for signed packets */
246 	  int is_sign;
247 	  find_pseudoheader(header, plen, NULL, NULL, &is_sign);
248 
249 	  forward->source = *udpaddr;
250 	  forward->dest = *dst_addr;
251 	  forward->iface = dst_iface;
252 	  forward->orig_id = ntohs(header->id);
253 	  forward->new_id = get_id(is_sign, forward->orig_id, crc);
254 	  forward->fd = udpfd;
255 	  forward->crc = crc;
256 	  forward->forwardall = 0;
257 	  header->id = htons(forward->new_id);
258 
259 	  /* In strict_order mode, or when using domain specific servers
260 	     always try servers in the order specified in resolv.conf,
261 	     otherwise, use the one last known to work. */
262 
263 	  if (type != 0  || (daemon->options & OPT_ORDER))
264 	    start = daemon->servers;
265 	  else if (!(start = daemon->last_server) ||
266 		   daemon->forwardcount++ > FORWARD_TEST ||
267 		   difftime(now, daemon->forwardtime) > FORWARD_TIME)
268 	    {
269 	      start = daemon->servers;
270 	      forward->forwardall = 1;
271 	      daemon->forwardcount = 0;
272 	      daemon->forwardtime = now;
273 	    }
274 	}
275     }
276 
277   /* check for send errors here (no route to host)
278      if we fail to send to all nameservers, send back an error
279      packet straight away (helps modem users when offline)  */
280 
281   if (!flags && forward)
282     {
283       struct server *firstsentto = start;
284       int forwarded = 0;
285 
286       while (1)
287 	{
288 	  /* only send to servers dealing with our domain.
289 	     domain may be NULL, in which case server->domain
290 	     must be NULL also. */
291 
292 	  if (type == (start->flags & SERV_TYPE) &&
293 	      (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
294 	      !(start->flags & SERV_LITERAL_ADDRESS))
295 	    {
296 	      int fd;
297 
298 	      /* find server socket to use, may need to get random one. */
299 	      if (start->sfd)
300 		fd = start->sfd->fd;
301 	      else
302 		{
303 #ifdef HAVE_IPV6
304 		  if (start->addr.sa.sa_family == AF_INET6)
305 		    {
306 		      if (!forward->rfd6 &&
307 			  !(forward->rfd6 = allocate_rfd(AF_INET6)))
308 			break;
309 		      daemon->rfd_save = forward->rfd6;
310 		      fd = forward->rfd6->fd;
311 		    }
312 		  else
313 #endif
314 		    {
315 		      if (!forward->rfd4 &&
316 			  !(forward->rfd4 = allocate_rfd(AF_INET)))
317 			break;
318 		      daemon->rfd_save = forward->rfd4;
319 		      fd = forward->rfd4->fd;
320 		    }
321 
322 #ifdef ANDROID
323 		  // Mark the socket so it goes out on the correct network. Note
324 		  // that we never clear the mark, only re-set it the next time we
325 		  // allocate a new random fd. This is because we buffer DNS
326 		  // queries (in daemon->srv_save, daemon->packet_len) and socket
327 		  // file descriptors (in daemon->rfd_save) with the expectation of
328 		  // being able to use them again.
329 		  //
330 		  // Server fds are marked separately in allocate_sfd.
331 		  setsockopt(fd, SOL_SOCKET, SO_MARK, &start->mark, sizeof(start->mark));
332 #endif
333 		}
334 
335 	      if (sendto(fd, (char *)header, plen, 0,
336 			 &start->addr.sa,
337 			 sa_len(&start->addr)) == -1)
338 		{
339 		  if (retry_send())
340 		    continue;
341 		}
342 	      else
343 		{
344 		  /* Keep info in case we want to re-send this packet */
345 		  daemon->srv_save = start;
346 		  daemon->packet_len = plen;
347 
348 		  if (!gotname)
349 		    strcpy(daemon->namebuff, "query");
350 		  if (start->addr.sa.sa_family == AF_INET)
351 		    log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
352 			      (struct all_addr *)&start->addr.in.sin_addr, NULL);
353 #ifdef HAVE_IPV6
354 		  else
355 		    log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
356 			      (struct all_addr *)&start->addr.in6.sin6_addr, NULL);
357 #endif
358 		  start->queries++;
359 		  forwarded = 1;
360 		  forward->sentto = start;
361 		  if (!forward->forwardall)
362 		    break;
363 		  forward->forwardall++;
364 		}
365 	    }
366 
367 	  if (!(start = start->next))
368  	    start = daemon->servers;
369 
370 	  if (start == firstsentto)
371 	    break;
372 	}
373 
374       if (forwarded)
375 	return 1;
376 
377       /* could not send on, prepare to return */
378       header->id = htons(forward->orig_id);
379       free_frec(forward); /* cancel */
380     }
381 
382   /* could not send on, return empty answer or address if known for whole domain */
383   if (udpfd != -1)
384     {
385       plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl);
386       send_from(udpfd, daemon->options & OPT_NOWILD, (char *)header, plen, udpaddr, dst_addr, dst_iface);
387     }
388 
389   return 0;
390 }
391 
process_reply(HEADER * header,time_t now,struct server * server,size_t n)392 static size_t process_reply(HEADER *header, time_t now,
393 			    struct server *server, size_t n)
394 {
395   unsigned char *pheader, *sizep;
396   int munged = 0, is_sign;
397   size_t plen;
398 
399   /* If upstream is advertising a larger UDP packet size
400      than we allow, trim it so that we don't get overlarge
401      requests for the client. We can't do this for signed packets. */
402 
403   if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign)) && !is_sign)
404     {
405       unsigned short udpsz;
406       unsigned char *psave = sizep;
407 
408       GETSHORT(udpsz, sizep);
409       if (udpsz > daemon->edns_pktsz)
410 	PUTSHORT(daemon->edns_pktsz, psave);
411     }
412 
413   if (header->opcode != QUERY || (header->rcode != NOERROR && header->rcode != NXDOMAIN))
414     return n;
415 
416   /* Complain loudly if the upstream server is non-recursive. */
417   if (!header->ra && header->rcode == NOERROR && ntohs(header->ancount) == 0 &&
418       server && !(server->flags & SERV_WARNED_RECURSIVE))
419     {
420       prettyprint_addr(&server->addr, daemon->namebuff);
421       my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
422       if (!(daemon->options & OPT_LOG))
423 	server->flags |= SERV_WARNED_RECURSIVE;
424     }
425 
426   if (daemon->bogus_addr && header->rcode != NXDOMAIN &&
427       check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now))
428     {
429       munged = 1;
430       header->rcode = NXDOMAIN;
431       header->aa = 0;
432     }
433   else
434     {
435       if (header->rcode == NXDOMAIN &&
436 	  extract_request(header, n, daemon->namebuff, NULL) &&
437 	  check_for_local_domain(daemon->namebuff, now))
438 	{
439 	  /* if we forwarded a query for a locally known name (because it was for
440 	     an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
441 	     since we know that the domain exists, even if upstream doesn't */
442 	  munged = 1;
443 	  header->aa = 1;
444 	  header->rcode = NOERROR;
445 	}
446 
447       if (extract_addresses(header, n, daemon->namebuff, now))
448 	{
449 	  my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected"));
450 	  munged = 1;
451 	}
452     }
453 
454   /* do this after extract_addresses. Ensure NODATA reply and remove
455      nameserver info. */
456 
457   if (munged)
458     {
459       header->ancount = htons(0);
460       header->nscount = htons(0);
461       header->arcount = htons(0);
462     }
463 
464   /* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
465      sections of the packet. Find the new length here and put back pseudoheader
466      if it was removed. */
467   return resize_packet(header, n, pheader, plen);
468 }
469 
470 /* sets new last_server */
reply_query(int fd,int family,time_t now)471 void reply_query(int fd, int family, time_t now)
472 {
473   /* packet from peer server, extract data for cache, and send to
474      original requester */
475   HEADER *header;
476   union mysockaddr serveraddr;
477   struct frec *forward;
478   socklen_t addrlen = sizeof(serveraddr);
479   ssize_t n = recvfrom(fd, daemon->packet, daemon->edns_pktsz, 0, &serveraddr.sa, &addrlen);
480   size_t nn;
481   struct server *server;
482 
483   /* packet buffer overwritten */
484   daemon->srv_save = NULL;
485 
486   /* Determine the address of the server replying  so that we can mark that as good */
487   serveraddr.sa.sa_family = family;
488 #ifdef HAVE_IPV6
489   if (serveraddr.sa.sa_family == AF_INET6)
490     serveraddr.in6.sin6_flowinfo = 0;
491 #endif
492 
493   /* spoof check: answer must come from known server, */
494   for (server = daemon->servers; server; server = server->next)
495     if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
496 	sockaddr_isequal(&server->addr, &serveraddr))
497       break;
498 
499   header = (HEADER *)daemon->packet;
500 
501   if (!server ||
502       n < (int)sizeof(HEADER) || !header->qr ||
503       !(forward = lookup_frec(ntohs(header->id), questions_crc(header, n, daemon->namebuff))))
504     return;
505 
506   server = forward->sentto;
507 
508   if ((header->rcode == SERVFAIL || header->rcode == REFUSED) &&
509       !(daemon->options & OPT_ORDER) &&
510       forward->forwardall == 0)
511     /* for broken servers, attempt to send to another one. */
512     {
513       unsigned char *pheader;
514       size_t plen;
515       int is_sign;
516 
517       /* recreate query from reply */
518       pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign);
519       if (!is_sign)
520 	{
521 	  header->ancount = htons(0);
522 	  header->nscount = htons(0);
523 	  header->arcount = htons(0);
524 	  if ((nn = resize_packet(header, (size_t)n, pheader, plen)))
525 	    {
526 	      header->qr = 0;
527 	      header->tc = 0;
528 	      forward_query(-1, NULL, NULL, 0, header, nn, now, forward);
529 	      return;
530 	    }
531 	}
532     }
533 
534   if ((forward->sentto->flags & SERV_TYPE) == 0)
535     {
536       if (header->rcode == SERVFAIL || header->rcode == REFUSED)
537 	server = NULL;
538       else
539 	{
540 	  struct server *last_server;
541 
542 	  /* find good server by address if possible, otherwise assume the last one we sent to */
543 	  for (last_server = daemon->servers; last_server; last_server = last_server->next)
544 	    if (!(last_server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR)) &&
545 		sockaddr_isequal(&last_server->addr, &serveraddr))
546 	      {
547 		server = last_server;
548 		break;
549 	      }
550 	}
551       if (!(daemon->options & OPT_ALL_SERVERS))
552 	daemon->last_server = server;
553     }
554 
555   /* If the answer is an error, keep the forward record in place in case
556      we get a good reply from another server. Kill it when we've
557      had replies from all to avoid filling the forwarding table when
558      everything is broken */
559   if (forward->forwardall == 0 || --forward->forwardall == 1 ||
560       (header->rcode != REFUSED && header->rcode != SERVFAIL))
561     {
562       if ((nn = process_reply(header, now, server, (size_t)n)))
563 	{
564 	  header->id = htons(forward->orig_id);
565 	  header->ra = 1; /* recursion if available */
566 	  send_from(forward->fd, daemon->options & OPT_NOWILD, daemon->packet, nn,
567 		    &forward->source, &forward->dest, forward->iface);
568 	}
569       free_frec(forward); /* cancel */
570     }
571 }
572 
573 
receive_query(struct listener * listen,time_t now)574 void receive_query(struct listener *listen, time_t now)
575 {
576   HEADER *header = (HEADER *)daemon->packet;
577   union mysockaddr source_addr;
578   unsigned short type;
579   struct all_addr dst_addr;
580   struct in_addr netmask, dst_addr_4;
581   size_t m;
582   ssize_t n;
583   int if_index = 0;
584   struct iovec iov[1];
585   struct msghdr msg;
586   struct cmsghdr *cmptr;
587   union {
588     struct cmsghdr align; /* this ensures alignment */
589 #ifdef HAVE_IPV6
590     char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
591 #endif
592 #if defined(HAVE_LINUX_NETWORK)
593     char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
594 #elif defined(IP_RECVDSTADDR)
595     char control[CMSG_SPACE(sizeof(struct in_addr)) +
596 		 CMSG_SPACE(sizeof(struct sockaddr_dl))];
597 #endif
598   } control_u;
599 
600   /* packet buffer overwritten */
601   daemon->srv_save = NULL;
602 
603   if (listen->family == AF_INET && (daemon->options & OPT_NOWILD))
604     {
605       dst_addr_4 = listen->iface->addr.in.sin_addr;
606       netmask = listen->iface->netmask;
607     }
608   else
609     {
610       dst_addr_4.s_addr = 0;
611       netmask.s_addr = 0;
612     }
613 
614   iov[0].iov_base = daemon->packet;
615   iov[0].iov_len = daemon->edns_pktsz;
616 
617   msg.msg_control = control_u.control;
618   msg.msg_controllen = sizeof(control_u);
619   msg.msg_flags = 0;
620   msg.msg_name = &source_addr;
621   msg.msg_namelen = sizeof(source_addr);
622   msg.msg_iov = iov;
623   msg.msg_iovlen = 1;
624 
625   if ((n = recvmsg(listen->fd, &msg, 0)) == -1)
626     return;
627 
628   if (n < (int)sizeof(HEADER) ||
629       (msg.msg_flags & MSG_TRUNC) ||
630       header->qr)
631     return;
632 
633   source_addr.sa.sa_family = listen->family;
634 #ifdef HAVE_IPV6
635   if (listen->family == AF_INET6)
636     source_addr.in6.sin6_flowinfo = 0;
637 #endif
638 
639   if (!(daemon->options & OPT_NOWILD))
640     {
641       struct ifreq ifr;
642 
643       if (msg.msg_controllen < sizeof(struct cmsghdr))
644 	return;
645 
646 #if defined(HAVE_LINUX_NETWORK)
647       if (listen->family == AF_INET)
648 	for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
649 	  if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO)
650 	    {
651 	      dst_addr_4 = dst_addr.addr.addr4 = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_spec_dst;
652 	      if_index = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_ifindex;
653 	    }
654 #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
655       if (listen->family == AF_INET)
656 	{
657 	  for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
658 	    if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
659 	      dst_addr_4 = dst_addr.addr.addr4 = *((struct in_addr *)CMSG_DATA(cmptr));
660 	    else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
661 	      if_index = ((struct sockaddr_dl *)CMSG_DATA(cmptr))->sdl_index;
662 	}
663 #endif
664 
665 #ifdef HAVE_IPV6
666       if (listen->family == AF_INET6)
667 	{
668 	  for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
669 	    if (cmptr->cmsg_level == IPV6_LEVEL && cmptr->cmsg_type == IPV6_PKTINFO)
670 	      {
671 		dst_addr.addr.addr6 = ((struct in6_pktinfo *)CMSG_DATA(cmptr))->ipi6_addr;
672 		if_index =((struct in6_pktinfo *)CMSG_DATA(cmptr))->ipi6_ifindex;
673 	      }
674 	}
675 #endif
676 
677       /* enforce available interface configuration */
678 
679       if (!indextoname(listen->fd, if_index, ifr.ifr_name) ||
680 	  !iface_check(listen->family, &dst_addr, ifr.ifr_name, &if_index))
681 	return;
682 
683       if (listen->family == AF_INET &&
684 	  (daemon->options & OPT_LOCALISE) &&
685 	  ioctl(listen->fd, SIOCGIFNETMASK, &ifr) == -1)
686 	return;
687 
688       netmask = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
689     }
690 
691   if (extract_request(header, (size_t)n, daemon->namebuff, &type))
692     {
693       char types[20];
694 
695       querystr(types, type);
696 
697       if (listen->family == AF_INET)
698 	log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
699 		  (struct all_addr *)&source_addr.in.sin_addr, types);
700 #ifdef HAVE_IPV6
701       else
702 	log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
703 		  (struct all_addr *)&source_addr.in6.sin6_addr, types);
704 #endif
705     }
706 
707   m = answer_request (header, ((char *) header) + PACKETSZ, (size_t)n,
708 		      dst_addr_4, netmask, now);
709   if (m >= 1)
710     {
711       send_from(listen->fd, daemon->options & OPT_NOWILD, (char *)header,
712 		m, &source_addr, &dst_addr, if_index);
713       daemon->local_answer++;
714     }
715   else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
716 			 header, (size_t)n, now, NULL))
717     daemon->queries_forwarded++;
718   else
719     daemon->local_answer++;
720 }
721 
722 /* The daemon forks before calling this: it should deal with one connection,
723    blocking as neccessary, and then return. Note, need to be a bit careful
724    about resources for debug mode, when the fork is suppressed: that's
725    done by the caller. */
tcp_request(int confd,time_t now,struct in_addr local_addr,struct in_addr netmask)726 unsigned char *tcp_request(int confd, time_t now,
727 			   struct in_addr local_addr, struct in_addr netmask)
728 {
729   int size = 0;
730   size_t m;
731   unsigned short qtype, gotname;
732   unsigned char c1, c2;
733   /* Max TCP packet + slop */
734   unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ);
735   HEADER *header;
736   struct server *last_server;
737 
738   while (1)
739     {
740       if (!packet ||
741 	  !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) ||
742 	  !(size = c1 << 8 | c2) ||
743 	  !read_write(confd, packet, size, 1))
744        	return packet;
745 
746       if (size < (int)sizeof(HEADER))
747 	continue;
748 
749       header = (HEADER *)packet;
750 
751       if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
752 	{
753 	  union mysockaddr peer_addr;
754 	  socklen_t peer_len = sizeof(union mysockaddr);
755 
756 	  if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) != -1)
757 	    {
758 	      char types[20];
759 
760 	      querystr(types, qtype);
761 
762 	      if (peer_addr.sa.sa_family == AF_INET)
763 		log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
764 			  (struct all_addr *)&peer_addr.in.sin_addr, types);
765 #ifdef HAVE_IPV6
766 	      else
767 		log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
768 			  (struct all_addr *)&peer_addr.in6.sin6_addr, types);
769 #endif
770 	    }
771 	}
772 
773       /* m > 0 if answered from cache */
774       m = answer_request(header, ((char *) header) + 65536, (unsigned int)size,
775 			 local_addr, netmask, now);
776 
777       /* Do this by steam now we're not in the select() loop */
778       check_log_writer(NULL);
779 
780       if (m == 0)
781 	{
782 	  unsigned short flags = 0;
783 	  struct all_addr *addrp = NULL;
784 	  int type = 0;
785 	  char *domain = NULL;
786 
787 	  if (gotname)
788 	    flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain);
789 
790 	  if (type != 0  || (daemon->options & OPT_ORDER) || !daemon->last_server)
791 	    last_server = daemon->servers;
792 	  else
793 	    last_server = daemon->last_server;
794 
795 	  if (!flags && last_server)
796 	    {
797 	      struct server *firstsendto = NULL;
798 	      unsigned int crc = questions_crc(header, (unsigned int)size, daemon->namebuff);
799 
800 	      /* Loop round available servers until we succeed in connecting to one.
801 	         Note that this code subtley ensures that consecutive queries on this connection
802 	         which can go to the same server, do so. */
803 	      while (1)
804 		{
805 		  if (!firstsendto)
806 		    firstsendto = last_server;
807 		  else
808 		    {
809 		      if (!(last_server = last_server->next))
810 			last_server = daemon->servers;
811 
812 		      if (last_server == firstsendto)
813 			break;
814 		    }
815 
816 		  /* server for wrong domain */
817 		  if (type != (last_server->flags & SERV_TYPE) ||
818 		      (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, last_server->domain)))
819 		    continue;
820 
821 		  if ((last_server->tcpfd == -1) &&
822 		      (last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) != -1 &&
823 		      (!local_bind(last_server->tcpfd, &last_server->source_addr,
824 				   last_server->interface, last_server->mark, 1) ||
825 		       connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1))
826 		    {
827 		      close(last_server->tcpfd);
828 		      last_server->tcpfd = -1;
829 		    }
830 
831 		  if (last_server->tcpfd == -1)
832 		    continue;
833 
834 		  c1 = size >> 8;
835 		  c2 = size;
836 
837 		  if (!read_write(last_server->tcpfd, &c1, 1, 0) ||
838 		      !read_write(last_server->tcpfd, &c2, 1, 0) ||
839 		      !read_write(last_server->tcpfd, packet, size, 0) ||
840 		      !read_write(last_server->tcpfd, &c1, 1, 1) ||
841 		      !read_write(last_server->tcpfd, &c2, 1, 1))
842 		    {
843 		      close(last_server->tcpfd);
844 		      last_server->tcpfd = -1;
845 		      continue;
846 		    }
847 
848 		  m = (c1 << 8) | c2;
849 		  if (!read_write(last_server->tcpfd, packet, m, 1))
850 		    return packet;
851 
852 		  if (!gotname)
853 		    strcpy(daemon->namebuff, "query");
854 		  if (last_server->addr.sa.sa_family == AF_INET)
855 		    log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
856 			      (struct all_addr *)&last_server->addr.in.sin_addr, NULL);
857 #ifdef HAVE_IPV6
858 		  else
859 		    log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
860 			      (struct all_addr *)&last_server->addr.in6.sin6_addr, NULL);
861 #endif
862 
863 		  /* There's no point in updating the cache, since this process will exit and
864 		     lose the information after a few queries. We make this call for the alias and
865 		     bogus-nxdomain side-effects. */
866 		  /* If the crc of the question section doesn't match the crc we sent, then
867 		     someone might be attempting to insert bogus values into the cache by
868 		     sending replies containing questions and bogus answers. */
869 		  if (crc == questions_crc(header, (unsigned int)m, daemon->namebuff))
870 		    m = process_reply(header, now, last_server, (unsigned int)m);
871 
872 		  break;
873 		}
874 	    }
875 
876 	  /* In case of local answer or no connections made. */
877 	  if (m == 0)
878 	    m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
879 	}
880 
881       check_log_writer(NULL);
882 
883       c1 = m>>8;
884       c2 = m;
885       if (!read_write(confd, &c1, 1, 0) ||
886 	  !read_write(confd, &c2, 1, 0) ||
887 	  !read_write(confd, packet, m, 0))
888 	return packet;
889     }
890 }
891 
allocate_frec(time_t now)892 static struct frec *allocate_frec(time_t now)
893 {
894   struct frec *f;
895 
896   if ((f = (struct frec *)whine_malloc(sizeof(struct frec))))
897     {
898       f->next = daemon->frec_list;
899       f->time = now;
900       f->sentto = NULL;
901       f->rfd4 = NULL;
902 #ifdef HAVE_IPV6
903       f->rfd6 = NULL;
904 #endif
905       daemon->frec_list = f;
906     }
907 
908   return f;
909 }
910 
allocate_rfd(int family)911 static struct randfd *allocate_rfd(int family)
912 {
913   static int finger = 0;
914   int i;
915 
916   /* limit the number of sockets we have open to avoid starvation of
917      (eg) TFTP. Once we have a reasonable number, randomness should be OK */
918 
919   for (i = 0; i < RANDOM_SOCKS; i++)
920     if (daemon->randomsocks[i].refcount == 0)
921       {
922 	if ((daemon->randomsocks[i].fd = random_sock(family)) == -1)
923 	  break;
924 
925 	daemon->randomsocks[i].refcount = 1;
926 	daemon->randomsocks[i].family = family;
927 	return &daemon->randomsocks[i];
928       }
929 
930   /* No free ones or cannot get new socket, grab an existing one */
931   for (i = 0; i < RANDOM_SOCKS; i++)
932     {
933       int j = (i+finger) % RANDOM_SOCKS;
934       if (daemon->randomsocks[j].refcount != 0 &&
935 	  daemon->randomsocks[j].family == family &&
936 	  daemon->randomsocks[j].refcount != 0xffff)
937 	{
938 	  finger = j;
939 	  daemon->randomsocks[j].refcount++;
940 	  return &daemon->randomsocks[j];
941 	}
942     }
943 
944   return NULL; /* doom */
945 }
946 
free_frec(struct frec * f)947 static void free_frec(struct frec *f)
948 {
949   if (f->rfd4 && --(f->rfd4->refcount) == 0)
950     close(f->rfd4->fd);
951 
952   f->rfd4 = NULL;
953   f->sentto = NULL;
954 
955 #ifdef HAVE_IPV6
956   if (f->rfd6 && --(f->rfd6->refcount) == 0)
957     close(f->rfd6->fd);
958 
959   f->rfd6 = NULL;
960 #endif
961 }
962 
963 /* if wait==NULL return a free or older than TIMEOUT record.
964    else return *wait zero if one available, or *wait is delay to
965    when the oldest in-use record will expire. Impose an absolute
966    limit of 4*TIMEOUT before we wipe things (for random sockets) */
get_new_frec(time_t now,int * wait)967 struct frec *get_new_frec(time_t now, int *wait)
968 {
969   struct frec *f, *oldest, *target;
970   int count;
971 
972   if (wait)
973     *wait = 0;
974 
975   for (f = daemon->frec_list, oldest = NULL, target =  NULL, count = 0; f; f = f->next, count++)
976     if (!f->sentto)
977       target = f;
978     else
979       {
980 	if (difftime(now, f->time) >= 4*TIMEOUT)
981 	  {
982 	    free_frec(f);
983 	    target = f;
984 	  }
985 
986 	if (!oldest || difftime(f->time, oldest->time) <= 0)
987 	  oldest = f;
988       }
989 
990   if (target)
991     {
992       target->time = now;
993       return target;
994     }
995 
996   /* can't find empty one, use oldest if there is one
997      and it's older than timeout */
998   if (oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
999     {
1000       /* keep stuff for twice timeout if we can by allocating a new
1001 	 record instead */
1002       if (difftime(now, oldest->time) < 2*TIMEOUT &&
1003 	  count <= daemon->ftabsize &&
1004 	  (f = allocate_frec(now)))
1005 	return f;
1006 
1007       if (!wait)
1008 	{
1009 	  free_frec(oldest);
1010 	  oldest->time = now;
1011 	}
1012       return oldest;
1013     }
1014 
1015   /* none available, calculate time 'till oldest record expires */
1016   if (count > daemon->ftabsize)
1017     {
1018       if (oldest && wait)
1019 	*wait = oldest->time + (time_t)TIMEOUT - now;
1020       return NULL;
1021     }
1022 
1023   if (!(f = allocate_frec(now)) && wait)
1024     /* wait one second on malloc failure */
1025     *wait = 1;
1026 
1027   return f; /* OK if malloc fails and this is NULL */
1028 }
1029 
1030 /* crc is all-ones if not known. */
lookup_frec(unsigned short id,unsigned int crc)1031 static struct frec *lookup_frec(unsigned short id, unsigned int crc)
1032 {
1033   struct frec *f;
1034 
1035   for(f = daemon->frec_list; f; f = f->next)
1036     if (f->sentto && f->new_id == id &&
1037 	(f->crc == crc || crc == 0xffffffff))
1038       return f;
1039 
1040   return NULL;
1041 }
1042 
lookup_frec_by_sender(unsigned short id,union mysockaddr * addr,unsigned int crc)1043 static struct frec *lookup_frec_by_sender(unsigned short id,
1044 					  union mysockaddr *addr,
1045 					  unsigned int crc)
1046 {
1047   struct frec *f;
1048 
1049   for(f = daemon->frec_list; f; f = f->next)
1050     if (f->sentto &&
1051 	f->orig_id == id &&
1052 	f->crc == crc &&
1053 	sockaddr_isequal(&f->source, addr))
1054       return f;
1055 
1056   return NULL;
1057 }
1058 
1059 /* A server record is going away, remove references to it */
server_gone(struct server * server)1060 void server_gone(struct server *server)
1061 {
1062   struct frec *f;
1063 
1064   for (f = daemon->frec_list; f; f = f->next)
1065     if (f->sentto && f->sentto == server)
1066       free_frec(f);
1067 
1068   if (daemon->last_server == server)
1069     daemon->last_server = NULL;
1070 
1071   if (daemon->srv_save == server)
1072     daemon->srv_save = NULL;
1073 }
1074 
1075 /* return unique random ids.
1076    For signed packets we can't change the ID without breaking the
1077    signing, so we keep the same one. In this case force is set, and this
1078    routine degenerates into killing any conflicting forward record. */
get_id(int force,unsigned short force_id,unsigned int crc)1079 static unsigned short get_id(int force, unsigned short force_id, unsigned int crc)
1080 {
1081   unsigned short ret = 0;
1082 
1083   if (force)
1084     {
1085       struct frec *f = lookup_frec(force_id, crc);
1086       if (f)
1087 	free_frec(f); /* free */
1088       ret = force_id;
1089     }
1090   else do
1091     ret = rand16();
1092   while (lookup_frec(ret, crc));
1093 
1094   return ret;
1095 }
1096 
1097 
1098 
1099 
1100 
1101