diff --git a/daemon/remote.c b/daemon/remote.c index 60852b03c..243d94c49 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -825,6 +825,9 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon) #ifdef USE_IPSECMOD size_t ipsecmod = 0; #endif /* USE_IPSECMOD */ +#ifdef USE_DNSCRYPT + size_t dnscrypt_shared_secret = 0; +#endif /* USE_DNSCRYPT */ msg = slabhash_get_mem(daemon->env->msg_cache); rrset = slabhash_get_mem(&daemon->env->rrset_cache->table); val = mod_get_mem(&worker->env, "validator"); @@ -836,6 +839,12 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon) #ifdef USE_IPSECMOD ipsecmod = mod_get_mem(&worker->env, "ipsecmod"); #endif /* USE_IPSECMOD */ +#ifdef USE_DNSCRYPT + if(daemon->dnscenv) { + dnscrypt_shared_secret = slabhash_get_mem( + daemon->dnscenv->shared_secrets_cache); + } +#endif /* USE_DNSCRYPT */ if(!print_longnum(ssl, "mem.cache.rrset"SQ, rrset)) return 0; @@ -855,6 +864,11 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon) if(!print_longnum(ssl, "mem.mod.ipsecmod"SQ, ipsecmod)) return 0; #endif /* USE_IPSECMOD */ +#ifdef USE_DNSCRYPT + if(!print_longnum(ssl, "mem.cache.dnscrypt_shared_secret"SQ, + dnscrypt_shared_secret)) + return 0; +#endif /* USE_DNSCRYPT */ return 1; } @@ -1041,6 +1055,12 @@ print_ext(SSL* ssl, struct ub_stats_info* s) (unsigned)s->svr.infra_cache_count)) return 0; if(!ssl_printf(ssl, "key.cache.count"SQ"%u\n", (unsigned)s->svr.key_cache_count)) return 0; +#ifdef USE_DNSCRYPT + if(!ssl_printf(ssl, "dnscrypt_shared_secret.cache.count"SQ"%u\n", + (unsigned)s->svr.shared_secret_cache_count)) return 0; + if(!ssl_printf(ssl, "num.query.dnscrypt.shared_secret.cachemiss"SQ"%lu\n", + (unsigned long)s->svr.num_query_dnscrypt_secret_missed_cache)) return 0; +#endif /* USE_DNSCRYPT */ return 1; } diff --git a/daemon/stats.c b/daemon/stats.c index bdfa8cffa..1058556be 100644 --- a/daemon/stats.c +++ b/daemon/stats.c @@ -158,6 +158,24 @@ get_queries_ratelimit(struct worker* worker, int reset) return r; } +#ifdef USE_DNSCRYPT +/** get the number of shared secret cache miss */ +static size_t +get_dnscrypt_cache_miss(struct worker* worker, int reset) +{ + size_t r; + struct dnsc_env* de = worker->daemon->dnscenv; + if(!de) return 0; + + lock_basic_lock(&de->shared_secrets_cache_lock); + r = de->num_query_dnscrypt_secret_missed_cache; + if(reset && !worker->env.cfg->stat_cumulative) + de->num_query_dnscrypt_secret_missed_cache = 0; + lock_basic_unlock(&de->shared_secrets_cache_lock); + return r; +} +#endif /* USE_DNSCRYPT */ + void server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset) { @@ -201,6 +219,21 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset) s->svr.key_cache_count = (long long)count_slabhash_entries(worker->env.key_cache->slab); else s->svr.key_cache_count = 0; +#ifdef USE_DNSCRYPT + if(worker->daemon->dnscenv) { + s->svr.num_query_dnscrypt_secret_missed_cache = + (long long)get_dnscrypt_cache_miss(worker, reset); + s->svr.shared_secret_cache_count = (long long)count_slabhash_entries( + worker->daemon->dnscenv->shared_secrets_cache); + } else { + s->svr.num_query_dnscrypt_secret_missed_cache = 0; + s->svr.shared_secret_cache_count = 0; + } +#else + s->svr.num_query_dnscrypt_secret_missed_cache = 0; + s->svr.shared_secret_cache_count = 0; +#endif /* USE_DNSCRYPT */ + /* get tcp accept usage */ s->svr.tcp_accept_usage = 0; for(lp = worker->front->cps; lp; lp = lp->next) { @@ -262,7 +295,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a) a->svr.num_query_dnscrypt_cleartext; total->svr.num_query_dnscrypt_crypted_malformed += \ a->svr.num_query_dnscrypt_crypted_malformed; -#endif +#endif /* USE_DNSCRYPT */ /* the max size reached is upped to higher of both */ if(a->svr.max_query_list_size > total->svr.max_query_list_size) total->svr.max_query_list_size = a->svr.max_query_list_size; diff --git a/dnscrypt/dnscrypt.c b/dnscrypt/dnscrypt.c index 4d6518d0d..bc4a70bd7 100644 --- a/dnscrypt/dnscrypt.c +++ b/dnscrypt/dnscrypt.c @@ -177,6 +177,9 @@ dnscrypt_server_uncurve(struct dnsc_env* env, hash); if(!entry) { + lock_basic_lock(&env->shared_secrets_cache_lock); + env->num_query_dnscrypt_secret_missed_cache++; + lock_basic_unlock(&env->shared_secrets_cache_lock); if(cert->es_version[1] == 2) { #ifdef USE_DNSCRYPT_XCHACHA20 if (crypto_box_curve25519xchacha20poly1305_beforenm( @@ -765,6 +768,10 @@ dnsc_create(void) fatal_exit("dnsc_create: could not initialize libsodium."); } env = (struct dnsc_env *) calloc(1, sizeof(struct dnsc_env)); + lock_basic_init(&env->shared_secrets_cache_lock); + lock_protect(&env->shared_secrets_cache_lock, + &env->num_query_dnscrypt_secret_missed_cache, + sizeof(env->num_query_dnscrypt_secret_missed_cache)); return env; } @@ -810,6 +817,7 @@ dnsc_delete(struct dnsc_env *env) sodium_free(env->certs); sodium_free(env->keypairs); slabhash_delete(env->shared_secrets_cache); + lock_basic_destroy(&env->shared_secrets_cache_lock); free(env); } diff --git a/dnscrypt/dnscrypt.h b/dnscrypt/dnscrypt.h index 0575d45a7..dde36d667 100644 --- a/dnscrypt/dnscrypt.h +++ b/dnscrypt/dnscrypt.h @@ -26,6 +26,7 @@ #include "config.h" #include "dnscrypt/cert.h" +#include "util/locks.h" #define DNSCRYPT_QUERY_HEADER_SIZE \ (DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_PUBLICKEYBYTES + crypto_box_HALF_NONCEBYTES + crypto_box_MACBYTES) @@ -63,6 +64,10 @@ struct dnsc_env { unsigned char hash_key[crypto_shorthash_KEYBYTES]; char * provider_name; struct slabhash *shared_secrets_cache; + /** lock on shared secret cache counters */ + lock_basic_type shared_secrets_cache_lock; + /** number of misses from shared_secrets_cache */ + size_t num_query_dnscrypt_secret_missed_cache; }; struct dnscrypt_query_header { diff --git a/doc/Changelog b/doc/Changelog index 356196e7a..f53d1ddc8 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -2,6 +2,8 @@ - Fix #1424: cachedb:testframe is not thread safe. - For #1417: escape ; in dnscrypt tests. - but reverted that, tests fails with that escape. + - Fix #1417: [dnscrypt] shared secret cache counters, and works when + dnscrypt is not enabled. 30 August 2017: Wouter - updated contrib/fastrpz.patch to apply with configparser changes. diff --git a/libunbound/unbound.h b/libunbound/unbound.h index 95d6ee101..ac747a7cc 100644 --- a/libunbound/unbound.h +++ b/libunbound/unbound.h @@ -622,6 +622,7 @@ struct ub_shm_stat_info { long long subnet; long long ipsecmod; long long respip; + long long dnscrypt_shared_secret; } mem; }; @@ -737,6 +738,10 @@ struct ub_server_stats { long long num_query_dnscrypt_cleartext; /** number of malformed encrypted queries */ long long num_query_dnscrypt_crypted_malformed; + /** number of queries which did not have a shared secret in cache */ + long long num_query_dnscrypt_secret_missed_cache; + /** number of dnscrypt shared secret cache entries */ + long long shared_secret_cache_count; }; /** diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index 73fe23c10..4b3efc134 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -207,7 +207,7 @@ static void pr_stats(const char* nm, struct ub_stats_info* s) PR_UL_NM("num.dnscrypt.cleartext", s->svr.num_query_dnscrypt_cleartext); PR_UL_NM("num.dnscrypt.malformed", s->svr.num_query_dnscrypt_crypted_malformed); -#endif +#endif /* USE_DNSCRYPT */ printf("%s.requestlist.avg"SQ"%g\n", nm, (s->svr.num_queries_missed_cache+s->svr.num_queries_prefetch)? (double)s->svr.sum_query_list_size/ @@ -251,6 +251,10 @@ static void print_mem(struct ub_shm_stat_info* shm_stat) #ifdef USE_IPSECMOD PR_LL("mem.mod.ipsecmod", shm_stat->mem.ipsecmod); #endif +#ifdef USE_DNSCRYPT + PR_LL("mem.cache.dnscrypt_shared_secret", + shm_stat->mem.dnscrypt_shared_secret); +#endif } /** print histogram */ @@ -351,6 +355,12 @@ static void print_extended(struct ub_stats_info* s) PR_UL("rrset.cache.count", s->svr.rrset_cache_count); PR_UL("infra.cache.count", s->svr.infra_cache_count); PR_UL("key.cache.count", s->svr.key_cache_count); +#ifdef USE_DNSCRYPT + PR_UL("dnscrypt_shared_secret.cache.count", + s->svr.shared_secret_cache_count); + PR_UL("num.query.dnscrypt.shared_secret.cachemiss", + s->svr.num_query_dnscrypt_secret_missed_cache); +#endif /* USE_DNSCRYPT */ } /** print statistics out of memory structures */ diff --git a/util/shm_side/shm_main.c b/util/shm_side/shm_main.c index bba2a8396..c0757ed7c 100644 --- a/util/shm_side/shm_main.c +++ b/util/shm_side/shm_main.c @@ -249,6 +249,13 @@ void shm_main_run(struct worker *worker) shm_stat->mem.msg = (long long)slabhash_get_mem(worker->env.msg_cache); shm_stat->mem.rrset = (long long)slabhash_get_mem(&worker->env.rrset_cache->table); + shm_stat->mem.dnscrypt_shared_secret = 0; +#ifdef USE_DNSCRYPT + if(worker->daemon->dnscenv) { + shm_stat->mem.dnscrypt_shared_secret = (long long)slabhash_get_mem( + worker->daemon->dnscenv->shared_secrets_cache); + } +#endif shm_stat->mem.val = (long long)mod_get_mem(&worker->env, "validator"); shm_stat->mem.iter = (long long)mod_get_mem(&worker->env,