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