blob: 8add61018a2cb0c3ff7f6be2766905e3a1e67bb6 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* dnsmasq is Copyright (c) 2000-2021 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
19static struct crec *cache_head = NULL, *cache_tail = NULL, **hash_table = NULL;
20#ifdef HAVE_DHCP
21static struct crec *dhcp_spare = NULL;
22#endif
23static struct crec *new_chain = NULL;
24static int insert_error;
25static union bigname *big_free = NULL;
26static int bignames_left, hash_size;
27
28static void make_non_terminals(struct crec *source);
29static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class,
30 time_t now, unsigned long ttl, unsigned int flags);
31
32/* type->string mapping: this is also used by the name-hash function as a mixing table. */
33static const struct {
34 unsigned int type;
35 const char * const name;
36} typestr[] = {
37 { 1, "A" },
38 { 2, "NS" },
39 { 5, "CNAME" },
40 { 6, "SOA" },
41 { 10, "NULL" },
42 { 11, "WKS" },
43 { 12, "PTR" },
44 { 13, "HINFO" },
45 { 15, "MX" },
46 { 16, "TXT" },
47 { 22, "NSAP" },
48 { 23, "NSAP_PTR" },
49 { 24, "SIG" },
50 { 25, "KEY" },
51 { 28, "AAAA" },
52 { 29, "LOC" },
53 { 33, "SRV" },
54 { 35, "NAPTR" },
55 { 36, "KX" },
56 { 37, "CERT" },
57 { 38, "A6" },
58 { 39, "DNAME" },
59 { 41, "OPT" },
60 { 43, "DS" },
61 { 46, "RRSIG" },
62 { 47, "NSEC" },
63 { 48, "DNSKEY" },
64 { 50, "NSEC3" },
65 { 51, "NSEC3PARAM" },
66 { 52, "TLSA" },
67 { 53, "SMIMEA" },
68 { 55, "HIP" },
69 { 249, "TKEY" },
70 { 250, "TSIG" },
71 { 251, "IXFR" },
72 { 252, "AXFR" },
73 { 253, "MAILB" },
74 { 254, "MAILA" },
75 { 255, "ANY" },
76 { 257, "CAA" }
77};
78
79static void cache_free(struct crec *crecp);
80static void cache_unlink(struct crec *crecp);
81static void cache_link(struct crec *crecp);
82static void rehash(int size);
83static void cache_hash(struct crec *crecp);
84
85void next_uid(struct crec *crecp)
86{
87 static unsigned int uid = 0;
88
89 if (crecp->uid == UID_NONE)
90 {
91 uid++;
92
93 /* uid == 0 used to indicate CNAME to interface name. */
94 if (uid == UID_NONE)
95 uid++;
96
97 crecp->uid = uid;
98 }
99}
100
101void cache_init(void)
102{
103 struct crec *crecp;
104 int i;
105
106 bignames_left = daemon->cachesize/10;
107
108 if (daemon->cachesize > 0)
109 {
110 crecp = safe_malloc(daemon->cachesize*sizeof(struct crec));
111
112 for (i=0; i < daemon->cachesize; i++, crecp++)
113 {
114 cache_link(crecp);
115 crecp->flags = 0;
116 crecp->uid = UID_NONE;
117 }
118 }
119
120 /* create initial hash table*/
121 rehash(daemon->cachesize);
122}
123
124/* In most cases, we create the hash table once here by calling this with (hash_table == NULL)
125 but if the hosts file(s) are big (some people have 50000 ad-block entries), the table
126 will be much too small, so the hosts reading code calls rehash every 1000 addresses, to
127 expand the table. */
128static void rehash(int size)
129{
130 struct crec **new, **old, *p, *tmp;
131 int i, new_size, old_size;
132
133 /* hash_size is a power of two. */
134 for (new_size = 64; new_size < size/10; new_size = new_size << 1);
135
136 /* must succeed in getting first instance, failure later is non-fatal */
137 if (!hash_table)
138 new = safe_malloc(new_size * sizeof(struct crec *));
139 else if (new_size <= hash_size || !(new = whine_malloc(new_size * sizeof(struct crec *))))
140 return;
141
142 for(i = 0; i < new_size; i++)
143 new[i] = NULL;
144
145 old = hash_table;
146 old_size = hash_size;
147 hash_table = new;
148 hash_size = new_size;
149
150 if (old)
151 {
152 for (i = 0; i < old_size; i++)
153 for (p = old[i]; p ; p = tmp)
154 {
155 tmp = p->hash_next;
156 cache_hash(p);
157 }
158 free(old);
159 }
160}
161
162static struct crec **hash_bucket(char *name)
163{
164 unsigned int c, val = 017465; /* Barker code - minimum self-correlation in cyclic shift */
165 const unsigned char *mix_tab = (const unsigned char*)typestr;
166
167 while((c = (unsigned char) *name++))
168 {
169 /* don't use tolower and friends here - they may be messed up by LOCALE */
170 if (c >= 'A' && c <= 'Z')
171 c += 'a' - 'A';
172 val = ((val << 7) | (val >> (32 - 7))) + (mix_tab[(val + c) & 0x3F] ^ c);
173 }
174
175 /* hash_size is a power of two */
176 return hash_table + ((val ^ (val >> 16)) & (hash_size - 1));
177}
178
179static void cache_hash(struct crec *crecp)
180{
181 /* maintain an invariant that all entries with F_REVERSE set
182 are at the start of the hash-chain and all non-reverse
183 immortal entries are at the end of the hash-chain.
184 This allows reverse searches and garbage collection to be optimised */
185
186 struct crec **up = hash_bucket(cache_get_name(crecp));
187
188 if (!(crecp->flags & F_REVERSE))
189 {
190 while (*up && ((*up)->flags & F_REVERSE))
191 up = &((*up)->hash_next);
192
193 if (crecp->flags & F_IMMORTAL)
194 while (*up && !((*up)->flags & F_IMMORTAL))
195 up = &((*up)->hash_next);
196 }
197 crecp->hash_next = *up;
198 *up = crecp;
199}
200
201static void cache_blockdata_free(struct crec *crecp)
202{
203 if (!(crecp->flags & F_NEG))
204 {
205 if (crecp->flags & F_SRV)
206 blockdata_free(crecp->addr.srv.target);
207#ifdef HAVE_DNSSEC
208 else if (crecp->flags & F_DNSKEY)
209 blockdata_free(crecp->addr.key.keydata);
210 else if (crecp->flags & F_DS)
211 blockdata_free(crecp->addr.ds.keydata);
212#endif
213 }
214}
215
216static void cache_free(struct crec *crecp)
217{
218 crecp->flags &= ~F_FORWARD;
219 crecp->flags &= ~F_REVERSE;
220 crecp->uid = UID_NONE; /* invalidate CNAMES pointing to this. */
221
222 if (cache_tail)
223 cache_tail->next = crecp;
224 else
225 cache_head = crecp;
226 crecp->prev = cache_tail;
227 crecp->next = NULL;
228 cache_tail = crecp;
229
230 /* retrieve big name for further use. */
231 if (crecp->flags & F_BIGNAME)
232 {
233 crecp->name.bname->next = big_free;
234 big_free = crecp->name.bname;
235 crecp->flags &= ~F_BIGNAME;
236 }
237
238 cache_blockdata_free(crecp);
239}
240
241/* insert a new cache entry at the head of the list (youngest entry) */
242static void cache_link(struct crec *crecp)
243{
244 if (cache_head) /* check needed for init code */
245 cache_head->prev = crecp;
246 crecp->next = cache_head;
247 crecp->prev = NULL;
248 cache_head = crecp;
249 if (!cache_tail)
250 cache_tail = crecp;
251}
252
253/* remove an arbitrary cache entry for promotion */
254static void cache_unlink (struct crec *crecp)
255{
256 if (crecp->prev)
257 crecp->prev->next = crecp->next;
258 else
259 cache_head = crecp->next;
260
261 if (crecp->next)
262 crecp->next->prev = crecp->prev;
263 else
264 cache_tail = crecp->prev;
265}
266
267char *cache_get_name(struct crec *crecp)
268{
269 if (crecp->flags & F_BIGNAME)
270 return crecp->name.bname->name;
271 else if (crecp->flags & F_NAMEP)
272 return crecp->name.namep;
273
274 return crecp->name.sname;
275}
276
277char *cache_get_cname_target(struct crec *crecp)
278{
279 if (crecp->addr.cname.is_name_ptr)
280 return crecp->addr.cname.target.name;
281 else
282 return cache_get_name(crecp->addr.cname.target.cache);
283}
284
285
286
287struct crec *cache_enumerate(int init)
288{
289 static int bucket;
290 static struct crec *cache;
291
292 if (init)
293 {
294 bucket = 0;
295 cache = NULL;
296 }
297 else if (cache && cache->hash_next)
298 cache = cache->hash_next;
299 else
300 {
301 cache = NULL;
302 while (bucket < hash_size)
303 if ((cache = hash_table[bucket++]))
304 break;
305 }
306
307 return cache;
308}
309
310static int is_outdated_cname_pointer(struct crec *crecp)
311{
312 if (!(crecp->flags & F_CNAME) || crecp->addr.cname.is_name_ptr)
313 return 0;
314
315 /* NB. record may be reused as DS or DNSKEY, where uid is
316 overloaded for something completely different */
317 if (crecp->addr.cname.target.cache &&
318 !(crecp->addr.cname.target.cache->flags & (F_DNSKEY | F_DS)) &&
319 crecp->addr.cname.uid == crecp->addr.cname.target.cache->uid)
320 return 0;
321
322 return 1;
323}
324
325static int is_expired(time_t now, struct crec *crecp)
326{
327 if (crecp->flags & F_IMMORTAL)
328 return 0;
329
330 if (difftime(now, crecp->ttd) < 0)
331 return 0;
332
333 return 1;
334}
335
336static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned short class, time_t now,
337 unsigned int flags, struct crec **target_crec, unsigned int *target_uid)
338{
339 /* Scan and remove old entries.
340 If (flags & F_FORWARD) then remove any forward entries for name and any expired
341 entries but only in the same hash bucket as name.
342 If (flags & F_REVERSE) then remove any reverse entries for addr and any expired
343 entries in the whole cache.
344 If (flags == 0) remove any expired entries in the whole cache.
345
346 In the flags & F_FORWARD case, the return code is valid, and returns a non-NULL pointer
347 to a cache entry if the name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
348
349 We take advantage of the fact that hash chains have stuff in the order <reverse>,<other>,<immortal>
350 so that when we hit an entry which isn't reverse and is immortal, we're done.
351
352 If we free a crec which is a CNAME target, return the entry and uid in target_crec and target_uid.
353 This entry will get re-used with the same name, to preserve CNAMEs. */
354
355 struct crec *crecp, **up;
356
357 (void)class;
358
359 if (flags & F_FORWARD)
360 {
361 for (up = hash_bucket(name), crecp = *up; crecp; crecp = crecp->hash_next)
362 {
363 if ((crecp->flags & F_FORWARD) && hostname_isequal(cache_get_name(crecp), name))
364 {
365 /* Don't delete DNSSEC in favour of a CNAME, they can co-exist */
366 if ((flags & crecp->flags & (F_IPV4 | F_IPV6 | F_SRV)) ||
367 (((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS))))
368 {
369 if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
370 return crecp;
371 *up = crecp->hash_next;
372 /* If this record is for the name we're inserting and is the target
373 of a CNAME record. Make the new record for the same name, in the same
374 crec, with the same uid to avoid breaking the existing CNAME. */
375 if (crecp->uid != UID_NONE)
376 {
377 if (target_crec)
378 *target_crec = crecp;
379 if (target_uid)
380 *target_uid = crecp->uid;
381 }
382 cache_unlink(crecp);
383 cache_free(crecp);
384 continue;
385 }
386
387#ifdef HAVE_DNSSEC
388 /* Deletion has to be class-sensitive for DS and DNSKEY */
389 if ((flags & crecp->flags & (F_DNSKEY | F_DS)) && crecp->uid == class)
390 {
391 if (crecp->flags & F_CONFIG)
392 return crecp;
393 *up = crecp->hash_next;
394 cache_unlink(crecp);
395 cache_free(crecp);
396 continue;
397 }
398#endif
399 }
400
401 if (is_expired(now, crecp) || is_outdated_cname_pointer(crecp))
402 {
403 *up = crecp->hash_next;
404 if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
405 {
406 cache_unlink(crecp);
407 cache_free(crecp);
408 }
409 continue;
410 }
411
412 up = &crecp->hash_next;
413 }
414 }
415 else
416 {
417 int i;
418 int addrlen = (flags & F_IPV6) ? IN6ADDRSZ : INADDRSZ;
419
420 for (i = 0; i < hash_size; i++)
421 for (crecp = hash_table[i], up = &hash_table[i];
422 crecp && ((crecp->flags & F_REVERSE) || !(crecp->flags & F_IMMORTAL));
423 crecp = crecp->hash_next)
424 if (is_expired(now, crecp))
425 {
426 *up = crecp->hash_next;
427 if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
428 {
429 cache_unlink(crecp);
430 cache_free(crecp);
431 }
432 }
433 else if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) &&
434 (flags & crecp->flags & F_REVERSE) &&
435 (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
436 memcmp(&crecp->addr, addr, addrlen) == 0)
437 {
438 *up = crecp->hash_next;
439 cache_unlink(crecp);
440 cache_free(crecp);
441 }
442 else
443 up = &crecp->hash_next;
444 }
445
446 return NULL;
447}
448
449/* Note: The normal calling sequence is
450 cache_start_insert
451 cache_insert * n
452 cache_end_insert
453
454 but an abort can cause the cache_end_insert to be missed
455 in which can the next cache_start_insert cleans things up. */
456
457void cache_start_insert(void)
458{
459 /* Free any entries which didn't get committed during the last
460 insert due to error.
461 */
462 while (new_chain)
463 {
464 struct crec *tmp = new_chain->next;
465 cache_free(new_chain);
466 new_chain = tmp;
467 }
468 new_chain = NULL;
469 insert_error = 0;
470}
471
472struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class,
473 time_t now, unsigned long ttl, unsigned int flags)
474{
475#ifdef HAVE_DNSSEC
476 if (flags & (F_DNSKEY | F_DS))
477 {
478 /* The DNSSEC validation process works by getting needed records into the
479 cache, then retrying the validation until they are all in place.
480 This can be messed up by very short TTLs, and _really_ messed up by
481 zero TTLs, so we force the TTL to be at least long enough to do a validation.
482 Ideally, we should use some kind of reference counting so that records are
483 locked until the validation that asked for them is complete, but this
484 is much easier, and just as effective. */
485 if (ttl < DNSSEC_MIN_TTL)
486 ttl = DNSSEC_MIN_TTL;
487 }
488 else
489#endif
490 {
491 if (daemon->max_cache_ttl != 0 && daemon->max_cache_ttl < ttl)
492 ttl = daemon->max_cache_ttl;
493 if (daemon->min_cache_ttl != 0 && daemon->min_cache_ttl > ttl)
494 ttl = daemon->min_cache_ttl;
495 }
496
497 return really_insert(name, addr, class, now, ttl, flags);
498}
499
500
501static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class,
502 time_t now, unsigned long ttl, unsigned int flags)
503{
504 struct crec *new, *target_crec = NULL;
505 union bigname *big_name = NULL;
506 int freed_all = flags & F_REVERSE;
507 int free_avail = 0;
508 unsigned int target_uid;
509
510 /* if previous insertion failed give up now. */
511 if (insert_error)
512 return NULL;
513
514 /* we don't cache zero-TTL records. */
515 if (ttl == 0)
516 {
517 insert_error = 1;
518 return NULL;
519 }
520
521 /* First remove any expired entries and entries for the name/address we
522 are currently inserting. */
523 if ((new = cache_scan_free(name, addr, class, now, flags, &target_crec, &target_uid)))
524 {
525 /* We're trying to insert a record over one from
526 /etc/hosts or DHCP, or other config. If the
527 existing record is for an A or AAAA or CNAME and
528 the record we're trying to insert is the same,
529 just drop the insert, but don't error the whole process. */
530 if ((flags & (F_IPV4 | F_IPV6)) && (flags & F_FORWARD) && addr)
531 {
532 if ((flags & F_IPV4) && (new->flags & F_IPV4) &&
533 new->addr.addr4.s_addr == addr->addr4.s_addr)
534 return new;
535 else if ((flags & F_IPV6) && (new->flags & F_IPV6) &&
536 IN6_ARE_ADDR_EQUAL(&new->addr.addr6, &addr->addr6))
537 return new;
538 }
539
540 insert_error = 1;
541 return NULL;
542 }
543
544 /* Now get a cache entry from the end of the LRU list */
545 if (!target_crec)
546 while (1) {
547 if (!(new = cache_tail)) /* no entries left - cache is too small, bail */
548 {
549 insert_error = 1;
550 return NULL;
551 }
552
553 /* Free entry at end of LRU list, use it. */
554 if (!(new->flags & (F_FORWARD | F_REVERSE)))
555 break;
556
557 /* End of LRU list is still in use: if we didn't scan all the hash
558 chains for expired entries do that now. If we already tried that
559 then it's time to start spilling things. */
560
561 /* If free_avail set, we believe that an entry has been freed.
562 Bugs have been known to make this not true, resulting in
563 a tight loop here. If that happens, abandon the
564 insert. Once in this state, all inserts will probably fail. */
565 if (free_avail)
566 {
567 static int warned = 0;
568 if (!warned)
569 {
570 my_syslog(LOG_ERR, _("Internal error in cache."));
571 warned = 1;
572 }
573 insert_error = 1;
574 return NULL;
575 }
576
577 if (freed_all)
578 {
579 /* For DNSSEC records, uid holds class. */
580 free_avail = 1; /* Must be free space now. */
581 cache_scan_free(cache_get_name(new), &new->addr, new->uid, now, new->flags, NULL, NULL);
582 daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]++;
583 }
584 else
585 {
586 cache_scan_free(NULL, NULL, class, now, 0, NULL, NULL);
587 freed_all = 1;
588 }
589 }
590
591 /* Check if we need to and can allocate extra memory for a long name.
592 If that fails, give up now, always succeed for DNSSEC records. */
593 if (name && (strlen(name) > SMALLDNAME-1))
594 {
595 if (big_free)
596 {
597 big_name = big_free;
598 big_free = big_free->next;
599 }
600 else if ((bignames_left == 0 && !(flags & (F_DS | F_DNSKEY))) ||
601 !(big_name = (union bigname *)whine_malloc(sizeof(union bigname))))
602 {
603 insert_error = 1;
604 return NULL;
605 }
606 else if (bignames_left != 0)
607 bignames_left--;
608
609 }
610
611 /* If we freed a cache entry for our name which was a CNAME target, use that.
612 and preserve the uid, so that existing CNAMES are not broken. */
613 if (target_crec)
614 {
615 new = target_crec;
616 new->uid = target_uid;
617 }
618
619 /* Got the rest: finally grab entry. */
620 cache_unlink(new);
621
622 new->flags = flags;
623 if (big_name)
624 {
625 new->name.bname = big_name;
626 new->flags |= F_BIGNAME;
627 }
628
629 if (name)
630 strcpy(cache_get_name(new), name);
631 else
632 *cache_get_name(new) = 0;
633
634#ifdef HAVE_DNSSEC
635 if (flags & (F_DS | F_DNSKEY))
636 new->uid = class;
637#endif
638
639 if (addr)
640 new->addr = *addr;
641
642 new->ttd = now + (time_t)ttl;
643 new->next = new_chain;
644 new_chain = new;
645
646 return new;
647}
648
649/* after end of insertion, commit the new entries */
650void cache_end_insert(void)
651{
652 if (insert_error)
653 return;
654
655 while (new_chain)
656 {
657 struct crec *tmp = new_chain->next;
658 /* drop CNAMEs which didn't find a target. */
659 if (is_outdated_cname_pointer(new_chain))
660 cache_free(new_chain);
661 else
662 {
663 cache_hash(new_chain);
664 cache_link(new_chain);
665 daemon->metrics[METRIC_DNS_CACHE_INSERTED]++;
666
667 /* If we're a child process, send this cache entry up the pipe to the master.
668 The marshalling process is rather nasty. */
669 if (daemon->pipe_to_parent != -1)
670 {
671 char *name = cache_get_name(new_chain);
672 ssize_t m = strlen(name);
673 unsigned int flags = new_chain->flags;
674#ifdef HAVE_DNSSEC
675 u16 class = new_chain->uid;
676#endif
677
678 read_write(daemon->pipe_to_parent, (unsigned char *)&m, sizeof(m), 0);
679 read_write(daemon->pipe_to_parent, (unsigned char *)name, m, 0);
680 read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->ttd, sizeof(new_chain->ttd), 0);
681 read_write(daemon->pipe_to_parent, (unsigned char *)&flags, sizeof(flags), 0);
682
683 if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_SRV))
684 read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr, sizeof(new_chain->addr), 0);
685 if (flags & F_SRV)
686 {
687 /* A negative SRV entry is possible and has no data, obviously. */
688 if (!(flags & F_NEG))
689 blockdata_write(new_chain->addr.srv.target, new_chain->addr.srv.targetlen, daemon->pipe_to_parent);
690 }
691#ifdef HAVE_DNSSEC
692 if (flags & F_DNSKEY)
693 {
694 read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0);
695 blockdata_write(new_chain->addr.key.keydata, new_chain->addr.key.keylen, daemon->pipe_to_parent);
696 }
697 else if (flags & F_DS)
698 {
699 read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0);
700 /* A negative DS entry is possible and has no data, obviously. */
701 if (!(flags & F_NEG))
702 blockdata_write(new_chain->addr.ds.keydata, new_chain->addr.ds.keylen, daemon->pipe_to_parent);
703 }
704#endif
705 }
706 }
707
708 new_chain = tmp;
709 }
710
711 /* signal end of cache insert in master process */
712 if (daemon->pipe_to_parent != -1)
713 {
714 ssize_t m = -1;
715 read_write(daemon->pipe_to_parent, (unsigned char *)&m, sizeof(m), 0);
716 }
717
718 new_chain = NULL;
719}
720
721
722/* A marshalled cache entry arrives on fd, read, unmarshall and insert into cache of master process. */
723int cache_recv_insert(time_t now, int fd)
724{
725 ssize_t m;
726 union all_addr addr;
727 unsigned long ttl;
728 time_t ttd;
729 unsigned int flags;
730 struct crec *crecp = NULL;
731
732 cache_start_insert();
733
734 while(1)
735 {
736
737 if (!read_write(fd, (unsigned char *)&m, sizeof(m), 1))
738 return 0;
739
740 if (m == -1)
741 {
742 cache_end_insert();
743 return 1;
744 }
745
746 if (!read_write(fd, (unsigned char *)daemon->namebuff, m, 1) ||
747 !read_write(fd, (unsigned char *)&ttd, sizeof(ttd), 1) ||
748 !read_write(fd, (unsigned char *)&flags, sizeof(flags), 1))
749 return 0;
750
751 daemon->namebuff[m] = 0;
752
753 ttl = difftime(ttd, now);
754
755 if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_SRV))
756 {
757 unsigned short class = C_IN;
758
759 if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1))
760 return 0;
761
762 if ((flags & F_SRV) && !(flags & F_NEG) && !(addr.srv.target = blockdata_read(fd, addr.srv.targetlen)))
763 return 0;
764
765#ifdef HAVE_DNSSEC
766 if (flags & F_DNSKEY)
767 {
768 if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) ||
769 !(addr.key.keydata = blockdata_read(fd, addr.key.keylen)))
770 return 0;
771 }
772 else if (flags & F_DS)
773 {
774 if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) ||
775 (!(flags & F_NEG) && !(addr.key.keydata = blockdata_read(fd, addr.key.keylen))))
776 return 0;
777 }
778#endif
779
780 crecp = really_insert(daemon->namebuff, &addr, class, now, ttl, flags);
781 }
782 else if (flags & F_CNAME)
783 {
784 struct crec *newc = really_insert(daemon->namebuff, NULL, C_IN, now, ttl, flags);
785 /* This relies on the fact that the target of a CNAME immediately precedes
786 it because of the order of extraction in extract_addresses, and
787 the order reversal on the new_chain. */
788 if (newc)
789 {
790 newc->addr.cname.is_name_ptr = 0;
791
792 if (!crecp)
793 newc->addr.cname.target.cache = NULL;
794 else
795 {
796 next_uid(crecp);
797 newc->addr.cname.target.cache = crecp;
798 newc->addr.cname.uid = crecp->uid;
799 }
800 }
801 }
802 }
803}
804
805int cache_find_non_terminal(char *name, time_t now)
806{
807 struct crec *crecp;
808
809 for (crecp = *hash_bucket(name); crecp; crecp = crecp->hash_next)
810 if (!is_outdated_cname_pointer(crecp) &&
811 !is_expired(now, crecp) &&
812 (crecp->flags & F_FORWARD) &&
813 !(crecp->flags & F_NXDOMAIN) &&
814 hostname_isequal(name, cache_get_name(crecp)))
815 return 1;
816
817 return 0;
818}
819
820struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsigned int prot)
821{
822 struct crec *ans;
823 int no_rr = prot & F_NO_RR;
824
825 prot &= ~F_NO_RR;
826
827 if (crecp) /* iterating */
828 ans = crecp->next;
829 else
830 {
831 /* first search, look for relevant entries and push to top of list
832 also free anything which has expired */
833 struct crec *next, **up, **insert = NULL, **chainp = &ans;
834 unsigned int ins_flags = 0;
835
836 for (up = hash_bucket(name), crecp = *up; crecp; crecp = next)
837 {
838 next = crecp->hash_next;
839
840 if (!is_expired(now, crecp) && !is_outdated_cname_pointer(crecp))
841 {
842 if ((crecp->flags & F_FORWARD) &&
843 (crecp->flags & prot) &&
844 hostname_isequal(cache_get_name(crecp), name))
845 {
846 if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
847 {
848 *chainp = crecp;
849 chainp = &crecp->next;
850 }
851 else
852 {
853 cache_unlink(crecp);
854 cache_link(crecp);
855 }
856
857 /* Move all but the first entry up the hash chain
858 this implements round-robin.
859 Make sure that re-ordering doesn't break the hash-chain
860 order invariants.
861 */
862 if (insert && (crecp->flags & (F_REVERSE | F_IMMORTAL)) == ins_flags)
863 {
864 *up = crecp->hash_next;
865 crecp->hash_next = *insert;
866 *insert = crecp;
867 insert = &crecp->hash_next;
868 }
869 else
870 {
871 if (!insert && !no_rr)
872 {
873 insert = up;
874 ins_flags = crecp->flags & (F_REVERSE | F_IMMORTAL);
875 }
876 up = &crecp->hash_next;
877 }
878 }
879 else
880 /* case : not expired, incorrect entry. */
881 up = &crecp->hash_next;
882 }
883 else
884 {
885 /* expired entry, free it */
886 *up = crecp->hash_next;
887 if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
888 {
889 cache_unlink(crecp);
890 cache_free(crecp);
891 }
892 }
893 }
894
895 *chainp = cache_head;
896 }
897
898 if (ans &&
899 (ans->flags & F_FORWARD) &&
900 (ans->flags & prot) &&
901 hostname_isequal(cache_get_name(ans), name))
902 return ans;
903
904 return NULL;
905}
906
907struct crec *cache_find_by_addr(struct crec *crecp, union all_addr *addr,
908 time_t now, unsigned int prot)
909{
910 struct crec *ans;
911 int addrlen = (prot == F_IPV6) ? IN6ADDRSZ : INADDRSZ;
912
913 if (crecp) /* iterating */
914 ans = crecp->next;
915 else
916 {
917 /* first search, look for relevant entries and push to top of list
918 also free anything which has expired. All the reverse entries are at the
919 start of the hash chain, so we can give up when we find the first
920 non-REVERSE one. */
921 int i;
922 struct crec **up, **chainp = &ans;
923
924 for (i=0; i<hash_size; i++)
925 for (crecp = hash_table[i], up = &hash_table[i];
926 crecp && (crecp->flags & F_REVERSE);
927 crecp = crecp->hash_next)
928 if (!is_expired(now, crecp))
929 {
930 if ((crecp->flags & prot) &&
931 memcmp(&crecp->addr, addr, addrlen) == 0)
932 {
933 if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
934 {
935 *chainp = crecp;
936 chainp = &crecp->next;
937 }
938 else
939 {
940 cache_unlink(crecp);
941 cache_link(crecp);
942 }
943 }
944 up = &crecp->hash_next;
945 }
946 else
947 {
948 *up = crecp->hash_next;
949 if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)))
950 {
951 cache_unlink(crecp);
952 cache_free(crecp);
953 }
954 }
955
956 *chainp = cache_head;
957 }
958
959 if (ans &&
960 (ans->flags & F_REVERSE) &&
961 (ans->flags & prot) &&
962 memcmp(&ans->addr, addr, addrlen) == 0)
963 return ans;
964
965 return NULL;
966}
967
968static void add_hosts_entry(struct crec *cache, union all_addr *addr, int addrlen,
969 unsigned int index, struct crec **rhash, int hashsz)
970{
971 struct crec *lookup = cache_find_by_name(NULL, cache_get_name(cache), 0, cache->flags & (F_IPV4 | F_IPV6));
972 int i;
973 unsigned int j;
974
975 /* Remove duplicates in hosts files. */
976 if (lookup && (lookup->flags & F_HOSTS) && memcmp(&lookup->addr, addr, addrlen) == 0)
977 {
978 free(cache);
979 return;
980 }
981
982 /* Ensure there is only one address -> name mapping (first one trumps)
983 We do this by steam here, The entries are kept in hash chains, linked
984 by ->next (which is unused at this point) held in hash buckets in
985 the array rhash, hashed on address. Note that rhash and the values
986 in ->next are only valid whilst reading hosts files: the buckets are
987 then freed, and the ->next pointer used for other things.
988
989 Only insert each unique address once into this hashing structure.
990
991 This complexity avoids O(n^2) divergent CPU use whilst reading
992 large (10000 entry) hosts files.
993
994 Note that we only do this process when bulk-reading hosts files,
995 for incremental reads, rhash is NULL, and we use cache lookups
996 instead.
997 */
998
999 if (rhash)
1000 {
1001 /* hash address */
1002 for (j = 0, i = 0; i < addrlen; i++)
1003 j = (j*2 +((unsigned char *)addr)[i]) % hashsz;
1004
1005 for (lookup = rhash[j]; lookup; lookup = lookup->next)
1006 if ((lookup->flags & cache->flags & (F_IPV4 | F_IPV6)) &&
1007 memcmp(&lookup->addr, addr, addrlen) == 0)
1008 {
1009 cache->flags &= ~F_REVERSE;
1010 break;
1011 }
1012
1013 /* maintain address hash chain, insert new unique address */
1014 if (!lookup)
1015 {
1016 cache->next = rhash[j];
1017 rhash[j] = cache;
1018 }
1019 }
1020 else
1021 {
1022 /* incremental read, lookup in cache */
1023 lookup = cache_find_by_addr(NULL, addr, 0, cache->flags & (F_IPV4 | F_IPV6));
1024 if (lookup && lookup->flags & F_HOSTS)
1025 cache->flags &= ~F_REVERSE;
1026 }
1027
1028 cache->uid = index;
1029 memcpy(&cache->addr, addr, addrlen);
1030 cache_hash(cache);
1031 make_non_terminals(cache);
1032}
1033
1034static int eatspace(FILE *f)
1035{
1036 int c, nl = 0;
1037
1038 while (1)
1039 {
1040 if ((c = getc(f)) == '#')
1041 while (c != '\n' && c != EOF)
1042 c = getc(f);
1043
1044 if (c == EOF)
1045 return 1;
1046
1047 if (!isspace(c))
1048 {
1049 ungetc(c, f);
1050 return nl;
1051 }
1052
1053 if (c == '\n')
1054 nl++;
1055 }
1056}
1057
1058static int gettok(FILE *f, char *token)
1059{
1060 int c, count = 0;
1061
1062 while (1)
1063 {
1064 if ((c = getc(f)) == EOF)
1065 return (count == 0) ? -1 : 1;
1066
1067 if (isspace(c) || c == '#')
1068 {
1069 ungetc(c, f);
1070 return eatspace(f);
1071 }
1072
1073 if (count < (MAXDNAME - 1))
1074 {
1075 token[count++] = c;
1076 token[count] = 0;
1077 }
1078 }
1079}
1080
1081int read_hostsfile(char *filename, unsigned int index, int cache_size, struct crec **rhash, int hashsz)
1082{
1083 FILE *f = fopen(filename, "r");
1084 char *token = daemon->namebuff, *domain_suffix = NULL;
1085 int addr_count = 0, name_count = cache_size, lineno = 1;
1086 unsigned int flags = 0;
1087 union all_addr addr;
1088 int atnl, addrlen = 0;
1089
1090 if (!f)
1091 {
1092 my_syslog(LOG_ERR, _("failed to load names from %s: %s"), filename, strerror(errno));
1093 return cache_size;
1094 }
1095
1096 lineno += eatspace(f);
1097
1098 while ((atnl = gettok(f, token)) != -1)
1099 {
1100 if (inet_pton(AF_INET, token, &addr) > 0)
1101 {
1102 flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4;
1103 addrlen = INADDRSZ;
1104 domain_suffix = get_domain(addr.addr4);
1105 }
1106 else if (inet_pton(AF_INET6, token, &addr) > 0)
1107 {
1108 flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6;
1109 addrlen = IN6ADDRSZ;
1110 domain_suffix = get_domain6(&addr.addr6);
1111 }
1112 else
1113 {
1114 my_syslog(LOG_ERR, _("bad address at %s line %d"), filename, lineno);
1115 while (atnl == 0)
1116 atnl = gettok(f, token);
1117 lineno += atnl;
1118 continue;
1119 }
1120
1121 addr_count++;
1122
1123 /* rehash every 1000 names. */
1124 if (rhash && ((name_count - cache_size) > 1000))
1125 {
1126 rehash(name_count);
1127 cache_size = name_count;
1128 }
1129
1130 while (atnl == 0)
1131 {
1132 struct crec *cache;
1133 int fqdn, nomem;
1134 char *canon;
1135
1136 if ((atnl = gettok(f, token)) == -1)
1137 break;
1138
1139 fqdn = !!strchr(token, '.');
1140
1141 if ((canon = canonicalise(token, &nomem)))
1142 {
1143 /* If set, add a version of the name with a default domain appended */
1144 if (option_bool(OPT_EXPAND) && domain_suffix && !fqdn &&
1145 (cache = whine_malloc(SIZEOF_BARE_CREC + strlen(canon) + 2 + strlen(domain_suffix))))
1146 {
1147 strcpy(cache->name.sname, canon);
1148 strcat(cache->name.sname, ".");
1149 strcat(cache->name.sname, domain_suffix);
1150 cache->flags = flags;
1151 cache->ttd = daemon->local_ttl;
1152 add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
1153 name_count++;
1154 }
1155 if ((cache = whine_malloc(SIZEOF_BARE_CREC + strlen(canon) + 1)))
1156 {
1157 strcpy(cache->name.sname, canon);
1158 cache->flags = flags;
1159 cache->ttd = daemon->local_ttl;
1160 add_hosts_entry(cache, &addr, addrlen, index, rhash, hashsz);
1161 name_count++;
1162 }
1163 free(canon);
1164
1165 }
1166 else if (!nomem)
1167 my_syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno);
1168 }
1169
1170 lineno += atnl;
1171 }
1172
1173 fclose(f);
1174
1175 if (rhash)
1176 rehash(name_count);
1177
1178 my_syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count);
1179
1180 return name_count;
1181}
1182
1183void cache_reload(void)
1184{
1185 struct crec *cache, **up, *tmp;
1186 int revhashsz, i, total_size = daemon->cachesize;
1187 struct hostsfile *ah;
1188 struct host_record *hr;
1189 struct name_list *nl;
1190 struct cname *a;
1191 struct crec lrec;
1192 struct mx_srv_record *mx;
1193 struct txt_record *txt;
1194 struct interface_name *intr;
1195 struct ptr_record *ptr;
1196 struct naptr *naptr;
1197#ifdef HAVE_DNSSEC
1198 struct ds_config *ds;
1199#endif
1200
1201 daemon->metrics[METRIC_DNS_CACHE_INSERTED] = 0;
1202 daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED] = 0;
1203
1204 for (i=0; i<hash_size; i++)
1205 for (cache = hash_table[i], up = &hash_table[i]; cache; cache = tmp)
1206 {
1207 cache_blockdata_free(cache);
1208
1209 tmp = cache->hash_next;
1210 if (cache->flags & (F_HOSTS | F_CONFIG))
1211 {
1212 *up = cache->hash_next;
1213 free(cache);
1214 }
1215 else if (!(cache->flags & F_DHCP))
1216 {
1217 *up = cache->hash_next;
1218 if (cache->flags & F_BIGNAME)
1219 {
1220 cache->name.bname->next = big_free;
1221 big_free = cache->name.bname;
1222 }
1223 cache->flags = 0;
1224 }
1225 else
1226 up = &cache->hash_next;
1227 }
1228
1229 /* Add locally-configured CNAMEs to the cache */
1230 for (a = daemon->cnames; a; a = a->next)
1231 if (a->alias[1] != '*' &&
1232 ((cache = whine_malloc(SIZEOF_POINTER_CREC))))
1233 {
1234 cache->flags = F_FORWARD | F_NAMEP | F_CNAME | F_IMMORTAL | F_CONFIG;
1235 cache->ttd = a->ttl;
1236 cache->name.namep = a->alias;
1237 cache->addr.cname.target.name = a->target;
1238 cache->addr.cname.is_name_ptr = 1;
1239 cache->uid = UID_NONE;
1240 cache_hash(cache);
1241 make_non_terminals(cache);
1242 }
1243
1244#ifdef HAVE_DNSSEC
1245 for (ds = daemon->ds; ds; ds = ds->next)
1246 if ((cache = whine_malloc(SIZEOF_POINTER_CREC)) &&
1247 (cache->addr.ds.keydata = blockdata_alloc(ds->digest, ds->digestlen)))
1248 {
1249 cache->flags = F_FORWARD | F_IMMORTAL | F_DS | F_CONFIG | F_NAMEP;
1250 cache->ttd = daemon->local_ttl;
1251 cache->name.namep = ds->name;
1252 cache->addr.ds.keylen = ds->digestlen;
1253 cache->addr.ds.algo = ds->algo;
1254 cache->addr.ds.keytag = ds->keytag;
1255 cache->addr.ds.digest = ds->digest_type;
1256 cache->uid = ds->class;
1257 cache_hash(cache);
1258 make_non_terminals(cache);
1259 }
1260#endif
1261
1262 /* borrow the packet buffer for a temporary by-address hash */
1263 memset(daemon->packet, 0, daemon->packet_buff_sz);
1264 revhashsz = daemon->packet_buff_sz / sizeof(struct crec *);
1265 /* we overwrote the buffer... */
1266 daemon->srv_save = NULL;
1267
1268 /* Do host_records in config. */
1269 for (hr = daemon->host_records; hr; hr = hr->next)
1270 for (nl = hr->names; nl; nl = nl->next)
1271 {
1272 if ((hr->flags & HR_4) &&
1273 (cache = whine_malloc(SIZEOF_POINTER_CREC)))
1274 {
1275 cache->name.namep = nl->name;
1276 cache->ttd = hr->ttl;
1277 cache->flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4 | F_NAMEP | F_CONFIG;
1278 add_hosts_entry(cache, (union all_addr *)&hr->addr, INADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz);
1279 }
1280
1281 if ((hr->flags & HR_6) &&
1282 (cache = whine_malloc(SIZEOF_POINTER_CREC)))
1283 {
1284 cache->name.namep = nl->name;
1285 cache->ttd = hr->ttl;
1286 cache->flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6 | F_NAMEP | F_CONFIG;
1287 add_hosts_entry(cache, (union all_addr *)&hr->addr6, IN6ADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz);
1288 }
1289 }
1290
1291 if (option_bool(OPT_NO_HOSTS) && !daemon->addn_hosts)
1292 {
1293 if (daemon->cachesize > 0)
1294 my_syslog(LOG_INFO, _("cleared cache"));
1295 }
1296 else
1297 {
1298 if (!option_bool(OPT_NO_HOSTS))
1299 total_size = read_hostsfile(HOSTSFILE, SRC_HOSTS, total_size, (struct crec **)daemon->packet, revhashsz);
1300
1301 daemon->addn_hosts = expand_filelist(daemon->addn_hosts);
1302 for (ah = daemon->addn_hosts; ah; ah = ah->next)
1303 if (!(ah->flags & AH_INACTIVE))
1304 total_size = read_hostsfile(ah->fname, ah->index, total_size, (struct crec **)daemon->packet, revhashsz);
1305 }
1306
1307 /* Make non-terminal records for all locally-define RRs */
1308 lrec.flags = F_FORWARD | F_CONFIG | F_NAMEP | F_IMMORTAL;
1309
1310 for (txt = daemon->txt; txt; txt = txt->next)
1311 {
1312 lrec.name.namep = txt->name;
1313 make_non_terminals(&lrec);
1314 }
1315
1316 for (naptr = daemon->naptr; naptr; naptr = naptr->next)
1317 {
1318 lrec.name.namep = naptr->name;
1319 make_non_terminals(&lrec);
1320 }
1321
1322 for (mx = daemon->mxnames; mx; mx = mx->next)
1323 {
1324 lrec.name.namep = mx->name;
1325 make_non_terminals(&lrec);
1326 }
1327
1328 for (intr = daemon->int_names; intr; intr = intr->next)
1329 {
1330 lrec.name.namep = intr->name;
1331 make_non_terminals(&lrec);
1332 }
1333
1334 for (ptr = daemon->ptr; ptr; ptr = ptr->next)
1335 {
1336 lrec.name.namep = ptr->name;
1337 make_non_terminals(&lrec);
1338 }
1339
1340#ifdef HAVE_INOTIFY
1341 set_dynamic_inotify(AH_HOSTS, total_size, (struct crec **)daemon->packet, revhashsz);
1342#endif
1343
1344}
1345
1346#ifdef HAVE_DHCP
1347struct in_addr a_record_from_hosts(char *name, time_t now)
1348{
1349 struct crec *crecp = NULL;
1350 struct in_addr ret;
1351
1352 while ((crecp = cache_find_by_name(crecp, name, now, F_IPV4)))
1353 if (crecp->flags & F_HOSTS)
1354 return crecp->addr.addr4;
1355
1356 my_syslog(MS_DHCP | LOG_WARNING, _("No IPv4 address found for %s"), name);
1357
1358 ret.s_addr = 0;
1359 return ret;
1360}
1361
1362void cache_unhash_dhcp(void)
1363{
1364 struct crec *cache, **up;
1365 int i;
1366
1367 for (i=0; i<hash_size; i++)
1368 for (cache = hash_table[i], up = &hash_table[i]; cache; cache = cache->hash_next)
1369 if (cache->flags & F_DHCP)
1370 {
1371 *up = cache->hash_next;
1372 cache->next = dhcp_spare;
1373 dhcp_spare = cache;
1374 }
1375 else
1376 up = &cache->hash_next;
1377}
1378
1379void cache_add_dhcp_entry(char *host_name, int prot,
1380 union all_addr *host_address, time_t ttd)
1381{
1382 struct crec *crec = NULL, *fail_crec = NULL;
1383 unsigned int flags = F_IPV4;
1384 int in_hosts = 0;
1385 size_t addrlen = sizeof(struct in_addr);
1386
1387 if (prot == AF_INET6)
1388 {
1389 flags = F_IPV6;
1390 addrlen = sizeof(struct in6_addr);
1391 }
1392
1393 inet_ntop(prot, host_address, daemon->addrbuff, ADDRSTRLEN);
1394
1395 while ((crec = cache_find_by_name(crec, host_name, 0, flags | F_CNAME)))
1396 {
1397 /* check all addresses associated with name */
1398 if (crec->flags & (F_HOSTS | F_CONFIG))
1399 {
1400 if (crec->flags & F_CNAME)
1401 my_syslog(MS_DHCP | LOG_WARNING,
1402 _("%s is a CNAME, not giving it to the DHCP lease of %s"),
1403 host_name, daemon->addrbuff);
1404 else if (memcmp(&crec->addr, host_address, addrlen) == 0)
1405 in_hosts = 1;
1406 else
1407 fail_crec = crec;
1408 }
1409 else if (!(crec->flags & F_DHCP))
1410 {
1411 cache_scan_free(host_name, NULL, C_IN, 0, crec->flags & (flags | F_CNAME | F_FORWARD), NULL, NULL);
1412 /* scan_free deletes all addresses associated with name */
1413 break;
1414 }
1415 }
1416
1417 /* if in hosts, don't need DHCP record */
1418 if (in_hosts)
1419 return;
1420
1421 /* Name in hosts, address doesn't match */
1422 if (fail_crec)
1423 {
1424 inet_ntop(prot, &fail_crec->addr, daemon->namebuff, MAXDNAME);
1425 my_syslog(MS_DHCP | LOG_WARNING,
1426 _("not giving name %s to the DHCP lease of %s because "
1427 "the name exists in %s with address %s"),
1428 host_name, daemon->addrbuff,
1429 record_source(fail_crec->uid), daemon->namebuff);
1430 return;
1431 }
1432
1433 if ((crec = cache_find_by_addr(NULL, (union all_addr *)host_address, 0, flags)))
1434 {
1435 if (crec->flags & F_NEG)
1436 {
1437 flags |= F_REVERSE;
1438 cache_scan_free(NULL, (union all_addr *)host_address, C_IN, 0, flags, NULL, NULL);
1439 }
1440 }
1441 else
1442 flags |= F_REVERSE;
1443
1444 if ((crec = dhcp_spare))
1445 dhcp_spare = dhcp_spare->next;
1446 else /* need new one */
1447 crec = whine_malloc(SIZEOF_POINTER_CREC);
1448
1449 if (crec) /* malloc may fail */
1450 {
1451 crec->flags = flags | F_NAMEP | F_DHCP | F_FORWARD;
1452 if (ttd == 0)
1453 crec->flags |= F_IMMORTAL;
1454 else
1455 crec->ttd = ttd;
1456 crec->addr = *host_address;
1457 crec->name.namep = host_name;
1458 crec->uid = UID_NONE;
1459 cache_hash(crec);
1460 make_non_terminals(crec);
1461 }
1462}
1463#endif
1464
1465/* Called when we put a local or DHCP name into the cache.
1466 Creates empty cache entries for subnames (ie,
1467 for three.two.one, for two.one and one), without
1468 F_IPV4 or F_IPV6 or F_CNAME set. These convert
1469 NXDOMAIN answers to NoData ones. */
1470static void make_non_terminals(struct crec *source)
1471{
1472 char *name = cache_get_name(source);
1473 struct crec *crecp, *tmp, **up;
1474 int type = F_HOSTS | F_CONFIG;
1475#ifdef HAVE_DHCP
1476 if (source->flags & F_DHCP)
1477 type = F_DHCP;
1478#endif
1479
1480 /* First delete any empty entries for our new real name. Note that
1481 we only delete empty entries deriving from DHCP for a new DHCP-derived
1482 entry and vice-versa for HOSTS and CONFIG. This ensures that
1483 non-terminals from DHCP go when we reload DHCP and
1484 for HOSTS/CONFIG when we re-read. */
1485 for (up = hash_bucket(name), crecp = *up; crecp; crecp = tmp)
1486 {
1487 tmp = crecp->hash_next;
1488
1489 if (!is_outdated_cname_pointer(crecp) &&
1490 (crecp->flags & F_FORWARD) &&
1491 (crecp->flags & type) &&
1492 !(crecp->flags & (F_IPV4 | F_IPV6 | F_CNAME | F_SRV | F_DNSKEY | F_DS)) &&
1493 hostname_isequal(name, cache_get_name(crecp)))
1494 {
1495 *up = crecp->hash_next;
1496#ifdef HAVE_DHCP
1497 if (type & F_DHCP)
1498 {
1499 crecp->next = dhcp_spare;
1500 dhcp_spare = crecp;
1501 }
1502 else
1503#endif
1504 free(crecp);
1505 break;
1506 }
1507 else
1508 up = &crecp->hash_next;
1509 }
1510
1511 while ((name = strchr(name, '.')))
1512 {
1513 name++;
1514
1515 /* Look for one existing, don't need another */
1516 for (crecp = *hash_bucket(name); crecp; crecp = crecp->hash_next)
1517 if (!is_outdated_cname_pointer(crecp) &&
1518 (crecp->flags & F_FORWARD) &&
1519 (crecp->flags & type) &&
1520 hostname_isequal(name, cache_get_name(crecp)))
1521 break;
1522
1523 if (crecp)
1524 {
1525 /* If the new name expires later, transfer that time to
1526 empty non-terminal entry. */
1527 if (!(crecp->flags & F_IMMORTAL))
1528 {
1529 if (source->flags & F_IMMORTAL)
1530 crecp->flags |= F_IMMORTAL;
1531 else if (difftime(crecp->ttd, source->ttd) < 0)
1532 crecp->ttd = source->ttd;
1533 }
1534 continue;
1535 }
1536
1537#ifdef HAVE_DHCP
1538 if ((source->flags & F_DHCP) && dhcp_spare)
1539 {
1540 crecp = dhcp_spare;
1541 dhcp_spare = dhcp_spare->next;
1542 }
1543 else
1544#endif
1545 crecp = whine_malloc(SIZEOF_POINTER_CREC);
1546
1547 if (crecp)
1548 {
1549 crecp->flags = (source->flags | F_NAMEP) & ~(F_IPV4 | F_IPV6 | F_CNAME | F_SRV | F_DNSKEY | F_DS | F_REVERSE);
1550 crecp->ttd = source->ttd;
1551 crecp->name.namep = name;
1552
1553 cache_hash(crecp);
1554 }
1555 }
1556}
1557
1558#ifndef NO_ID
1559int cache_make_stat(struct txt_record *t)
1560{
1561 static char *buff = NULL;
1562 static int bufflen = 60;
1563 int len;
1564 struct server *serv, *serv1;
1565 char *p;
1566
1567 if (!buff && !(buff = whine_malloc(60)))
1568 return 0;
1569
1570 p = buff;
1571
1572 switch (t->stat)
1573 {
1574 case TXT_STAT_CACHESIZE:
1575 sprintf(buff+1, "%d", daemon->cachesize);
1576 break;
1577
1578 case TXT_STAT_INSERTS:
1579 sprintf(buff+1, "%d", daemon->metrics[METRIC_DNS_CACHE_INSERTED]);
1580 break;
1581
1582 case TXT_STAT_EVICTIONS:
1583 sprintf(buff+1, "%d", daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]);
1584 break;
1585
1586 case TXT_STAT_MISSES:
1587 sprintf(buff+1, "%u", daemon->metrics[METRIC_DNS_QUERIES_FORWARDED]);
1588 break;
1589
1590 case TXT_STAT_HITS:
1591 sprintf(buff+1, "%u", daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]);
1592 break;
1593
1594#ifdef HAVE_AUTH
1595 case TXT_STAT_AUTH:
1596 sprintf(buff+1, "%u", daemon->metrics[METRIC_DNS_AUTH_ANSWERED]);
1597 break;
1598#endif
1599
1600 case TXT_STAT_SERVERS:
1601 /* sum counts from different records for same server */
1602 for (serv = daemon->servers; serv; serv = serv->next)
1603 serv->flags &= ~SERV_MARK;
1604
1605 for (serv = daemon->servers; serv; serv = serv->next)
1606 if (!(serv->flags & SERV_MARK))
1607 {
1608 char *new, *lenp;
1609 int port, newlen, bytes_avail, bytes_needed;
1610 unsigned int queries = 0, failed_queries = 0;
1611 for (serv1 = serv; serv1; serv1 = serv1->next)
1612 if (!(serv1->flags & SERV_MARK) && sockaddr_isequal(&serv->addr, &serv1->addr))
1613 {
1614 serv1->flags |= SERV_MARK;
1615 queries += serv1->queries;
1616 failed_queries += serv1->failed_queries;
1617 }
1618 port = prettyprint_addr(&serv->addr, daemon->addrbuff);
1619 lenp = p++; /* length */
1620 bytes_avail = bufflen - (p - buff );
1621 bytes_needed = snprintf(p, bytes_avail, "%s#%d %u %u", daemon->addrbuff, port, queries, failed_queries);
1622 if (bytes_needed >= bytes_avail)
1623 {
1624 /* expand buffer if necessary */
1625 newlen = bytes_needed + 1 + bufflen - bytes_avail;
1626 if (!(new = whine_malloc(newlen)))
1627 return 0;
1628 memcpy(new, buff, bufflen);
1629 free(buff);
1630 p = new + (p - buff);
1631 lenp = p - 1;
1632 buff = new;
1633 bufflen = newlen;
1634 bytes_avail = bufflen - (p - buff );
1635 bytes_needed = snprintf(p, bytes_avail, "%s#%d %u %u", daemon->addrbuff, port, queries, failed_queries);
1636 }
1637 *lenp = bytes_needed;
1638 p += bytes_needed;
1639 }
1640 t->txt = (unsigned char *)buff;
1641 t->len = p - buff;
1642
1643 return 1;
1644 }
1645
1646 len = strlen(buff+1);
1647 t->txt = (unsigned char *)buff;
1648 t->len = len + 1;
1649 *buff = len;
1650 return 1;
1651}
1652#endif
1653
1654/* There can be names in the cache containing control chars, don't
1655 mess up logging or open security holes. */
1656static char *sanitise(char *name)
1657{
1658 unsigned char *r;
1659 if (name)
1660 for (r = (unsigned char *)name; *r; r++)
1661 if (!isprint((int)*r))
1662 return "<name unprintable>";
1663
1664 return name;
1665}
1666
1667
1668void dump_cache(time_t now)
1669{
1670 struct server *serv, *serv1;
1671
1672 my_syslog(LOG_INFO, _("time %lu"), (unsigned long)now);
1673 my_syslog(LOG_INFO, _("cache size %d, %d/%d cache insertions re-used unexpired cache entries."),
1674 daemon->cachesize, daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED], daemon->metrics[METRIC_DNS_CACHE_INSERTED]);
1675 my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"),
1676 daemon->metrics[METRIC_DNS_QUERIES_FORWARDED], daemon->metrics[METRIC_DNS_LOCAL_ANSWERED]);
1677#ifdef HAVE_AUTH
1678 my_syslog(LOG_INFO, _("queries for authoritative zones %u"), daemon->metrics[METRIC_DNS_AUTH_ANSWERED]);
1679#endif
1680
1681 blockdata_report();
1682
1683 /* sum counts from different records for same server */
1684 for (serv = daemon->servers; serv; serv = serv->next)
1685 serv->flags &= ~SERV_MARK;
1686
1687 for (serv = daemon->servers; serv; serv = serv->next)
1688 if (!(serv->flags & SERV_MARK))
1689 {
1690 int port;
1691 unsigned int queries = 0, failed_queries = 0;
1692 for (serv1 = serv; serv1; serv1 = serv1->next)
1693 if (!(serv1->flags & SERV_MARK) && sockaddr_isequal(&serv->addr, &serv1->addr))
1694 {
1695 serv1->flags |= SERV_MARK;
1696 queries += serv1->queries;
1697 failed_queries += serv1->failed_queries;
1698 }
1699 port = prettyprint_addr(&serv->addr, daemon->addrbuff);
1700 my_syslog(LOG_INFO, _("server %s#%d: queries sent %u, retried or failed %u"), daemon->addrbuff, port, queries, failed_queries);
1701 }
1702
1703 if (option_bool(OPT_DEBUG) || option_bool(OPT_LOG))
1704 {
1705 struct crec *cache ;
1706 int i;
1707 my_syslog(LOG_INFO, "Host Address Flags Expires");
1708
1709 for (i=0; i<hash_size; i++)
1710 for (cache = hash_table[i]; cache; cache = cache->hash_next)
1711 {
1712 char *t = " ";
1713 char *a = daemon->addrbuff, *p = daemon->namebuff, *n = cache_get_name(cache);
1714 *a = 0;
1715 if (strlen(n) == 0 && !(cache->flags & F_REVERSE))
1716 n = "<Root>";
1717 p += sprintf(p, "%-30.30s ", sanitise(n));
1718 if ((cache->flags & F_CNAME) && !is_outdated_cname_pointer(cache))
1719 a = sanitise(cache_get_cname_target(cache));
1720 else if ((cache->flags & F_SRV) && !(cache->flags & F_NEG))
1721 {
1722 int targetlen = cache->addr.srv.targetlen;
1723 ssize_t len = sprintf(a, "%u %u %u ", cache->addr.srv.priority,
1724 cache->addr.srv.weight, cache->addr.srv.srvport);
1725
1726 if (targetlen > (40 - len))
1727 targetlen = 40 - len;
1728 blockdata_retrieve(cache->addr.srv.target, targetlen, a + len);
1729 a[len + targetlen] = 0;
1730 }
1731#ifdef HAVE_DNSSEC
1732 else if (cache->flags & F_DS)
1733 {
1734 if (!(cache->flags & F_NEG))
1735 sprintf(a, "%5u %3u %3u", cache->addr.ds.keytag,
1736 cache->addr.ds.algo, cache->addr.ds.digest);
1737 }
1738 else if (cache->flags & F_DNSKEY)
1739 sprintf(a, "%5u %3u %3u", cache->addr.key.keytag,
1740 cache->addr.key.algo, cache->addr.key.flags);
1741#endif
1742 else if (!(cache->flags & F_NEG) || !(cache->flags & F_FORWARD))
1743 {
1744 a = daemon->addrbuff;
1745 if (cache->flags & F_IPV4)
1746 inet_ntop(AF_INET, &cache->addr, a, ADDRSTRLEN);
1747 else if (cache->flags & F_IPV6)
1748 inet_ntop(AF_INET6, &cache->addr, a, ADDRSTRLEN);
1749 }
1750
1751 if (cache->flags & F_IPV4)
1752 t = "4";
1753 else if (cache->flags & F_IPV6)
1754 t = "6";
1755 else if (cache->flags & F_CNAME)
1756 t = "C";
1757 else if (cache->flags & F_SRV)
1758 t = "V";
1759#ifdef HAVE_DNSSEC
1760 else if (cache->flags & F_DS)
1761 t = "S";
1762 else if (cache->flags & F_DNSKEY)
1763 t = "K";
1764#endif
1765 p += sprintf(p, "%-40.40s %s%s%s%s%s%s%s%s%s ", a, t,
1766 cache->flags & F_FORWARD ? "F" : " ",
1767 cache->flags & F_REVERSE ? "R" : " ",
1768 cache->flags & F_IMMORTAL ? "I" : " ",
1769 cache->flags & F_DHCP ? "D" : " ",
1770 cache->flags & F_NEG ? "N" : " ",
1771 cache->flags & F_NXDOMAIN ? "X" : " ",
1772 cache->flags & F_HOSTS ? "H" : " ",
1773 cache->flags & F_DNSSECOK ? "V" : " ");
1774#ifdef HAVE_BROKEN_RTC
1775 p += sprintf(p, "%lu", cache->flags & F_IMMORTAL ? 0: (unsigned long)(cache->ttd - now));
1776#else
1777 p += sprintf(p, "%s", cache->flags & F_IMMORTAL ? "\n" : ctime(&(cache->ttd)));
1778 /* ctime includes trailing \n - eat it */
1779 *(p-1) = 0;
1780#endif
1781 my_syslog(LOG_INFO, "%s", daemon->namebuff);
1782 }
1783 }
1784}
1785
1786char *record_source(unsigned int index)
1787{
1788 struct hostsfile *ah;
1789
1790 if (index == SRC_CONFIG)
1791 return "config";
1792 else if (index == SRC_HOSTS)
1793 return HOSTSFILE;
1794
1795 for (ah = daemon->addn_hosts; ah; ah = ah->next)
1796 if (ah->index == index)
1797 return ah->fname;
1798
1799#ifdef HAVE_INOTIFY
1800 for (ah = daemon->dynamic_dirs; ah; ah = ah->next)
1801 if (ah->index == index)
1802 return ah->fname;
1803#endif
1804
1805 return "<unknown>";
1806}
1807
1808char *querystr(char *desc, unsigned short type)
1809{
1810 unsigned int i;
1811 int len = 10; /* strlen("type=xxxxx") */
1812 const char *types = NULL;
1813 static char *buff = NULL;
1814 static int bufflen = 0;
1815
1816 for (i = 0; i < (sizeof(typestr)/sizeof(typestr[0])); i++)
1817 if (typestr[i].type == type)
1818 {
1819 types = typestr[i].name;
1820 len = strlen(types);
1821 break;
1822 }
1823
1824 if (desc)
1825 {
1826 len += 2; /* braces */
1827 len += strlen(desc);
1828 }
1829 len++; /* terminator */
1830
1831 if (!buff || bufflen < len)
1832 {
1833 if (buff)
1834 free(buff);
1835 else if (len < 20)
1836 len = 20;
1837
1838 buff = whine_malloc(len);
1839 bufflen = len;
1840 }
1841
1842 if (buff)
1843 {
1844 if (desc)
1845 {
1846 if (types)
1847 sprintf(buff, "%s[%s]", desc, types);
1848 else
1849 sprintf(buff, "%s[type=%d]", desc, type);
1850 }
1851 else
1852 {
1853 if (types)
1854 sprintf(buff, "<%s>", types);
1855 else
1856 sprintf(buff, "<type=%d>", type);
1857 }
1858 }
1859
1860 return buff ? buff : "";
1861}
1862
1863static char *edestr(int ede)
1864{
1865 switch (ede)
1866 {
1867 case EDE_OTHER: return "other";
1868 case EDE_USUPDNSKEY: return "unsupported DNSKEY algorithm";
1869 case EDE_USUPDS: return "unsupported DS digest";
1870 case EDE_STALE: return "stale answer";
1871 case EDE_FORGED: return "forged";
1872 case EDE_DNSSEC_IND: return "DNSSEC indeterminate";
1873 case EDE_DNSSEC_BOGUS: return "DNSSEC bogus";
1874 case EDE_SIG_EXP: return "DNSSEC signature expired";
1875 case EDE_SIG_NYV: return "DNSSEC sig not yet valid";
1876 case EDE_NO_DNSKEY: return "DNSKEY missing";
1877 case EDE_NO_RRSIG: return "RRSIG missing";
1878 case EDE_NO_ZONEKEY: return "no zone key bit set";
1879 case EDE_NO_NSEC: return "NSEC(3) missing";
1880 case EDE_CACHED_ERR: return "cached error";
1881 case EDE_NOT_READY: return "not ready";
1882 case EDE_BLOCKED: return "blocked";
1883 case EDE_CENSORED: return "censored";
1884 case EDE_FILTERED: return "filtered";
1885 case EDE_PROHIBITED: return "prohibited";
1886 case EDE_STALE_NXD: return "stale NXDOMAIN";
1887 case EDE_NOT_AUTH: return "not authoritative";
1888 case EDE_NOT_SUP: return "not supported";
1889 case EDE_NO_AUTH: return "no reachable authority";
1890 case EDE_NETERR: return "network error";
1891 case EDE_INVALID_DATA: return "invalid data";
1892 default: return "unknown";
1893 }
1894}
1895
1896void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg)
1897{
1898 char *source, *dest = arg;
1899 char *verb = "is";
1900 char *extra = "";
1901
1902 if (!option_bool(OPT_LOG))
1903 return;
1904
1905#ifdef HAVE_DNSSEC
1906 if ((flags & F_DNSSECOK) && option_bool(OPT_EXTRALOG))
1907 extra = " (DNSSEC signed)";
1908#endif
1909
1910 name = sanitise(name);
1911
1912 if (addr)
1913 {
1914 dest = daemon->addrbuff;
1915
1916 if (flags & F_KEYTAG)
1917 sprintf(daemon->addrbuff, arg, addr->log.keytag, addr->log.algo, addr->log.digest);
1918 else if (flags & F_RCODE)
1919 {
1920 unsigned int rcode = addr->log.rcode;
1921
1922 if (rcode == SERVFAIL)
1923 dest = "SERVFAIL";
1924 else if (rcode == REFUSED)
1925 dest = "REFUSED";
1926 else if (rcode == NOTIMP)
1927 dest = "not implemented";
1928 else
1929 sprintf(daemon->addrbuff, "%u", rcode);
1930
1931 if (addr->log.ede != EDE_UNSET)
1932 {
1933 extra = daemon->addrbuff;
1934 sprintf(extra, " (EDE: %s)", edestr(addr->log.ede));
1935 }
1936 }
1937 else if (flags & (F_IPV4 | F_IPV6))
1938 inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6,
1939 addr, daemon->addrbuff, ADDRSTRLEN);
1940 else
1941 dest = arg;
1942 }
1943
1944 if (flags & F_REVERSE)
1945 {
1946 dest = name;
1947 name = daemon->addrbuff;
1948 }
1949
1950 if (flags & F_NEG)
1951 {
1952 if (flags & F_NXDOMAIN)
1953 dest = "NXDOMAIN";
1954 else
1955 {
1956 if (flags & F_IPV4)
1957 dest = "NODATA-IPv4";
1958 else if (flags & F_IPV6)
1959 dest = "NODATA-IPv6";
1960 else
1961 dest = "NODATA";
1962 }
1963 }
1964 else if (flags & F_CNAME)
1965 dest = "<CNAME>";
1966 else if (flags & F_SRV)
1967 dest = "<SRV>";
1968 else if (flags & F_RRNAME)
1969 dest = arg;
1970
1971 if (flags & F_CONFIG)
1972 source = "config";
1973 else if (flags & F_DHCP)
1974 source = "DHCP";
1975 else if (flags & F_HOSTS)
1976 source = arg;
1977 else if (flags & F_UPSTREAM)
1978 source = "reply";
1979 else if (flags & F_SECSTAT)
1980 {
1981 if (addr && addr->log.ede != EDE_UNSET && option_bool(OPT_EXTRALOG))
1982 {
1983 extra = daemon->addrbuff;
1984 sprintf(extra, " (EDE: %s)", edestr(addr->log.ede));
1985 }
1986 source = "validation";
1987 dest = arg;
1988 }
1989 else if (flags & F_AUTH)
1990 source = "auth";
1991 else if (flags & F_SERVER)
1992 {
1993 source = "forwarded";
1994 verb = "to";
1995 }
1996 else if (flags & F_QUERY)
1997 {
1998 source = arg;
1999 verb = "from";
2000 }
2001 else if (flags & F_DNSSEC)
2002 {
2003 source = arg;
2004 verb = "to";
2005 }
2006 else if (flags & F_IPSET)
2007 {
2008 source = "ipset add";
2009 dest = name;
2010 name = arg;
2011 verb = daemon->addrbuff;
2012 }
2013 else
2014 source = "cached";
2015
2016 if (strlen(name) == 0)
2017 name = ".";
2018
2019 if (option_bool(OPT_EXTRALOG))
2020 {
2021 if (flags & F_NOEXTRA)
2022 my_syslog(LOG_INFO, "%u %s %s %s %s%s", daemon->log_display_id, source, name, verb, dest, extra);
2023 else
2024 {
2025 int port = prettyprint_addr(daemon->log_source_addr, daemon->addrbuff2);
2026 my_syslog(LOG_INFO, "%u %s/%u %s %s %s %s%s", daemon->log_display_id, daemon->addrbuff2, port, source, name, verb, dest, extra);
2027 }
2028 }
2029 else
2030 my_syslog(LOG_INFO, "%s %s %s %s%s", source, name, verb, dest, extra);
2031}