- 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:
parent
e12160f6cc
commit
87a108b346
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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@
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
2588
util/configlexer.c
2588
util/configlexer.c
File diff suppressed because it is too large
Load Diff
@ -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) }
|
||||
|
1659
util/configparser.c
1659
util/configparser.c
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
@ -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"));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user