]>
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
);
1148 set_dynamic_inotify(AH_HOSTS
, total_size
, (struct crec
**)daemon
->packet
, revhashsz
);
1154 struct in_addr
a_record_from_hosts(char *name
, time_t now
)
1156 struct crec
*crecp
= NULL
;
1159 while ((crecp
= cache_find_by_name(crecp
, name
, now
, F_IPV4
)))
1160 if (crecp
->flags
& F_HOSTS
)
1161 return *(struct in_addr
*)&crecp
->addr
;
1163 my_syslog(MS_DHCP
| LOG_WARNING
, _("No IPv4 address found for %s"), name
);
1169 void cache_unhash_dhcp(void)
1171 struct crec
*cache
, **up
;
1174 for (i
=0; i
<hash_size
; i
++)
1175 for (cache
= hash_table
[i
], up
= &hash_table
[i
]; cache
; cache
= cache
->hash_next
)
1176 if (cache
->flags
& F_DHCP
)
1178 *up
= cache
->hash_next
;
1179 cache
->next
= dhcp_spare
;
1183 up
= &cache
->hash_next
;
1186 static void add_dhcp_cname(struct crec
*target
, time_t ttd
)
1188 struct crec
*aliasc
;
1191 for (a
= daemon
->cnames
; a
; a
= a
->next
)
1192 if (hostname_isequal(cache_get_name(target
), a
->target
))
1194 if ((aliasc
= dhcp_spare
))
1195 dhcp_spare
= dhcp_spare
->next
;
1196 else /* need new one */
1197 aliasc
= whine_malloc(sizeof(struct crec
));
1201 aliasc
->flags
= F_FORWARD
| F_NAMEP
| F_DHCP
| F_CNAME
| F_CONFIG
;
1203 aliasc
->flags
|= F_IMMORTAL
;
1206 aliasc
->name
.namep
= a
->alias
;
1207 aliasc
->addr
.cname
.target
.cache
= target
;
1208 aliasc
->addr
.cname
.uid
= target
->uid
;
1209 aliasc
->uid
= next_uid();
1211 add_dhcp_cname(aliasc
, ttd
);
1216 void cache_add_dhcp_entry(char *host_name
, int prot
,
1217 struct all_addr
*host_address
, time_t ttd
)
1219 struct crec
*crec
= NULL
, *fail_crec
= NULL
;
1220 unsigned short flags
= F_IPV4
;
1222 size_t addrlen
= sizeof(struct in_addr
);
1225 if (prot
== AF_INET6
)
1228 addrlen
= sizeof(struct in6_addr
);
1232 inet_ntop(prot
, host_address
, daemon
->addrbuff
, ADDRSTRLEN
);
1234 while ((crec
= cache_find_by_name(crec
, host_name
, 0, flags
| F_CNAME
)))
1236 /* check all addresses associated with name */
1237 if (crec
->flags
& (F_HOSTS
| F_CONFIG
))
1239 if (crec
->flags
& F_CNAME
)
1240 my_syslog(MS_DHCP
| LOG_WARNING
,
1241 _("%s is a CNAME, not giving it to the DHCP lease of %s"),
1242 host_name
, daemon
->addrbuff
);
1243 else if (memcmp(&crec
->addr
.addr
, host_address
, addrlen
) == 0)
1248 else if (!(crec
->flags
& F_DHCP
))
1250 cache_scan_free(host_name
, NULL
, 0, crec
->flags
& (flags
| F_CNAME
| F_FORWARD
));
1251 /* scan_free deletes all addresses associated with name */
1256 /* if in hosts, don't need DHCP record */
1260 /* Name in hosts, address doesn't match */
1263 inet_ntop(prot
, &fail_crec
->addr
.addr
, daemon
->namebuff
, MAXDNAME
);
1264 my_syslog(MS_DHCP
| LOG_WARNING
,
1265 _("not giving name %s to the DHCP lease of %s because "
1266 "the name exists in %s with address %s"),
1267 host_name
, daemon
->addrbuff
,
1268 record_source(fail_crec
->uid
), daemon
->namebuff
);
1272 if ((crec
= cache_find_by_addr(NULL
, (struct all_addr
*)host_address
, 0, flags
)))
1274 if (crec
->flags
& F_NEG
)
1277 cache_scan_free(NULL
, (struct all_addr
*)host_address
, 0, flags
);
1283 if ((crec
= dhcp_spare
))
1284 dhcp_spare
= dhcp_spare
->next
;
1285 else /* need new one */
1286 crec
= whine_malloc(sizeof(struct crec
));
1288 if (crec
) /* malloc may fail */
1290 crec
->flags
= flags
| F_NAMEP
| F_DHCP
| F_FORWARD
;
1292 crec
->flags
|= F_IMMORTAL
;
1295 crec
->addr
.addr
= *host_address
;
1296 crec
->name
.namep
= host_name
;
1297 crec
->uid
= next_uid();
1300 add_dhcp_cname(crec
, ttd
);
1305 int cache_make_stat(struct txt_record
*t
)
1307 static char *buff
= NULL
;
1308 static int bufflen
= 60;
1310 struct server
*serv
, *serv1
;
1313 if (!buff
&& !(buff
= whine_malloc(60)))
1320 case TXT_STAT_CACHESIZE
:
1321 sprintf(buff
+1, "%d", daemon
->cachesize
);
1324 case TXT_STAT_INSERTS
:
1325 sprintf(buff
+1, "%d", cache_inserted
);
1328 case TXT_STAT_EVICTIONS
:
1329 sprintf(buff
+1, "%d", cache_live_freed
);
1332 case TXT_STAT_MISSES
:
1333 sprintf(buff
+1, "%u", daemon
->queries_forwarded
);
1337 sprintf(buff
+1, "%u", daemon
->local_answer
);
1342 sprintf(buff
+1, "%u", daemon
->auth_answer
);
1346 case TXT_STAT_SERVERS
:
1347 /* sum counts from different records for same server */
1348 for (serv
= daemon
->servers
; serv
; serv
= serv
->next
)
1349 serv
->flags
&= ~SERV_COUNTED
;
1351 for (serv
= daemon
->servers
; serv
; serv
= serv
->next
)
1353 (SERV_NO_ADDR
| SERV_LITERAL_ADDRESS
| SERV_COUNTED
| SERV_USE_RESOLV
| SERV_NO_REBIND
)))
1356 int port
, newlen
, bytes_avail
, bytes_needed
;
1357 unsigned int queries
= 0, failed_queries
= 0;
1358 for (serv1
= serv
; serv1
; serv1
= serv1
->next
)
1359 if (!(serv1
->flags
&
1360 (SERV_NO_ADDR
| SERV_LITERAL_ADDRESS
| SERV_COUNTED
| SERV_USE_RESOLV
| SERV_NO_REBIND
)) &&
1361 sockaddr_isequal(&serv
->addr
, &serv1
->addr
))
1363 serv1
->flags
|= SERV_COUNTED
;
1364 queries
+= serv1
->queries
;
1365 failed_queries
+= serv1
->failed_queries
;
1367 port
= prettyprint_addr(&serv
->addr
, daemon
->addrbuff
);
1368 lenp
= p
++; /* length */
1369 bytes_avail
= (p
- buff
) + bufflen
;
1370 bytes_needed
= snprintf(p
, bytes_avail
, "%s#%d %u %u", daemon
->addrbuff
, port
, queries
, failed_queries
);
1371 if (bytes_needed
>= bytes_avail
)
1373 /* expand buffer if necessary */
1374 newlen
= bytes_needed
+ 1 + bufflen
- bytes_avail
;
1375 if (!(new = whine_malloc(newlen
)))
1377 memcpy(new, buff
, bufflen
);
1379 p
= new + (p
- buff
);
1383 bytes_avail
= (p
- buff
) + bufflen
;
1384 bytes_needed
= snprintf(p
, bytes_avail
, "%s#%d %u %u", daemon
->addrbuff
, port
, queries
, failed_queries
);
1386 *lenp
= bytes_needed
;
1389 t
->txt
= (unsigned char *)buff
;
1394 len
= strlen(buff
+1);
1395 t
->txt
= (unsigned char *)buff
;
1401 void dump_cache(time_t now
)
1403 struct server
*serv
, *serv1
;
1406 my_syslog(LOG_INFO
, _("time %lu"), (unsigned long)now
);
1407 my_syslog(LOG_INFO
, _("cache size %d, %d/%d cache insertions re-used unexpired cache entries."),
1408 daemon
->cachesize
, cache_live_freed
, cache_inserted
);
1409 my_syslog(LOG_INFO
, _("queries forwarded %u, queries answered locally %u"),
1410 daemon
->queries_forwarded
, daemon
->local_answer
);
1412 my_syslog(LOG_INFO
, _("queries for authoritative zones %u"), daemon
->auth_answer
);
1418 /* sum counts from different records for same server */
1419 for (serv
= daemon
->servers
; serv
; serv
= serv
->next
)
1420 serv
->flags
&= ~SERV_COUNTED
;
1422 for (serv
= daemon
->servers
; serv
; serv
= serv
->next
)
1424 (SERV_NO_ADDR
| SERV_LITERAL_ADDRESS
| SERV_COUNTED
| SERV_USE_RESOLV
| SERV_NO_REBIND
)))
1427 unsigned int queries
= 0, failed_queries
= 0;
1428 for (serv1
= serv
; serv1
; serv1
= serv1
->next
)
1429 if (!(serv1
->flags
&
1430 (SERV_NO_ADDR
| SERV_LITERAL_ADDRESS
| SERV_COUNTED
| SERV_USE_RESOLV
| SERV_NO_REBIND
)) &&
1431 sockaddr_isequal(&serv
->addr
, &serv1
->addr
))
1433 serv1
->flags
|= SERV_COUNTED
;
1434 queries
+= serv1
->queries
;
1435 failed_queries
+= serv1
->failed_queries
;
1437 port
= prettyprint_addr(&serv
->addr
, daemon
->addrbuff
);
1438 my_syslog(LOG_INFO
, _("server %s#%d: queries sent %u, retried or failed %u"), daemon
->addrbuff
, port
, queries
, failed_queries
);
1441 if (option_bool(OPT_DEBUG
) || option_bool(OPT_LOG
))
1443 struct crec
*cache
;
1445 my_syslog(LOG_INFO
, "Host Address Flags Expires");
1447 for (i
=0; i
<hash_size
; i
++)
1448 for (cache
= hash_table
[i
]; cache
; cache
= cache
->hash_next
)
1450 char *a
= daemon
->addrbuff
, *p
= daemon
->namebuff
, *n
= cache_get_name(cache
);
1452 if (strlen(n
) == 0 && !(cache
->flags
& F_REVERSE
))
1454 p
+= sprintf(p
, "%-30.30s ", n
);
1455 if ((cache
->flags
& F_CNAME
) && !is_outdated_cname_pointer(cache
))
1456 a
= cache_get_cname_target(cache
);
1458 else if (cache
->flags
& F_DS
)
1460 if (cache
->flags
& F_DNSKEY
)
1462 sprintf(a
, "%5u %3u %s", cache
->addr
.sig
.keytag
,
1463 cache
->addr
.sig
.algo
, querystr("", cache
->addr
.sig
.type_covered
));
1464 else if (!(cache
->flags
& F_NEG
))
1465 sprintf(a
, "%5u %3u %3u", cache
->addr
.ds
.keytag
,
1466 cache
->addr
.ds
.algo
, cache
->addr
.ds
.digest
);
1468 else if (cache
->flags
& F_DNSKEY
)
1469 sprintf(a
, "%5u %3u %3u", cache
->addr
.key
.keytag
,
1470 cache
->addr
.key
.algo
, cache
->addr
.key
.flags
);
1472 else if (!(cache
->flags
& F_NEG
) || !(cache
->flags
& F_FORWARD
))
1474 a
= daemon
->addrbuff
;
1475 if (cache
->flags
& F_IPV4
)
1476 inet_ntop(AF_INET
, &cache
->addr
.addr
, a
, ADDRSTRLEN
);
1478 else if (cache
->flags
& F_IPV6
)
1479 inet_ntop(AF_INET6
, &cache
->addr
.addr
, a
, ADDRSTRLEN
);
1483 if (cache
->flags
& F_IPV4
)
1485 else if (cache
->flags
& F_IPV6
)
1487 else if (cache
->flags
& F_CNAME
)
1490 else if ((cache
->flags
& (F_DS
| F_DNSKEY
)) == (F_DS
| F_DNSKEY
))
1491 t
= "G"; /* DNSKEY and DS set -> RRISG */
1492 else if (cache
->flags
& F_DS
)
1494 else if (cache
->flags
& F_DNSKEY
)
1497 p
+= sprintf(p
, "%-40.40s %s%s%s%s%s%s%s%s%s ", a
, t
,
1498 cache
->flags
& F_FORWARD
? "F" : " ",
1499 cache
->flags
& F_REVERSE
? "R" : " ",
1500 cache
->flags
& F_IMMORTAL
? "I" : " ",
1501 cache
->flags
& F_DHCP
? "D" : " ",
1502 cache
->flags
& F_NEG
? "N" : " ",
1503 cache
->flags
& F_NXDOMAIN
? "X" : " ",
1504 cache
->flags
& F_HOSTS
? "H" : " ",
1505 cache
->flags
& F_DNSSECOK
? "V" : " ");
1506 #ifdef HAVE_BROKEN_RTC
1507 p
+= sprintf(p
, "%lu", cache
->flags
& F_IMMORTAL
? 0: (unsigned long)(cache
->ttd
- now
));
1509 p
+= sprintf(p
, "%s", cache
->flags
& F_IMMORTAL
? "\n" : ctime(&(cache
->ttd
)));
1510 /* ctime includes trailing \n - eat it */
1513 my_syslog(LOG_INFO
, daemon
->namebuff
);
1518 char *record_source(unsigned int index
)
1520 struct hostsfile
*ah
;
1522 if (index
== SRC_CONFIG
)
1524 else if (index
== SRC_HOSTS
)
1527 for (ah
= daemon
->addn_hosts
; ah
; ah
= ah
->next
)
1528 if (ah
->index
== index
)
1532 for (ah
= daemon
->dynamic_dirs
; ah
; ah
= ah
->next
)
1533 if (ah
->index
== index
)
1540 char *querystr(char *desc
, unsigned short type
)
1543 int len
= 10; /* strlen("type=xxxxx") */
1544 const char *types
= NULL
;
1545 static char *buff
= NULL
;
1546 static int bufflen
= 0;
1548 for (i
= 0; i
< (sizeof(typestr
)/sizeof(typestr
[0])); i
++)
1549 if (typestr
[i
].type
== type
)
1551 types
= typestr
[i
].name
;
1552 len
= strlen(types
);
1556 len
+= 3; /* braces, terminator */
1557 len
+= strlen(desc
);
1559 if (!buff
|| bufflen
< len
)
1566 buff
= whine_malloc(len
);
1573 sprintf(buff
, "%s[%s]", desc
, types
);
1575 sprintf(buff
, "%s[type=%d]", desc
, type
);
1578 return buff
? buff
: "";
1581 void log_query(unsigned int flags
, char *name
, struct all_addr
*addr
, char *arg
)
1583 char *source
, *dest
= daemon
->addrbuff
;
1586 if (!option_bool(OPT_LOG
))
1591 if (flags
& F_KEYTAG
)
1592 sprintf(daemon
->addrbuff
, arg
, addr
->addr
.keytag
);
1596 inet_ntop(flags
& F_IPV4
? AF_INET
: AF_INET6
,
1597 addr
, daemon
->addrbuff
, ADDRSTRLEN
);
1599 strncpy(daemon
->addrbuff
, inet_ntoa(addr
->addr
.addr4
), ADDRSTRLEN
);
1606 if (flags
& F_REVERSE
)
1609 name
= daemon
->addrbuff
;
1614 if (flags
& F_NXDOMAIN
)
1619 dest
= "NODATA-IPv4";
1620 else if (flags
& F_IPV6
)
1621 dest
= "NODATA-IPv6";
1626 else if (flags
& F_CNAME
)
1628 else if (flags
& F_RRNAME
)
1631 if (flags
& F_CONFIG
)
1633 else if (flags
& F_DHCP
)
1635 else if (flags
& F_HOSTS
)
1637 else if (flags
& F_UPSTREAM
)
1639 else if (flags
& F_SECSTAT
)
1640 source
= "validation";
1641 else if (flags
& F_AUTH
)
1643 else if (flags
& F_SERVER
)
1645 source
= "forwarded";
1648 else if (flags
& F_QUERY
)
1653 else if (flags
& F_DNSSEC
)
1658 else if (flags
& F_IPSET
)
1660 source
= "ipset add";
1663 verb
= daemon
->addrbuff
;
1668 if (strlen(name
) == 0)
1671 if (option_bool(OPT_EXTRALOG
))
1673 int port
= prettyprint_addr(daemon
->log_source_addr
, daemon
->addrbuff2
);
1674 if (flags
& F_NOEXTRA
)
1675 my_syslog(LOG_INFO
, "* %s/%u %s %s %s %s", daemon
->addrbuff2
, port
, source
, name
, verb
, dest
);
1677 my_syslog(LOG_INFO
, "%u %s/%u %s %s %s %s", daemon
->log_display_id
, daemon
->addrbuff2
, port
, source
, name
, verb
, dest
);
1680 my_syslog(LOG_INFO
, "%s %s %s %s", source
, name
, verb
, dest
);