]>
git.ipfire.org Git - people/ms/dnsmasq.git/blob - src/cache.c
1 /* dnsmasq is Copyright (c) 2000-2005 Simon Kelley
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 dated June, 1991.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
15 static struct crec
*cache_head
, *cache_tail
, **hash_table
;
16 static struct crec
*dhcp_inuse
, *dhcp_spare
, *new_chain
;
17 static int cache_inserted
, cache_live_freed
, insert_error
;
18 static union bigname
*big_free
;
19 static int bignames_left
, log_queries
, cache_size
, hash_size
;
21 static char *addrbuff
;
23 /* type->string mapping: this is also used by the name-hash function as a mixing table. */
26 const char * const name
;
59 static void cache_free(struct crec
*crecp
);
60 static void cache_unlink(struct crec
*crecp
);
61 static void cache_link(struct crec
*crecp
);
62 static char *record_source(struct hostsfile
*add_hosts
, int index
);
63 static void rehash(int size
);
64 static void cache_hash(struct crec
*crecp
);
66 void cache_init(int size
, int logq
)
71 if ((log_queries
= logq
))
72 addrbuff
= safe_malloc(ADDRSTRLEN
);
76 cache_head
= cache_tail
= NULL
;
77 dhcp_inuse
= dhcp_spare
= NULL
;
82 bignames_left
= size
/10;
85 cache_inserted
= cache_live_freed
= 0;
89 crecp
= safe_malloc(size
*sizeof(struct crec
));
91 for (i
=0; i
<size
; i
++, crecp
++)
99 /* create initial hash table*/
103 /* In most cases, we create the hash table once here by calling this with (hash_table == NULL)
104 but if the hosts file(s) are big (some people have 50000 ad-block entries), the table
105 will be much too small, so the hosts reading code calls rehash every 1000 addresses, to
107 static void rehash(int size
)
109 struct crec
**new, **old
, *p
, *tmp
;
110 int i
, new_size
, old_size
;
112 /* hash_size is a power of two. */
113 for (new_size
= 64; new_size
< size
/10; new_size
= new_size
<< 1);
115 /* must succeed in getting first instance, failure later is non-fatal */
117 new = safe_malloc(new_size
* sizeof(struct crec
*));
118 else if (new_size
<= hash_size
|| !(new = malloc(new_size
* sizeof(struct crec
*))))
121 for(i
= 0; i
< new_size
; i
++)
125 old_size
= hash_size
;
127 hash_size
= new_size
;
131 for (i
= 0; i
< old_size
; i
++)
132 for (p
= old
[i
]; p
; p
= tmp
)
141 static struct crec
**hash_bucket(char *name
)
143 unsigned int c
, val
= 017465; /* Barker code - minimum self-correlation in cyclic shift */
144 const unsigned char *mix_tab
= (const unsigned char*)typestr
;
146 while((c
= (unsigned char) *name
++))
148 /* don't use tolower and friends here - they may be messed up by LOCALE */
149 if (c
>= 'A' && c
<= 'Z')
151 val
= ((val
<< 7) | (val
>> (32 - 7))) + (mix_tab
[(val
+ c
) & 0x3F] ^ c
);
154 /* hash_size is a power of two */
155 return hash_table
+ ((val
^ (val
>> 16)) & (hash_size
- 1));
158 static void cache_hash(struct crec
*crecp
)
160 struct crec
**bucket
= hash_bucket(cache_get_name(crecp
));
161 crecp
->hash_next
= *bucket
;
165 static void cache_free(struct crec
*crecp
)
167 crecp
->flags
&= ~F_FORWARD
;
168 crecp
->flags
&= ~F_REVERSE
;
169 crecp
->uid
= uid
++; /* invalidate CNAMES pointing to this. */
172 cache_tail
->next
= crecp
;
175 crecp
->prev
= cache_tail
;
179 /* retrieve big name for further use. */
180 if (crecp
->flags
& F_BIGNAME
)
182 crecp
->name
.bname
->next
= big_free
;
183 big_free
= crecp
->name
.bname
;
184 crecp
->flags
&= ~F_BIGNAME
;
188 /* insert a new cache entry at the head of the list (youngest entry) */
189 static void cache_link(struct crec
*crecp
)
191 if (cache_head
) /* check needed for init code */
192 cache_head
->prev
= crecp
;
193 crecp
->next
= cache_head
;
200 /* remove an arbitrary cache entry for promotion */
201 static void cache_unlink (struct crec
*crecp
)
204 crecp
->prev
->next
= crecp
->next
;
206 cache_head
= crecp
->next
;
209 crecp
->next
->prev
= crecp
->prev
;
211 cache_tail
= crecp
->prev
;
214 char *cache_get_name(struct crec
*crecp
)
216 if (crecp
->flags
& F_BIGNAME
)
217 return crecp
->name
.bname
->name
;
218 else if (crecp
->flags
& F_DHCP
)
219 return crecp
->name
.namep
;
221 return crecp
->name
.sname
;
224 static int is_outdated_cname_pointer(struct crec
*crecp
)
226 struct crec
*target
= crecp
->addr
.cname
.cache
;
228 if (!(crecp
->flags
& F_CNAME
))
234 if (crecp
->addr
.cname
.uid
== target
->uid
)
240 static int is_expired(time_t now
, struct crec
*crecp
)
242 if (crecp
->flags
& F_IMMORTAL
)
245 if (difftime(now
, crecp
->ttd
) < 0)
251 static int cache_scan_free(char *name
, struct all_addr
*addr
, time_t now
, unsigned short flags
)
253 /* Scan and remove old entries.
254 If (flags & F_FORWARD) then remove any forward entries for name and any expired
255 entries but only in the same hash bucket as name.
256 If (flags & F_REVERSE) then remove any reverse entries for addr and any expired
257 entries in the whole cache.
258 If (flags == 0) remove any expired entries in the whole cache.
260 In the flags & F_FORWARD case, the return code is valid, and returns zero if the
261 name exists in the cache as a HOSTS or DHCP entry (these are never deleted) */
263 struct crec
*crecp
, **up
;
265 if (flags
& F_FORWARD
)
267 for (up
= hash_bucket(name
), crecp
= *up
; crecp
; crecp
= crecp
->hash_next
)
268 if (is_expired(now
, crecp
) || is_outdated_cname_pointer(crecp
))
270 *up
= crecp
->hash_next
;
271 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
)))
277 else if ((crecp
->flags
& F_FORWARD
) &&
278 ((flags
& crecp
->flags
& (F_IPV4
| F_IPV6
)) || ((crecp
->flags
| flags
) & F_CNAME
)) &&
279 hostname_isequal(cache_get_name(crecp
), name
))
281 if (crecp
->flags
& (F_HOSTS
| F_DHCP
))
283 *up
= crecp
->hash_next
;
288 up
= &crecp
->hash_next
;
294 int addrlen
= (flags
& F_IPV6
) ? IN6ADDRSZ
: INADDRSZ
;
296 int addrlen
= INADDRSZ
;
298 for (i
= 0; i
< hash_size
; i
++)
299 for (crecp
= hash_table
[i
], up
= &hash_table
[i
]; crecp
; crecp
= crecp
->hash_next
)
300 if (is_expired(now
, crecp
))
302 *up
= crecp
->hash_next
;
303 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
)))
309 else if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
)) &&
310 (flags
& crecp
->flags
& F_REVERSE
) &&
311 (flags
& crecp
->flags
& (F_IPV4
| F_IPV6
)) &&
312 memcmp(&crecp
->addr
.addr
, addr
, addrlen
) == 0)
314 *up
= crecp
->hash_next
;
319 up
= &crecp
->hash_next
;
325 /* Note: The normal calling sequence is
330 but an abort can cause the cache_end_insert to be missed
331 in which can the next cache_start_insert cleans things up. */
333 void cache_start_insert(void)
335 /* Free any entries which didn't get committed during the last
340 struct crec
*tmp
= new_chain
->next
;
341 cache_free(new_chain
);
348 struct crec
*cache_insert(char *name
, struct all_addr
*addr
,
349 time_t now
, unsigned long ttl
, unsigned short flags
)
352 int addrlen
= (flags
& F_IPV6
) ? IN6ADDRSZ
: INADDRSZ
;
354 int addrlen
= INADDRSZ
;
357 union bigname
*big_name
= NULL
;
358 int freed_all
= flags
& F_REVERSE
;
360 log_query(flags
| F_UPSTREAM
, name
, addr
, 0, NULL
, 0);
362 /* name is needed as workspace by log_query in this case */
363 if ((flags
& F_NEG
) && (flags
& F_REVERSE
))
366 /* CONFIG bit no needed except for logging */
369 /* if previous insertion failed give up now. */
373 /* First remove any expired entries and entries for the name/address we
374 are currently inserting. Fail is we attempt to delete a name from
375 /etc/hosts or DHCP. */
376 if (!cache_scan_free(name
, addr
, now
, flags
))
382 /* Now get a cache entry from the end of the LRU list */
384 if (!(new = cache_tail
)) /* no entries left - cache is too small, bail */
390 /* End of LRU list is still in use: if we didn't scan all the hash
391 chains for expired entries do that now. If we already tried that
392 then it's time to start spilling things. */
394 if (new->flags
& (F_FORWARD
| F_REVERSE
))
398 cache_scan_free(cache_get_name(new), &new->addr
.addr
, now
, new->flags
);
403 cache_scan_free(NULL
, NULL
, now
, 0);
409 /* Check if we need to and can allocate extra memory for a long name.
410 If that fails, give up now. */
411 if (name
&& (strlen(name
) > SMALLDNAME
-1))
416 big_free
= big_free
->next
;
418 else if (!bignames_left
||
419 !(big_name
= (union bigname
*)malloc(sizeof(union bigname
))))
429 /* Got the rest: finally grab entry. */
437 new->name
.bname
= big_name
;
438 new->flags
|= F_BIGNAME
;
441 strcpy(cache_get_name(new), name
);
443 *cache_get_name(new) = 0;
445 memcpy(&new->addr
.addr
, addr
, addrlen
);
447 new->addr
.cname
.cache
= NULL
;
449 new->ttd
= now
+ (time_t)ttl
;
450 new->next
= new_chain
;
456 /* after end of insertion, commit the new entries */
457 void cache_end_insert(void)
464 struct crec
*tmp
= new_chain
->next
;
465 /* drop CNAMEs which didn't find a target. */
466 if (is_outdated_cname_pointer(new_chain
))
467 cache_free(new_chain
);
470 cache_hash(new_chain
);
471 cache_link(new_chain
);
479 struct crec
*cache_find_by_name(struct crec
*crecp
, char *name
, time_t now
, unsigned short prot
)
483 if (crecp
) /* iterating */
487 /* first search, look for relevant entries and push to top of list
488 also free anything which has expired */
489 struct crec
*next
, **up
, **insert
= NULL
, **chainp
= &ans
;
491 for (up
= hash_bucket(name
), crecp
= *up
; crecp
; crecp
= next
)
493 next
= crecp
->hash_next
;
495 if (!is_expired(now
, crecp
) && !is_outdated_cname_pointer(crecp
))
497 if ((crecp
->flags
& F_FORWARD
) &&
498 (crecp
->flags
& prot
) &&
499 hostname_isequal(cache_get_name(crecp
), name
))
501 if (crecp
->flags
& (F_HOSTS
| F_DHCP
))
504 chainp
= &crecp
->next
;
512 /* move all but the first entry up the hash chain
513 this implements round-robin */
517 up
= &crecp
->hash_next
;
521 *up
= crecp
->hash_next
;
522 crecp
->hash_next
= *insert
;
524 insert
= &crecp
->hash_next
;
528 /* case : not expired, incorrect entry. */
529 up
= &crecp
->hash_next
;
533 /* expired entry, free it */
534 *up
= crecp
->hash_next
;
535 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
)))
543 *chainp
= cache_head
;
547 (ans
->flags
& F_FORWARD
) &&
548 (ans
->flags
& prot
) &&
549 hostname_isequal(cache_get_name(ans
), name
))
555 struct crec
*cache_find_by_addr(struct crec
*crecp
, struct all_addr
*addr
,
556 time_t now
, unsigned short prot
)
560 int addrlen
= (prot
== F_IPV6
) ? IN6ADDRSZ
: INADDRSZ
;
562 int addrlen
= INADDRSZ
;
565 if (crecp
) /* iterating */
569 /* first search, look for relevant entries and push to top of list
570 also free anything which has expired */
572 struct crec
**up
, **chainp
= &ans
;
574 for(i
=0; i
<hash_size
; i
++)
575 for (crecp
= hash_table
[i
], up
= &hash_table
[i
]; crecp
; crecp
= crecp
->hash_next
)
576 if (!is_expired(now
, crecp
))
578 if ((crecp
->flags
& F_REVERSE
) &&
579 (crecp
->flags
& prot
) &&
580 memcmp(&crecp
->addr
.addr
, addr
, addrlen
) == 0)
582 if (crecp
->flags
& (F_HOSTS
| F_DHCP
))
585 chainp
= &crecp
->next
;
593 up
= &crecp
->hash_next
;
597 *up
= crecp
->hash_next
;
598 if (!(crecp
->flags
& (F_HOSTS
| F_DHCP
)))
605 *chainp
= cache_head
;
609 (ans
->flags
& F_REVERSE
) &&
610 (ans
->flags
& prot
) &&
611 memcmp(&ans
->addr
.addr
, addr
, addrlen
) == 0)
617 static void add_hosts_entry(struct crec
*cache
, struct all_addr
*addr
, int addrlen
,
618 unsigned short flags
, int index
, int addr_dup
)
620 struct crec
*lookup
= cache_find_by_name(NULL
, cache
->name
.sname
, 0, flags
& (F_IPV4
| F_IPV6
));
623 /* Remove duplicates in hosts files. */
624 if (lookup
&& (lookup
->flags
& F_HOSTS
) &&
625 memcmp(&lookup
->addr
.addr
, addr
, addrlen
) == 0)
629 /* Ensure there is only one address -> name mapping (first one trumps)
630 We do this by steam here, first we see if the address is the same as
631 the last one we saw, which eliminates most in the case of an ad-block
632 file with thousands of entries for the same address.
633 Then we search and bail at the first matching address that came from
634 a HOSTS file. Since the first host entry gets reverse, we know
635 then that it must exist without searching exhaustively for it. */
640 for (i
=0; i
<hash_size
; i
++)
642 for (lookup
= hash_table
[i
]; lookup
; lookup
= lookup
->hash_next
)
643 if ((lookup
->flags
& F_HOSTS
) &&
644 (lookup
->flags
& flags
& (F_IPV4
| F_IPV6
)) &&
645 memcmp(&lookup
->addr
.addr
, addr
, addrlen
) == 0)
654 cache
->flags
= flags
;
656 memcpy(&cache
->addr
.addr
, addr
, addrlen
);
661 static int read_hostsfile(char *filename
, int opts
, char *buff
, char *domain_suffix
, int index
, int cache_size
)
663 FILE *f
= fopen(filename
, "r");
665 int addr_count
= 0, name_count
= cache_size
, lineno
= 0;
666 unsigned short flags
, saved_flags
= 0;
667 struct all_addr addr
, saved_addr
;
671 syslog(LOG_ERR
, _("failed to load names from %s: %m"), filename
);
675 while ((line
= fgets(buff
, MAXDNAME
, f
)))
677 char *token
= strtok(line
, " \t\n\r");
678 int addrlen
, addr_dup
= 0;
682 if (!token
|| (*token
== '#'))
686 if (inet_pton(AF_INET
, token
, &addr
) > 0)
688 flags
= F_HOSTS
| F_IMMORTAL
| F_FORWARD
| F_REVERSE
| F_IPV4
;
691 else if (inet_pton(AF_INET6
, token
, &addr
) > 0)
693 flags
= F_HOSTS
| F_IMMORTAL
| F_FORWARD
| F_REVERSE
| F_IPV6
;
697 if ((addr
.addr
.addr4
.s_addr
= inet_addr(token
)) != (in_addr_t
) -1)
699 flags
= F_HOSTS
| F_IMMORTAL
| F_FORWARD
| F_REVERSE
| F_IPV4
;
705 syslog(LOG_ERR
, _("bad address at %s line %d"), filename
, lineno
);
709 if (saved_flags
== flags
&& memcmp(&addr
, &saved_addr
, addrlen
) == 0)
719 /* rehash every 1000 names. */
720 if ((name_count
- cache_size
) > 1000)
723 cache_size
= name_count
;
726 while ((token
= strtok(NULL
, " \t\n\r")) && (*token
!= '#'))
729 if (canonicalise(token
))
731 /* If set, add a version of the name with a default domain appended */
732 if ((opts
& OPT_EXPAND
) && domain_suffix
&& !strchr(token
, '.') &&
733 (cache
= malloc(sizeof(struct crec
) +
734 strlen(token
)+2+strlen(domain_suffix
)-SMALLDNAME
)))
736 strcpy(cache
->name
.sname
, token
);
737 strcat(cache
->name
.sname
, ".");
738 strcat(cache
->name
.sname
, domain_suffix
);
739 add_hosts_entry(cache
, &addr
, addrlen
, flags
, index
, addr_dup
);
743 if ((cache
= malloc(sizeof(struct crec
) + strlen(token
)+1-SMALLDNAME
)))
745 strcpy(cache
->name
.sname
, token
);
746 add_hosts_entry(cache
, &addr
, addrlen
, flags
, index
, addr_dup
);
751 syslog(LOG_ERR
, _("bad name at %s line %d"), filename
, lineno
);
758 syslog(LOG_INFO
, _("read %s - %d addresses"), filename
, addr_count
);
763 void cache_reload(int opts
, char *buff
, char *domain_suffix
, struct hostsfile
*addn_hosts
)
765 struct crec
*cache
, **up
, *tmp
;
766 int i
, total_size
= cache_size
;
768 cache_inserted
= cache_live_freed
= 0;
770 for (i
=0; i
<hash_size
; i
++)
771 for (cache
= hash_table
[i
], up
= &hash_table
[i
]; cache
; cache
= tmp
)
773 tmp
= cache
->hash_next
;
774 if (cache
->flags
& F_HOSTS
)
776 *up
= cache
->hash_next
;
779 else if (!(cache
->flags
& F_DHCP
))
781 *up
= cache
->hash_next
;
782 if (cache
->flags
& F_BIGNAME
)
784 cache
->name
.bname
->next
= big_free
;
785 big_free
= cache
->name
.bname
;
790 up
= &cache
->hash_next
;
793 if ((opts
& OPT_NO_HOSTS
) && !addn_hosts
)
796 syslog(LOG_INFO
, _("cleared cache"));
800 if (!(opts
& OPT_NO_HOSTS
))
801 total_size
= read_hostsfile(HOSTSFILE
, opts
, buff
, domain_suffix
, 0, total_size
);
804 total_size
= read_hostsfile(addn_hosts
->fname
, opts
, buff
, domain_suffix
, addn_hosts
->index
, total_size
);
805 addn_hosts
= addn_hosts
->next
;
809 void cache_unhash_dhcp(void)
811 struct crec
*tmp
, *cache
, **up
;
814 for (i
=0; i
<hash_size
; i
++)
815 for (cache
= hash_table
[i
], up
= &hash_table
[i
]; cache
; cache
= cache
->hash_next
)
816 if (cache
->flags
& F_DHCP
)
817 *up
= cache
->hash_next
;
819 up
= &cache
->hash_next
;
821 /* prev field links all dhcp entries */
822 for (cache
= dhcp_inuse
; cache
; cache
= tmp
)
825 cache
->prev
= dhcp_spare
;
832 void cache_add_dhcp_entry(struct daemon
*daemon
, char *host_name
,
833 struct in_addr
*host_address
, time_t ttd
)
836 unsigned short flags
= F_DHCP
| F_FORWARD
| F_IPV4
| F_REVERSE
;
841 if ((crec
= cache_find_by_name(NULL
, host_name
, 0, F_IPV4
| F_CNAME
)))
843 if (crec
->flags
& F_HOSTS
)
845 if (crec
->addr
.addr
.addr
.addr4
.s_addr
!= host_address
->s_addr
)
847 strcpy(daemon
->namebuff
, inet_ntoa(crec
->addr
.addr
.addr
.addr4
));
849 _("not giving name %s to the DHCP lease of %s because "
850 "the name exists in %s with address %s"),
851 host_name
, inet_ntoa(*host_address
),
852 record_source(daemon
->addn_hosts
, crec
->uid
), daemon
->namebuff
);
856 else if (!(crec
->flags
& F_DHCP
))
857 cache_scan_free(host_name
, NULL
, 0, crec
->flags
& (F_IPV4
| F_CNAME
| F_FORWARD
));
860 if ((crec
= cache_find_by_addr(NULL
, (struct all_addr
*)host_address
, 0, F_IPV4
)))
862 if (crec
->flags
& F_NEG
)
863 cache_scan_free(NULL
, (struct all_addr
*)host_address
, 0, F_IPV4
| F_REVERSE
);
865 /* avoid multiple reverse mappings */
869 if ((crec
= dhcp_spare
))
870 dhcp_spare
= dhcp_spare
->prev
;
871 else /* need new one */
872 crec
= malloc(sizeof(struct crec
));
874 if (crec
) /* malloc may fail */
878 crec
->flags
|= F_IMMORTAL
;
881 crec
->addr
.addr
.addr
.addr4
= *host_address
;
882 crec
->name
.namep
= host_name
;
883 crec
->prev
= dhcp_inuse
;
891 void dump_cache(struct daemon
*daemon
, time_t now
)
893 syslog(LOG_INFO
, _("time %lu, cache size %d, %d/%d cache insertions re-used unexpired cache entries."),
894 (unsigned long)now
, daemon
->cachesize
, cache_live_freed
, cache_inserted
);
896 if ((daemon
->options
& (OPT_DEBUG
| OPT_LOG
)) &&
897 (addrbuff
|| (addrbuff
= malloc(ADDRSTRLEN
))))
901 syslog(LOG_DEBUG
, "Host Address Flags Expires");
903 for (i
=0; i
<hash_size
; i
++)
904 for (cache
= hash_table
[i
]; cache
; cache
= cache
->hash_next
)
906 if ((cache
->flags
& F_NEG
) && (cache
->flags
& F_FORWARD
))
908 else if (cache
->flags
& F_CNAME
)
911 addrbuff
[ADDRSTRLEN
-1] = 0;
912 if (!is_outdated_cname_pointer(cache
))
913 strncpy(addrbuff
, cache_get_name(cache
->addr
.cname
.cache
), ADDRSTRLEN
);
916 else if (cache
->flags
& F_IPV4
)
917 inet_ntop(AF_INET
, &cache
->addr
.addr
, addrbuff
, ADDRSTRLEN
);
918 else if (cache
->flags
& F_IPV6
)
919 inet_ntop(AF_INET6
, &cache
->addr
.addr
, addrbuff
, ADDRSTRLEN
);
922 strcpy(addrbuff
, inet_ntoa(cache
->addr
.addr
.addr
.addr4
));
925 #ifdef HAVE_BROKEN_RTC
926 "%-40.40s %-30.30s %s%s%s%s%s%s%s%s%s%s %lu",
928 "%-40.40s %-30.30s %s%s%s%s%s%s%s%s%s%s %s",
930 cache_get_name(cache
), addrbuff
,
931 cache
->flags
& F_IPV4
? "4" : "",
932 cache
->flags
& F_IPV6
? "6" : "",
933 cache
->flags
& F_CNAME
? "C" : "",
934 cache
->flags
& F_FORWARD
? "F" : " ",
935 cache
->flags
& F_REVERSE
? "R" : " ",
936 cache
->flags
& F_IMMORTAL
? "I" : " ",
937 cache
->flags
& F_DHCP
? "D" : " ",
938 cache
->flags
& F_NEG
? "N" : " ",
939 cache
->flags
& F_NXDOMAIN
? "X" : " ",
940 cache
->flags
& F_HOSTS
? "H" : " ",
941 #ifdef HAVE_BROKEN_RTC
942 cache
->flags
& F_IMMORTAL
? 0: (unsigned long)(cache
->ttd
- now
)
944 cache
->flags
& F_IMMORTAL
? "\n" : ctime(&(cache
->ttd
))
951 static char *record_source(struct hostsfile
*addn_hosts
, int index
)
953 char *source
= HOSTSFILE
;
956 if (addn_hosts
->index
== index
)
958 source
= addn_hosts
->fname
;
961 addn_hosts
= addn_hosts
->next
;
967 void log_query(unsigned short flags
, char *name
, struct all_addr
*addr
,
968 unsigned short type
, struct hostsfile
*addn_hosts
, int index
)
979 if (flags
& F_REVERSE
)
981 inet_ntop(flags
& F_IPV4
? AF_INET
: AF_INET6
,
982 addr
, name
, MAXDNAME
);
984 strcpy(name
, inet_ntoa(addr
->addr
.addr4
));
987 if (flags
& F_NXDOMAIN
)
988 strcpy(addrbuff
, "<NXDOMAIN>");
990 strcpy(addrbuff
, "<NODATA>");
993 strcat(addrbuff
, "-IPv4");
994 else if (flags
& F_IPV6
)
995 strcat(addrbuff
, "-IPv6");
997 else if (flags
& F_CNAME
)
999 /* nasty abuse of IPV4 and IPV6 flags */
1001 strcpy(addrbuff
, "<MX>");
1002 else if (flags
& F_IPV6
)
1003 strcpy(addrbuff
, "<SRV>");
1004 else if (flags
& F_NXDOMAIN
)
1005 strcpy(addrbuff
, "<TXT>");
1006 else if (flags
& F_BIGNAME
)
1007 strcpy(addrbuff
, "<PTR>");
1009 strcpy(addrbuff
, "<CNAME>");
1013 inet_ntop(flags
& F_IPV4
? AF_INET
: AF_INET6
,
1014 addr
, addrbuff
, ADDRSTRLEN
);
1016 strcpy(addrbuff
, inet_ntoa(addr
->addr
.addr4
));
1021 else if (flags
& F_HOSTS
)
1022 source
= record_source(addn_hosts
, index
);
1023 else if (flags
& F_CONFIG
)
1025 else if (flags
& F_UPSTREAM
)
1027 else if (flags
& F_SERVER
)
1029 source
= "forwarded";
1032 else if (flags
& F_QUERY
)
1038 sprintf(types
, "query[type=%d]", type
);
1039 for (i
= 0; i
< (sizeof(typestr
)/sizeof(typestr
[0])); i
++)
1040 if (typestr
[i
].type
== type
)
1041 sprintf(types
,"query[%s]", typestr
[i
].name
);
1049 if (strlen(name
) == 0)
1052 if ((flags
& F_FORWARD
) | (flags
& F_NEG
))
1053 syslog(LOG_DEBUG
, "%s %s %s %s", source
, name
, verb
, addrbuff
);
1054 else if (flags
& F_REVERSE
)
1055 syslog(LOG_DEBUG
, "%s %s is %s", source
, addrbuff
, name
);