1 /* dnsmasq is Copyright (c) 2000-2016 Simon Kelley
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.
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.
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/>.
19 static struct crec
*cache_head
= NULL
, *cache_tail
= NULL
, **hash_table
= NULL
;
21 static struct crec
*dhcp_spare
= NULL
;
23 static struct crec
*new_chain
= NULL
;
24 static int cache_inserted
= 0, cache_live_freed
= 0, insert_error
;
25 static union bigname
*big_free
= NULL
;
26 static int bignames_left
, hash_size
;
28 /* type->string mapping: this is also used by the name-hash function as a mixing table. */
31 const char * const name
;
69 static void cache_free(struct crec
*crecp
);
70 static void cache_unlink(struct crec
*crecp
);
71 static void cache_link(struct crec
*crecp
);
72 static void rehash(int size
);
73 static void cache_hash(struct crec
*crecp
);
75 static unsigned int next_uid(void)
77 static unsigned int uid
= 0;
81 /* uid == 0 used to indicate CNAME to interface name. */
82 if (uid
== SRC_INTERFACE
)
93 bignames_left
= daemon
->cachesize
/10;
95 if (daemon
->cachesize
> 0)
97 crecp
= safe_malloc(daemon
->cachesize
*sizeof(struct crec
));
99 for (i
=0; i
< daemon
->cachesize
; i
++, crecp
++)
103 crecp
->uid
= next_uid();
107 /* create initial hash table*/
108 rehash(daemon
->cachesize
);
111 /* In most cases, we create the hash table once here by calling this with (hash_table == NULL)
112 but if the hosts file(s) are big (some people have 50000 ad-block entries), the table
113 will be much too small, so the hosts reading code calls rehash every 1000 addresses, to
115 static void rehash(int size
)
117 struct crec
**new, **old
, *p
, *tmp
;
118 int i
, new_size
, old_size
;
120 /* hash_size is a power of two. */
121 for (new_size
= 64; new_size
< size
/10; new_size
= new_size
<< 1);
123 /* must succeed in getting first instance, failure later is non-fatal */
125 new = safe_malloc(new_size
* sizeof(struct crec
*));
126 else if (new_size
<= hash_size
|| !(new = whine_malloc(new_size
* sizeof(struct crec
*))))
129 for(i
= 0; i
< new_size
; i
++)
133 old_size
= hash_size
;
135 hash_size
= new_size
;
139 for (i
= 0; i
< old_size
; i
++)
140 for (p
= old
[i
]; p
; p
= tmp
)
149 static struct crec
**hash_bucket(char *name
)
151 unsigned int c
, val
= 017465; /* Barker code - minimum self-correlation in cyclic shift */
152 const unsigned char *mix_tab
= (const unsigned char*)typestr
;
154 while((c
= (unsigned char) *name
++))
156 /* don't use tolower and friends here - they may be messed up by LOCALE */
157 if (c
>= 'A' && c
<= 'Z')
159 val
= ((val
<< 7) | (val
>> (32 - 7))) + (mix_tab
[(val
+ c
) & 0x3F] ^ c
);
162 /* hash_size is a power of two */
163 return hash_table
+ ((val
^ (val
>> 16)) & (hash_size
- 1));
166 static void cache_hash(struct crec
*crecp
)
168 /* maintain an invariant that all entries with F_REVERSE set
169 are at the start of the hash-chain and all non-reverse
170 immortal entries are at the end of the hash-chain.
171 This allows reverse searches and garbage collection to be optimised */
173 struct crec
**up
= hash_bucket(cache_get_name(crecp
));
175 if (!(crecp
->flags
& F_REVERSE
))
177 while (*up
&& ((*up
)->flags
& F_REVERSE
))
178 up
= &((*up
)->hash_next
);
180 if (crecp
->flags
& F_IMMORTAL
)
181 while (*up
&& !((*up
)->flags
& F_IMMORTAL
))
182 up
= &((*up
)->hash_next
);
184 crecp
->hash_next
= *up
;
189 static void cache_blockdata_free(struct crec
*crecp
)
191 if (crecp
->flags
& F_DNSKEY
)
192 blockdata_free(crecp
->addr
.key
.keydata
);
193 else if ((crecp
->flags
& F_DS
) && !(crecp
->flags
& F_NEG
))
194 blockdata_free(crecp
->addr
.ds
.keydata
);
198 static void cache_free(struct crec
*crecp
)
200 crecp
->flags
&= ~F_FORWARD
;
201 crecp
->flags
&= ~F_REVERSE
;
202 crecp
->uid
= next_uid(); /* invalidate CNAMES pointing to this. */
205 cache_tail
->next
= crecp
;
208 crecp
->prev
= cache_tail
;
212 /* retrieve big name for further use. */
213 if (crecp
->flags
& F_BIGNAME
)
215 crecp
->name
.bname
->next
= big_free
;
216 big_free
= crecp
->name
.bname
;
217 crecp
->flags
&= ~F_BIGNAME
;
221 cache_blockdata_free(crecp
);
225 /* insert a new cache entry at the head of the list (youngest entry) */
226 static void cache_link(struct crec
*crecp
)
228 if (cache_head
) /* check needed for init code */
229 cache_head
->prev
= crecp
;
230 crecp
->next
= cache_head
;
237 /* remove an arbitrary cache entry for promotion */
238 static void cache_unlink (struct crec
*crecp
)
241 crecp
->prev
->next
= crecp
->next
;
243 cache_head
= crecp
->next
;
246 crecp
->next
->prev
= crecp
->prev
;
248 cache_tail
= crecp
->prev
;
251 char *cache_get_name(struct crec
*crecp
)
253 if (crecp
->flags
& F_BIGNAME
)
254 return crecp
->name
.bname
->name
;
255 else if (crecp
->flags
& F_NAMEP
)
256 return crecp
->name
.namep
;
258 return crecp
->name
.sname
;
261 char *cache_get_cname_target(struct crec
*crecp
)
263 if (crecp
->addr
.cname
.uid
!= SRC_INTERFACE
)
264 return cache_get_name(crecp
->addr
.cname
.target
.cache
);
266 return crecp
->addr
.cname
.target
.int_name
->name
;
271 struct crec
*cache_enumerate(int init
)
274 static struct crec
*cache
;
281 else if (cache
&& cache
->hash_next
)
282 cache
= cache
->hash_next
;
286 while (bucket
< hash_size
)
287 if ((cache
= hash_table
[bucket
++]))
294 static int is_outdated_cname_pointer(struct crec
*crecp
)
296 if (!(crecp
->flags
& F_CNAME
) || crecp
->addr
.cname
.uid
== SRC_INTERFACE
)
299 /* NB. record may be reused as DS or DNSKEY, where uid is
300 overloaded for something completely different */
301 if (crecp
->addr
.cname
.target
.cache
&&
302 (crecp
->addr
.cname
.target
.cache
->flags
& (F_IPV4
| F_IPV6
| F_CNAME
)) &&
303 crecp
->addr
.cname
.uid
== crecp
->addr
.cname
.target
.cache
->uid
)
309 static int is_expired(time_t now
, struct crec
*crecp
)
311 if (crecp
->flags
& F_IMMORTAL
)
314 if (difftime(now
, crecp
->ttd
) < 0)
320 static struct crec
*cache_scan_free(char *name
, struct all_addr
*addr
, time_t now
, unsigned short flags
)
322 /* Scan and remove old entries.
323 If (flags & F_FORWARD) then remove any forward entries for name and any expired
324 entries but only in the same hash bucket as name.
325 If (flags & F_REVERSE) then remove any reverse entries for addr and any expired
326 entries in the whole cache.
327 If (flags == 0) remove any expired entries in the whole cache.
329 In the flags & F_FORWARD case, the return code is valid, and returns a non-NULL pointer
330 to a cache entry if the name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
332 We take advantage of the fact that hash chains have stuff in the order <reverse>,<other>,<immortal>
333 so that when we hit an entry which isn't reverse and is immortal, we're done. */
335 struct crec
*crecp
, **up
;
337 if (flags
& F_FORWARD
)
339 for (up
= hash_bucket(name
), crecp
= *up
; crecp
; crecp
= crecp
->hash_next
)
341 if (is_expired(now
, crecp
) || is_outdated_cname_pointer(crecp
))
343 *up
= crecp
->hash_next
;
344 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
)))
352 if ((crecp
->flags
& F_FORWARD
) && hostname_isequal(cache_get_name(crecp
), name
))
354 /* Don't delete DNSSEC in favour of a CNAME, they can co-exist */
355 if ((flags
& crecp
->flags
& (F_IPV4
| F_IPV6
)) ||
356 (((crecp
->flags
| flags
) & F_CNAME
) && !(crecp
->flags
& (F_DNSKEY
| F_DS
))))
358 if (crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
))
360 *up
= crecp
->hash_next
;
367 /* Deletion has to be class-sensitive for DS and DNSKEY */
368 if ((flags
& crecp
->flags
& (F_DNSKEY
| F_DS
)) && crecp
->uid
== addr
->addr
.dnssec
.class)
370 if (crecp
->flags
& F_CONFIG
)
372 *up
= crecp
->hash_next
;
379 up
= &crecp
->hash_next
;
386 int addrlen
= (flags
& F_IPV6
) ? IN6ADDRSZ
: INADDRSZ
;
388 int addrlen
= INADDRSZ
;
390 for (i
= 0; i
< hash_size
; i
++)
391 for (crecp
= hash_table
[i
], up
= &hash_table
[i
];
392 crecp
&& ((crecp
->flags
& F_REVERSE
) || !(crecp
->flags
& F_IMMORTAL
));
393 crecp
= crecp
->hash_next
)
394 if (is_expired(now
, crecp
))
396 *up
= crecp
->hash_next
;
397 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
)))
403 else if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
)) &&
404 (flags
& crecp
->flags
& F_REVERSE
) &&
405 (flags
& crecp
->flags
& (F_IPV4
| F_IPV6
)) &&
406 memcmp(&crecp
->addr
.addr
, addr
, addrlen
) == 0)
408 *up
= crecp
->hash_next
;
413 up
= &crecp
->hash_next
;
419 /* Note: The normal calling sequence is
424 but an abort can cause the cache_end_insert to be missed
425 in which can the next cache_start_insert cleans things up. */
427 void cache_start_insert(void)
429 /* Free any entries which didn't get committed during the last
434 struct crec
*tmp
= new_chain
->next
;
435 cache_free(new_chain
);
442 struct crec
*cache_insert(char *name
, struct all_addr
*addr
,
443 time_t now
, unsigned long ttl
, unsigned short flags
)
446 union bigname
*big_name
= NULL
;
447 int freed_all
= flags
& F_REVERSE
;
450 /* Don't log DNSSEC records here, done elsewhere */
451 if (flags
& (F_IPV4
| F_IPV6
| F_CNAME
))
453 log_query(flags
| F_UPSTREAM
, name
, addr
, NULL
);
454 /* Don't mess with TTL for DNSSEC records. */
455 if (daemon
->max_cache_ttl
!= 0 && daemon
->max_cache_ttl
< ttl
)
456 ttl
= daemon
->max_cache_ttl
;
457 if (daemon
->min_cache_ttl
!= 0 && daemon
->min_cache_ttl
> ttl
)
458 ttl
= daemon
->min_cache_ttl
;
461 /* if previous insertion failed give up now. */
465 /* First remove any expired entries and entries for the name/address we
466 are currently inserting. */
467 if ((new = cache_scan_free(name
, addr
, now
, flags
)))
469 /* We're trying to insert a record over one from
470 /etc/hosts or DHCP, or other config. If the
471 existing record is for an A or AAAA and
472 the record we're trying to insert is the same,
473 just drop the insert, but don't error the whole process. */
474 if ((flags
& (F_IPV4
| F_IPV6
)) && (flags
& F_FORWARD
) && addr
)
476 if ((flags
& F_IPV4
) && (new->flags
& F_IPV4
) &&
477 new->addr
.addr
.addr
.addr4
.s_addr
== addr
->addr
.addr4
.s_addr
)
480 else if ((flags
& F_IPV6
) && (new->flags
& F_IPV6
) &&
481 IN6_ARE_ADDR_EQUAL(&new->addr
.addr
.addr
.addr6
, &addr
->addr
.addr6
))
490 /* Now get a cache entry from the end of the LRU list */
492 if (!(new = cache_tail
)) /* no entries left - cache is too small, bail */
498 /* End of LRU list is still in use: if we didn't scan all the hash
499 chains for expired entries do that now. If we already tried that
500 then it's time to start spilling things. */
502 if (new->flags
& (F_FORWARD
| F_REVERSE
))
504 /* If free_avail set, we believe that an entry has been freed.
505 Bugs have been known to make this not true, resulting in
506 a tight loop here. If that happens, abandon the
507 insert. Once in this state, all inserts will probably fail. */
510 static int warned
= 0;
513 my_syslog(LOG_ERR
, _("Internal error in cache."));
522 struct all_addr free_addr
= new->addr
.addr
;;
525 /* For DNSSEC records, addr holds class. */
526 if (new->flags
& (F_DS
| F_DNSKEY
))
527 free_addr
.addr
.dnssec
.class = new->uid
;
530 free_avail
= 1; /* Must be free space now. */
531 cache_scan_free(cache_get_name(new), &free_addr
, now
, new->flags
);
536 cache_scan_free(NULL
, NULL
, now
, 0);
542 /* Check if we need to and can allocate extra memory for a long name.
543 If that fails, give up now, always succeed for DNSSEC records. */
544 if (name
&& (strlen(name
) > SMALLDNAME
-1))
549 big_free
= big_free
->next
;
551 else if ((bignames_left
== 0 && !(flags
& (F_DS
| F_DNSKEY
))) ||
552 !(big_name
= (union bigname
*)whine_malloc(sizeof(union bigname
))))
557 else if (bignames_left
!= 0)
562 /* Got the rest: finally grab entry. */
570 new->name
.bname
= big_name
;
571 new->flags
|= F_BIGNAME
;
575 strcpy(cache_get_name(new), name
);
577 *cache_get_name(new) = 0;
582 if (flags
& (F_DS
| F_DNSKEY
))
583 new->uid
= addr
->addr
.dnssec
.class;
586 new->addr
.addr
= *addr
;
589 new->ttd
= now
+ (time_t)ttl
;
590 new->next
= new_chain
;
596 /* after end of insertion, commit the new entries */
597 void cache_end_insert(void)
604 struct crec
*tmp
= new_chain
->next
;
605 /* drop CNAMEs which didn't find a target. */
606 if (is_outdated_cname_pointer(new_chain
))
607 cache_free(new_chain
);
610 cache_hash(new_chain
);
611 cache_link(new_chain
);
619 struct crec
*cache_find_by_name(struct crec
*crecp
, char *name
, time_t now
, unsigned int prot
)
622 int no_rr
= prot
& F_NO_RR
;
626 if (crecp
) /* iterating */
630 /* first search, look for relevant entries and push to top of list
631 also free anything which has expired */
632 struct crec
*next
, **up
, **insert
= NULL
, **chainp
= &ans
;
633 unsigned short ins_flags
= 0;
635 for (up
= hash_bucket(name
), crecp
= *up
; crecp
; crecp
= next
)
637 next
= crecp
->hash_next
;
639 if (!is_expired(now
, crecp
) && !is_outdated_cname_pointer(crecp
))
641 if ((crecp
->flags
& F_FORWARD
) &&
642 (crecp
->flags
& prot
) &&
643 hostname_isequal(cache_get_name(crecp
), name
))
645 if (crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
))
648 chainp
= &crecp
->next
;
656 /* Move all but the first entry up the hash chain
657 this implements round-robin.
658 Make sure that re-ordering doesn't break the hash-chain
661 if (insert
&& (crecp
->flags
& (F_REVERSE
| F_IMMORTAL
)) == ins_flags
)
663 *up
= crecp
->hash_next
;
664 crecp
->hash_next
= *insert
;
666 insert
= &crecp
->hash_next
;
670 if (!insert
&& !no_rr
)
673 ins_flags
= crecp
->flags
& (F_REVERSE
| F_IMMORTAL
);
675 up
= &crecp
->hash_next
;
679 /* case : not expired, incorrect entry. */
680 up
= &crecp
->hash_next
;
684 /* expired entry, free it */
685 *up
= crecp
->hash_next
;
686 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
)))
694 *chainp
= cache_head
;
698 (ans
->flags
& F_FORWARD
) &&
699 (ans
->flags
& prot
) &&
700 hostname_isequal(cache_get_name(ans
), name
))
706 struct crec
*cache_find_by_addr(struct crec
*crecp
, struct all_addr
*addr
,
707 time_t now
, unsigned int prot
)
711 int addrlen
= (prot
== F_IPV6
) ? IN6ADDRSZ
: INADDRSZ
;
713 int addrlen
= INADDRSZ
;
716 if (crecp
) /* iterating */
720 /* first search, look for relevant entries and push to top of list
721 also free anything which has expired. All the reverse entries are at the
722 start of the hash chain, so we can give up when we find the first
725 struct crec
**up
, **chainp
= &ans
;
727 for (i
=0; i
<hash_size
; i
++)
728 for (crecp
= hash_table
[i
], up
= &hash_table
[i
];
729 crecp
&& (crecp
->flags
& F_REVERSE
);
730 crecp
= crecp
->hash_next
)
731 if (!is_expired(now
, crecp
))
733 if ((crecp
->flags
& prot
) &&
734 memcmp(&crecp
->addr
.addr
, addr
, addrlen
) == 0)
736 if (crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
))
739 chainp
= &crecp
->next
;
747 up
= &crecp
->hash_next
;
751 *up
= crecp
->hash_next
;
752 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
)))
759 *chainp
= cache_head
;
763 (ans
->flags
& F_REVERSE
) &&
764 (ans
->flags
& prot
) &&
765 memcmp(&ans
->addr
.addr
, addr
, addrlen
) == 0)
771 static void add_hosts_cname(struct crec
*target
)
776 for (a
= daemon
->cnames
; a
; a
= a
->next
)
777 if (hostname_isequal(cache_get_name(target
), a
->target
) &&
778 (crec
= whine_malloc(sizeof(struct crec
))))
780 crec
->flags
= F_FORWARD
| F_IMMORTAL
| F_NAMEP
| F_CONFIG
| F_CNAME
;
782 crec
->name
.namep
= a
->alias
;
783 crec
->addr
.cname
.target
.cache
= target
;
784 crec
->addr
.cname
.uid
= target
->uid
;
785 crec
->uid
= next_uid();
787 add_hosts_cname(crec
); /* handle chains */
791 static void add_hosts_entry(struct crec
*cache
, struct all_addr
*addr
, int addrlen
,
792 unsigned int index
, struct crec
**rhash
, int hashsz
)
794 struct crec
*lookup
= cache_find_by_name(NULL
, cache_get_name(cache
), 0, cache
->flags
& (F_IPV4
| F_IPV6
));
795 int i
, nameexists
= 0;
798 /* Remove duplicates in hosts files. */
799 if (lookup
&& (lookup
->flags
& F_HOSTS
))
802 if (memcmp(&lookup
->addr
.addr
, addr
, addrlen
) == 0)
809 /* Ensure there is only one address -> name mapping (first one trumps)
810 We do this by steam here, The entries are kept in hash chains, linked
811 by ->next (which is unused at this point) held in hash buckets in
812 the array rhash, hashed on address. Note that rhash and the values
813 in ->next are only valid whilst reading hosts files: the buckets are
814 then freed, and the ->next pointer used for other things.
816 Only insert each unique address once into this hashing structure.
818 This complexity avoids O(n^2) divergent CPU use whilst reading
819 large (10000 entry) hosts files.
821 Note that we only do this process when bulk-reading hosts files,
822 for incremental reads, rhash is NULL, and we use cache lookups
829 for (j
= 0, i
= 0; i
< addrlen
; i
++)
830 j
= (j
*2 +((unsigned char *)addr
)[i
]) % hashsz
;
832 for (lookup
= rhash
[j
]; lookup
; lookup
= lookup
->next
)
833 if ((lookup
->flags
& cache
->flags
& (F_IPV4
| F_IPV6
)) &&
834 memcmp(&lookup
->addr
.addr
, addr
, addrlen
) == 0)
836 cache
->flags
&= ~F_REVERSE
;
840 /* maintain address hash chain, insert new unique address */
843 cache
->next
= rhash
[j
];
849 /* incremental read, lookup in cache */
850 lookup
= cache_find_by_addr(NULL
, addr
, 0, cache
->flags
& (F_IPV4
| F_IPV6
));
851 if (lookup
&& lookup
->flags
& F_HOSTS
)
852 cache
->flags
&= ~F_REVERSE
;
856 memcpy(&cache
->addr
.addr
, addr
, addrlen
);
859 /* don't need to do alias stuff for second and subsequent addresses. */
861 add_hosts_cname(cache
);
864 static int eatspace(FILE *f
)
870 if ((c
= getc(f
)) == '#')
871 while (c
!= '\n' && c
!= EOF
)
888 static int gettok(FILE *f
, char *token
)
894 if ((c
= getc(f
)) == EOF
)
895 return (count
== 0) ? EOF
: 1;
897 if (isspace(c
) || c
== '#')
903 if (count
< (MAXDNAME
- 1))
911 int read_hostsfile(char *filename
, unsigned int index
, int cache_size
, struct crec
**rhash
, int hashsz
)
913 FILE *f
= fopen(filename
, "r");
914 char *token
= daemon
->namebuff
, *domain_suffix
= NULL
;
915 int addr_count
= 0, name_count
= cache_size
, lineno
= 0;
916 unsigned short flags
= 0;
917 struct all_addr addr
;
918 int atnl
, addrlen
= 0;
922 my_syslog(LOG_ERR
, _("failed to load names from %s: %s"), filename
, strerror(errno
));
928 while ((atnl
= gettok(f
, token
)) != EOF
)
932 if (inet_pton(AF_INET
, token
, &addr
) > 0)
934 flags
= F_HOSTS
| F_IMMORTAL
| F_FORWARD
| F_REVERSE
| F_IPV4
;
936 domain_suffix
= get_domain(addr
.addr
.addr4
);
939 else if (inet_pton(AF_INET6
, token
, &addr
) > 0)
941 flags
= F_HOSTS
| F_IMMORTAL
| F_FORWARD
| F_REVERSE
| F_IPV6
;
943 domain_suffix
= get_domain6(&addr
.addr
.addr6
);
948 my_syslog(LOG_ERR
, _("bad address at %s line %d"), filename
, lineno
);
950 atnl
= gettok(f
, token
);
956 /* rehash every 1000 names. */
957 if (rhash
&& ((name_count
- cache_size
) > 1000))
960 cache_size
= name_count
;
969 if ((atnl
= gettok(f
, token
)) == EOF
)
972 fqdn
= !!strchr(token
, '.');
974 if ((canon
= canonicalise(token
, &nomem
)))
976 /* If set, add a version of the name with a default domain appended */
977 if (option_bool(OPT_EXPAND
) && domain_suffix
&& !fqdn
&&
978 (cache
= whine_malloc(sizeof(struct crec
) +
979 strlen(canon
)+2+strlen(domain_suffix
)-SMALLDNAME
)))
981 strcpy(cache
->name
.sname
, canon
);
982 strcat(cache
->name
.sname
, ".");
983 strcat(cache
->name
.sname
, domain_suffix
);
984 cache
->flags
= flags
;
985 cache
->ttd
= daemon
->local_ttl
;
986 add_hosts_entry(cache
, &addr
, addrlen
, index
, rhash
, hashsz
);
989 if ((cache
= whine_malloc(sizeof(struct crec
) + strlen(canon
)+1-SMALLDNAME
)))
991 strcpy(cache
->name
.sname
, canon
);
992 cache
->flags
= flags
;
993 cache
->ttd
= daemon
->local_ttl
;
994 add_hosts_entry(cache
, &addr
, addrlen
, index
, rhash
, hashsz
);
1001 my_syslog(LOG_ERR
, _("bad name at %s line %d"), filename
, lineno
);
1010 my_syslog(LOG_INFO
, _("read %s - %d addresses"), filename
, addr_count
);
1015 void cache_reload(void)
1017 struct crec
*cache
, **up
, *tmp
;
1018 int revhashsz
, i
, total_size
= daemon
->cachesize
;
1019 struct hostsfile
*ah
;
1020 struct host_record
*hr
;
1021 struct name_list
*nl
;
1023 struct interface_name
*intr
;
1025 struct ds_config
*ds
;
1028 cache_inserted
= cache_live_freed
= 0;
1030 for (i
=0; i
<hash_size
; i
++)
1031 for (cache
= hash_table
[i
], up
= &hash_table
[i
]; cache
; cache
= tmp
)
1034 cache_blockdata_free(cache
);
1036 tmp
= cache
->hash_next
;
1037 if (cache
->flags
& (F_HOSTS
| F_CONFIG
))
1039 *up
= cache
->hash_next
;
1042 else if (!(cache
->flags
& F_DHCP
))
1044 *up
= cache
->hash_next
;
1045 if (cache
->flags
& F_BIGNAME
)
1047 cache
->name
.bname
->next
= big_free
;
1048 big_free
= cache
->name
.bname
;
1053 up
= &cache
->hash_next
;
1056 /* Add CNAMEs to interface_names to the cache */
1057 for (a
= daemon
->cnames
; a
; a
= a
->next
)
1058 for (intr
= daemon
->int_names
; intr
; intr
= intr
->next
)
1059 if (hostname_isequal(a
->target
, intr
->name
) &&
1060 ((cache
= whine_malloc(sizeof(struct crec
)))))
1062 cache
->flags
= F_FORWARD
| F_NAMEP
| F_CNAME
| F_IMMORTAL
| F_CONFIG
;
1063 cache
->ttd
= a
->ttl
;
1064 cache
->name
.namep
= a
->alias
;
1065 cache
->addr
.cname
.target
.int_name
= intr
;
1066 cache
->addr
.cname
.uid
= SRC_INTERFACE
;
1067 cache
->uid
= next_uid();
1069 add_hosts_cname(cache
); /* handle chains */
1073 for (ds
= daemon
->ds
; ds
; ds
= ds
->next
)
1074 if ((cache
= whine_malloc(sizeof(struct crec
))) &&
1075 (cache
->addr
.ds
.keydata
= blockdata_alloc(ds
->digest
, ds
->digestlen
)))
1077 cache
->flags
= F_FORWARD
| F_IMMORTAL
| F_DS
| F_CONFIG
| F_NAMEP
;
1078 cache
->ttd
= daemon
->local_ttl
;
1079 cache
->name
.namep
= ds
->name
;
1080 cache
->addr
.ds
.keylen
= ds
->digestlen
;
1081 cache
->addr
.ds
.algo
= ds
->algo
;
1082 cache
->addr
.ds
.keytag
= ds
->keytag
;
1083 cache
->addr
.ds
.digest
= ds
->digest_type
;
1084 cache
->uid
= ds
->class;
1089 /* borrow the packet buffer for a temporary by-address hash */
1090 memset(daemon
->packet
, 0, daemon
->packet_buff_sz
);
1091 revhashsz
= daemon
->packet_buff_sz
/ sizeof(struct crec
*);
1092 /* we overwrote the buffer... */
1093 daemon
->srv_save
= NULL
;
1095 /* Do host_records in config. */
1096 for (hr
= daemon
->host_records
; hr
; hr
= hr
->next
)
1097 for (nl
= hr
->names
; nl
; nl
= nl
->next
)
1099 if (hr
->addr
.s_addr
!= 0 &&
1100 (cache
= whine_malloc(sizeof(struct crec
))))
1102 cache
->name
.namep
= nl
->name
;
1103 cache
->ttd
= hr
->ttl
;
1104 cache
->flags
= F_HOSTS
| F_IMMORTAL
| F_FORWARD
| F_REVERSE
| F_IPV4
| F_NAMEP
| F_CONFIG
;
1105 add_hosts_entry(cache
, (struct all_addr
*)&hr
->addr
, INADDRSZ
, SRC_CONFIG
, (struct crec
**)daemon
->packet
, revhashsz
);
1108 if (!IN6_IS_ADDR_UNSPECIFIED(&hr
->addr6
) &&
1109 (cache
= whine_malloc(sizeof(struct crec
))))
1111 cache
->name
.namep
= nl
->name
;
1112 cache
->ttd
= hr
->ttl
;
1113 cache
->flags
= F_HOSTS
| F_IMMORTAL
| F_FORWARD
| F_REVERSE
| F_IPV6
| F_NAMEP
| F_CONFIG
;
1114 add_hosts_entry(cache
, (struct all_addr
*)&hr
->addr6
, IN6ADDRSZ
, SRC_CONFIG
, (struct crec
**)daemon
->packet
, revhashsz
);
1119 if (option_bool(OPT_NO_HOSTS
) && !daemon
->addn_hosts
)
1121 if (daemon
->cachesize
> 0)
1122 my_syslog(LOG_INFO
, _("cleared cache"));
1126 if (!option_bool(OPT_NO_HOSTS
))
1127 total_size
= read_hostsfile(HOSTSFILE
, SRC_HOSTS
, total_size
, (struct crec
**)daemon
->packet
, revhashsz
);
1129 daemon
->addn_hosts
= expand_filelist(daemon
->addn_hosts
);
1130 for (ah
= daemon
->addn_hosts
; ah
; ah
= ah
->next
)
1131 if (!(ah
->flags
& AH_INACTIVE
))
1132 total_size
= read_hostsfile(ah
->fname
, ah
->index
, total_size
, (struct crec
**)daemon
->packet
, revhashsz
);
1136 set_dynamic_inotify(AH_HOSTS
, total_size
, (struct crec
**)daemon
->packet
, revhashsz
);
1142 struct in_addr
a_record_from_hosts(char *name
, time_t now
)
1144 struct crec
*crecp
= NULL
;
1147 while ((crecp
= cache_find_by_name(crecp
, name
, now
, F_IPV4
)))
1148 if (crecp
->flags
& F_HOSTS
)
1149 return *(struct in_addr
*)&crecp
->addr
;
1151 my_syslog(MS_DHCP
| LOG_WARNING
, _("No IPv4 address found for %s"), name
);
1157 void cache_unhash_dhcp(void)
1159 struct crec
*cache
, **up
;
1162 for (i
=0; i
<hash_size
; i
++)
1163 for (cache
= hash_table
[i
], up
= &hash_table
[i
]; cache
; cache
= cache
->hash_next
)
1164 if (cache
->flags
& F_DHCP
)
1166 *up
= cache
->hash_next
;
1167 cache
->next
= dhcp_spare
;
1171 up
= &cache
->hash_next
;
1174 static void add_dhcp_cname(struct crec
*target
, time_t ttd
)
1176 struct crec
*aliasc
;
1179 for (a
= daemon
->cnames
; a
; a
= a
->next
)
1180 if (hostname_isequal(cache_get_name(target
), a
->target
))
1182 if ((aliasc
= dhcp_spare
))
1183 dhcp_spare
= dhcp_spare
->next
;
1184 else /* need new one */
1185 aliasc
= whine_malloc(sizeof(struct crec
));
1189 aliasc
->flags
= F_FORWARD
| F_NAMEP
| F_DHCP
| F_CNAME
| F_CONFIG
;
1191 aliasc
->flags
|= F_IMMORTAL
;
1194 aliasc
->name
.namep
= a
->alias
;
1195 aliasc
->addr
.cname
.target
.cache
= target
;
1196 aliasc
->addr
.cname
.uid
= target
->uid
;
1197 aliasc
->uid
= next_uid();
1199 add_dhcp_cname(aliasc
, ttd
);
1204 void cache_add_dhcp_entry(char *host_name
, int prot
,
1205 struct all_addr
*host_address
, time_t ttd
)
1207 struct crec
*crec
= NULL
, *fail_crec
= NULL
;
1208 unsigned short flags
= F_IPV4
;
1210 size_t addrlen
= sizeof(struct in_addr
);
1213 if (prot
== AF_INET6
)
1216 addrlen
= sizeof(struct in6_addr
);
1220 inet_ntop(prot
, host_address
, daemon
->addrbuff
, ADDRSTRLEN
);
1222 while ((crec
= cache_find_by_name(crec
, host_name
, 0, flags
| F_CNAME
)))
1224 /* check all addresses associated with name */
1225 if (crec
->flags
& (F_HOSTS
| F_CONFIG
))
1227 if (crec
->flags
& F_CNAME
)
1228 my_syslog(MS_DHCP
| LOG_WARNING
,
1229 _("%s is a CNAME, not giving it to the DHCP lease of %s"),
1230 host_name
, daemon
->addrbuff
);
1231 else if (memcmp(&crec
->addr
.addr
, host_address
, addrlen
) == 0)
1236 else if (!(crec
->flags
& F_DHCP
))
1238 cache_scan_free(host_name
, NULL
, 0, crec
->flags
& (flags
| F_CNAME
| F_FORWARD
));
1239 /* scan_free deletes all addresses associated with name */
1244 /* if in hosts, don't need DHCP record */
1248 /* Name in hosts, address doesn't match */
1251 inet_ntop(prot
, &fail_crec
->addr
.addr
, daemon
->namebuff
, MAXDNAME
);
1252 my_syslog(MS_DHCP
| LOG_WARNING
,
1253 _("not giving name %s to the DHCP lease of %s because "
1254 "the name exists in %s with address %s"),
1255 host_name
, daemon
->addrbuff
,
1256 record_source(fail_crec
->uid
), daemon
->namebuff
);
1260 if ((crec
= cache_find_by_addr(NULL
, (struct all_addr
*)host_address
, 0, flags
)))
1262 if (crec
->flags
& F_NEG
)
1265 cache_scan_free(NULL
, (struct all_addr
*)host_address
, 0, flags
);
1271 if ((crec
= dhcp_spare
))
1272 dhcp_spare
= dhcp_spare
->next
;
1273 else /* need new one */
1274 crec
= whine_malloc(sizeof(struct crec
));
1276 if (crec
) /* malloc may fail */
1278 crec
->flags
= flags
| F_NAMEP
| F_DHCP
| F_FORWARD
;
1280 crec
->flags
|= F_IMMORTAL
;
1283 crec
->addr
.addr
= *host_address
;
1284 crec
->name
.namep
= host_name
;
1285 crec
->uid
= next_uid();
1288 add_dhcp_cname(crec
, ttd
);
1293 int cache_make_stat(struct txt_record
*t
)
1295 static char *buff
= NULL
;
1296 static int bufflen
= 60;
1298 struct server
*serv
, *serv1
;
1301 if (!buff
&& !(buff
= whine_malloc(60)))
1308 case TXT_STAT_CACHESIZE
:
1309 sprintf(buff
+1, "%d", daemon
->cachesize
);
1312 case TXT_STAT_INSERTS
:
1313 sprintf(buff
+1, "%d", cache_inserted
);
1316 case TXT_STAT_EVICTIONS
:
1317 sprintf(buff
+1, "%d", cache_live_freed
);
1320 case TXT_STAT_MISSES
:
1321 sprintf(buff
+1, "%u", daemon
->queries_forwarded
);
1325 sprintf(buff
+1, "%u", daemon
->local_answer
);
1330 sprintf(buff
+1, "%u", daemon
->auth_answer
);
1334 case TXT_STAT_SERVERS
:
1335 /* sum counts from different records for same server */
1336 for (serv
= daemon
->servers
; serv
; serv
= serv
->next
)
1337 serv
->flags
&= ~SERV_COUNTED
;
1339 for (serv
= daemon
->servers
; serv
; serv
= serv
->next
)
1341 (SERV_NO_ADDR
| SERV_LITERAL_ADDRESS
| SERV_COUNTED
| SERV_USE_RESOLV
| SERV_NO_REBIND
)))
1344 int port
, newlen
, bytes_avail
, bytes_needed
;
1345 unsigned int queries
= 0, failed_queries
= 0;
1346 for (serv1
= serv
; serv1
; serv1
= serv1
->next
)
1347 if (!(serv1
->flags
&
1348 (SERV_NO_ADDR
| SERV_LITERAL_ADDRESS
| SERV_COUNTED
| SERV_USE_RESOLV
| SERV_NO_REBIND
)) &&
1349 sockaddr_isequal(&serv
->addr
, &serv1
->addr
))
1351 serv1
->flags
|= SERV_COUNTED
;
1352 queries
+= serv1
->queries
;
1353 failed_queries
+= serv1
->failed_queries
;
1355 port
= prettyprint_addr(&serv
->addr
, daemon
->addrbuff
);
1356 lenp
= p
++; /* length */
1357 bytes_avail
= bufflen
- (p
- buff
);
1358 bytes_needed
= snprintf(p
, bytes_avail
, "%s#%d %u %u", daemon
->addrbuff
, port
, queries
, failed_queries
);
1359 if (bytes_needed
>= bytes_avail
)
1361 /* expand buffer if necessary */
1362 newlen
= bytes_needed
+ 1 + bufflen
- bytes_avail
;
1363 if (!(new = whine_malloc(newlen
)))
1365 memcpy(new, buff
, bufflen
);
1367 p
= new + (p
- buff
);
1371 bytes_avail
= bufflen
- (p
- buff
);
1372 bytes_needed
= snprintf(p
, bytes_avail
, "%s#%d %u %u", daemon
->addrbuff
, port
, queries
, failed_queries
);
1374 *lenp
= bytes_needed
;
1377 t
->txt
= (unsigned char *)buff
;
1382 len
= strlen(buff
+1);
1383 t
->txt
= (unsigned char *)buff
;
1389 /* There can be names in the cache containing control chars, don't
1390 mess up logging or open security holes. */
1391 static char *sanitise(char *name
)
1395 for (r
= (unsigned char *)name
; *r
; r
++)
1396 if (!isprint((int)*r
))
1397 return "<name unprintable>";
1403 void dump_cache(time_t now
)
1405 struct server
*serv
, *serv1
;
1408 my_syslog(LOG_INFO
, _("time %lu"), (unsigned long)now
);
1409 my_syslog(LOG_INFO
, _("cache size %d, %d/%d cache insertions re-used unexpired cache entries."),
1410 daemon
->cachesize
, cache_live_freed
, cache_inserted
);
1411 my_syslog(LOG_INFO
, _("queries forwarded %u, queries answered locally %u"),
1412 daemon
->queries_forwarded
, daemon
->local_answer
);
1414 my_syslog(LOG_INFO
, _("queries for authoritative zones %u"), daemon
->auth_answer
);
1420 /* sum counts from different records for same server */
1421 for (serv
= daemon
->servers
; serv
; serv
= serv
->next
)
1422 serv
->flags
&= ~SERV_COUNTED
;
1424 for (serv
= daemon
->servers
; serv
; serv
= serv
->next
)
1426 (SERV_NO_ADDR
| SERV_LITERAL_ADDRESS
| SERV_COUNTED
| SERV_USE_RESOLV
| SERV_NO_REBIND
)))
1429 unsigned int queries
= 0, failed_queries
= 0;
1430 for (serv1
= serv
; serv1
; serv1
= serv1
->next
)
1431 if (!(serv1
->flags
&
1432 (SERV_NO_ADDR
| SERV_LITERAL_ADDRESS
| SERV_COUNTED
| SERV_USE_RESOLV
| SERV_NO_REBIND
)) &&
1433 sockaddr_isequal(&serv
->addr
, &serv1
->addr
))
1435 serv1
->flags
|= SERV_COUNTED
;
1436 queries
+= serv1
->queries
;
1437 failed_queries
+= serv1
->failed_queries
;
1439 port
= prettyprint_addr(&serv
->addr
, daemon
->addrbuff
);
1440 my_syslog(LOG_INFO
, _("server %s#%d: queries sent %u, retried or failed %u"), daemon
->addrbuff
, port
, queries
, failed_queries
);
1443 if (option_bool(OPT_DEBUG
) || option_bool(OPT_LOG
) || daemon
->hosts_cache
!= NULL
)
1445 struct crec
*cache
;
1447 int dumping_hosts
= daemon
->hosts_cache
!= NULL
;
1448 FILE *hosts_cache
= NULL
;
1449 if (dumping_hosts
) {
1450 hosts_cache
= fopen(daemon
->hosts_cache
, "w");
1451 if (hosts_cache
== NULL
) {
1453 my_syslog(LOG_WARNING
, "Failed to open hosts cache file: \"%s\"", daemon
->hosts_cache
);
1457 my_syslog(LOG_INFO
, "Host Address Flags Expires");
1459 for (i
=0; i
<hash_size
; i
++)
1460 for (cache
= hash_table
[i
]; cache
; cache
= cache
->hash_next
)
1462 char *a
= daemon
->addrbuff
, *p
= daemon
->namebuff
, *n
= cache_get_name(cache
);
1464 if (strlen(n
) == 0 && !(cache
->flags
& F_REVERSE
))
1466 p
+= sprintf(p
, "%-30.30s ", sanitise(n
));
1467 if ((cache
->flags
& F_CNAME
))
1469 if (!is_outdated_cname_pointer(cache
))
1470 a
= cache_get_cname_target(cache
);
1472 fprintf(hosts_cache
, "#%s\t%s\n", cache_get_cname_target(cache
), n
);
1475 else if (cache
->flags
& F_DS
)
1477 if (!(cache
->flags
& F_NEG
))
1478 sprintf(a
, "%5u %3u %3u", cache
->addr
.ds
.keytag
,
1479 cache
->addr
.ds
.algo
, cache
->addr
.ds
.digest
);
1481 else if (cache
->flags
& F_DNSKEY
)
1482 sprintf(a
, "%5u %3u %3u", cache
->addr
.key
.keytag
,
1483 cache
->addr
.key
.algo
, cache
->addr
.key
.flags
);
1485 else if (!(cache
->flags
& F_NEG
) || !(cache
->flags
& F_FORWARD
))
1487 a
= daemon
->addrbuff
;
1488 if (cache
->flags
& F_IPV4
)
1489 inet_ntop(AF_INET
, &cache
->addr
.addr
, a
, ADDRSTRLEN
);
1491 else if (cache
->flags
& F_IPV6
)
1492 inet_ntop(AF_INET6
, &cache
->addr
.addr
, a
, ADDRSTRLEN
);
1495 fprintf(hosts_cache
, "%s\t%s\n", a
, n
);
1498 if (cache
->flags
& F_IPV4
)
1500 else if (cache
->flags
& F_IPV6
)
1502 else if (cache
->flags
& F_CNAME
)
1505 else if (cache
->flags
& F_DS
)
1507 else if (cache
->flags
& F_DNSKEY
)
1510 p
+= sprintf(p
, "%-40.40s %s%s%s%s%s%s%s%s%s ", a
, t
,
1511 cache
->flags
& F_FORWARD
? "F" : " ",
1512 cache
->flags
& F_REVERSE
? "R" : " ",
1513 cache
->flags
& F_IMMORTAL
? "I" : " ",
1514 cache
->flags
& F_DHCP
? "D" : " ",
1515 cache
->flags
& F_NEG
? "N" : " ",
1516 cache
->flags
& F_NXDOMAIN
? "X" : " ",
1517 cache
->flags
& F_HOSTS
? "H" : " ",
1518 cache
->flags
& F_DNSSECOK
? "V" : " ");
1519 #ifdef HAVE_BROKEN_RTC
1520 p
+= sprintf(p
, "%lu", cache
->flags
& F_IMMORTAL
? 0: (unsigned long)(cache
->ttd
- now
));
1522 p
+= sprintf(p
, "%s", cache
->flags
& F_IMMORTAL
? "\n" : ctime(&(cache
->ttd
)));
1523 /* ctime includes trailing \n - eat it */
1526 my_syslog(LOG_INFO
, daemon
->namebuff
);
1529 fclose(hosts_cache
);
1533 char *record_source(unsigned int index
)
1535 struct hostsfile
*ah
;
1537 if (index
== SRC_CONFIG
)
1539 else if (index
== SRC_HOSTS
)
1542 for (ah
= daemon
->addn_hosts
; ah
; ah
= ah
->next
)
1543 if (ah
->index
== index
)
1547 for (ah
= daemon
->dynamic_dirs
; ah
; ah
= ah
->next
)
1548 if (ah
->index
== index
)
1555 char *querystr(char *desc
, unsigned short type
)
1558 int len
= 10; /* strlen("type=xxxxx") */
1559 const char *types
= NULL
;
1560 static char *buff
= NULL
;
1561 static int bufflen
= 0;
1563 for (i
= 0; i
< (sizeof(typestr
)/sizeof(typestr
[0])); i
++)
1564 if (typestr
[i
].type
== type
)
1566 types
= typestr
[i
].name
;
1567 len
= strlen(types
);
1571 len
+= 3; /* braces, terminator */
1572 len
+= strlen(desc
);
1574 if (!buff
|| bufflen
< len
)
1581 buff
= whine_malloc(len
);
1588 sprintf(buff
, "%s[%s]", desc
, types
);
1590 sprintf(buff
, "%s[type=%d]", desc
, type
);
1593 return buff
? buff
: "";
1596 void log_query(unsigned int flags
, char *name
, struct all_addr
*addr
, char *arg
)
1598 char *source
, *dest
= daemon
->addrbuff
;
1601 if (!option_bool(OPT_LOG
))
1604 name
= sanitise(name
);
1608 if (flags
& F_KEYTAG
)
1609 sprintf(daemon
->addrbuff
, arg
, addr
->addr
.log
.keytag
, addr
->addr
.log
.algo
, addr
->addr
.log
.digest
);
1613 inet_ntop(flags
& F_IPV4
? AF_INET
: AF_INET6
,
1614 addr
, daemon
->addrbuff
, ADDRSTRLEN
);
1616 strncpy(daemon
->addrbuff
, inet_ntoa(addr
->addr
.addr4
), ADDRSTRLEN
);
1623 if (flags
& F_REVERSE
)
1626 name
= daemon
->addrbuff
;
1631 if (flags
& F_NXDOMAIN
)
1636 dest
= "NODATA-IPv4";
1637 else if (flags
& F_IPV6
)
1638 dest
= "NODATA-IPv6";
1643 else if (flags
& F_CNAME
)
1645 else if (flags
& F_RRNAME
)
1648 if (flags
& F_CONFIG
)
1650 else if (flags
& F_DHCP
)
1652 else if (flags
& F_HOSTS
)
1654 else if (flags
& F_UPSTREAM
)
1656 else if (flags
& F_SECSTAT
)
1657 source
= "validation";
1658 else if (flags
& F_AUTH
)
1660 else if (flags
& F_SERVER
)
1662 source
= "forwarded";
1665 else if (flags
& F_QUERY
)
1670 else if (flags
& F_DNSSEC
)
1675 else if (flags
& F_IPSET
)
1677 source
= "ipset add";
1680 verb
= daemon
->addrbuff
;
1685 if (strlen(name
) == 0)
1688 if (option_bool(OPT_EXTRALOG
))
1690 int port
= prettyprint_addr(daemon
->log_source_addr
, daemon
->addrbuff2
);
1691 if (flags
& F_NOEXTRA
)
1692 my_syslog(LOG_INFO
, "* %s/%u %s %s %s %s", daemon
->addrbuff2
, port
, source
, name
, verb
, dest
);
1694 my_syslog(LOG_INFO
, "%u %s/%u %s %s %s %s", daemon
->log_display_id
, daemon
->addrbuff2
, port
, source
, name
, verb
, dest
);
1697 my_syslog(LOG_INFO
, "%s %s %s %s", source
, name
, verb
, dest
);