- Fix #1440: [dnscrypt] client nonce cache.

git-svn-id: https://unbound.nlnetlabs.nl/svn/trunk@4351 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
wouter 2017-09-18 08:55:08 +00:00
parent e12160f6cc
commit 87a108b346
18 changed files with 2562 additions and 2114 deletions

View File

@ -827,6 +827,7 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
#endif /* USE_IPSECMOD */
#ifdef USE_DNSCRYPT
size_t dnscrypt_shared_secret = 0;
size_t dnscrypt_nonce = 0;
#endif /* USE_DNSCRYPT */
msg = slabhash_get_mem(daemon->env->msg_cache);
rrset = slabhash_get_mem(&daemon->env->rrset_cache->table);
@ -843,6 +844,7 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
if(daemon->dnscenv) {
dnscrypt_shared_secret = slabhash_get_mem(
daemon->dnscenv->shared_secrets_cache);
dnscrypt_nonce = slabhash_get_mem(daemon->dnscenv->nonces_cache);
}
#endif /* USE_DNSCRYPT */
@ -868,6 +870,9 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon)
if(!print_longnum(ssl, "mem.cache.dnscrypt_shared_secret"SQ,
dnscrypt_shared_secret))
return 0;
if(!print_longnum(ssl, "mem.cache.dnscrypt_nonce"SQ,
dnscrypt_nonce))
return 0;
#endif /* USE_DNSCRYPT */
return 1;
}
@ -1058,8 +1063,12 @@ print_ext(SSL* ssl, struct ub_stats_info* s)
#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, "dnscrypt_nonce.cache.count"SQ"%u\n",
(unsigned)s->svr.nonce_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;
if(!ssl_printf(ssl, "num.query.dnscrypt.replay"SQ"%lu\n",
(unsigned long)s->svr.num_query_dnscrypt_replay)) return 0;
#endif /* USE_DNSCRYPT */
return 1;
}

View File

@ -174,6 +174,21 @@ get_dnscrypt_cache_miss(struct worker* worker, int reset)
lock_basic_unlock(&de->shared_secrets_cache_lock);
return r;
}
/** get the number of replayed queries */
static size_t
get_dnscrypt_replay(struct worker* worker, int reset)
{
size_t r;
struct dnsc_env* de = worker->daemon->dnscenv;
lock_basic_lock(&de->nonces_cache_lock);
r = de->num_query_dnscrypt_replay;
if(reset && !worker->env.cfg->stat_cumulative)
de->num_query_dnscrypt_replay = 0;
lock_basic_unlock(&de->nonces_cache_lock);
return r;
}
#endif /* USE_DNSCRYPT */
void
@ -225,13 +240,21 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
(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);
s->svr.nonce_cache_count = (long long)count_slabhash_entries(
worker->daemon->dnscenv->nonces_cache);
s->svr.num_query_dnscrypt_replay =
(long long)get_dnscrypt_replay(worker, reset);
} else {
s->svr.num_query_dnscrypt_secret_missed_cache = 0;
s->svr.shared_secret_cache_count = 0;
s->svr.nonce_cache_count = 0;
s->svr.num_query_dnscrypt_replay = 0;
}
#else
s->svr.num_query_dnscrypt_secret_missed_cache = 0;
s->svr.shared_secret_cache_count = 0;
s->svr.nonce_cache_count = 0;
s->svr.num_query_dnscrypt_replay = 0;
#endif /* USE_DNSCRYPT */
/* get tcp accept usage */

View File

@ -60,6 +60,17 @@ struct shared_secret_cache_key {
};
struct nonce_cache_key {
/** the nonce used by the client */
uint8_t nonce[crypto_box_HALF_NONCEBYTES];
/** the client_magic used by the client, this is associated to 1 cert only */
uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN];
/** the client public key */
uint8_t client_publickey[crypto_box_PUBLICKEYBYTES];
/** the hash table entry, data is uint8_t */
struct lruhash_entry entry;
};
/**
* Generate a key suitable to find shared secret in slabhash.
* \param[in] key: a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH
@ -135,6 +146,87 @@ dnsc_shared_secrets_lookup(struct slabhash* cache,
return slabhash_lookup(cache, hash, key, 0);
}
/**
* Generate a key hash suitable to find a nonce in slabhash.
* \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES
* \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN
* \param[in] pk: The public key of the client. uint8_t pointer of size
* crypto_box_PUBLICKEYBYTES.
* \return the hash of the key.
*/
static uint32_t
dnsc_nonce_cache_key_hash(const uint8_t nonce[crypto_box_HALF_NONCEBYTES],
const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN],
const uint8_t pk[crypto_box_PUBLICKEYBYTES])
{
uint32_t h = 0;
h = hashlittle(nonce, crypto_box_HALF_NONCEBYTES, h);
h = hashlittle(magic_query, DNSCRYPT_MAGIC_HEADER_LEN, h);
return hashlittle(pk, crypto_box_PUBLICKEYBYTES, h);
}
/**
* Inserts a nonce, magic_query, pk tuple into the nonces_cache slabhash.
* \param[in] cache: the slabhash in which to look for the key.
* \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES
* \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN
* \param[in] pk: The public key of the client. uint8_t pointer of size
* crypto_box_PUBLICKEYBYTES.
* \param[in] hash: the hash of the key.
*/
static void
dnsc_nonce_cache_insert(struct slabhash *cache,
const uint8_t nonce[crypto_box_HALF_NONCEBYTES],
const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN],
const uint8_t pk[crypto_box_PUBLICKEYBYTES],
uint32_t hash)
{
struct nonce_cache_key* k =
(struct nonce_cache_key*)calloc(1, sizeof(*k));
if(!k) {
free(k);
return;
}
lock_rw_init(&k->entry.lock);
memcpy(k->nonce, nonce, crypto_box_HALF_NONCEBYTES);
memcpy(k->magic_query, magic_query, DNSCRYPT_MAGIC_HEADER_LEN);
memcpy(k->client_publickey, pk, crypto_box_PUBLICKEYBYTES);
k->entry.hash = hash;
k->entry.key = k;
k->entry.data = NULL;
slabhash_insert(cache,
hash, &k->entry,
NULL,
NULL);
}
/**
* Lookup a record in nonces_cache.
* \param[in] cache: the slabhash in which to look for the key.
* \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES
* \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN
* \param[in] pk: The public key of the client. uint8_t pointer of size
* crypto_box_PUBLICKEYBYTES.
* \param[in] hash: the hash of the key.
* \return a pointer to the locked cache entry or NULL on failure.
*/
static struct lruhash_entry*
dnsc_nonces_lookup(struct slabhash* cache,
const uint8_t nonce[crypto_box_HALF_NONCEBYTES],
const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN],
const uint8_t pk[crypto_box_PUBLICKEYBYTES],
uint32_t hash)
{
struct nonce_cache_key k;
memset(&k, 0, sizeof(k));
k.entry.hash = hash;
memcpy(k.nonce, nonce, crypto_box_HALF_NONCEBYTES);
memcpy(k.magic_query, magic_query, DNSCRYPT_MAGIC_HEADER_LEN);
memcpy(k.client_publickey, pk, crypto_box_PUBLICKEYBYTES);
return slabhash_lookup(cache, hash, &k, 0);
}
/**
* Decrypt a query using the dnsccert that was found using dnsc_find_cert.
* The client nonce will be extracted from the encrypted query and stored in
@ -163,11 +255,44 @@ dnscrypt_server_uncurve(struct dnsc_env* env,
struct lruhash_entry* entry;
uint32_t hash;
uint32_t nonce_hash;
if (len <= DNSCRYPT_QUERY_HEADER_SIZE) {
return -1;
}
query_header = (struct dnscrypt_query_header *)buf;
/* Detect replay attacks */
nonce_hash = dnsc_nonce_cache_key_hash(
query_header->nonce,
cert->magic_query,
query_header->publickey);
lock_basic_lock(&env->nonces_cache_lock);
entry = dnsc_nonces_lookup(
env->nonces_cache,
query_header->nonce,
cert->magic_query,
query_header->publickey,
nonce_hash);
if(entry) {
lock_rw_unlock(&entry->lock);
env->num_query_dnscrypt_replay++;
lock_basic_unlock(&env->nonces_cache_lock);
return -1;
}
dnsc_nonce_cache_insert(
env->nonces_cache,
query_header->nonce,
cert->magic_query,
query_header->publickey,
nonce_hash);
lock_basic_unlock(&env->nonces_cache_lock);
/* Find existing shared secret */
hash = dnsc_shared_secrets_cache_key(key,
cert->es_version[1],
query_header->publickey,
@ -770,8 +895,16 @@ dnsc_create(void)
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));
&env->num_query_dnscrypt_secret_missed_cache,
sizeof(env->num_query_dnscrypt_secret_missed_cache));
lock_basic_init(&env->nonces_cache_lock);
lock_protect(&env->nonces_cache_lock,
&env->nonces_cache,
sizeof(env->nonces_cache));
lock_protect(&env->nonces_cache_lock,
&env->num_query_dnscrypt_replay,
sizeof(env->num_query_dnscrypt_replay));
return env;
}
@ -803,6 +936,16 @@ dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
if(!env->shared_secrets_cache){
fatal_exit("dnsc_apply_cfg: could not create shared secrets cache.");
}
env->nonces_cache = slabhash_create(
cfg->dnscrypt_nonce_cache_slabs,
HASH_DEFAULT_STARTARRAY,
cfg->dnscrypt_nonce_cache_size,
dnsc_nonces_sizefunc,
dnsc_nonces_compfunc,
dnsc_nonces_delkeyfunc,
dnsc_nonces_deldatafunc,
NULL
);
return 0;
}
@ -817,7 +960,9 @@ dnsc_delete(struct dnsc_env *env)
sodium_free(env->certs);
sodium_free(env->keypairs);
slabhash_delete(env->shared_secrets_cache);
slabhash_delete(env->nonces_cache);
lock_basic_destroy(&env->shared_secrets_cache_lock);
lock_basic_destroy(&env->nonces_cache_lock);
free(env);
}
@ -858,3 +1003,51 @@ dnsc_shared_secrets_deldatafunc(void* d, void* ATTR_UNUSED(arg))
uint8_t* data = (uint8_t*)d;
free(data);
}
/**
* #########################################################
* ############### Nonces cache functions ##################
* #########################################################
*/
size_t
dnsc_nonces_sizefunc(void *k, void* ATTR_UNUSED(d))
{
struct nonce_cache_key* nk = (struct nonce_cache_key*)k;
size_t key_size = sizeof(struct nonce_cache_key)
+ lock_get_mem(&nk->entry.lock);
(void)nk; /* otherwise ssk is unused if no threading, or fixed locksize */
return key_size;
}
int
dnsc_nonces_compfunc(void *m1, void *m2)
{
struct nonce_cache_key *k1 = m1, *k2 = m2;
return
sodium_memcmp(
k1->nonce,
k2->nonce,
crypto_box_HALF_NONCEBYTES) != 0 ||
sodium_memcmp(
k1->magic_query,
k2->magic_query,
DNSCRYPT_MAGIC_HEADER_LEN) != 0 ||
sodium_memcmp(
k1->client_publickey, k2->client_publickey,
crypto_box_PUBLICKEYBYTES) != 0;
}
void
dnsc_nonces_delkeyfunc(void *k, void* ATTR_UNUSED(arg))
{
struct nonce_cache_key* nk = (struct nonce_cache_key*)k;
lock_rw_destroy(&nk->entry.lock);
free(nk);
}
void
dnsc_nonces_deldatafunc(void* ATTR_UNUSED(d), void* ATTR_UNUSED(arg))
{
return;
}

View File

@ -63,11 +63,20 @@ struct dnsc_env {
uint64_t nonce_ts_last;
unsigned char hash_key[crypto_shorthash_KEYBYTES];
char * provider_name;
/** Caches */
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;
/** slabhash keeping track of nonce/cient pk/server sk pairs. */
struct slabhash *nonces_cache;
/** lock on nonces_cache, used to avoid race condition in updating the hash */
lock_basic_type nonces_cache_lock;
/** number of replayed queries */
size_t num_query_dnscrypt_replay;
};
struct dnscrypt_query_header {
@ -139,5 +148,26 @@ void dnsc_shared_secrets_delkeyfunc(void *k, void* arg);
*/
void dnsc_shared_secrets_deldatafunc(void* d, void* arg);
/**
* Computes the size of the nonce cache entry.
*/
size_t dnsc_nonces_sizefunc(void *k, void *d);
/**
* Compares two nonce cache keys.
*/
int dnsc_nonces_compfunc(void *m1, void *m2);
/**
* Function to delete a nonce cache key.
*/
void dnsc_nonces_delkeyfunc(void *k, void* arg);
/**
* Function to delete a nonce cache value.
*/
void dnsc_nonces_deldatafunc(void* d, void* arg);
#endif /* USE_DNSCRYPT */
#endif

View File

@ -4,6 +4,7 @@
control.
- Fix #1435: Please allow UDP to be disabled separately upstream and
downstream.
- Fix #1440: [dnscrypt] client nonce cache.
15 September 2017: Wouter
- Fix unbound-host to report error for DNSSEC state of failed lookups.

View File

@ -337,6 +337,19 @@ number of queries that were successfully answered using a cache lookup
.I threadX.num.cachemiss
number of queries that needed recursive processing
.TP
.I threadX.num.dnscrypt.crypted
number of queries that were encrypted and sucessfully decapsulated by dnscrypt.
.TP
.I threadX.num.dnscrypt.cert
number of queries that were requesting dnscrypt certificates.
.TP
.I threadX.num.dnscrypt.cleartext
number of queries received on dnscrypt port that were cleartext and not a
request for certificates.
.TP
.I threadX.num.dnscrypt.malformed
number of request that were neither cleartext, not valid dnscrypt messages.
.TP
.I threadX.num.prefetch
number of cache prefetches performed. This number is included in
cachehits, as the original query had the unprefetched answer from cache,
@ -393,6 +406,18 @@ summed over threads.
.I total.num.cachemiss
summed over threads.
.TP
.I total.num.dnscrypt.crypted
summed over threads.
.TP
.I total.num.dnscrypt.cert
summed over threads.
.TP
.I total.num.dnscrypt.cleartext
summed over threads.
.TP
.I total.num.dnscrypt.malformed
summed over threads.
.TP
.I total.num.prefetch
summed over threads.
.TP
@ -439,6 +464,12 @@ Memory in bytes in use by the RRset cache.
.I mem.cache.message
Memory in bytes in use by the message cache.
.TP
.I mem.cache.dnscrypt_shared_secret
Memory in bytes in use by the dnscrypt shared secrets cache.
.TP
.I mem.cache.dnscrypt_nonce
Memory in bytes in use by the dnscrypt nonce cache.
.TP
.I mem.mod.iterator
Memory in bytes in use by the iterator module.
.TP
@ -497,6 +528,14 @@ These queries are also included in the num.query.edns.present number.
The number of queries that are turned away from being send to nameserver due to
ratelimiting.
.TP
.I num.query.dnscrypt.shared_secret.cachemiss
The number of dnscrypt queries that did not find a shared secret in the cache.
The can be use to compute the shared secret hitrate.
.TP
.I num.query.dnscrypt.replay
The number of dnscrypt queries that found a nonce hit in the nonce cache and
hence are considered a query replay.
.TP
.I num.answer.rcode.NXDOMAIN
The number of answers to queries, from cache or from recursion, that had the
return code NXDOMAIN. Also printed for the other return codes.
@ -546,6 +585,19 @@ timing and protocol support information.
.I key.cache.count
The number of items in the key cache. These are DNSSEC keys, one item
per delegation point, and their validation status.
.TP
.I dnscrypt_shared_secret.cache.count
The number of items in the shared secret cache. These are precomputed shared
secrets for a given client public key/server secret key pair. Shared secrets
are CPU intensive and this cache allow to avoid recomputing the shared secret
when multiple dnscrypt queries are sent from the same client.
.TP
.I dnscrypt_nonce.cache.count
The number of items in the client nonce cache. This cache is used to prevent
dnscrypt queries replay. The client nonce must be unique for each client public
key/server secret key pair. This cache should be able to host QPS * `replay
window` interval keys to prevent replay of a query during `replay window`
seconds.
.SH "FILES"
.TP
.I @ub_conf_file@

View File

@ -1523,6 +1523,17 @@ using the same public key. It saves a substantial amount of CPU.
Give power of 2 number of slabs, this is used to reduce lock contention
in the dnscrypt shared secrets cache. Close to the number of cpus is
a fairly good setting.
.TP
.B dnscrypt\-nonce\-cache\-size: \fI<memory size>
Give the size of the data structure in which the client nonces are kept in.
Default 4m. In bytes or use m(mega), k(kilo), g(giga).
The nonce cache is used to prevent dnscrypt message replaying. Client nonce
should be unique for any pair of client pk/server sk.
.TP
.B dnscrypt\-nonce\-cache\-slabs: \fI<number>
Give power of 2 number of slabs, this is used to reduce lock contention
in the dnscrypt nonce cache. Close to the number of cpus is
a fairly good setting.
.SS "EDNS Client Subnet Module Options"
.LP
The ECS module must be configured in the \fBmodule\-config:\fR "subnetcache

View File

@ -623,6 +623,7 @@ struct ub_shm_stat_info {
long long ipsecmod;
long long respip;
long long dnscrypt_shared_secret;
long long dnscrypt_nonce;
} mem;
};
@ -742,6 +743,10 @@ struct ub_server_stats {
long long num_query_dnscrypt_secret_missed_cache;
/** number of dnscrypt shared secret cache entries */
long long shared_secret_cache_count;
/** number of queries which are replays */
long long num_query_dnscrypt_replay;
/** number of dnscrypt nonces cache entries */
long long nonce_cache_count;
};
/**

View File

@ -254,6 +254,8 @@ static void print_mem(struct ub_shm_stat_info* shm_stat)
#ifdef USE_DNSCRYPT
PR_LL("mem.cache.dnscrypt_shared_secret",
shm_stat->mem.dnscrypt_shared_secret);
PR_LL("mem.cache.dnscrypt_nonce",
shm_stat->mem.dnscrypt_nonce);
#endif
}
@ -360,6 +362,9 @@ static void print_extended(struct ub_stats_info* s)
s->svr.shared_secret_cache_count);
PR_UL("num.query.dnscrypt.shared_secret.cachemiss",
s->svr.num_query_dnscrypt_secret_missed_cache);
PR_UL("dnscrypt_nonce.cache.count", s->svr.nonce_cache_count);
PR_UL("num.query.dnscrypt.replay",
s->svr.num_query_dnscrypt_replay);
#endif /* USE_DNSCRYPT */
}

View File

@ -285,6 +285,8 @@ config_create(void)
cfg->dnscrypt_secret_key = NULL;
cfg->dnscrypt_shared_secret_cache_size = 4*1024*1024;
cfg->dnscrypt_shared_secret_cache_slabs = 4;
cfg->dnscrypt_nonce_cache_size = 4*1024*1024;
cfg->dnscrypt_nonce_cache_slabs = 4;
#ifdef USE_IPSECMOD
cfg->ipsecmod_enabled = 1;
cfg->ipsecmod_ignore_bogus = 0;
@ -574,6 +576,10 @@ int config_set_option(struct config_file* cfg, const char* opt,
dnscrypt_shared_secret_cache_size)
else S_POW2("dnscrypt-shared-secret-cache-slabs:",
dnscrypt_shared_secret_cache_slabs)
else S_MEMSIZE("dnscrypt-nonce-cache-size:",
dnscrypt_nonce_cache_size)
else S_POW2("dnscrypt-nonce-cache-slabs:",
dnscrypt_nonce_cache_slabs)
#endif
else if(strcmp(opt, "ip-ratelimit:") == 0) {
IS_NUMBER_OR_ZERO; cfg->ip_ratelimit = atoi(val);
@ -940,6 +946,10 @@ config_get_option(struct config_file* cfg, const char* opt,
dnscrypt_shared_secret_cache_size)
else O_DEC(opt, "dnscrypt-shared-secret-cache-slabs",
dnscrypt_shared_secret_cache_slabs)
else O_MEM(opt, "dnscrypt-nonce-cache-size",
dnscrypt_nonce_cache_size)
else O_DEC(opt, "dnscrypt-nonce-cache-slabs",
dnscrypt_nonce_cache_slabs)
#endif
else O_YNO(opt, "unblock-lan-zones", unblock_lan_zones)
else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones)

View File

@ -470,7 +470,10 @@ struct config_file {
size_t dnscrypt_shared_secret_cache_size;
/** number of slabs for dnscrypt shared secrets cache */
size_t dnscrypt_shared_secret_cache_slabs;
/** memory size in bytes for dnscrypt nonces cache */
size_t dnscrypt_nonce_cache_size;
/** number of slabs for dnscrypt nonces cache */
size_t dnscrypt_nonce_cache_slabs;
/** IPsec module */
#ifdef USE_IPSECMOD
/** false to bypass the IPsec module */

File diff suppressed because it is too large Load Diff

View File

@ -421,6 +421,8 @@ dnscrypt-shared-secret-cache-size{COLON} {
YDVAR(1, VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE) }
dnscrypt-shared-secret-cache-slabs{COLON} {
YDVAR(1, VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS) }
dnscrypt-nonce-cache-size{COLON} { YDVAR(1, VAR_DNSCRYPT_NONCE_CACHE_SIZE) }
dnscrypt-nonce-cache-slabs{COLON} { YDVAR(1, VAR_DNSCRYPT_NONCE_CACHE_SLABS) }
ipsecmod-enabled{COLON} { YDVAR(1, VAR_IPSECMOD_ENABLED) }
ipsecmod-ignore-bogus{COLON} { YDVAR(1, VAR_IPSECMOD_IGNORE_BOGUS) }
ipsecmod-hook{COLON} { YDVAR(1, VAR_IPSECMOD_HOOK) }

File diff suppressed because it is too large Load Diff

View File

@ -254,16 +254,18 @@ extern int yydebug;
VAR_DNSCRYPT_PROVIDER_CERT = 464,
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 465,
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 466,
VAR_IPSECMOD_ENABLED = 467,
VAR_IPSECMOD_HOOK = 468,
VAR_IPSECMOD_IGNORE_BOGUS = 469,
VAR_IPSECMOD_MAX_TTL = 470,
VAR_IPSECMOD_WHITELIST = 471,
VAR_IPSECMOD_STRICT = 472,
VAR_CACHEDB = 473,
VAR_CACHEDB_BACKEND = 474,
VAR_CACHEDB_SECRETSEED = 475,
VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 476
VAR_DNSCRYPT_NONCE_CACHE_SIZE = 467,
VAR_DNSCRYPT_NONCE_CACHE_SLABS = 468,
VAR_IPSECMOD_ENABLED = 469,
VAR_IPSECMOD_HOOK = 470,
VAR_IPSECMOD_IGNORE_BOGUS = 471,
VAR_IPSECMOD_MAX_TTL = 472,
VAR_IPSECMOD_WHITELIST = 473,
VAR_IPSECMOD_STRICT = 474,
VAR_CACHEDB = 475,
VAR_CACHEDB_BACKEND = 476,
VAR_CACHEDB_SECRETSEED = 477,
VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 478
};
#endif
/* Tokens. */
@ -476,16 +478,18 @@ extern int yydebug;
#define VAR_DNSCRYPT_PROVIDER_CERT 464
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 465
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 466
#define VAR_IPSECMOD_ENABLED 467
#define VAR_IPSECMOD_HOOK 468
#define VAR_IPSECMOD_IGNORE_BOGUS 469
#define VAR_IPSECMOD_MAX_TTL 470
#define VAR_IPSECMOD_WHITELIST 471
#define VAR_IPSECMOD_STRICT 472
#define VAR_CACHEDB 473
#define VAR_CACHEDB_BACKEND 474
#define VAR_CACHEDB_SECRETSEED 475
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 476
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 467
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 468
#define VAR_IPSECMOD_ENABLED 469
#define VAR_IPSECMOD_HOOK 470
#define VAR_IPSECMOD_IGNORE_BOGUS 471
#define VAR_IPSECMOD_MAX_TTL 472
#define VAR_IPSECMOD_WHITELIST 473
#define VAR_IPSECMOD_STRICT 474
#define VAR_CACHEDB 475
#define VAR_CACHEDB_BACKEND 476
#define VAR_CACHEDB_SECRETSEED 477
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 478
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
@ -496,7 +500,7 @@ union YYSTYPE
char* str;
#line 500 "util/configparser.h" /* yacc.c:1909 */
#line 504 "util/configparser.h" /* yacc.c:1909 */
};
typedef union YYSTYPE YYSTYPE;

View File

@ -146,6 +146,8 @@ extern struct config_parser_state* cfg_parser;
%token VAR_DNSCRYPT_SECRET_KEY VAR_DNSCRYPT_PROVIDER_CERT
%token VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE
%token VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS
%token VAR_DNSCRYPT_NONCE_CACHE_SIZE
%token VAR_DNSCRYPT_NONCE_CACHE_SLABS
%token VAR_IPSECMOD_ENABLED VAR_IPSECMOD_HOOK VAR_IPSECMOD_IGNORE_BOGUS
%token VAR_IPSECMOD_MAX_TTL VAR_IPSECMOD_WHITELIST VAR_IPSECMOD_STRICT
%token VAR_CACHEDB VAR_CACHEDB_BACKEND VAR_CACHEDB_SECRETSEED
@ -2338,7 +2340,9 @@ content_dnsc:
dnsc_dnscrypt_enable | dnsc_dnscrypt_port | dnsc_dnscrypt_provider |
dnsc_dnscrypt_secret_key | dnsc_dnscrypt_provider_cert |
dnsc_dnscrypt_shared_secret_cache_size |
dnsc_dnscrypt_shared_secret_cache_slabs
dnsc_dnscrypt_shared_secret_cache_slabs |
dnsc_dnscrypt_nonce_cache_size |
dnsc_dnscrypt_nonce_cache_slabs
;
dnsc_dnscrypt_enable: VAR_DNSCRYPT_ENABLE STRING_ARG
{
@ -2402,6 +2406,27 @@ dnsc_dnscrypt_shared_secret_cache_slabs: VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS
free($2);
}
;
dnsc_dnscrypt_nonce_cache_size: VAR_DNSCRYPT_NONCE_CACHE_SIZE STRING_ARG
{
OUTYY(("P(dnscrypt_nonce_cache_size:%s)\n", $2));
if(!cfg_parse_memsize($2, &cfg_parser->cfg->dnscrypt_nonce_cache_size))
yyerror("memory size expected");
free($2);
}
;
dnsc_dnscrypt_nonce_cache_slabs: VAR_DNSCRYPT_NONCE_CACHE_SLABS STRING_ARG
{
OUTYY(("P(dnscrypt_nonce_cache_slabs:%s)\n", $2));
if(atoi($2) == 0)
yyerror("number expected");
else {
cfg_parser->cfg->dnscrypt_nonce_cache_slabs = atoi($2);
if(!is_pow2(cfg_parser->cfg->dnscrypt_nonce_cache_slabs))
yyerror("must be a power of 2");
}
free($2);
}
;
cachedbstart: VAR_CACHEDB
{
OUTYY(("\nP(cachedb:)\n"));

View File

@ -233,6 +233,7 @@ fptr_whitelist_hash_sizefunc(lruhash_sizefunc_type fptr)
#endif
#ifdef USE_DNSCRYPT
else if(fptr == &dnsc_shared_secrets_sizefunc) return 1;
else if(fptr == &dnsc_nonces_sizefunc) return 1;
#endif
return 0;
}
@ -249,6 +250,7 @@ fptr_whitelist_hash_compfunc(lruhash_compfunc_type fptr)
else if(fptr == &test_slabhash_compfunc) return 1;
#ifdef USE_DNSCRYPT
else if(fptr == &dnsc_shared_secrets_compfunc) return 1;
else if(fptr == &dnsc_nonces_compfunc) return 1;
#endif
return 0;
}
@ -265,6 +267,7 @@ fptr_whitelist_hash_delkeyfunc(lruhash_delkeyfunc_type fptr)
else if(fptr == &test_slabhash_delkey) return 1;
#ifdef USE_DNSCRYPT
else if(fptr == &dnsc_shared_secrets_delkeyfunc) return 1;
else if(fptr == &dnsc_nonces_delkeyfunc) return 1;
#endif
return 0;
}
@ -283,6 +286,7 @@ fptr_whitelist_hash_deldatafunc(lruhash_deldatafunc_type fptr)
#endif
#ifdef USE_DNSCRYPT
else if(fptr == &dnsc_shared_secrets_deldatafunc) return 1;
else if(fptr == &dnsc_nonces_deldatafunc) return 1;
#endif
return 0;
}

View File

@ -254,6 +254,8 @@ void shm_main_run(struct worker *worker)
if(worker->daemon->dnscenv) {
shm_stat->mem.dnscrypt_shared_secret = (long long)slabhash_get_mem(
worker->daemon->dnscenv->shared_secrets_cache);
shm_stat->mem.dnscrypt_nonce = (long long)slabhash_get_mem(
worker->daemon->dnscenv->nonces_cache);
}
#endif
shm_stat->mem.val = (long long)mod_get_mem(&worker->env,