diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-12-23 19:06:36 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-12-26 19:09:10 +0100 |
commit | a150ff5e4e2481eb28d6ed6e0d3e176623e25f5a (patch) | |
tree | d21c32a68262a5c7ea74c5dd36ad6f96f6138bd7 /src/resolve | |
parent | ed29bfdce6ef8b1c6e14bb4e77e19e7048f35dd4 (diff) |
resolved: gather statistics about resolved names
This collects statistical data about transactions, dnssec verifications
and the cache, and exposes it over the bus. The systemd-resolve-host
tool learns new options to query these statistics and reset them.
Diffstat (limited to 'src/resolve')
-rw-r--r-- | src/resolve/resolved-bus.c | 85 | ||||
-rw-r--r-- | src/resolve/resolved-dns-cache.c | 27 | ||||
-rw-r--r-- | src/resolve/resolved-dns-cache.h | 4 | ||||
-rw-r--r-- | src/resolve/resolved-dns-transaction.c | 17 | ||||
-rw-r--r-- | src/resolve/resolved-manager.h | 3 |
5 files changed, 133 insertions, 3 deletions
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index af08a0555d..273bfbe949 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -1214,16 +1214,101 @@ static int bus_property_get_search_domains( return sd_bus_message_close_container(reply); } +static int bus_property_get_transaction_statistics( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + Manager *m = userdata; + + assert(reply); + assert(m); + + return sd_bus_message_append(reply, "(tt)", + (uint64_t) hashmap_size(m->dns_transactions), + (uint64_t) m->n_transactions_total); +} + +static int bus_property_get_cache_statistics( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + uint64_t size = 0, hit = 0, miss = 0; + Manager *m = userdata; + DnsScope *s; + + assert(reply); + assert(m); + + LIST_FOREACH(scopes, s, m->dns_scopes) { + size += dns_cache_size(&s->cache); + hit += s->cache.n_hit; + miss += s->cache.n_miss; + } + + return sd_bus_message_append(reply, "(ttt)", size, hit, miss); +} + +static int bus_property_get_dnssec_statistics( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + Manager *m = userdata; + + assert(reply); + assert(m); + + return sd_bus_message_append(reply, "(tttt)", + (uint64_t) m->n_dnssec_secure, + (uint64_t) m->n_dnssec_insecure, + (uint64_t) m->n_dnssec_bogus, + (uint64_t) m->n_dnssec_indeterminate); +} + +static int bus_method_reset_statistics(sd_bus_message *message, void *userdata, sd_bus_error *error) { + Manager *m = userdata; + DnsScope *s; + + assert(message); + assert(m); + + LIST_FOREACH(scopes, s, m->dns_scopes) + s->cache.n_hit = s->cache.n_miss = 0; + + m->n_transactions_total = 0; + m->n_dnssec_secure = m->n_dnssec_insecure = m->n_dnssec_bogus = m->n_dnssec_indeterminate = 0; + + return sd_bus_reply_method_return(message, NULL); +} + static const sd_bus_vtable resolve_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("LLMNRHostname", "s", NULL, offsetof(Manager, llmnr_hostname), 0), SD_BUS_PROPERTY("DNSServers", "a(iiay)", bus_property_get_dns_servers, 0, 0), SD_BUS_PROPERTY("SearchDomains", "a(is)", bus_property_get_search_domains, 0, 0), + SD_BUS_PROPERTY("TransactionStatistics", "(tt)", bus_property_get_transaction_statistics, 0, 0), + SD_BUS_PROPERTY("CacheStatistics", "(ttt)", bus_property_get_cache_statistics, 0, 0), + SD_BUS_PROPERTY("DNSSECStatistics", "(tttt)", bus_property_get_dnssec_statistics, 0, 0), SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, 0), SD_BUS_VTABLE_END, }; diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index f9fe2c2e30..49d5090d36 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -740,6 +740,8 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **r log_debug("Ignoring cache for ANY lookup: %s", key_str); } + c->n_miss++; + *ret = NULL; *rcode = DNS_RCODE_SUCCESS; return 0; @@ -757,6 +759,8 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **r log_debug("Cache miss for %s", key_str); } + c->n_miss++; + *ret = NULL; *rcode = DNS_RCODE_SUCCESS; return 0; @@ -794,9 +798,15 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **r *rcode = DNS_RCODE_SUCCESS; *authenticated = nsec->authenticated; - return !bitmap_isset(nsec->rr->nsec.types, key->type) && - !bitmap_isset(nsec->rr->nsec.types, DNS_TYPE_CNAME) && - !bitmap_isset(nsec->rr->nsec.types, DNS_TYPE_DNAME); + if (!bitmap_isset(nsec->rr->nsec.types, key->type) && + !bitmap_isset(nsec->rr->nsec.types, DNS_TYPE_CNAME) && + !bitmap_isset(nsec->rr->nsec.types, DNS_TYPE_DNAME)) { + c->n_hit++; + return 1; + } + + c->n_miss++; + return 0; } if (log_get_max_level() >= LOG_DEBUG) { @@ -811,6 +821,8 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **r } if (n <= 0) { + c->n_hit++; + *ret = NULL; *rcode = nxdomain ? DNS_RCODE_NXDOMAIN : DNS_RCODE_SUCCESS; *authenticated = have_authenticated && !have_non_authenticated; @@ -830,6 +842,8 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **r return r; } + c->n_hit++; + *ret = answer; *rcode = DNS_RCODE_SUCCESS; *authenticated = have_authenticated && !have_non_authenticated; @@ -974,3 +988,10 @@ bool dns_cache_is_empty(DnsCache *cache) { return hashmap_isempty(cache->by_key); } + +unsigned dns_cache_size(DnsCache *cache) { + if (!cache) + return 0; + + return hashmap_size(cache->by_key); +} diff --git a/src/resolve/resolved-dns-cache.h b/src/resolve/resolved-dns-cache.h index 856c975299..9c85ca4c58 100644 --- a/src/resolve/resolved-dns-cache.h +++ b/src/resolve/resolved-dns-cache.h @@ -29,6 +29,8 @@ typedef struct DnsCache { Hashmap *by_key; Prioq *by_expiry; + unsigned n_hit; + unsigned n_miss; } DnsCache; #include "resolved-dns-answer.h" @@ -47,4 +49,6 @@ int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_ void dns_cache_dump(DnsCache *cache, FILE *f); bool dns_cache_is_empty(DnsCache *cache); +unsigned dns_cache_size(DnsCache *cache); + int dns_cache_export_shared_to_packet(DnsCache *cache, DnsPacket *p); diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 0f48f9bf81..af6f28ea0f 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -153,6 +153,8 @@ int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsResourceKey *key) LIST_PREPEND(transactions_by_scope, s->transactions, t); t->scope = s; + s->manager->n_transactions_total ++; + if (ret) *ret = t; @@ -1996,6 +1998,8 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) { if (r < 0) return r; + t->scope->manager->n_dnssec_secure++; + /* Exit the loop, we dropped something from the answer, start from the beginning */ changed = true; break; @@ -2018,6 +2022,8 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) { if (r < 0) return r; + t->scope->manager->n_dnssec_insecure++; + changed = true; break; } @@ -2039,11 +2045,22 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) { if (r < 0) return r; + t->scope->manager->n_dnssec_insecure++; + changed = true; break; } } + if (IN_SET(result, + DNSSEC_INVALID, + DNSSEC_SIGNATURE_EXPIRED, + DNSSEC_NO_SIGNATURE, + DNSSEC_UNSUPPORTED_ALGORITHM)) + t->scope->manager->n_dnssec_bogus++; + else + t->scope->manager->n_dnssec_indeterminate++; + r = dns_transaction_is_primary_response(t, rr); if (r < 0) return r; diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h index b52273403a..dd85d3ba47 100644 --- a/src/resolve/resolved-manager.h +++ b/src/resolve/resolved-manager.h @@ -128,6 +128,9 @@ struct Manager { sd_bus_slot *prepare_for_sleep_slot; sd_event_source *sigusr1_event_source; + + unsigned n_transactions_total; + unsigned n_dnssec_secure, n_dnssec_insecure, n_dnssec_bogus, n_dnssec_indeterminate; }; /* Manager */ |