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