]>
git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/cache.c
1 /* dnsmasq is Copyright (c) 2000-2015 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
)
193 if (crecp
->flags
& F_DS
)
194 blockdata_free(crecp
->addr
.sig
.keydata
);
196 blockdata_free(crecp
->addr
.key
.keydata
);
198 else if ((crecp
->flags
& F_DS
) && !(crecp
->flags
& F_NEG
))
199 blockdata_free(crecp
->addr
.ds
.keydata
);
203 static void cache_free(struct crec
*crecp
)
205 crecp
->flags
&= ~F_FORWARD
;
206 crecp
->flags
&= ~F_REVERSE
;
207 crecp
->uid
= next_uid(); /* invalidate CNAMES pointing to this. */
210 cache_tail
->next
= crecp
;
213 crecp
->prev
= cache_tail
;
217 /* retrieve big name for further use. */
218 if (crecp
->flags
& F_BIGNAME
)
220 crecp
->name
.bname
->next
= big_free
;
221 big_free
= crecp
->name
.bname
;
222 crecp
->flags
&= ~F_BIGNAME
;
226 cache_blockdata_free(crecp
);
230 /* insert a new cache entry at the head of the list (youngest entry) */
231 static void cache_link(struct crec
*crecp
)
233 if (cache_head
) /* check needed for init code */
234 cache_head
->prev
= crecp
;
235 crecp
->next
= cache_head
;
242 /* remove an arbitrary cache entry for promotion */
243 static void cache_unlink (struct crec
*crecp
)
246 crecp
->prev
->next
= crecp
->next
;
248 cache_head
= crecp
->next
;
251 crecp
->next
->prev
= crecp
->prev
;
253 cache_tail
= crecp
->prev
;
256 char *cache_get_name(struct crec
*crecp
)
258 if (crecp
->flags
& F_BIGNAME
)
259 return crecp
->name
.bname
->name
;
260 else if (crecp
->flags
& F_NAMEP
)
261 return crecp
->name
.namep
;
263 return crecp
->name
.sname
;
266 char *cache_get_cname_target(struct crec
*crecp
)
268 if (crecp
->addr
.cname
.uid
!= SRC_INTERFACE
)
269 return cache_get_name(crecp
->addr
.cname
.target
.cache
);
271 return crecp
->addr
.cname
.target
.int_name
->name
;
276 struct crec
*cache_enumerate(int init
)
279 static struct crec
*cache
;
286 else if (cache
&& cache
->hash_next
)
287 cache
= cache
->hash_next
;
291 while (bucket
< hash_size
)
292 if ((cache
= hash_table
[bucket
++]))
299 static int is_outdated_cname_pointer(struct crec
*crecp
)
301 if (!(crecp
->flags
& F_CNAME
) || crecp
->addr
.cname
.uid
== SRC_INTERFACE
)
304 /* NB. record may be reused as DS or DNSKEY, where uid is
305 overloaded for something completely different */
306 if (crecp
->addr
.cname
.target
.cache
&&
307 (crecp
->addr
.cname
.target
.cache
->flags
& (F_IPV4
| F_IPV6
| F_CNAME
)) &&
308 crecp
->addr
.cname
.uid
== crecp
->addr
.cname
.target
.cache
->uid
)
314 static int is_expired(time_t now
, struct crec
*crecp
)
316 if (crecp
->flags
& F_IMMORTAL
)
319 if (difftime(now
, crecp
->ttd
) < 0)
325 static struct crec
*cache_scan_free(char *name
, struct all_addr
*addr
, time_t now
, unsigned short flags
)
327 /* Scan and remove old entries.
328 If (flags & F_FORWARD) then remove any forward entries for name and any expired
329 entries but only in the same hash bucket as name.
330 If (flags & F_REVERSE) then remove any reverse entries for addr and any expired
331 entries in the whole cache.
332 If (flags == 0) remove any expired entries in the whole cache.
334 In the flags & F_FORWARD case, the return code is valid, and returns a non-NULL pointer
335 to a cache entry if the name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
337 We take advantage of the fact that hash chains have stuff in the order <reverse>,<other>,<immortal>
338 so that when we hit an entry which isn't reverse and is immortal, we're done. */
340 struct crec
*crecp
, **up
;
342 if (flags
& F_FORWARD
)
344 for (up
= hash_bucket(name
), crecp
= *up
; crecp
; crecp
= crecp
->hash_next
)
346 if (is_expired(now
, crecp
) || is_outdated_cname_pointer(crecp
))
348 *up
= crecp
->hash_next
;
349 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
)))
357 if ((crecp
->flags
& F_FORWARD
) && hostname_isequal(cache_get_name(crecp
), name
))
359 /* Don't delete DNSSEC in favour of a CNAME, they can co-exist */
360 if ((flags
& crecp
->flags
& (F_IPV4
| F_IPV6
)) ||
361 (((crecp
->flags
| flags
) & F_CNAME
) && !(crecp
->flags
& (F_DNSKEY
| F_DS
))))
363 if (crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
))
365 *up
= crecp
->hash_next
;
372 /* Deletion has to be class-sensitive for DS, DNSKEY, RRSIG, also
373 type-covered sensitive for RRSIG */
374 if ((flags
& (F_DNSKEY
| F_DS
)) &&
375 (flags
& (F_DNSKEY
| F_DS
)) == (crecp
->flags
& (F_DNSKEY
| F_DS
)) &&
376 crecp
->uid
== addr
->addr
.dnssec
.class &&
377 (!((flags
& (F_DS
| F_DNSKEY
)) == (F_DS
| F_DNSKEY
)) ||
378 crecp
->addr
.sig
.type_covered
== addr
->addr
.dnssec
.type
))
380 if (crecp
->flags
& F_CONFIG
)
382 *up
= crecp
->hash_next
;
389 up
= &crecp
->hash_next
;
396 int addrlen
= (flags
& F_IPV6
) ? IN6ADDRSZ
: INADDRSZ
;
398 int addrlen
= INADDRSZ
;
400 for (i
= 0; i
< hash_size
; i
++)
401 for (crecp
= hash_table
[i
], up
= &hash_table
[i
];
402 crecp
&& ((crecp
->flags
& F_REVERSE
) || !(crecp
->flags
& F_IMMORTAL
));
403 crecp
= crecp
->hash_next
)
404 if (is_expired(now
, crecp
))
406 *up
= crecp
->hash_next
;
407 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
)))
413 else if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
)) &&
414 (flags
& crecp
->flags
& F_REVERSE
) &&
415 (flags
& crecp
->flags
& (F_IPV4
| F_IPV6
)) &&
416 memcmp(&crecp
->addr
.addr
, addr
, addrlen
) == 0)
418 *up
= crecp
->hash_next
;
423 up
= &crecp
->hash_next
;
429 /* Note: The normal calling sequence is
434 but an abort can cause the cache_end_insert to be missed
435 in which can the next cache_start_insert cleans things up. */
437 void cache_start_insert(void)
439 /* Free any entries which didn't get committed during the last
444 struct crec
*tmp
= new_chain
->next
;
445 cache_free(new_chain
);
452 struct crec
*cache_insert(char *name
, struct all_addr
*addr
,
453 time_t now
, unsigned long ttl
, unsigned short flags
)
456 union bigname
*big_name
= NULL
;
457 int freed_all
= flags
& F_REVERSE
;
460 /* Don't log DNSSEC records here, done elsewhere */
461 if (flags
& (F_IPV4
| F_IPV6
| F_CNAME
))
463 log_query(flags
| F_UPSTREAM
, name
, addr
, NULL
);
464 /* Don't mess with TTL for DNSSEC records. */
465 if (daemon
->max_cache_ttl
!= 0 && daemon
->max_cache_ttl
< ttl
)
466 ttl
= daemon
->max_cache_ttl
;
467 if (daemon
->min_cache_ttl
!= 0 && daemon
->min_cache_ttl
> ttl
)
468 ttl
= daemon
->min_cache_ttl
;
471 /* if previous insertion failed give up now. */
475 /* First remove any expired entries and entries for the name/address we
476 are currently inserting. */
477 if ((new = cache_scan_free(name
, addr
, now
, flags
)))
479 /* We're trying to insert a record over one from
480 /etc/hosts or DHCP, or other config. If the
481 existing record is for an A or AAAA and
482 the record we're trying to insert is the same,
483 just drop the insert, but don't error the whole process. */
484 if ((flags
& (F_IPV4
| F_IPV6
)) && (flags
& F_FORWARD
))
486 if ((flags
& F_IPV4
) && (new->flags
& F_IPV4
) &&
487 new->addr
.addr
.addr
.addr4
.s_addr
== addr
->addr
.addr4
.s_addr
)
490 else if ((flags
& F_IPV6
) && (new->flags
& F_IPV6
) &&
491 IN6_ARE_ADDR_EQUAL(&new->addr
.addr
.addr
.addr6
, &addr
->addr
.addr6
))
500 /* Now get a cache entry from the end of the LRU list */
502 if (!(new = cache_tail
)) /* no entries left - cache is too small, bail */
508 /* End of LRU list is still in use: if we didn't scan all the hash
509 chains for expired entries do that now. If we already tried that
510 then it's time to start spilling things. */
512 if (new->flags
& (F_FORWARD
| F_REVERSE
))
514 /* If free_avail set, we believe that an entry has been freed.
515 Bugs have been known to make this not true, resulting in
516 a tight loop here. If that happens, abandon the
517 insert. Once in this state, all inserts will probably fail. */
520 static int warned
= 0;
523 my_syslog(LOG_ERR
, _("Internal error in cache."));
532 struct all_addr free_addr
= new->addr
.addr
;;
535 /* For DNSSEC records, addr holds class and type_covered for RRSIG */
536 if (new->flags
& (F_DS
| F_DNSKEY
))
538 free_addr
.addr
.dnssec
.class = new->uid
;
539 if ((new->flags
& (F_DS
| F_DNSKEY
)) == (F_DS
| F_DNSKEY
))
540 free_addr
.addr
.dnssec
.type
= new->addr
.sig
.type_covered
;
544 free_avail
= 1; /* Must be free space now. */
545 cache_scan_free(cache_get_name(new), &free_addr
, now
, new->flags
);
550 cache_scan_free(NULL
, NULL
, now
, 0);
556 /* Check if we need to and can allocate extra memory for a long name.
557 If that fails, give up now, always succeed for DNSSEC records. */
558 if (name
&& (strlen(name
) > SMALLDNAME
-1))
563 big_free
= big_free
->next
;
565 else if ((bignames_left
== 0 && !(flags
& (F_DS
| F_DNSKEY
))) ||
566 !(big_name
= (union bigname
*)whine_malloc(sizeof(union bigname
))))
571 else if (bignames_left
!= 0)
576 /* Got the rest: finally grab entry. */
584 new->name
.bname
= big_name
;
585 new->flags
|= F_BIGNAME
;
589 strcpy(cache_get_name(new), name
);
591 *cache_get_name(new) = 0;
596 if (flags
& (F_DS
| F_DNSKEY
))
597 new->uid
= addr
->addr
.dnssec
.class;
600 new->addr
.addr
= *addr
;
603 new->ttd
= now
+ (time_t)ttl
;
604 new->next
= new_chain
;
610 /* after end of insertion, commit the new entries */
611 void cache_end_insert(void)
618 struct crec
*tmp
= new_chain
->next
;
619 /* drop CNAMEs which didn't find a target. */
620 if (is_outdated_cname_pointer(new_chain
))
621 cache_free(new_chain
);
624 cache_hash(new_chain
);
625 cache_link(new_chain
);
633 struct crec
*cache_find_by_name(struct crec
*crecp
, char *name
, time_t now
, unsigned int prot
)
636 int no_rr
= prot
& F_NO_RR
;
640 if (crecp
) /* iterating */
644 /* first search, look for relevant entries and push to top of list
645 also free anything which has expired */
646 struct crec
*next
, **up
, **insert
= NULL
, **chainp
= &ans
;
647 unsigned short ins_flags
= 0;
649 for (up
= hash_bucket(name
), crecp
= *up
; crecp
; crecp
= next
)
651 next
= crecp
->hash_next
;
653 if (!is_expired(now
, crecp
) && !is_outdated_cname_pointer(crecp
))
655 if ((crecp
->flags
& F_FORWARD
) &&
657 (((crecp
->flags
& (F_DNSKEY
| F_DS
)) == (prot
& (F_DNSKEY
| F_DS
))) || (prot
& F_NSIGMATCH
)) &&
659 (crecp
->flags
& prot
) &&
660 hostname_isequal(cache_get_name(crecp
), name
))
662 if (crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
))
665 chainp
= &crecp
->next
;
673 /* Move all but the first entry up the hash chain
674 this implements round-robin.
675 Make sure that re-ordering doesn't break the hash-chain
678 if (insert
&& (crecp
->flags
& (F_REVERSE
| F_IMMORTAL
)) == ins_flags
)
680 *up
= crecp
->hash_next
;
681 crecp
->hash_next
= *insert
;
683 insert
= &crecp
->hash_next
;
687 if (!insert
&& !no_rr
)
690 ins_flags
= crecp
->flags
& (F_REVERSE
| F_IMMORTAL
);
692 up
= &crecp
->hash_next
;
696 /* case : not expired, incorrect entry. */
697 up
= &crecp
->hash_next
;
701 /* expired entry, free it */
702 *up
= crecp
->hash_next
;
703 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
)))
711 *chainp
= cache_head
;
715 (ans
->flags
& F_FORWARD
) &&
717 (((ans
->flags
& (F_DNSKEY
| F_DS
)) == (prot
& (F_DNSKEY
| F_DS
))) || (prot
& F_NSIGMATCH
)) &&
719 (ans
->flags
& prot
) &&
720 hostname_isequal(cache_get_name(ans
), name
))
726 struct crec
*cache_find_by_addr(struct crec
*crecp
, struct all_addr
*addr
,
727 time_t now
, unsigned int prot
)
731 int addrlen
= (prot
== F_IPV6
) ? IN6ADDRSZ
: INADDRSZ
;
733 int addrlen
= INADDRSZ
;
736 if (crecp
) /* iterating */
740 /* first search, look for relevant entries and push to top of list
741 also free anything which has expired. All the reverse entries are at the
742 start of the hash chain, so we can give up when we find the first
745 struct crec
**up
, **chainp
= &ans
;
747 for (i
=0; i
<hash_size
; i
++)
748 for (crecp
= hash_table
[i
], up
= &hash_table
[i
];
749 crecp
&& (crecp
->flags
& F_REVERSE
);
750 crecp
= crecp
->hash_next
)
751 if (!is_expired(now
, crecp
))
753 if ((crecp
->flags
& prot
) &&
754 memcmp(&crecp
->addr
.addr
, addr
, addrlen
) == 0)
756 if (crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
))
759 chainp
= &crecp
->next
;
767 up
= &crecp
->hash_next
;
771 *up
= crecp
->hash_next
;
772 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
| F_CONFIG
)))
779 *chainp
= cache_head
;
783 (ans
->flags
& F_REVERSE
) &&
784 (ans
->flags
& prot
) &&
785 memcmp(&ans
->addr
.addr
, addr
, addrlen
) == 0)
791 static void add_hosts_cname(struct crec
*target
)
796 for (a
= daemon
->cnames
; a
; a
= a
->next
)
797 if (hostname_isequal(cache_get_name(target
), a
->target
) &&
798 (crec
= whine_malloc(sizeof(struct crec
))))
800 crec
->flags
= F_FORWARD
| F_IMMORTAL
| F_NAMEP
| F_CONFIG
| F_CNAME
;
801 crec
->name
.namep
= a
->alias
;
802 crec
->addr
.cname
.target
.cache
= target
;
803 crec
->addr
.cname
.uid
= target
->uid
;
804 crec
->uid
= next_uid();
806 add_hosts_cname(crec
); /* handle chains */
810 static void add_hosts_entry(struct crec
*cache
, struct all_addr
*addr
, int addrlen
,
811 unsigned int index
, struct crec
**rhash
, int hashsz
)
813 struct crec
*lookup
= cache_find_by_name(NULL
, cache_get_name(cache
), 0, cache
->flags
& (F_IPV4
| F_IPV6
));
814 int i
, nameexists
= 0;
817 /* Remove duplicates in hosts files. */
818 if (lookup
&& (lookup
->flags
& F_HOSTS
))
821 if (memcmp(&lookup
->addr
.addr
, addr
, addrlen
) == 0)
828 /* Ensure there is only one address -> name mapping (first one trumps)
829 We do this by steam here, The entries are kept in hash chains, linked
830 by ->next (which is unused at this point) held in hash buckets in
831 the array rhash, hashed on address. Note that rhash and the values
832 in ->next are only valid whilst reading hosts files: the buckets are
833 then freed, and the ->next pointer used for other things.
835 Only insert each unique address once into this hashing structure.
837 This complexity avoids O(n^2) divergent CPU use whilst reading
838 large (10000 entry) hosts files.
840 Note that we only do this process when bulk-reading hosts files,
841 for incremental reads, rhash is NULL, and we use cache lookups
848 for (j
= 0, i
= 0; i
< addrlen
; i
++)
849 j
= (j
*2 +((unsigned char *)addr
)[i
]) % hashsz
;
851 for (lookup
= rhash
[j
]; lookup
; lookup
= lookup
->next
)
852 if ((lookup
->flags
& cache
->flags
& (F_IPV4
| F_IPV6
)) &&
853 memcmp(&lookup
->addr
.addr
, addr
, addrlen
) == 0)
855 cache
->flags
&= ~F_REVERSE
;
859 /* maintain address hash chain, insert new unique address */
862 cache
->next
= rhash
[j
];
868 /* incremental read, lookup in cache */
869 lookup
= cache_find_by_addr(NULL
, addr
, 0, cache
->flags
& (F_IPV4
| F_IPV6
));
870 if (lookup
&& lookup
->flags
& F_HOSTS
)
871 cache
->flags
&= ~F_REVERSE
;
875 memcpy(&cache
->addr
.addr
, addr
, addrlen
);
878 /* don't need to do alias stuff for second and subsequent addresses. */
880 add_hosts_cname(cache
);
883 static int eatspace(FILE *f
)
889 if ((c
= getc(f
)) == '#')
890 while (c
!= '\n' && c
!= EOF
)
907 static int gettok(FILE *f
, char *token
)
913 if ((c
= getc(f
)) == EOF
)
914 return (count
== 0) ? EOF
: 1;
916 if (isspace(c
) || c
== '#')
922 if (count
< (MAXDNAME
- 1))
930 int read_hostsfile(char *filename
, unsigned int index
, int cache_size
, struct crec
**rhash
, int hashsz
)
932 FILE *f
= fopen(filename
, "r");
933 char *token
= daemon
->namebuff
, *domain_suffix
= NULL
;
934 int addr_count
= 0, name_count
= cache_size
, lineno
= 0;
935 unsigned short flags
= 0;
936 struct all_addr addr
;
937 int atnl
, addrlen
= 0;
941 my_syslog(LOG_ERR
, _("failed to load names from %s: %s"), filename
, strerror(errno
));
947 while ((atnl
= gettok(f
, token
)) != EOF
)
951 if (inet_pton(AF_INET
, token
, &addr
) > 0)
953 flags
= F_HOSTS
| F_IMMORTAL
| F_FORWARD
| F_REVERSE
| F_IPV4
;
955 domain_suffix
= get_domain(addr
.addr
.addr4
);
958 else if (inet_pton(AF_INET6
, token
, &addr
) > 0)
960 flags
= F_HOSTS
| F_IMMORTAL
| F_FORWARD
| F_REVERSE
| F_IPV6
;
962 domain_suffix
= get_domain6(&addr
.addr
.addr6
);
967 my_syslog(LOG_ERR
, _("bad address at %s line %d"), filename
, lineno
);
969 atnl
= gettok(f
, token
);
975 /* rehash every 1000 names. */
976 if (rhash
&& ((name_count
- cache_size
) > 1000))
979 cache_size
= name_count
;
988 if ((atnl
= gettok(f
, token
)) == EOF
)
991 fqdn
= !!strchr(token
, '.');
993 if ((canon
= canonicalise(token
, &nomem
)))
995 /* If set, add a version of the name with a default domain appended */
996 if (option_bool(OPT_EXPAND
) && domain_suffix
&& !fqdn
&&
997 (cache
= whine_malloc(sizeof(struct crec
) +
998 strlen(canon
)+2+strlen(domain_suffix
)-SMALLDNAME
)))
1000 strcpy(cache
->name
.sname
, canon
);
1001 strcat(cache
->name
.sname
, ".");
1002 strcat(cache
->name
.sname
, domain_suffix
);
1003 cache
->flags
= flags
;
1004 add_hosts_entry(cache
, &addr
, addrlen
, index
, rhash
, hashsz
);
1007 if ((cache
= whine_malloc(sizeof(struct crec
) + strlen(canon
)+1-SMALLDNAME
)))
1009 strcpy(cache
->name
.sname
, canon
);
1010 cache
->flags
= flags
;
1011 add_hosts_entry(cache
, &addr
, addrlen
, index
, rhash
, hashsz
);
1018 my_syslog(LOG_ERR
, _("bad name at %s line %d"), filename
, lineno
);
1027 my_syslog(LOG_INFO
, _("read %s - %d addresses"), filename
, addr_count
);
1032 void cache_reload(void)
1034 struct crec
*cache
, **up
, *tmp
;
1035 int revhashsz
, i
, total_size
= daemon
->cachesize
;
1036 struct hostsfile
*ah
;
1037 struct host_record
*hr
;
1038 struct name_list
*nl
;
1040 struct interface_name
*intr
;
1042 struct ds_config
*ds
;
1045 cache_inserted
= cache_live_freed
= 0;
1047 for (i
=0; i
<hash_size
; i
++)
1048 for (cache
= hash_table
[i
], up
= &hash_table
[i
]; cache
; cache
= tmp
)
1051 cache_blockdata_free(cache
);
1053 tmp
= cache
->hash_next
;
1054 if (cache
->flags
& (F_HOSTS
| F_CONFIG
))
1056 *up
= cache
->hash_next
;
1059 else if (!(cache
->flags
& F_DHCP
))
1061 *up
= cache
->hash_next
;
1062 if (cache
->flags
& F_BIGNAME
)
1064 cache
->name
.bname
->next
= big_free
;
1065 big_free
= cache
->name
.bname
;
1070 up
= &cache
->hash_next
;
1073 /* Add CNAMEs to interface_names to the cache */
1074 for (a
= daemon
->cnames
; a
; a
= a
->next
)
1075 for (intr
= daemon
->int_names
; intr
; intr
= intr
->next
)
1076 if (hostname_isequal(a
->target
, intr
->name
) &&
1077 ((cache
= whine_malloc(sizeof(struct crec
)))))
1079 cache
->flags
= F_FORWARD
| F_NAMEP
| F_CNAME
| F_IMMORTAL
| F_CONFIG
;
1080 cache
->name
.namep
= a
->alias
;
1081 cache
->addr
.cname
.target
.int_name
= intr
;
1082 cache
->addr
.cname
.uid
= SRC_INTERFACE
;
1083 cache
->uid
= next_uid();
1085 add_hosts_cname(cache
); /* handle chains */
1089 for (ds
= daemon
->ds
; ds
; ds
= ds
->next
)
1090 if ((cache
= whine_malloc(sizeof(struct crec
))) &&
1091 (cache
->addr
.ds
.keydata
= blockdata_alloc(ds
->digest
, ds
->digestlen
)))
1093 cache
->flags
= F_FORWARD
| F_IMMORTAL
| F_DS
| F_CONFIG
| F_NAMEP
;
1094 cache
->name
.namep
= ds
->name
;
1095 cache
->addr
.ds
.keylen
= ds
->digestlen
;
1096 cache
->addr
.ds
.algo
= ds
->algo
;
1097 cache
->addr
.ds
.keytag
= ds
->keytag
;
1098 cache
->addr
.ds
.digest
= ds
->digest_type
;
1099 cache
->uid
= ds
->class;
1104 /* borrow the packet buffer for a temporary by-address hash */
1105 memset(daemon
->packet
, 0, daemon
->packet_buff_sz
);
1106 revhashsz
= daemon
->packet_buff_sz
/ sizeof(struct crec
*);
1107 /* we overwrote the buffer... */
1108 daemon
->srv_save
= NULL
;
1110 /* Do host_records in config. */
1111 for (hr
= daemon
->host_records
; hr
; hr
= hr
->next
)
1112 for (nl
= hr
->names
; nl
; nl
= nl
->next
)
1114 if (hr
->addr
.s_addr
!= 0 &&
1115 (cache
= whine_malloc(sizeof(struct crec
))))
1117 cache
->name
.namep
= nl
->name
;
1118 cache
->flags
= F_HOSTS
| F_IMMORTAL
| F_FORWARD
| F_REVERSE
| F_IPV4
| F_NAMEP
| F_CONFIG
;
1119 add_hosts_entry(cache
, (struct all_addr
*)&hr
->addr
, INADDRSZ
, SRC_CONFIG
, (struct crec
**)daemon
->packet
, revhashsz
);
1122 if (!IN6_IS_ADDR_UNSPECIFIED(&hr
->addr6
) &&
1123 (cache
= whine_malloc(sizeof(struct crec
))))
1125 cache
->name
.namep
= nl
->name
;
1126 cache
->flags
= F_HOSTS
| F_IMMORTAL
| F_FORWARD
| F_REVERSE
| F_IPV6
| F_NAMEP
| F_CONFIG
;
1127 add_hosts_entry(cache
, (struct all_addr
*)&hr
->addr6
, IN6ADDRSZ
, SRC_CONFIG
, (struct crec
**)daemon
->packet
, revhashsz
);
1132 if (option_bool(OPT_NO_HOSTS
) && !daemon
->addn_hosts
)
1134 if (daemon
->cachesize
> 0)
1135 my_syslog(LOG_INFO
, _("cleared cache"));
1139 if (!option_bool(OPT_NO_HOSTS
))
1140 total_size
= read_hostsfile(HOSTSFILE
, SRC_HOSTS
, total_size
, (struct crec
**)daemon
->packet
, revhashsz
);
1142 daemon
->addn_hosts
= expand_filelist(daemon
->addn_hosts
);
1143 for (ah
= daemon
->addn_hosts
; ah
; ah
= ah
->next
)
1144 if (!(ah
->flags
& AH_INACTIVE
))
1145 total_size
= read_hostsfile(ah
->fname
, ah
->index
, total_size
, (struct crec
**)daemon
->packet
, revhashsz
);
1149 set_dynamic_inotify(AH_HOSTS
, total_size
, (struct crec
**)daemon
->packet
, revhashsz
);
1155 struct in_addr
a_record_from_hosts(char *name
, time_t now
)
1157 struct crec
*crecp
= NULL
;
1160 while ((crecp
= cache_find_by_name(crecp
, name
, now
, F_IPV4
)))
1161 if (crecp
->flags
& F_HOSTS
)
1162 return *(struct in_addr
*)&crecp
->addr
;
1164 my_syslog(MS_DHCP
| LOG_WARNING
, _("No IPv4 address found for %s"), name
);
1170 void cache_unhash_dhcp(void)
1172 struct crec
*cache
, **up
;
1175 for (i
=0; i
<hash_size
; i
++)
1176 for (cache
= hash_table
[i
], up
= &hash_table
[i
]; cache
; cache
= cache
->hash_next
)
1177 if (cache
->flags
& F_DHCP
)
1179 *up
= cache
->hash_next
;
1180 cache
->next
= dhcp_spare
;
1184 up
= &cache
->hash_next
;
1187 static void add_dhcp_cname(struct crec
*target
, time_t ttd
)
1189 struct crec
*aliasc
;
1192 for (a
= daemon
->cnames
; a
; a
= a
->next
)
1193 if (hostname_isequal(cache_get_name(target
), a
->target
))
1195 if ((aliasc
= dhcp_spare
))
1196 dhcp_spare
= dhcp_spare
->next
;
1197 else /* need new one */
1198 aliasc
= whine_malloc(sizeof(struct crec
));
1202 aliasc
->flags
= F_FORWARD
| F_NAMEP
| F_DHCP
| F_CNAME
| F_CONFIG
;
1204 aliasc
->flags
|= F_IMMORTAL
;
1207 aliasc
->name
.namep
= a
->alias
;
1208 aliasc
->addr
.cname
.target
.cache
= target
;
1209 aliasc
->addr
.cname
.uid
= target
->uid
;
1210 aliasc
->uid
= next_uid();
1212 add_dhcp_cname(aliasc
, ttd
);
1217 void cache_add_dhcp_entry(char *host_name
, int prot
,
1218 struct all_addr
*host_address
, time_t ttd
)
1220 struct crec
*crec
= NULL
, *fail_crec
= NULL
;
1221 unsigned short flags
= F_IPV4
;
1223 size_t addrlen
= sizeof(struct in_addr
);
1226 if (prot
== AF_INET6
)
1229 addrlen
= sizeof(struct in6_addr
);
1233 inet_ntop(prot
, host_address
, daemon
->addrbuff
, ADDRSTRLEN
);
1235 while ((crec
= cache_find_by_name(crec
, host_name
, 0, flags
| F_CNAME
)))
1237 /* check all addresses associated with name */
1238 if (crec
->flags
& (F_HOSTS
| F_CONFIG
))
1240 if (crec
->flags
& F_CNAME
)
1241 my_syslog(MS_DHCP
| LOG_WARNING
,
1242 _("%s is a CNAME, not giving it to the DHCP lease of %s"),
1243 host_name
, daemon
->addrbuff
);
1244 else if (memcmp(&crec
->addr
.addr
, host_address
, addrlen
) == 0)
1249 else if (!(crec
->flags
& F_DHCP
))
1251 cache_scan_free(host_name
, NULL
, 0, crec
->flags
& (flags
| F_CNAME
| F_FORWARD
));
1252 /* scan_free deletes all addresses associated with name */
1257 /* if in hosts, don't need DHCP record */
1261 /* Name in hosts, address doesn't match */
1264 inet_ntop(prot
, &fail_crec
->addr
.addr
, daemon
->namebuff
, MAXDNAME
);
1265 my_syslog(MS_DHCP
| LOG_WARNING
,
1266 _("not giving name %s to the DHCP lease of %s because "
1267 "the name exists in %s with address %s"),
1268 host_name
, daemon
->addrbuff
,
1269 record_source(fail_crec
->uid
), daemon
->namebuff
);
1273 if ((crec
= cache_find_by_addr(NULL
, (struct all_addr
*)host_address
, 0, flags
)))
1275 if (crec
->flags
& F_NEG
)
1278 cache_scan_free(NULL
, (struct all_addr
*)host_address
, 0, flags
);
1284 if ((crec
= dhcp_spare
))
1285 dhcp_spare
= dhcp_spare
->next
;
1286 else /* need new one */
1287 crec
= whine_malloc(sizeof(struct crec
));
1289 if (crec
) /* malloc may fail */
1291 crec
->flags
= flags
| F_NAMEP
| F_DHCP
| F_FORWARD
;
1293 crec
->flags
|= F_IMMORTAL
;
1296 crec
->addr
.addr
= *host_address
;
1297 crec
->name
.namep
= host_name
;
1298 crec
->uid
= next_uid();
1301 add_dhcp_cname(crec
, ttd
);
1306 int cache_make_stat(struct txt_record
*t
)
1308 static char *buff
= NULL
;
1309 static int bufflen
= 60;
1311 struct server
*serv
, *serv1
;
1314 if (!buff
&& !(buff
= whine_malloc(60)))
1321 case TXT_STAT_CACHESIZE
:
1322 sprintf(buff
+1, "%d", daemon
->cachesize
);
1325 case TXT_STAT_INSERTS
:
1326 sprintf(buff
+1, "%d", cache_inserted
);
1329 case TXT_STAT_EVICTIONS
:
1330 sprintf(buff
+1, "%d", cache_live_freed
);
1333 case TXT_STAT_MISSES
:
1334 sprintf(buff
+1, "%u", daemon
->queries_forwarded
);
1338 sprintf(buff
+1, "%u", daemon
->local_answer
);
1343 sprintf(buff
+1, "%u", daemon
->auth_answer
);
1347 case TXT_STAT_SERVERS
:
1348 /* sum counts from different records for same server */
1349 for (serv
= daemon
->servers
; serv
; serv
= serv
->next
)
1350 serv
->flags
&= ~SERV_COUNTED
;
1352 for (serv
= daemon
->servers
; serv
; serv
= serv
->next
)
1354 (SERV_NO_ADDR
| SERV_LITERAL_ADDRESS
| SERV_COUNTED
| SERV_USE_RESOLV
| SERV_NO_REBIND
)))
1357 int port
, newlen
, bytes_avail
, bytes_needed
;
1358 unsigned int queries
= 0, failed_queries
= 0;
1359 for (serv1
= serv
; serv1
; serv1
= serv1
->next
)
1360 if (!(serv1
->flags
&
1361 (SERV_NO_ADDR
| SERV_LITERAL_ADDRESS
| SERV_COUNTED
| SERV_USE_RESOLV
| SERV_NO_REBIND
)) &&
1362 sockaddr_isequal(&serv
->addr
, &serv1
->addr
))
1364 serv1
->flags
|= SERV_COUNTED
;
1365 queries
+= serv1
->queries
;
1366 failed_queries
+= serv1
->failed_queries
;
1368 port
= prettyprint_addr(&serv
->addr
, daemon
->addrbuff
);
1369 lenp
= p
++; /* length */
1370 bytes_avail
= (p
- buff
) + bufflen
;
1371 bytes_needed
= snprintf(p
, bytes_avail
, "%s#%d %u %u", daemon
->addrbuff
, port
, queries
, failed_queries
);
1372 if (bytes_needed
>= bytes_avail
)
1374 /* expand buffer if necessary */
1375 newlen
= bytes_needed
+ 1 + bufflen
- bytes_avail
;
1376 if (!(new = whine_malloc(newlen
)))
1378 memcpy(new, buff
, bufflen
);
1380 p
= new + (p
- buff
);
1384 bytes_avail
= (p
- buff
) + bufflen
;
1385 bytes_needed
= snprintf(p
, bytes_avail
, "%s#%d %u %u", daemon
->addrbuff
, port
, queries
, failed_queries
);
1387 *lenp
= bytes_needed
;
1390 t
->txt
= (unsigned char *)buff
;
1395 len
= strlen(buff
+1);
1396 t
->txt
= (unsigned char *)buff
;
1402 void dump_cache(time_t now
)
1404 struct server
*serv
, *serv1
;
1407 my_syslog(LOG_INFO
, _("time %lu"), (unsigned long)now
);
1408 my_syslog(LOG_INFO
, _("cache size %d, %d/%d cache insertions re-used unexpired cache entries."),
1409 daemon
->cachesize
, cache_live_freed
, cache_inserted
);
1410 my_syslog(LOG_INFO
, _("queries forwarded %u, queries answered locally %u"),
1411 daemon
->queries_forwarded
, daemon
->local_answer
);
1413 my_syslog(LOG_INFO
, _("queries for authoritative zones %u"), daemon
->auth_answer
);
1419 /* sum counts from different records for same server */
1420 for (serv
= daemon
->servers
; serv
; serv
= serv
->next
)
1421 serv
->flags
&= ~SERV_COUNTED
;
1423 for (serv
= daemon
->servers
; serv
; serv
= serv
->next
)
1425 (SERV_NO_ADDR
| SERV_LITERAL_ADDRESS
| SERV_COUNTED
| SERV_USE_RESOLV
| SERV_NO_REBIND
)))
1428 unsigned int queries
= 0, failed_queries
= 0;
1429 for (serv1
= serv
; serv1
; serv1
= serv1
->next
)
1430 if (!(serv1
->flags
&
1431 (SERV_NO_ADDR
| SERV_LITERAL_ADDRESS
| SERV_COUNTED
| SERV_USE_RESOLV
| SERV_NO_REBIND
)) &&
1432 sockaddr_isequal(&serv
->addr
, &serv1
->addr
))
1434 serv1
->flags
|= SERV_COUNTED
;
1435 queries
+= serv1
->queries
;
1436 failed_queries
+= serv1
->failed_queries
;
1438 port
= prettyprint_addr(&serv
->addr
, daemon
->addrbuff
);
1439 my_syslog(LOG_INFO
, _("server %s#%d: queries sent %u, retried or failed %u"), daemon
->addrbuff
, port
, queries
, failed_queries
);
1442 if (option_bool(OPT_DEBUG
) || option_bool(OPT_LOG
))
1444 struct crec
*cache
;
1446 my_syslog(LOG_INFO
, "Host Address Flags Expires");
1448 for (i
=0; i
<hash_size
; i
++)
1449 for (cache
= hash_table
[i
]; cache
; cache
= cache
->hash_next
)
1451 char *a
= daemon
->addrbuff
, *p
= daemon
->namebuff
, *n
= cache_get_name(cache
);
1453 if (strlen(n
) == 0 && !(cache
->flags
& F_REVERSE
))
1455 p
+= sprintf(p
, "%-30.30s ", n
);
1456 if ((cache
->flags
& F_CNAME
) && !is_outdated_cname_pointer(cache
))
1457 a
= cache_get_cname_target(cache
);
1459 else if (cache
->flags
& F_DS
)
1461 if (cache
->flags
& F_DNSKEY
)
1463 sprintf(a
, "%5u %3u %s", cache
->addr
.sig
.keytag
,
1464 cache
->addr
.sig
.algo
, querystr("", cache
->addr
.sig
.type_covered
));
1465 else if (!(cache
->flags
& F_NEG
))
1466 sprintf(a
, "%5u %3u %3u", cache
->addr
.ds
.keytag
,
1467 cache
->addr
.ds
.algo
, cache
->addr
.ds
.digest
);
1469 else if (cache
->flags
& F_DNSKEY
)
1470 sprintf(a
, "%5u %3u %3u", cache
->addr
.key
.keytag
,
1471 cache
->addr
.key
.algo
, cache
->addr
.key
.flags
);
1473 else if (!(cache
->flags
& F_NEG
) || !(cache
->flags
& F_FORWARD
))
1475 a
= daemon
->addrbuff
;
1476 if (cache
->flags
& F_IPV4
)
1477 inet_ntop(AF_INET
, &cache
->addr
.addr
, a
, ADDRSTRLEN
);
1479 else if (cache
->flags
& F_IPV6
)
1480 inet_ntop(AF_INET6
, &cache
->addr
.addr
, a
, ADDRSTRLEN
);
1484 if (cache
->flags
& F_IPV4
)
1486 else if (cache
->flags
& F_IPV6
)
1488 else if (cache
->flags
& F_CNAME
)
1491 else if ((cache
->flags
& (F_DS
| F_DNSKEY
)) == (F_DS
| F_DNSKEY
))
1492 t
= "G"; /* DNSKEY and DS set -> RRISG */
1493 else if (cache
->flags
& F_DS
)
1495 else if (cache
->flags
& F_DNSKEY
)
1498 p
+= sprintf(p
, "%-40.40s %s%s%s%s%s%s%s%s%s ", a
, t
,
1499 cache
->flags
& F_FORWARD
? "F" : " ",
1500 cache
->flags
& F_REVERSE
? "R" : " ",
1501 cache
->flags
& F_IMMORTAL
? "I" : " ",
1502 cache
->flags
& F_DHCP
? "D" : " ",
1503 cache
->flags
& F_NEG
? "N" : " ",
1504 cache
->flags
& F_NXDOMAIN
? "X" : " ",
1505 cache
->flags
& F_HOSTS
? "H" : " ",
1506 cache
->flags
& F_DNSSECOK
? "V" : " ");
1507 #ifdef HAVE_BROKEN_RTC
1508 p
+= sprintf(p
, "%lu", cache
->flags
& F_IMMORTAL
? 0: (unsigned long)(cache
->ttd
- now
));
1510 p
+= sprintf(p
, "%s", cache
->flags
& F_IMMORTAL
? "\n" : ctime(&(cache
->ttd
)));
1511 /* ctime includes trailing \n - eat it */
1514 my_syslog(LOG_INFO
, daemon
->namebuff
);
1519 char *record_source(unsigned int index
)
1521 struct hostsfile
*ah
;
1523 if (index
== SRC_CONFIG
)
1525 else if (index
== SRC_HOSTS
)
1528 for (ah
= daemon
->addn_hosts
; ah
; ah
= ah
->next
)
1529 if (ah
->index
== index
)
1533 for (ah
= daemon
->dynamic_dirs
; ah
; ah
= ah
->next
)
1534 if (ah
->index
== index
)
1541 char *querystr(char *desc
, unsigned short type
)
1544 int len
= 10; /* strlen("type=xxxxx") */
1545 const char *types
= NULL
;
1546 static char *buff
= NULL
;
1547 static int bufflen
= 0;
1549 for (i
= 0; i
< (sizeof(typestr
)/sizeof(typestr
[0])); i
++)
1550 if (typestr
[i
].type
== type
)
1552 types
= typestr
[i
].name
;
1553 len
= strlen(types
);
1557 len
+= 3; /* braces, terminator */
1558 len
+= strlen(desc
);
1560 if (!buff
|| bufflen
< len
)
1567 buff
= whine_malloc(len
);
1574 sprintf(buff
, "%s[%s]", desc
, types
);
1576 sprintf(buff
, "%s[type=%d]", desc
, type
);
1579 return buff
? buff
: "";
1582 void log_query(unsigned int flags
, char *name
, struct all_addr
*addr
, char *arg
)
1584 char *source
, *dest
= daemon
->addrbuff
;
1587 if (!option_bool(OPT_LOG
))
1592 if (flags
& F_KEYTAG
)
1593 sprintf(daemon
->addrbuff
, arg
, addr
->addr
.keytag
);
1597 inet_ntop(flags
& F_IPV4
? AF_INET
: AF_INET6
,
1598 addr
, daemon
->addrbuff
, ADDRSTRLEN
);
1600 strncpy(daemon
->addrbuff
, inet_ntoa(addr
->addr
.addr4
), ADDRSTRLEN
);
1607 if (flags
& F_REVERSE
)
1610 name
= daemon
->addrbuff
;
1615 if (flags
& F_NXDOMAIN
)
1620 dest
= "NODATA-IPv4";
1621 else if (flags
& F_IPV6
)
1622 dest
= "NODATA-IPv6";
1627 else if (flags
& F_CNAME
)
1629 else if (flags
& F_RRNAME
)
1632 if (flags
& F_CONFIG
)
1634 else if (flags
& F_DHCP
)
1636 else if (flags
& F_HOSTS
)
1638 else if (flags
& F_UPSTREAM
)
1640 else if (flags
& F_SECSTAT
)
1641 source
= "validation";
1642 else if (flags
& F_AUTH
)
1644 else if (flags
& F_SERVER
)
1646 source
= "forwarded";
1649 else if (flags
& F_QUERY
)
1654 else if (flags
& F_DNSSEC
)
1659 else if (flags
& F_IPSET
)
1661 source
= "ipset add";
1664 verb
= daemon
->addrbuff
;
1669 if (strlen(name
) == 0)
1672 if (option_bool(OPT_EXTRALOG
))
1674 int port
= prettyprint_addr(daemon
->log_source_addr
, daemon
->addrbuff2
);
1675 if (flags
& F_NOEXTRA
)
1676 my_syslog(LOG_INFO
, "* %s/%u %s %s %s %s", daemon
->addrbuff2
, port
, source
, name
, verb
, dest
);
1678 my_syslog(LOG_INFO
, "%u %s/%u %s %s %s %s", daemon
->log_display_id
, daemon
->addrbuff2
, port
, source
, name
, verb
, dest
);
1681 my_syslog(LOG_INFO
, "%s %s %s %s", source
, name
, verb
, dest
);