mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Cache stats availble in CHAOS .bind domain.
This commit is contained in:
@@ -1753,12 +1753,22 @@ When it receives a SIGUSR1,
|
||||
writes statistics to the system log. It writes the cache size,
|
||||
the number of names which have had to removed from the cache before
|
||||
they expired in order to make room for new names and the total number
|
||||
of names that have been inserted into the cache. For each upstream
|
||||
of names that have been inserted into the cache. The number of cache hits and
|
||||
misses and the number of authoritative queries answered are also given. For each upstream
|
||||
server it gives the number of queries sent, and the number which
|
||||
resulted in an error. In
|
||||
.B --no-daemon
|
||||
mode or when full logging is enabled (-q), a complete dump of the
|
||||
contents of the cache is made.
|
||||
|
||||
The cache statistics are also available in the DNS as answers to
|
||||
queries of class CHAOS and type TXT in domain bind. The domain names are cachesize.bind, insertions.bind, evictions.bind,
|
||||
misses.bind, hits.bind, auth.bind and servers.bind. An example command to query this, using the
|
||||
.B dig
|
||||
utility would be
|
||||
|
||||
dig +short chaos txt cachesize.bind
|
||||
|
||||
.PP
|
||||
When it receives SIGUSR2 and it is logging direct to a file (see
|
||||
.B --log-facility
|
||||
|
||||
95
src/cache.c
95
src/cache.c
@@ -1262,6 +1262,101 @@ void cache_add_dhcp_entry(char *host_name, int prot,
|
||||
}
|
||||
#endif
|
||||
|
||||
int cache_make_stat(struct txt_record *t)
|
||||
{
|
||||
static char *buff = NULL;
|
||||
static int bufflen = 60;
|
||||
int len;
|
||||
struct server *serv, *serv1;
|
||||
char *p;
|
||||
|
||||
if (!buff && !(buff = whine_malloc(60)))
|
||||
return 0;
|
||||
|
||||
p = buff;
|
||||
|
||||
switch (t->stat)
|
||||
{
|
||||
case TXT_STAT_CACHESIZE:
|
||||
sprintf(buff+1, "%d", daemon->cachesize);
|
||||
break;
|
||||
|
||||
case TXT_STAT_INSERTS:
|
||||
sprintf(buff+1, "%d", cache_inserted);
|
||||
break;
|
||||
|
||||
case TXT_STAT_EVICTIONS:
|
||||
sprintf(buff+1, "%d", cache_live_freed);
|
||||
break;
|
||||
|
||||
case TXT_STAT_MISSES:
|
||||
sprintf(buff+1, "%u", daemon->queries_forwarded);
|
||||
break;
|
||||
|
||||
case TXT_STAT_HITS:
|
||||
sprintf(buff+1, "%u", daemon->local_answer);
|
||||
break;
|
||||
|
||||
#ifdef HAVE_AUTH
|
||||
case TXT_STAT_AUTH:
|
||||
sprintf(buff+1, "%u", daemon->auth_answer);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case TXT_STAT_SERVERS:
|
||||
/* sum counts from different records for same server */
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
serv->flags &= ~SERV_COUNTED;
|
||||
|
||||
for (serv = daemon->servers; serv; serv = serv->next)
|
||||
if (!(serv->flags &
|
||||
(SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED | SERV_USE_RESOLV | SERV_NO_REBIND)))
|
||||
{
|
||||
char *new, *lenp;
|
||||
int port, newlen, bytes_avail, bytes_needed;
|
||||
unsigned int queries = 0, failed_queries = 0;
|
||||
for (serv1 = serv; serv1; serv1 = serv1->next)
|
||||
if (!(serv1->flags &
|
||||
(SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED | SERV_USE_RESOLV | SERV_NO_REBIND)) &&
|
||||
sockaddr_isequal(&serv->addr, &serv1->addr))
|
||||
{
|
||||
serv1->flags |= SERV_COUNTED;
|
||||
queries += serv1->queries;
|
||||
failed_queries += serv1->failed_queries;
|
||||
}
|
||||
port = prettyprint_addr(&serv->addr, daemon->addrbuff);
|
||||
lenp = p++; /* length */
|
||||
bytes_avail = (p - buff) + bufflen;
|
||||
bytes_needed = snprintf(p, bytes_avail, "%s#%d %u %u", daemon->addrbuff, port, queries, failed_queries);
|
||||
if (bytes_needed >= bytes_avail)
|
||||
{
|
||||
/* expand buffer if necessary */
|
||||
newlen = bytes_needed + 1 + bufflen - bytes_avail;
|
||||
if (!(new = whine_malloc(newlen)))
|
||||
return 0;
|
||||
memcpy(new, buff, bufflen);
|
||||
free(buff);
|
||||
p = new + (p - buff);
|
||||
lenp = p - 1;
|
||||
buff = new;
|
||||
bufflen = newlen;
|
||||
bytes_avail = (p - buff) + bufflen;
|
||||
bytes_needed = snprintf(p, bytes_avail, "%s#%d %u %u", daemon->addrbuff, port, queries, failed_queries);
|
||||
}
|
||||
*lenp = bytes_needed;
|
||||
p += bytes_needed;
|
||||
}
|
||||
t->txt = (unsigned char *)buff;
|
||||
t->len = p - buff;
|
||||
return 1;
|
||||
}
|
||||
|
||||
len = strlen(buff+1);
|
||||
t->txt = (unsigned char *)buff;
|
||||
t->len = len + 1;
|
||||
*buff = len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void dump_cache(time_t now)
|
||||
{
|
||||
|
||||
@@ -280,10 +280,19 @@ struct naptr {
|
||||
struct naptr *next;
|
||||
};
|
||||
|
||||
#define TXT_STAT_CACHESIZE 1
|
||||
#define TXT_STAT_INSERTS 2
|
||||
#define TXT_STAT_EVICTIONS 3
|
||||
#define TXT_STAT_MISSES 4
|
||||
#define TXT_STAT_HITS 5
|
||||
#define TXT_STAT_AUTH 6
|
||||
#define TXT_STAT_SERVERS 7
|
||||
|
||||
struct txt_record {
|
||||
char *name;
|
||||
unsigned char *txt;
|
||||
unsigned short class, len;
|
||||
int stat;
|
||||
struct txt_record *next;
|
||||
};
|
||||
|
||||
@@ -1027,6 +1036,7 @@ void cache_add_dhcp_entry(char *host_name, int prot, struct all_addr *host_addre
|
||||
struct in_addr a_record_from_hosts(char *name, time_t now);
|
||||
void cache_unhash_dhcp(void);
|
||||
void dump_cache(time_t now);
|
||||
int cache_make_stat(struct txt_record *t);
|
||||
char *cache_get_name(struct crec *crecp);
|
||||
char *cache_get_cname_target(struct crec *crecp);
|
||||
struct crec *cache_enumerate(int init);
|
||||
|
||||
33
src/option.c
33
src/option.c
@@ -615,19 +615,24 @@ static int atoi_check8(char *a, int *res)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void add_txt(char *name, char *txt)
|
||||
static void add_txt(char *name, char *txt, int stat)
|
||||
{
|
||||
size_t len = strlen(txt);
|
||||
struct txt_record *r = opt_malloc(sizeof(struct txt_record));
|
||||
|
||||
if (txt)
|
||||
{
|
||||
size_t len = strlen(txt);
|
||||
r->txt = opt_malloc(len+1);
|
||||
r->len = len+1;
|
||||
*(r->txt) = len;
|
||||
memcpy((r->txt)+1, txt, len);
|
||||
}
|
||||
|
||||
r->stat = stat;
|
||||
r->name = opt_string_alloc(name);
|
||||
r->next = daemon->txt;
|
||||
daemon->txt = r;
|
||||
r->class = C_CHAOS;
|
||||
r->txt = opt_malloc(len+1);
|
||||
r->len = len+1;
|
||||
*(r->txt) = len;
|
||||
memcpy((r->txt)+1, txt, len);
|
||||
}
|
||||
|
||||
static void do_usage(void)
|
||||
@@ -3609,6 +3614,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
new->next = daemon->txt;
|
||||
daemon->txt = new;
|
||||
new->class = C_IN;
|
||||
new->stat = 0;
|
||||
|
||||
if (!(new->name = canonicalise_opt(arg)))
|
||||
ret_err(_("bad TXT record"));
|
||||
@@ -4258,9 +4264,18 @@ void read_opts(int argc, char **argv, char *compile_opts)
|
||||
daemon->soa_refresh = SOA_REFRESH;
|
||||
daemon->soa_retry = SOA_RETRY;
|
||||
daemon->soa_expiry = SOA_EXPIRY;
|
||||
add_txt("version.bind", "dnsmasq-" VERSION );
|
||||
add_txt("authors.bind", "Simon Kelley");
|
||||
add_txt("copyright.bind", COPYRIGHT);
|
||||
add_txt("version.bind", "dnsmasq-" VERSION, 0 );
|
||||
add_txt("authors.bind", "Simon Kelley", 0);
|
||||
add_txt("copyright.bind", COPYRIGHT, 0);
|
||||
add_txt("cachesize.bind", NULL, TXT_STAT_CACHESIZE);
|
||||
add_txt("insertions.bind", NULL, TXT_STAT_INSERTS);
|
||||
add_txt("evictions.bind", NULL, TXT_STAT_EVICTIONS);
|
||||
add_txt("misses.bind", NULL, TXT_STAT_MISSES);
|
||||
add_txt("hits.bind", NULL, TXT_STAT_HITS);
|
||||
#ifdef HAVE_AUTH
|
||||
add_txt("auth.bind", NULL, TXT_STAT_AUTH);
|
||||
#endif
|
||||
add_txt("servers.bind", NULL, TXT_STAT_SERVERS);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
||||
@@ -1547,10 +1547,20 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
||||
ans = 1;
|
||||
if (!dryrun)
|
||||
{
|
||||
unsigned long ttl = daemon->local_ttl;
|
||||
int ok = 1;
|
||||
log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
|
||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
daemon->local_ttl, NULL,
|
||||
T_TXT, t->class, "t", t->len, t->txt))
|
||||
/* Dynamically generate stat record */
|
||||
if (t->stat != 0)
|
||||
{
|
||||
ttl = 0;
|
||||
if (!cache_make_stat(t))
|
||||
ok = 0;
|
||||
}
|
||||
|
||||
if (ok && add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||
ttl, NULL,
|
||||
T_TXT, t->class, "t", t->len, t->txt))
|
||||
anscount++;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user