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