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