1/* dnsmasq is Copyright (c) 2000-2009 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 cache_inserted = 0, cache_live_freed = 0, insert_error;
25static union bigname *big_free = NULL;
26static int bignames_left, hash_size;
27static int uid = 0;
28static char *addrbuff = NULL;
29
30/* type->string mapping: this is also used by the name-hash function as a mixing table. */
31static const struct {
32  unsigned int type;
33  const char * const name;
34} typestr[] = {
35  { 1,   "A" },
36  { 2,   "NS" },
37  { 5,   "CNAME" },
38  { 6,   "SOA" },
39  { 10,  "NULL" },
40  { 11,  "WKS" },
41  { 12,  "PTR" },
42  { 13,  "HINFO" },
43  { 15,  "MX" },
44  { 16,  "TXT" },
45  { 22,  "NSAP" },
46  { 23,  "NSAP_PTR" },
47  { 24,  "SIG" },
48  { 25,  "KEY" },
49  { 28,  "AAAA" },
50  { 33,  "SRV" },
51  { 35,  "NAPTR" },
52  { 36,  "KX" },
53  { 37,  "CERT" },
54  { 38,  "A6" },
55  { 39,  "DNAME" },
56  { 41,  "OPT" },
57  { 48,  "DNSKEY" },
58  { 249, "TKEY" },
59  { 250, "TSIG" },
60  { 251, "IXFR" },
61  { 252, "AXFR" },
62  { 253, "MAILB" },
63  { 254, "MAILA" },
64  { 255, "ANY" }
65};
66
67static void cache_free(struct crec *crecp);
68static void cache_unlink(struct crec *crecp);
69static void cache_link(struct crec *crecp);
70static void rehash(int size);
71static void cache_hash(struct crec *crecp);
72
73void cache_init(void)
74{
75  struct crec *crecp;
76  int i;
77
78  if (daemon->options & OPT_LOG)
79    addrbuff = safe_malloc(ADDRSTRLEN);
80
81  bignames_left = daemon->cachesize/10;
82
83  if (daemon->cachesize > 0)
84    {
85      crecp = safe_malloc(daemon->cachesize*sizeof(struct crec));
86
87      for (i=0; i < daemon->cachesize; i++, crecp++)
88	{
89	  cache_link(crecp);
90	  crecp->flags = 0;
91	  crecp->uid = uid++;
92	}
93    }
94
95  /* create initial hash table*/
96  rehash(daemon->cachesize);
97}
98
99/* In most cases, we create the hash table once here by calling this with (hash_table == NULL)
100   but if the hosts file(s) are big (some people have 50000 ad-block entries), the table
101   will be much too small, so the hosts reading code calls rehash every 1000 addresses, to
102   expand the table. */
103static void rehash(int size)
104{
105  struct crec **new, **old, *p, *tmp;
106  int i, new_size, old_size;
107
108  /* hash_size is a power of two. */
109  for (new_size = 64; new_size < size/10; new_size = new_size << 1);
110
111  /* must succeed in getting first instance, failure later is non-fatal */
112  if (!hash_table)
113    new = safe_malloc(new_size * sizeof(struct crec *));
114  else if (new_size <= hash_size || !(new = whine_malloc(new_size * sizeof(struct crec *))))
115    return;
116
117  for(i = 0; i < new_size; i++)
118    new[i] = NULL;
119
120  old = hash_table;
121  old_size = hash_size;
122  hash_table = new;
123  hash_size = new_size;
124
125  if (old)
126    {
127      for (i = 0; i < old_size; i++)
128	for (p = old[i]; p ; p = tmp)
129	  {
130	    tmp = p->hash_next;
131	    cache_hash(p);
132	  }
133      free(old);
134    }
135}
136
137static struct crec **hash_bucket(char *name)
138{
139  unsigned int c, val = 017465; /* Barker code - minimum self-correlation in cyclic shift */
140  const unsigned char *mix_tab = (const unsigned char*)typestr;
141
142  while((c = (unsigned char) *name++))
143    {
144      /* don't use tolower and friends here - they may be messed up by LOCALE */
145      if (c >= 'A' && c <= 'Z')
146	c += 'a' - 'A';
147      val = ((val << 7) | (val >> (32 - 7))) + (mix_tab[(val + c) & 0x3F] ^ c);
148    }
149
150  /* hash_size is a power of two */
151  return hash_table + ((val ^ (val >> 16)) & (hash_size - 1));
152}
153
154static void cache_hash(struct crec *crecp)
155{
156  /* maintain an invariant that all entries with F_REVERSE set
157     are at the start of the hash-chain  and all non-reverse
158     immortal entries are at the end of the hash-chain.
159     This allows reverse searches and garbage collection to be optimised */
160
161  struct crec **up = hash_bucket(cache_get_name(crecp));
162
163  if (!(crecp->flags & F_REVERSE))
164    {
165      while (*up && ((*up)->flags & F_REVERSE))
166	up = &((*up)->hash_next);
167
168      if (crecp->flags & F_IMMORTAL)
169	while (*up && !((*up)->flags & F_IMMORTAL))
170	  up = &((*up)->hash_next);
171    }
172  crecp->hash_next = *up;
173  *up = crecp;
174}
175
176static void cache_free(struct crec *crecp)
177{
178  crecp->flags &= ~F_FORWARD;
179  crecp->flags &= ~F_REVERSE;
180  crecp->uid = uid++; /* invalidate CNAMES pointing to this. */
181
182  if (cache_tail)
183    cache_tail->next = crecp;
184  else
185    cache_head = crecp;
186  crecp->prev = cache_tail;
187  crecp->next = NULL;
188  cache_tail = crecp;
189
190  /* retrieve big name for further use. */
191  if (crecp->flags & F_BIGNAME)
192    {
193      crecp->name.bname->next = big_free;
194      big_free = crecp->name.bname;
195      crecp->flags &= ~F_BIGNAME;
196    }
197}
198
199/* insert a new cache entry at the head of the list (youngest entry) */
200static void cache_link(struct crec *crecp)
201{
202  if (cache_head) /* check needed for init code */
203    cache_head->prev = crecp;
204  crecp->next = cache_head;
205  crecp->prev = NULL;
206  cache_head = crecp;
207  if (!cache_tail)
208    cache_tail = crecp;
209}
210
211/* remove an arbitrary cache entry for promotion */
212static void cache_unlink (struct crec *crecp)
213{
214  if (crecp->prev)
215    crecp->prev->next = crecp->next;
216  else
217    cache_head = crecp->next;
218
219  if (crecp->next)
220    crecp->next->prev = crecp->prev;
221  else
222    cache_tail = crecp->prev;
223}
224
225char *cache_get_name(struct crec *crecp)
226{
227  if (crecp->flags & F_BIGNAME)
228    return crecp->name.bname->name;
229  else if (crecp->flags & (F_DHCP | F_CONFIG))
230    return crecp->name.namep;
231
232  return crecp->name.sname;
233}
234
235static int is_outdated_cname_pointer(struct crec *crecp)
236{
237  if (!(crecp->flags & F_CNAME))
238    return 0;
239
240  if (crecp->addr.cname.cache && crecp->addr.cname.uid == crecp->addr.cname.cache->uid)
241    return 0;
242
243  return 1;
244}
245
246static int is_expired(time_t now, struct crec *crecp)
247{
248  if (crecp->flags & F_IMMORTAL)
249    return 0;
250
251  if (difftime(now, crecp->ttd) < 0)
252    return 0;
253
254  return 1;
255}
256
257static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags)
258{
259  /* Scan and remove old entries.
260     If (flags & F_FORWARD) then remove any forward entries for name and any expired
261     entries but only in the same hash bucket as name.
262     If (flags & F_REVERSE) then remove any reverse entries for addr and any expired
263     entries in the whole cache.
264     If (flags == 0) remove any expired entries in the whole cache.
265
266     In the flags & F_FORWARD case, the return code is valid, and returns zero if the
267     name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
268
269     We take advantage of the fact that hash chains have stuff in the order <reverse>,<other>,<immortal>
270     so that when we hit an entry which isn't reverse and is immortal, we're done. */
271
272  struct crec *crecp, **up;
273
274  if (flags & F_FORWARD)
275    {
276      for (up = hash_bucket(name), crecp = *up; crecp; crecp = crecp->hash_next)
277	if (is_expired(now, crecp) || is_outdated_cname_pointer(crecp))
278	  {
279	    *up = crecp->hash_next;
280	    if (!(crecp->flags & (F_HOSTS | F_DHCP)))
281	      {
282		cache_unlink(crecp);
283		cache_free(crecp);
284	      }
285	  }
286	else if ((crecp->flags & F_FORWARD) &&
287		 ((flags & crecp->flags & (F_IPV4 | F_IPV6)) || ((crecp->flags | flags) & F_CNAME)) &&
288		 hostname_isequal(cache_get_name(crecp), name))
289	  {
290	    if (crecp->flags & (F_HOSTS | F_DHCP))
291	      return 0;
292	    *up = crecp->hash_next;
293	    cache_unlink(crecp);
294	    cache_free(crecp);
295	  }
296	else
297	  up = &crecp->hash_next;
298    }
299  else
300    {
301      int i;
302#ifdef HAVE_IPV6
303      int addrlen = (flags & F_IPV6) ? IN6ADDRSZ : INADDRSZ;
304#else
305      int addrlen = INADDRSZ;
306#endif
307      for (i = 0; i < hash_size; i++)
308	for (crecp = hash_table[i], up = &hash_table[i];
309	     crecp && ((crecp->flags & F_REVERSE) || !(crecp->flags & F_IMMORTAL));
310	     crecp = crecp->hash_next)
311	  if (is_expired(now, crecp))
312	    {
313	      *up = crecp->hash_next;
314	      if (!(crecp->flags & (F_HOSTS | F_DHCP)))
315		{
316		  cache_unlink(crecp);
317		  cache_free(crecp);
318		}
319	    }
320	  else if (!(crecp->flags & (F_HOSTS | F_DHCP)) &&
321		   (flags & crecp->flags & F_REVERSE) &&
322		   (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
323		   memcmp(&crecp->addr.addr, addr, addrlen) == 0)
324	    {
325	      *up = crecp->hash_next;
326	      cache_unlink(crecp);
327	      cache_free(crecp);
328	    }
329	  else
330	    up = &crecp->hash_next;
331    }
332
333  return 1;
334}
335
336/* Note: The normal calling sequence is
337   cache_start_insert
338   cache_insert * n
339   cache_end_insert
340
341   but an abort can cause the cache_end_insert to be missed
342   in which can the next cache_start_insert cleans things up. */
343
344void cache_start_insert(void)
345{
346  /* Free any entries which didn't get committed during the last
347     insert due to error.
348  */
349  while (new_chain)
350    {
351      struct crec *tmp = new_chain->next;
352      cache_free(new_chain);
353      new_chain = tmp;
354    }
355  new_chain = NULL;
356  insert_error = 0;
357}
358
359struct crec *cache_insert(char *name, struct all_addr *addr,
360			  time_t now,  unsigned long ttl, unsigned short flags)
361{
362  struct crec *new;
363  union bigname *big_name = NULL;
364  int freed_all = flags & F_REVERSE;
365  int free_avail = 0;
366
367  log_query(flags | F_UPSTREAM, name, addr, NULL);
368
369  /* CONFIG bit means something else when stored in cache entries */
370  flags &= ~F_CONFIG;
371
372  /* if previous insertion failed give up now. */
373  if (insert_error)
374    return NULL;
375
376  /* First remove any expired entries and entries for the name/address we
377     are currently inserting. Fail is we attempt to delete a name from
378     /etc/hosts or DHCP. */
379  if (!cache_scan_free(name, addr, now, flags))
380    {
381      insert_error = 1;
382      return NULL;
383    }
384
385  /* Now get a cache entry from the end of the LRU list */
386  while (1) {
387    if (!(new = cache_tail)) /* no entries left - cache is too small, bail */
388      {
389	insert_error = 1;
390	return NULL;
391      }
392
393    /* End of LRU list is still in use: if we didn't scan all the hash
394       chains for expired entries do that now. If we already tried that
395       then it's time to start spilling things. */
396
397    if (new->flags & (F_FORWARD | F_REVERSE))
398      {
399	/* If free_avail set, we believe that an entry has been freed.
400	   Bugs have been known to make this not true, resulting in
401	   a tight loop here. If that happens, abandon the
402	   insert. Once in this state, all inserts will probably fail. */
403	if (free_avail)
404	  {
405	    insert_error = 1;
406	    return NULL;
407	  }
408
409	if (freed_all)
410	  {
411	    free_avail = 1; /* Must be free space now. */
412	    cache_scan_free(cache_get_name(new), &new->addr.addr, now, new->flags);
413	    cache_live_freed++;
414	  }
415	else
416	  {
417	    cache_scan_free(NULL, NULL, now, 0);
418	    freed_all = 1;
419	  }
420	continue;
421      }
422
423    /* Check if we need to and can allocate extra memory for a long name.
424       If that fails, give up now. */
425    if (name && (strlen(name) > SMALLDNAME-1))
426      {
427	if (big_free)
428	  {
429	    big_name = big_free;
430	    big_free = big_free->next;
431	  }
432	else if (!bignames_left ||
433		 !(big_name = (union bigname *)whine_malloc(sizeof(union bigname))))
434	  {
435	    insert_error = 1;
436	    return NULL;
437	  }
438	else
439	  bignames_left--;
440
441      }
442
443    /* Got the rest: finally grab entry. */
444    cache_unlink(new);
445    break;
446  }
447
448  new->flags = flags;
449  if (big_name)
450    {
451      new->name.bname = big_name;
452      new->flags |= F_BIGNAME;
453    }
454
455  if (name)
456    strcpy(cache_get_name(new), name);
457  else
458    *cache_get_name(new) = 0;
459
460  if (addr)
461    new->addr.addr = *addr;
462  else
463    new->addr.cname.cache = NULL;
464
465  new->ttd = now + (time_t)ttl;
466  new->next = new_chain;
467  new_chain = new;
468
469  return new;
470}
471
472/* after end of insertion, commit the new entries */
473void cache_end_insert(void)
474{
475  if (insert_error)
476    return;
477
478  while (new_chain)
479    {
480      struct crec *tmp = new_chain->next;
481      /* drop CNAMEs which didn't find a target. */
482      if (is_outdated_cname_pointer(new_chain))
483	cache_free(new_chain);
484      else
485	{
486	  cache_hash(new_chain);
487	  cache_link(new_chain);
488	  cache_inserted++;
489	}
490      new_chain = tmp;
491    }
492  new_chain = NULL;
493}
494
495struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsigned short prot)
496{
497  struct crec *ans;
498
499  if (crecp) /* iterating */
500    ans = crecp->next;
501  else
502    {
503      /* first search, look for relevant entries and push to top of list
504	 also free anything which has expired */
505      struct crec *next, **up, **insert = NULL, **chainp = &ans;
506      int ins_flags = 0;
507
508      for (up = hash_bucket(name), crecp = *up; crecp; crecp = next)
509	{
510	  next = crecp->hash_next;
511
512	  if (!is_expired(now, crecp) && !is_outdated_cname_pointer(crecp))
513	    {
514	      if ((crecp->flags & F_FORWARD) &&
515		  (crecp->flags & prot) &&
516		  hostname_isequal(cache_get_name(crecp), name))
517		{
518		  if (crecp->flags & (F_HOSTS | F_DHCP))
519		    {
520		      *chainp = crecp;
521		      chainp = &crecp->next;
522		    }
523		  else
524		    {
525		      cache_unlink(crecp);
526		      cache_link(crecp);
527		    }
528
529		  /* Move all but the first entry up the hash chain
530		     this implements round-robin.
531		     Make sure that re-ordering doesn't break the hash-chain
532		     order invariants.
533		  */
534		  if (insert && (crecp->flags & (F_REVERSE | F_IMMORTAL)) == ins_flags)
535		    {
536		      *up = crecp->hash_next;
537		      crecp->hash_next = *insert;
538		      *insert = crecp;
539		      insert = &crecp->hash_next;
540		    }
541		  else
542		    {
543		      if (!insert)
544			{
545			  insert = up;
546			  ins_flags = crecp->flags & (F_REVERSE | F_IMMORTAL);
547			}
548		      up = &crecp->hash_next;
549		    }
550		}
551	      else
552		/* case : not expired, incorrect entry. */
553		up = &crecp->hash_next;
554	    }
555	  else
556	    {
557	      /* expired entry, free it */
558	      *up = crecp->hash_next;
559	      if (!(crecp->flags & (F_HOSTS | F_DHCP)))
560		{
561		  cache_unlink(crecp);
562		  cache_free(crecp);
563		}
564	    }
565	}
566
567      *chainp = cache_head;
568    }
569
570  if (ans &&
571      (ans->flags & F_FORWARD) &&
572      (ans->flags & prot) &&
573      hostname_isequal(cache_get_name(ans), name))
574    return ans;
575
576  return NULL;
577}
578
579struct crec *cache_find_by_addr(struct crec *crecp, struct all_addr *addr,
580				time_t now, unsigned short prot)
581{
582  struct crec *ans;
583#ifdef HAVE_IPV6
584  int addrlen = (prot == F_IPV6) ? IN6ADDRSZ : INADDRSZ;
585#else
586  int addrlen = INADDRSZ;
587#endif
588
589  if (crecp) /* iterating */
590    ans = crecp->next;
591  else
592    {
593      /* first search, look for relevant entries and push to top of list
594	 also free anything which has expired. All the reverse entries are at the
595	 start of the hash chain, so we can give up when we find the first
596	 non-REVERSE one.  */
597       int i;
598       struct crec **up, **chainp = &ans;
599
600       for (i=0; i<hash_size; i++)
601	 for (crecp = hash_table[i], up = &hash_table[i];
602	      crecp && (crecp->flags & F_REVERSE);
603	      crecp = crecp->hash_next)
604	   if (!is_expired(now, crecp))
605	     {
606	       if ((crecp->flags & prot) &&
607		   memcmp(&crecp->addr.addr, addr, addrlen) == 0)
608		 {
609		   if (crecp->flags & (F_HOSTS | F_DHCP))
610		     {
611		       *chainp = crecp;
612		       chainp = &crecp->next;
613		     }
614		   else
615		     {
616		       cache_unlink(crecp);
617		       cache_link(crecp);
618		     }
619		 }
620	       up = &crecp->hash_next;
621	     }
622	   else
623	     {
624	       *up = crecp->hash_next;
625	       if (!(crecp->flags & (F_HOSTS | F_DHCP)))
626		 {
627		   cache_unlink(crecp);
628		   cache_free(crecp);
629		 }
630	     }
631
632       *chainp = cache_head;
633    }
634
635  if (ans &&
636      (ans->flags & F_REVERSE) &&
637      (ans->flags & prot) &&
638      memcmp(&ans->addr.addr, addr, addrlen) == 0)
639    return ans;
640
641  return NULL;
642}
643
644static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrlen,
645			    unsigned short flags, int index, int addr_dup)
646{
647  struct crec *lookup = cache_find_by_name(NULL, cache->name.sname, 0, flags & (F_IPV4 | F_IPV6));
648  int i, nameexists = 0;
649  struct cname *a;
650
651  /* Remove duplicates in hosts files. */
652  if (lookup && (lookup->flags & F_HOSTS))
653    {
654      nameexists = 1;
655      if (memcmp(&lookup->addr.addr, addr, addrlen) == 0)
656	{
657	  free(cache);
658	  return;
659	}
660    }
661
662  /* Ensure there is only one address -> name mapping (first one trumps)
663     We do this by steam here, first we see if the address is the same as
664     the last one we saw, which eliminates most in the case of an ad-block
665     file with thousands of entries for the same address.
666     Then we search and bail at the first matching address that came from
667     a HOSTS file. Since the first host entry gets reverse, we know
668     then that it must exist without searching exhaustively for it. */
669
670  if (addr_dup)
671    flags &= ~F_REVERSE;
672  else
673    for (i=0; i<hash_size; i++)
674      {
675	for (lookup = hash_table[i]; lookup; lookup = lookup->hash_next)
676	  if ((lookup->flags & F_HOSTS) &&
677	      (lookup->flags & flags & (F_IPV4 | F_IPV6)) &&
678	      memcmp(&lookup->addr.addr, addr, addrlen) == 0)
679	    {
680	      flags &= ~F_REVERSE;
681	      break;
682	    }
683	if (lookup)
684	  break;
685      }
686
687  cache->flags = flags;
688  cache->uid = index;
689  memcpy(&cache->addr.addr, addr, addrlen);
690  cache_hash(cache);
691
692  /* don't need to do alias stuff for second and subsequent addresses. */
693  if (!nameexists)
694    for (a = daemon->cnames; a; a = a->next)
695      if (hostname_isequal(cache->name.sname, a->target) &&
696	  (lookup = whine_malloc(sizeof(struct crec))))
697	{
698	  lookup->flags = F_FORWARD | F_IMMORTAL | F_CONFIG | F_HOSTS | F_CNAME;
699	  lookup->name.namep = a->alias;
700	  lookup->addr.cname.cache = cache;
701	  lookup->addr.cname.uid = index;
702	  cache_hash(lookup);
703	}
704}
705
706static int eatspace(FILE *f)
707{
708  int c, nl = 0;
709
710  while (1)
711    {
712      if ((c = getc(f)) == '#')
713	while (c != '\n' && c != EOF)
714	  c = getc(f);
715
716      if (c == EOF)
717	return 1;
718
719      if (!isspace(c))
720	{
721	  ungetc(c, f);
722	  return nl;
723	}
724
725      if (c == '\n')
726	nl = 1;
727    }
728}
729
730static int gettok(FILE *f, char *token)
731{
732  int c, count = 0;
733
734  while (1)
735    {
736      if ((c = getc(f)) == EOF)
737	return (count == 0) ? EOF : 1;
738
739      if (isspace(c) || c == '#')
740	{
741	  ungetc(c, f);
742	  return eatspace(f);
743	}
744
745      if (count < (MAXDNAME - 1))
746	{
747	  token[count++] = c;
748	  token[count] = 0;
749	}
750    }
751}
752
753static int read_hostsfile(char *filename, int index, int cache_size)
754{
755  FILE *f = fopen(filename, "r");
756  char *token = daemon->namebuff, *domain_suffix = NULL;
757  int addr_count = 0, name_count = cache_size, lineno = 0;
758  unsigned short flags = 0, saved_flags = 0;
759  struct all_addr addr, saved_addr;
760  int atnl, addrlen = 0, addr_dup;
761
762  if (!f)
763    {
764      my_syslog(LOG_ERR, _("failed to load names from %s: %s"), filename, strerror(errno));
765      return 0;
766    }
767
768  eatspace(f);
769
770  while ((atnl = gettok(f, token)) != EOF)
771    {
772      addr_dup = 0;
773      lineno++;
774
775#ifdef HAVE_IPV6
776      if (inet_pton(AF_INET, token, &addr) > 0)
777	{
778	  flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4;
779	  addrlen = INADDRSZ;
780	  domain_suffix = get_domain(addr.addr.addr4);
781	}
782      else if (inet_pton(AF_INET6, token, &addr) > 0)
783	{
784	  flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6;
785	  addrlen = IN6ADDRSZ;
786	  domain_suffix = daemon->domain_suffix;
787	}
788#else
789      if ((addr.addr.addr4.s_addr = inet_addr(token)) != (in_addr_t) -1)
790	{
791	  flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4;
792	  addrlen = INADDRSZ;
793	  domain_suffix = get_domain(addr.addr.addr4);
794	}
795#endif
796      else
797	{
798	  my_syslog(LOG_ERR, _("bad address at %s line %d"), filename, lineno);
799	  while (atnl == 0)
800	    atnl = gettok(f, token);
801	  continue;
802	}
803
804      if (saved_flags == flags && memcmp(&addr, &saved_addr, addrlen) == 0)
805	addr_dup = 1;
806      else
807	{
808	  saved_flags = flags;
809	  saved_addr = addr;
810	}
811
812      addr_count++;
813
814      /* rehash every 1000 names. */
815      if ((name_count - cache_size) > 1000)
816	{
817	  rehash(name_count);
818	  cache_size = name_count;
819	}
820
821      while (atnl == 0)
822	{
823	  struct crec *cache;
824	  int fqdn, nomem;
825	  char *canon;
826
827	  if ((atnl = gettok(f, token)) == EOF)
828	    break;
829
830	  fqdn = !!strchr(token, '.');
831
832	  if ((canon = canonicalise(token, &nomem)))
833	    {
834	      /* If set, add a version of the name with a default domain appended */
835	      if ((daemon->options & OPT_EXPAND) && domain_suffix && !fqdn &&
836		  (cache = whine_malloc(sizeof(struct crec) +
837					strlen(canon)+2+strlen(domain_suffix)-SMALLDNAME)))
838		{
839		  strcpy(cache->name.sname, canon);
840		  strcat(cache->name.sname, ".");
841		  strcat(cache->name.sname, domain_suffix);
842		  add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup);
843		  addr_dup = 1;
844		  name_count++;
845		}
846	      if ((cache = whine_malloc(sizeof(struct crec) + strlen(canon)+1-SMALLDNAME)))
847		{
848		  strcpy(cache->name.sname, canon);
849		  add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup);
850		  name_count++;
851		}
852	      free(canon);
853
854	    }
855	  else if (!nomem)
856	    my_syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno);
857	}
858    }
859
860  fclose(f);
861  rehash(name_count);
862
863  my_syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count);
864
865  return name_count;
866}
867
868void cache_reload(void)
869{
870  struct crec *cache, **up, *tmp;
871  int i, total_size = daemon->cachesize;
872  struct hostsfile *ah;
873
874  cache_inserted = cache_live_freed = 0;
875
876  for (i=0; i<hash_size; i++)
877    for (cache = hash_table[i], up = &hash_table[i]; cache; cache = tmp)
878      {
879	tmp = cache->hash_next;
880	if (cache->flags & F_HOSTS)
881	  {
882	    *up = cache->hash_next;
883	    free(cache);
884	  }
885	else if (!(cache->flags & F_DHCP))
886	  {
887	    *up = cache->hash_next;
888	    if (cache->flags & F_BIGNAME)
889	      {
890		cache->name.bname->next = big_free;
891		big_free = cache->name.bname;
892	      }
893	    cache->flags = 0;
894	  }
895	else
896	  up = &cache->hash_next;
897      }
898
899  if ((daemon->options & OPT_NO_HOSTS) && !daemon->addn_hosts)
900    {
901      if (daemon->cachesize > 0)
902	my_syslog(LOG_INFO, _("cleared cache"));
903      return;
904    }
905
906  if (!(daemon->options & OPT_NO_HOSTS))
907    total_size = read_hostsfile(HOSTSFILE, 0, total_size);
908
909  for (i = 0, ah = daemon->addn_hosts; ah; ah = ah->next)
910    {
911      if (i <= ah->index)
912	i = ah->index + 1;
913
914      if (ah->flags & AH_DIR)
915	ah->flags |= AH_INACTIVE;
916      else
917	ah->flags &= ~AH_INACTIVE;
918    }
919
920  for (ah = daemon->addn_hosts; ah; ah = ah->next)
921    if (!(ah->flags & AH_INACTIVE))
922      {
923	struct stat buf;
924	if (stat(ah->fname, &buf) != -1 && S_ISDIR(buf.st_mode))
925	  {
926	    DIR *dir_stream;
927	    struct dirent *ent;
928
929	    /* don't read this as a file */
930	    ah->flags |= AH_INACTIVE;
931
932	    if (!(dir_stream = opendir(ah->fname)))
933	      my_syslog(LOG_ERR, _("cannot access directory %s: %s"),
934			ah->fname, strerror(errno));
935	    else
936	      {
937		while ((ent = readdir(dir_stream)))
938		  {
939		    size_t lendir = strlen(ah->fname);
940		    size_t lenfile = strlen(ent->d_name);
941		    struct hostsfile *ah1;
942		    char *path;
943
944		    /* ignore emacs backups and dotfiles */
945		    if (lenfile == 0 ||
946			ent->d_name[lenfile - 1] == '~' ||
947			(ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
948			ent->d_name[0] == '.')
949		      continue;
950
951		    /* see if we have an existing record.
952		       dir is ah->fname
953		       file is ent->d_name
954		       path to match is ah1->fname */
955
956		    for (ah1 = daemon->addn_hosts; ah1; ah1 = ah1->next)
957		      {
958			if (lendir < strlen(ah1->fname) &&
959			    strstr(ah1->fname, ah->fname) == ah1->fname &&
960			    ah1->fname[lendir] == '/' &&
961			    strcmp(ah1->fname + lendir + 1, ent->d_name) == 0)
962			  {
963			    ah1->flags &= ~AH_INACTIVE;
964			    break;
965			  }
966		      }
967
968		    /* make new record */
969		    if (!ah1)
970		      {
971			if (!(ah1 = whine_malloc(sizeof(struct hostsfile))))
972			  continue;
973
974			if (!(path = whine_malloc(lendir + lenfile + 2)))
975			  {
976			    free(ah1);
977			    continue;
978			  }
979
980			strcpy(path, ah->fname);
981			strcat(path, "/");
982			strcat(path, ent->d_name);
983			ah1->fname = path;
984			ah1->index = i++;
985			ah1->flags = AH_DIR;
986			ah1->next = daemon->addn_hosts;
987			daemon->addn_hosts = ah1;
988		      }
989
990		    /* inactivate record if not regular file */
991		    if ((ah1->flags & AH_DIR) && stat(ah1->fname, &buf) != -1 && !S_ISREG(buf.st_mode))
992		      ah1->flags |= AH_INACTIVE;
993
994		  }
995		closedir(dir_stream);
996	      }
997	  }
998      }
999
1000  for (ah = daemon->addn_hosts; ah; ah = ah->next)
1001    if (!(ah->flags & AH_INACTIVE))
1002      total_size = read_hostsfile(ah->fname, ah->index, total_size);
1003}
1004
1005char *get_domain(struct in_addr addr)
1006{
1007  struct cond_domain *c;
1008
1009  for (c = daemon->cond_domain; c; c = c->next)
1010    if (ntohl(addr.s_addr) >= ntohl(c->start.s_addr) &&
1011        ntohl(addr.s_addr) <= ntohl(c->end.s_addr))
1012      return c->domain;
1013
1014  return daemon->domain_suffix;
1015}
1016
1017#ifdef HAVE_DHCP
1018void cache_unhash_dhcp(void)
1019{
1020  struct crec *cache, **up;
1021  int i;
1022
1023  for (i=0; i<hash_size; i++)
1024    for (cache = hash_table[i], up = &hash_table[i]; cache; cache = cache->hash_next)
1025      if (cache->flags & F_DHCP)
1026	{
1027	  *up = cache->hash_next;
1028	  cache->next = dhcp_spare;
1029	  dhcp_spare = cache;
1030	}
1031      else
1032	up = &cache->hash_next;
1033}
1034
1035void cache_add_dhcp_entry(char *host_name,
1036			  struct in_addr *host_address, time_t ttd)
1037{
1038  struct crec *crec = NULL, *aliasc;
1039  unsigned short flags =  F_DHCP | F_FORWARD | F_IPV4 | F_REVERSE;
1040  int in_hosts = 0;
1041  struct cname *a;
1042
1043  while ((crec = cache_find_by_name(crec, host_name, 0, F_IPV4 | F_CNAME)))
1044    {
1045      /* check all addresses associated with name */
1046      if (crec->flags & F_HOSTS)
1047	{
1048	  if (crec->addr.addr.addr.addr4.s_addr != host_address->s_addr)
1049	    {
1050	      strcpy(daemon->namebuff, inet_ntoa(crec->addr.addr.addr.addr4));
1051	      my_syslog(LOG_WARNING,
1052			_("not giving name %s to the DHCP lease of %s because "
1053			  "the name exists in %s with address %s"),
1054			host_name, inet_ntoa(*host_address),
1055			record_source(crec->uid), daemon->namebuff);
1056	      return;
1057	    }
1058	  else
1059	    /* if in hosts, don't need DHCP record */
1060	    in_hosts = 1;
1061	}
1062      else if (!(crec->flags & F_DHCP))
1063	{
1064	  cache_scan_free(host_name, NULL, 0, crec->flags & (F_IPV4 | F_CNAME | F_FORWARD));
1065	  /* scan_free deletes all addresses associated with name */
1066	  break;
1067	}
1068    }
1069
1070   if (in_hosts)
1071    return;
1072
1073   if ((crec = cache_find_by_addr(NULL, (struct all_addr *)host_address, 0, F_IPV4)))
1074     {
1075       if (crec->flags & F_NEG)
1076	 cache_scan_free(NULL, (struct all_addr *)host_address, 0, F_IPV4 | F_REVERSE);
1077       else
1078	 /* avoid multiple reverse mappings */
1079	 flags &= ~F_REVERSE;
1080     }
1081
1082   if ((crec = dhcp_spare))
1083    dhcp_spare = dhcp_spare->next;
1084  else /* need new one */
1085    crec = whine_malloc(sizeof(struct crec));
1086
1087  if (crec) /* malloc may fail */
1088    {
1089      crec->flags = flags;
1090      if (ttd == 0)
1091	crec->flags |= F_IMMORTAL;
1092      else
1093	crec->ttd = ttd;
1094      crec->addr.addr.addr.addr4 = *host_address;
1095      crec->name.namep = host_name;
1096      crec->uid = uid++;
1097      cache_hash(crec);
1098
1099      for (a = daemon->cnames; a; a = a->next)
1100	if (hostname_isequal(host_name, a->target))
1101	  {
1102	    if ((aliasc = dhcp_spare))
1103	      dhcp_spare = dhcp_spare->next;
1104	    else /* need new one */
1105	      aliasc = whine_malloc(sizeof(struct crec));
1106
1107	    if (aliasc)
1108	      {
1109		aliasc->flags = F_FORWARD | F_CONFIG | F_DHCP | F_CNAME;
1110		if (ttd == 0)
1111		  aliasc->flags |= F_IMMORTAL;
1112		else
1113		  aliasc->ttd = ttd;
1114		aliasc->name.namep = a->alias;
1115		aliasc->addr.cname.cache = crec;
1116		aliasc->addr.cname.uid = crec->uid;
1117		cache_hash(aliasc);
1118	      }
1119	  }
1120    }
1121}
1122#endif
1123
1124
1125void dump_cache(time_t now)
1126{
1127  struct server *serv, *serv1;
1128
1129  my_syslog(LOG_INFO, _("time %lu"), (unsigned long)now);
1130  my_syslog(LOG_INFO, _("cache size %d, %d/%d cache insertions re-used unexpired cache entries."),
1131	    daemon->cachesize, cache_live_freed, cache_inserted);
1132  my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"),
1133	    daemon->queries_forwarded, daemon->local_answer);
1134
1135  if (!addrbuff && !(addrbuff = whine_malloc(ADDRSTRLEN)))
1136    return;
1137
1138  /* sum counts from different records for same server */
1139  for (serv = daemon->servers; serv; serv = serv->next)
1140    serv->flags &= ~SERV_COUNTED;
1141
1142  for (serv = daemon->servers; serv; serv = serv->next)
1143    if (!(serv->flags & (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED)))
1144      {
1145	int port;
1146	unsigned int queries = 0, failed_queries = 0;
1147	for (serv1 = serv; serv1; serv1 = serv1->next)
1148	  if (!(serv1->flags & (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED)) && sockaddr_isequal(&serv->addr, &serv1->addr))
1149	    {
1150	      serv1->flags |= SERV_COUNTED;
1151	      queries += serv1->queries;
1152	      failed_queries += serv1->failed_queries;
1153	    }
1154	port = prettyprint_addr(&serv->addr, addrbuff);
1155	my_syslog(LOG_INFO, _("server %s#%d: queries sent %u, retried or failed %u"), addrbuff, port, queries, failed_queries);
1156      }
1157
1158  if ((daemon->options & (OPT_DEBUG | OPT_LOG)))
1159    {
1160      struct crec *cache ;
1161      int i;
1162      my_syslog(LOG_DEBUG, "Host                                     Address                        Flags     Expires");
1163
1164      for (i=0; i<hash_size; i++)
1165	for (cache = hash_table[i]; cache; cache = cache->hash_next)
1166	  {
1167	    char *a, *p = daemon->namebuff;
1168	    p += sprintf(p, "%-40.40s ", cache_get_name(cache));
1169	    if ((cache->flags & F_NEG) && (cache->flags & F_FORWARD))
1170	      a = "";
1171	    else if (cache->flags & F_CNAME)
1172	      {
1173		a = "";
1174		if (!is_outdated_cname_pointer(cache))
1175		  a = cache_get_name(cache->addr.cname.cache);
1176	      }
1177#ifdef HAVE_IPV6
1178	    else
1179	      {
1180		a = addrbuff;
1181		if (cache->flags & F_IPV4)
1182		  inet_ntop(AF_INET, &cache->addr.addr, addrbuff, ADDRSTRLEN);
1183		else if (cache->flags & F_IPV6)
1184		  inet_ntop(AF_INET6, &cache->addr.addr, addrbuff, ADDRSTRLEN);
1185	      }
1186#else
1187            else
1188	      a = inet_ntoa(cache->addr.addr.addr.addr4);
1189#endif
1190	    p += sprintf(p, "%-30.30s %s%s%s%s%s%s%s%s%s%s  ", a,
1191			 cache->flags & F_IPV4 ? "4" : "",
1192			 cache->flags & F_IPV6 ? "6" : "",
1193			 cache->flags & F_CNAME ? "C" : "",
1194			 cache->flags & F_FORWARD ? "F" : " ",
1195			 cache->flags & F_REVERSE ? "R" : " ",
1196			 cache->flags & F_IMMORTAL ? "I" : " ",
1197			 cache->flags & F_DHCP ? "D" : " ",
1198			 cache->flags & F_NEG ? "N" : " ",
1199			 cache->flags & F_NXDOMAIN ? "X" : " ",
1200			 cache->flags & F_HOSTS ? "H" : " ");
1201#ifdef HAVE_BROKEN_RTC
1202	    p += sprintf(p, "%lu", cache->flags & F_IMMORTAL ? 0: (unsigned long)(cache->ttd - now));
1203#else
1204	    p += sprintf(p, "%s", cache->flags & F_IMMORTAL ? "\n" : ctime(&(cache->ttd)));
1205	    /* ctime includes trailing \n - eat it */
1206	    *(p-1) = 0;
1207#endif
1208	    my_syslog(LOG_DEBUG, daemon->namebuff);
1209	  }
1210    }
1211}
1212
1213char *record_source(int index)
1214{
1215  struct hostsfile *ah;
1216
1217  if (index == 0)
1218    return HOSTSFILE;
1219
1220  for (ah = daemon->addn_hosts; ah; ah = ah->next)
1221    if (ah->index == index)
1222      return ah->fname;
1223
1224  return "<unknown>";
1225}
1226
1227void querystr(char *str, unsigned short type)
1228{
1229  unsigned int i;
1230
1231  sprintf(str, "query[type=%d]", type);
1232  for (i = 0; i < (sizeof(typestr)/sizeof(typestr[0])); i++)
1233    if (typestr[i].type == type)
1234      sprintf(str,"query[%s]", typestr[i].name);
1235}
1236
1237void log_query(unsigned short flags, char *name, struct all_addr *addr, char *arg)
1238{
1239  char *source, *dest = addrbuff;
1240  char *verb = "is";
1241
1242  if (!(daemon->options & OPT_LOG))
1243    return;
1244
1245  if (addr)
1246    {
1247#ifdef HAVE_IPV6
1248      inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6,
1249		addr, addrbuff, ADDRSTRLEN);
1250#else
1251      strncpy(addrbuff, inet_ntoa(addr->addr.addr4), ADDRSTRLEN);
1252#endif
1253    }
1254
1255  if (flags & F_REVERSE)
1256    {
1257      dest = name;
1258      name = addrbuff;
1259    }
1260
1261  if (flags & F_NEG)
1262    {
1263      if (flags & F_NXDOMAIN)
1264	{
1265	  if (flags & F_IPV4)
1266	    dest = "NXDOMAIN-IPv4";
1267	  else if (flags & F_IPV6)
1268	    dest = "NXDOMAIN-IPv6";
1269	  else
1270	    dest = "NXDOMAIN";
1271	}
1272      else
1273	{
1274	  if (flags & F_IPV4)
1275	    dest = "NODATA-IPv4";
1276	  else if (flags & F_IPV6)
1277	    dest = "NODATA-IPv6";
1278	  else
1279	    dest = "NODATA";
1280	}
1281    }
1282  else if (flags & F_CNAME)
1283    {
1284      /* nasty abuse of NXDOMAIN and CNAME flags */
1285      if (flags & F_NXDOMAIN)
1286	dest = arg;
1287      else
1288	dest = "<CNAME>";
1289    }
1290
1291  if (flags & F_CONFIG)
1292    source = "config";
1293  else if (flags & F_DHCP)
1294    source = "DHCP";
1295  else if (flags & F_HOSTS)
1296    source = arg;
1297  else if (flags & F_UPSTREAM)
1298    source = "reply";
1299  else if (flags & F_SERVER)
1300    {
1301      source = "forwarded";
1302      verb = "to";
1303    }
1304  else if (flags & F_QUERY)
1305    {
1306      source = arg;
1307      verb = "from";
1308    }
1309  else
1310    source = "cached";
1311
1312  if (strlen(name) == 0)
1313    name = ".";
1314
1315  my_syslog(LOG_DEBUG, "%s %s %s %s", source, name, verb, dest);
1316}
1317
1318