Upgrade Unbound to 1.7.1.
This commit is contained in:
commit
6c94117e62
@ -112,7 +112,7 @@ iterator/iter_scrub.c iterator/iter_utils.c services/listen_dnsport.c \
|
||||
services/localzone.c services/mesh.c services/modstack.c services/view.c \
|
||||
services/outbound_list.c services/outside_network.c util/alloc.c \
|
||||
util/config_file.c util/configlexer.c util/configparser.c \
|
||||
util/shm_side/shm_main.c services/authzone.c\
|
||||
util/shm_side/shm_main.c services/authzone.c \
|
||||
util/fptr_wlist.c util/locks.c util/log.c util/mini_event.c util/module.c \
|
||||
util/netevent.c util/net_help.c util/random.c util/rbtree.c util/regional.c \
|
||||
util/rtt.c util/storage/dnstree.c util/storage/lookup3.c \
|
||||
@ -124,7 +124,7 @@ validator/val_nsec3.c validator/val_nsec.c validator/val_secalgo.c \
|
||||
validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
|
||||
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
|
||||
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
|
||||
cachedb/cachedb.c respip/respip.c $(CHECKLOCK_SRC) \
|
||||
cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
|
||||
$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
|
||||
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
|
||||
as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
|
||||
@ -135,7 +135,7 @@ fptr_wlist.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
|
||||
random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
|
||||
slabhash.lo timehist.lo tube.lo winsock_event.lo autotrust.lo val_anchor.lo \
|
||||
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
|
||||
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo authzone.lo\
|
||||
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
|
||||
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
|
||||
$(IPSECMOD_OBJ) respip.lo
|
||||
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
|
||||
@ -645,7 +645,8 @@ infra.lo infra.o: $(srcdir)/services/cache/infra.c config.h $(srcdir)/sldns/rrde
|
||||
rrset.lo rrset.o: $(srcdir)/services/cache/rrset.c config.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/sldns/rrdef.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h \
|
||||
$(srcdir)/util/net_help.h
|
||||
as112.lo as112.o: $(srcdir)/util/as112.c $(srcdir)/util/as112.h
|
||||
dname.lo dname.o: $(srcdir)/util/data/dname.c config.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
|
||||
@ -882,7 +883,7 @@ netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/neteve
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
|
||||
$(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/dnstap/dnstap.h \
|
||||
\
|
||||
|
||||
net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
|
||||
@ -960,11 +961,11 @@ validator.lo validator.o: $(srcdir)/validator/validator.c config.h $(srcdir)/val
|
||||
$(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_kcache.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_nsec.h \
|
||||
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_neg.h $(srcdir)/validator/val_sigcrypt.h \
|
||||
$(srcdir)/validator/autotrust.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
|
||||
$(srcdir)/validator/autotrust.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
|
||||
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
|
||||
$(srcdir)/services/modstack.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
|
||||
val_kcache.lo val_kcache.o: $(srcdir)/validator/val_kcache.c config.h $(srcdir)/validator/val_kcache.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/testcode/checklocks.h $(srcdir)/validator/val_kentry.h $(srcdir)/util/config_file.h \
|
||||
@ -1054,11 +1055,16 @@ subnet-whitelist.lo subnet-whitelist.o: $(srcdir)/edns-subnet/subnet-whitelist.c
|
||||
cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h $(srcdir)/cachedb/cachedb.h $(srcdir)/util/module.h \
|
||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
|
||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/data/msgencode.h $(srcdir)/services/cache/dns.h \
|
||||
$(srcdir)/validator/val_neg.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_secalgo.h \
|
||||
$(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h $(srcdir)/sldns/parseutil.h \
|
||||
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h
|
||||
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/cachedb/redis.h $(srcdir)/util/regional.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/data/msgencode.h \
|
||||
$(srcdir)/services/cache/dns.h $(srcdir)/validator/val_neg.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/validator/val_secalgo.h $(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h \
|
||||
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h
|
||||
redis.lo redis.o: $(srcdir)/cachedb/redis.c config.h $(srcdir)/cachedb/redis.h $(srcdir)/cachedb/cachedb.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/testcode/checklocks.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
|
||||
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/alloc.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
|
||||
respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
|
||||
@ -1204,12 +1210,12 @@ remote.lo remote.o: $(srcdir)/daemon/remote.c config.h \
|
||||
$(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
|
||||
$(srcdir)/services/view.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/data/dname.h \
|
||||
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kcache.h \
|
||||
$(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h \
|
||||
$(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
|
||||
$(srcdir)/iterator/iter_delegpt.h $(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h \
|
||||
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
|
||||
$(srcdir)/services/view.h $(srcdir)/services/authzone.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
|
||||
$(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_anchor.h \
|
||||
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
|
||||
$(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/services/outside_network.h \
|
||||
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
|
||||
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
@ -1222,7 +1228,8 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
|
||||
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
|
||||
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
|
||||
$(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
|
||||
$(srcdir)/validator/val_neg.h
|
||||
unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/daemon/remote.h \
|
||||
@ -1319,7 +1326,8 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
|
||||
$(srcdir)/util/tube.h $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
|
||||
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
|
||||
$(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
|
||||
$(srcdir)/validator/val_neg.h
|
||||
replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h \
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "config.h"
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/cachedb.h"
|
||||
#include "cachedb/redis.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/config_file.h"
|
||||
@ -56,7 +57,20 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
#define CACHEDB_HASHSIZE 256 /* bit hash */
|
||||
/* header file for htobe64 */
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
#ifdef HAVE_LIBKERN_OSBYTEORDER_H
|
||||
/* In practice this is specific to MacOS X. We assume it doesn't have
|
||||
* htobe64/be64toh but has alternatives with a different name. */
|
||||
# include <libkern/OSByteOrder.h>
|
||||
# define htobe64(x) OSSwapHostToBigInt64(x)
|
||||
# define be64toh(x) OSSwapBigToHostInt64(x)
|
||||
#endif
|
||||
|
||||
/** the unit test testframe for cachedb, its module state contains
|
||||
* a cache for a couple queries (in memory). */
|
||||
@ -176,6 +190,10 @@ static struct cachedb_backend testframe_backend = { "testframe",
|
||||
static struct cachedb_backend*
|
||||
cachedb_find_backend(const char* str)
|
||||
{
|
||||
#ifdef USE_REDIS
|
||||
if(strcmp(str, redis_backend.name) == 0)
|
||||
return &redis_backend;
|
||||
#endif
|
||||
if(strcmp(str, testframe_backend.name) == 0)
|
||||
return &testframe_backend;
|
||||
/* TODO add more backends here */
|
||||
@ -571,7 +589,8 @@ cachedb_intcache_lookup(struct module_qstate* qstate)
|
||||
qstate->region, qstate->env->scratch,
|
||||
1 /* no partial messages with only a CNAME */
|
||||
);
|
||||
if(!msg && qstate->env->neg_cache) {
|
||||
if(!msg && qstate->env->neg_cache &&
|
||||
iter_qname_indicates_dnssec(qstate->env, &qstate->qinfo)) {
|
||||
/* lookup in negative cache; may result in
|
||||
* NOERROR/NODATA or NXDOMAIN answers that need validation */
|
||||
msg = val_neg_getmsg(qstate->env->neg_cache, &qstate->qinfo,
|
||||
|
@ -87,6 +87,8 @@ struct cachedb_backend {
|
||||
uint8_t*, size_t);
|
||||
};
|
||||
|
||||
#define CACHEDB_HASHSIZE 256 /* bit hash */
|
||||
|
||||
/** Init the cachedb module */
|
||||
int cachedb_init(struct module_env* env, int id);
|
||||
/** Deinit the cachedb module */
|
||||
|
283
contrib/unbound/cachedb/redis.c
Normal file
283
contrib/unbound/cachedb/redis.c
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
* cachedb/redis.c - cachedb redis module
|
||||
*
|
||||
* Copyright (c) 2018, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file contains a module that uses the redis database to cache
|
||||
* dns responses.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/redis.h"
|
||||
#include "cachedb/cachedb.h"
|
||||
#include "util/alloc.h"
|
||||
#include "util/config_file.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
#ifdef USE_REDIS
|
||||
#include "hiredis/hiredis.h"
|
||||
|
||||
struct redis_moddata {
|
||||
redisContext** ctxs; /* thread-specific redis contexts */
|
||||
int numctxs; /* number of ctx entries */
|
||||
const char* server_host; /* server's IP address or host name */
|
||||
int server_port; /* server's TCP port */
|
||||
struct timeval timeout; /* timeout for connection setup and commands */
|
||||
};
|
||||
|
||||
static redisContext*
|
||||
redis_connect(const struct redis_moddata* moddata)
|
||||
{
|
||||
redisContext* ctx;
|
||||
|
||||
ctx = redisConnectWithTimeout(moddata->server_host,
|
||||
moddata->server_port, moddata->timeout);
|
||||
if(!ctx || ctx->err) {
|
||||
const char *errstr = "out of memory";
|
||||
if(ctx)
|
||||
errstr = ctx->errstr;
|
||||
log_err("failed to connect to redis server: %s", errstr);
|
||||
goto fail;
|
||||
}
|
||||
if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) {
|
||||
log_err("failed to set redis timeout");
|
||||
goto fail;
|
||||
}
|
||||
return ctx;
|
||||
|
||||
fail:
|
||||
if(ctx)
|
||||
redisFree(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
{
|
||||
int i;
|
||||
struct redis_moddata* moddata = NULL;
|
||||
|
||||
verbose(VERB_ALGO, "redis_init");
|
||||
|
||||
moddata = calloc(1, sizeof(struct redis_moddata));
|
||||
if(!moddata) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
moddata->numctxs = env->cfg->num_threads;
|
||||
moddata->ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*));
|
||||
if(!moddata->ctxs) {
|
||||
log_err("out of memory");
|
||||
free(moddata);
|
||||
return 0;
|
||||
}
|
||||
/* note: server_host is a shallow reference to configured string.
|
||||
* we don't have to free it in this module. */
|
||||
moddata->server_host = env->cfg->redis_server_host;
|
||||
moddata->server_port = env->cfg->redis_server_port;
|
||||
moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000;
|
||||
moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000;
|
||||
for(i = 0; i < moddata->numctxs; i++)
|
||||
moddata->ctxs[i] = redis_connect(moddata);
|
||||
cachedb_env->backend_data = moddata;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
redis_deinit(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
{
|
||||
struct redis_moddata* moddata = (struct redis_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
(void)env;
|
||||
|
||||
verbose(VERB_ALGO, "redis_deinit");
|
||||
|
||||
if(!moddata)
|
||||
return;
|
||||
if(moddata->ctxs) {
|
||||
int i;
|
||||
for(i = 0; i < moddata->numctxs; i++) {
|
||||
if(moddata->ctxs[i])
|
||||
redisFree(moddata->ctxs[i]);
|
||||
}
|
||||
free(moddata->ctxs);
|
||||
}
|
||||
free(moddata);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a redis command and get a reply. Unified so that it can be used for
|
||||
* both SET and GET. If 'data' is non-NULL the command is supposed to be
|
||||
* SET and GET otherwise, but the implementation of this function is agnostic
|
||||
* about the semantics (except for logging): 'command', 'data', and 'data_len'
|
||||
* are opaquely passed to redisCommand().
|
||||
* This function first checks whether a connection with a redis server has
|
||||
* been established; if not it tries to set up a new one.
|
||||
* It returns redisReply returned from redisCommand() or NULL if some low
|
||||
* level error happens. The caller is responsible to check the return value,
|
||||
* if it's non-NULL, it has to free it with freeReplyObject().
|
||||
*/
|
||||
static redisReply*
|
||||
redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
const char* command, const uint8_t* data, size_t data_len)
|
||||
{
|
||||
redisContext* ctx;
|
||||
redisReply* rep;
|
||||
struct redis_moddata* d = (struct redis_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
|
||||
/* We assume env->alloc->thread_num is a unique ID for each thread
|
||||
* in [0, num-of-threads). We could treat it as an error condition
|
||||
* if the assumption didn't hold, but it seems to be a fundamental
|
||||
* assumption throughout the unbound architecture, so we simply assert
|
||||
* it. */
|
||||
log_assert(env->alloc->thread_num < d->numctxs);
|
||||
ctx = d->ctxs[env->alloc->thread_num];
|
||||
|
||||
/* If we've not established a connection to the server or we've closed
|
||||
* it on a failure, try to re-establish a new one. Failures will be
|
||||
* logged in redis_connect(). */
|
||||
if(!ctx) {
|
||||
ctx = redis_connect(d);
|
||||
d->ctxs[env->alloc->thread_num] = ctx;
|
||||
}
|
||||
if(!ctx)
|
||||
return NULL;
|
||||
|
||||
/* Send the command and get a reply, synchronously. */
|
||||
rep = (redisReply*)redisCommand(ctx, command, data, data_len);
|
||||
if(!rep) {
|
||||
/* Once an error as a NULL-reply is returned the context cannot
|
||||
* be reused and we'll need to set up a new connection. */
|
||||
log_err("redis_command: failed to receive a reply, "
|
||||
"closing connection: %s", ctx->errstr);
|
||||
redisFree(ctx);
|
||||
d->ctxs[env->alloc->thread_num] = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check error in reply to unify logging in that case.
|
||||
* The caller may perform context-dependent checks and logging. */
|
||||
if(rep->type == REDIS_REPLY_ERROR)
|
||||
log_err("redis: %s resulted in an error: %s",
|
||||
data ? "set" : "get", rep->str);
|
||||
|
||||
return rep;
|
||||
}
|
||||
|
||||
static int
|
||||
redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, struct sldns_buffer* result_buffer)
|
||||
{
|
||||
redisReply* rep;
|
||||
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+1]; /* "GET " + key */
|
||||
int n;
|
||||
int ret = 0;
|
||||
|
||||
verbose(VERB_ALGO, "redis_lookup of %s", key);
|
||||
|
||||
n = snprintf(cmdbuf, sizeof(cmdbuf), "GET %s", key);
|
||||
if(n < 0 || n >= (int)sizeof(cmdbuf)) {
|
||||
log_err("redis_lookup: unexpected failure to build command");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0);
|
||||
if(!rep)
|
||||
return 0;
|
||||
switch (rep->type) {
|
||||
case REDIS_REPLY_NIL:
|
||||
verbose(VERB_ALGO, "redis_lookup: no data cached");
|
||||
break;
|
||||
case REDIS_REPLY_STRING:
|
||||
verbose(VERB_ALGO, "redis_lookup found %d bytes",
|
||||
(int)rep->len);
|
||||
if((size_t)rep->len > sldns_buffer_capacity(result_buffer)) {
|
||||
log_err("redis_lookup: replied data too long: %lu",
|
||||
(size_t)rep->len);
|
||||
break;
|
||||
}
|
||||
sldns_buffer_clear(result_buffer);
|
||||
sldns_buffer_write(result_buffer, rep->str, rep->len);
|
||||
sldns_buffer_flip(result_buffer);
|
||||
ret = 1;
|
||||
break;
|
||||
case REDIS_REPLY_ERROR:
|
||||
break; /* already logged */
|
||||
default:
|
||||
log_err("redis_lookup: unexpected type of reply for (%d)",
|
||||
rep->type);
|
||||
break;
|
||||
}
|
||||
freeReplyObject(rep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
redis_store(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, uint8_t* data, size_t data_len)
|
||||
{
|
||||
redisReply* rep;
|
||||
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+3+1]; /* "SET " + key + " %b" */
|
||||
int n;
|
||||
|
||||
verbose(VERB_ALGO, "redis_store %s (%d bytes)", key, (int)data_len);
|
||||
|
||||
/* build command to set to a binary safe string */
|
||||
n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b", key);
|
||||
if(n < 0 || n >= (int)sizeof(cmdbuf)) {
|
||||
log_err("redis_store: unexpected failure to build command");
|
||||
return;
|
||||
}
|
||||
|
||||
rep = redis_command(env, cachedb_env, cmdbuf, data, data_len);
|
||||
if(rep) {
|
||||
verbose(VERB_ALGO, "redis_store set completed");
|
||||
if(rep->type != REDIS_REPLY_STATUS &&
|
||||
rep->type != REDIS_REPLY_ERROR) {
|
||||
log_err("redis_store: unexpected type of reply (%d)",
|
||||
rep->type);
|
||||
}
|
||||
freeReplyObject(rep);
|
||||
}
|
||||
}
|
||||
|
||||
struct cachedb_backend redis_backend = { "redis",
|
||||
redis_init, redis_deinit, redis_lookup, redis_store
|
||||
};
|
||||
#endif /* USE_REDIS */
|
||||
#endif /* USE_CACHEDB */
|
45
contrib/unbound/cachedb/redis.h
Normal file
45
contrib/unbound/cachedb/redis.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* cachedb/redis.h - cachedb redis module
|
||||
*
|
||||
* Copyright (c) 2018, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file contains a module that uses the redis database to cache
|
||||
* dns responses.
|
||||
*/
|
||||
|
||||
/** the redis backend definition, contains callable functions
|
||||
* and name string */
|
||||
extern struct cachedb_backend redis_backend;
|
@ -84,6 +84,10 @@
|
||||
don't. */
|
||||
#define HAVE_DECL_NID_ED25519 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_ED448', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_NID_ED448 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_NID_SECP384R1 1
|
||||
@ -96,6 +100,10 @@
|
||||
don't. */
|
||||
/* #undef HAVE_DECL_REALLOCARRAY */
|
||||
|
||||
/* Define to 1 if you have the declaration of `redisConnect', and to 0 if you
|
||||
don't. */
|
||||
/* #undef HAVE_DECL_REDISCONNECT */
|
||||
|
||||
/* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0
|
||||
if you don't. */
|
||||
#define HAVE_DECL_SK_SSL_COMP_POP_FREE 1
|
||||
@ -234,6 +242,9 @@
|
||||
/* Define to 1 if you have the <grp.h> header file. */
|
||||
#define HAVE_GRP_H 1
|
||||
|
||||
/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
|
||||
/* #undef HAVE_HIREDIS_HIREDIS_H */
|
||||
|
||||
/* If you have HMAC_Update */
|
||||
#define HAVE_HMAC_UPDATE 1
|
||||
|
||||
@ -264,6 +275,9 @@
|
||||
/* Define to 1 if you have the `kill' function. */
|
||||
#define HAVE_KILL 1
|
||||
|
||||
/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
|
||||
/* #undef HAVE_LIBKERN_OSBYTEORDER_H */
|
||||
|
||||
/* Define if we have LibreSSL */
|
||||
/* #undef HAVE_LIBRESSL */
|
||||
|
||||
@ -480,6 +494,9 @@
|
||||
/* Define to 1 if systemd should be used */
|
||||
/* #undef HAVE_SYSTEMD */
|
||||
|
||||
/* Define to 1 if you have the <sys/endian.h> header file. */
|
||||
#define HAVE_SYS_ENDIAN_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ipc.h> header file. */
|
||||
#define HAVE_SYS_IPC_H 1
|
||||
|
||||
@ -611,7 +628,7 @@
|
||||
#define PACKAGE_NAME "unbound"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "unbound 1.7.0"
|
||||
#define PACKAGE_STRING "unbound 1.7.1"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "unbound"
|
||||
@ -620,7 +637,7 @@
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.7.0"
|
||||
#define PACKAGE_VERSION "1.7.1"
|
||||
|
||||
/* default pidfile location */
|
||||
#define PIDFILE "/var/unbound/unbound.pid"
|
||||
@ -639,7 +656,7 @@
|
||||
#define ROOT_CERT_FILE "/var/unbound/icannbundle.pem"
|
||||
|
||||
/* version number for resource files */
|
||||
#define RSRC_PACKAGE_VERSION 1,7,0,0
|
||||
#define RSRC_PACKAGE_VERSION 1,7,1,0
|
||||
|
||||
/* Directory to chdir to */
|
||||
#define RUN_DIR "/var/unbound"
|
||||
@ -704,6 +721,9 @@
|
||||
/* Define this to enable ED25519 support. */
|
||||
/* #undef USE_ED25519 */
|
||||
|
||||
/* Define this to enable ED448 support. */
|
||||
/* #undef USE_ED448 */
|
||||
|
||||
/* Define this to enable GOST support. */
|
||||
#define USE_GOST 1
|
||||
|
||||
@ -719,6 +739,9 @@
|
||||
/* Define this to enable client TCP Fast Open. */
|
||||
/* #undef USE_OSX_MSG_FASTOPEN */
|
||||
|
||||
/* Define this to use hiredis client. */
|
||||
/* #undef USE_REDIS */
|
||||
|
||||
/* Define this to enable SHA1 support. */
|
||||
#define USE_SHA1 1
|
||||
|
||||
@ -1223,6 +1246,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
|
||||
/** default port for DNS traffic. */
|
||||
#define UNBOUND_DNS_PORT 53
|
||||
/** default port for DNS over TLS traffic. */
|
||||
#define UNBOUND_DNS_OVER_TLS_PORT 853
|
||||
/** default port for unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
|
@ -83,6 +83,10 @@
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_ED25519
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_ED448', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_ED448
|
||||
|
||||
/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_NID_SECP384R1
|
||||
@ -95,6 +99,10 @@
|
||||
don't. */
|
||||
#undef HAVE_DECL_REALLOCARRAY
|
||||
|
||||
/* Define to 1 if you have the declaration of `redisConnect', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_REDISCONNECT
|
||||
|
||||
/* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0
|
||||
if you don't. */
|
||||
#undef HAVE_DECL_SK_SSL_COMP_POP_FREE
|
||||
@ -233,6 +241,9 @@
|
||||
/* Define to 1 if you have the <grp.h> header file. */
|
||||
#undef HAVE_GRP_H
|
||||
|
||||
/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
|
||||
#undef HAVE_HIREDIS_HIREDIS_H
|
||||
|
||||
/* If you have HMAC_Update */
|
||||
#undef HAVE_HMAC_UPDATE
|
||||
|
||||
@ -263,6 +274,9 @@
|
||||
/* Define to 1 if you have the `kill' function. */
|
||||
#undef HAVE_KILL
|
||||
|
||||
/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
|
||||
#undef HAVE_LIBKERN_OSBYTEORDER_H
|
||||
|
||||
/* Define if we have LibreSSL */
|
||||
#undef HAVE_LIBRESSL
|
||||
|
||||
@ -479,6 +493,9 @@
|
||||
/* Define to 1 if systemd should be used */
|
||||
#undef HAVE_SYSTEMD
|
||||
|
||||
/* Define to 1 if you have the <sys/endian.h> header file. */
|
||||
#undef HAVE_SYS_ENDIAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ipc.h> header file. */
|
||||
#undef HAVE_SYS_IPC_H
|
||||
|
||||
@ -703,6 +720,9 @@
|
||||
/* Define this to enable ED25519 support. */
|
||||
#undef USE_ED25519
|
||||
|
||||
/* Define this to enable ED448 support. */
|
||||
#undef USE_ED448
|
||||
|
||||
/* Define this to enable GOST support. */
|
||||
#undef USE_GOST
|
||||
|
||||
@ -718,6 +738,9 @@
|
||||
/* Define this to enable client TCP Fast Open. */
|
||||
#undef USE_OSX_MSG_FASTOPEN
|
||||
|
||||
/* Define this to use hiredis client. */
|
||||
#undef USE_REDIS
|
||||
|
||||
/* Define this to enable SHA1 support. */
|
||||
#undef USE_SHA1
|
||||
|
||||
@ -1222,6 +1245,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
|
||||
/** default port for DNS traffic. */
|
||||
#define UNBOUND_DNS_PORT 53
|
||||
/** default port for DNS over TLS traffic. */
|
||||
#define UNBOUND_DNS_OVER_TLS_PORT 853
|
||||
/** default port for unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
|
139
contrib/unbound/configure
vendored
139
contrib/unbound/configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.7.0.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.7.1.
|
||||
#
|
||||
# Report bugs to <unbound-bugs@nlnetlabs.nl>.
|
||||
#
|
||||
@ -590,8 +590,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='unbound'
|
||||
PACKAGE_TARNAME='unbound'
|
||||
PACKAGE_VERSION='1.7.0'
|
||||
PACKAGE_STRING='unbound 1.7.0'
|
||||
PACKAGE_VERSION='1.7.1'
|
||||
PACKAGE_STRING='unbound 1.7.1'
|
||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@ -859,11 +859,13 @@ enable_gost
|
||||
enable_ecdsa
|
||||
enable_dsa
|
||||
enable_ed25519
|
||||
enable_ed448
|
||||
enable_event_api
|
||||
enable_tfo_client
|
||||
enable_tfo_server
|
||||
with_libevent
|
||||
with_libexpat
|
||||
with_libhiredis
|
||||
enable_static_exe
|
||||
enable_systemd
|
||||
enable_lock_checks
|
||||
@ -1438,7 +1440,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures unbound 1.7.0 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.7.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1503,7 +1505,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of unbound 1.7.0:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.7.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1544,6 +1546,7 @@ Optional Features:
|
||||
--disable-ecdsa Disable ECDSA support
|
||||
--disable-dsa Disable DSA support
|
||||
--disable-ed25519 Disable ED25519 support
|
||||
--disable-ed448 Disable ED448 support
|
||||
--enable-event-api Enable (experimental) pluggable event base
|
||||
libunbound API installed to unbound-event.h
|
||||
--enable-tfo-client Enable TCP Fast Open for client mode
|
||||
@ -1610,6 +1613,7 @@ Optional Packages:
|
||||
an explicit path). Slower, but allows use of large
|
||||
outgoing port ranges.
|
||||
--with-libexpat=path specify explicit path for libexpat.
|
||||
--with-libhiredis=path specify explicit path for libhiredis.
|
||||
--with-dnstap-socket-path=pathname
|
||||
set default dnstap socket path
|
||||
--with-protobuf-c=path Path where protobuf-c is installed, for dnstap
|
||||
@ -1718,7 +1722,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
unbound configure 1.7.0
|
||||
unbound configure 1.7.1
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@ -2427,7 +2431,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by unbound $as_me 1.7.0, which was
|
||||
It was created by unbound $as_me 1.7.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@ -2779,11 +2783,11 @@ UNBOUND_VERSION_MAJOR=1
|
||||
|
||||
UNBOUND_VERSION_MINOR=7
|
||||
|
||||
UNBOUND_VERSION_MICRO=0
|
||||
UNBOUND_VERSION_MICRO=1
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=7
|
||||
LIBUNBOUND_REVISION=8
|
||||
LIBUNBOUND_REVISION=9
|
||||
LIBUNBOUND_AGE=5
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@ -2843,6 +2847,7 @@ LIBUNBOUND_AGE=5
|
||||
# 1.6.7 had 7:6:5
|
||||
# 1.6.8 had 7:7:5
|
||||
# 1.7.0 had 7:8:5
|
||||
# 1.7.1 had 7:9:5
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@ -14477,7 +14482,7 @@ CC=$lt_save_CC
|
||||
|
||||
|
||||
# Checks for header files.
|
||||
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/ipc.h sys/shm.h
|
||||
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h
|
||||
do :
|
||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
|
||||
@ -18314,6 +18319,50 @@ _ACEOF
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check whether --enable-ed448 was given.
|
||||
if test "${enable_ed448+set}" = set; then :
|
||||
enableval=$enable_ed448;
|
||||
fi
|
||||
|
||||
use_ed448="no"
|
||||
case "$enable_ed448" in
|
||||
no)
|
||||
;;
|
||||
*)
|
||||
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
||||
ac_fn_c_check_decl "$LINENO" "NID_ED448" "ac_cv_have_decl_NID_ED448" "$ac_includes_default
|
||||
#include <openssl/evp.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_have_decl_NID_ED448" = xyes; then :
|
||||
ac_have_decl=1
|
||||
else
|
||||
ac_have_decl=0
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_NID_ED448 $ac_have_decl
|
||||
_ACEOF
|
||||
if test $ac_have_decl = 1; then :
|
||||
|
||||
use_ed448="yes"
|
||||
|
||||
else
|
||||
if test "x$enable_ed448" = "xyes"; then as_fn_error $? "OpenSSL does not support ED448 and you used --enable-ed448." "$LINENO" 5
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
if test $use_ed448 = "yes"; then
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define USE_ED448 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check whether --enable-event-api was given.
|
||||
if test "${enable_event_api+set}" = set; then :
|
||||
enableval=$enable_event_api;
|
||||
@ -18810,6 +18859,70 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
# hiredis (redis C client for cachedb)
|
||||
|
||||
# Check whether --with-libhiredis was given.
|
||||
if test "${with_libhiredis+set}" = set; then :
|
||||
withval=$with_libhiredis;
|
||||
else
|
||||
withval="no"
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libhiredis" >&5
|
||||
$as_echo_n "checking for libhiredis... " >&6; }
|
||||
found_libhiredis="no"
|
||||
if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/hiredis/hiredis.h"; then
|
||||
found_libhiredis="yes"
|
||||
if test "$dir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$dir/include"
|
||||
LDFLAGS="$LDFLAGS -L$dir/lib"
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
|
||||
$as_echo "found in $dir" >&6; }
|
||||
|
||||
$as_echo "#define USE_REDIS 1" >>confdefs.h
|
||||
|
||||
LIBS="$LIBS -lhiredis"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libhiredis != x_yes; then
|
||||
as_fn_error $? "Could not find libhiredis, hiredis.h" "$LINENO" 5
|
||||
fi
|
||||
for ac_header in hiredis/hiredis.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "hiredis/hiredis.h" "ac_cv_header_hiredis_hiredis_h" "$ac_includes_default
|
||||
"
|
||||
if test "x$ac_cv_header_hiredis_hiredis_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_HIREDIS_HIREDIS_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
ac_fn_c_check_decl "$LINENO" "redisConnect" "ac_cv_have_decl_redisConnect" "$ac_includes_default
|
||||
#include <hiredis/hiredis.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_have_decl_redisConnect" = xyes; then :
|
||||
ac_have_decl=1
|
||||
else
|
||||
ac_have_decl=0
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_DECL_REDISCONNECT $ac_have_decl
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
# set static linking if requested
|
||||
|
||||
staticexe=""
|
||||
@ -20928,7 +21041,7 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
version=1.7.0
|
||||
version=1.7.1
|
||||
|
||||
date=`date +'%b %e, %Y'`
|
||||
|
||||
@ -21447,7 +21560,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by unbound $as_me 1.7.0, which was
|
||||
This file was extended by unbound $as_me 1.7.1, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -21513,7 +21626,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
unbound config.status 1.7.0
|
||||
unbound config.status 1.7.1
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
@ -11,14 +11,14 @@ sinclude(dnscrypt/dnscrypt.m4)
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[7])
|
||||
m4_define([VERSION_MICRO],[0])
|
||||
m4_define([VERSION_MICRO],[1])
|
||||
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=7
|
||||
LIBUNBOUND_REVISION=8
|
||||
LIBUNBOUND_REVISION=9
|
||||
LIBUNBOUND_AGE=5
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@ -78,6 +78,7 @@ LIBUNBOUND_AGE=5
|
||||
# 1.6.7 had 7:6:5
|
||||
# 1.6.8 had 7:7:5
|
||||
# 1.7.0 had 7:8:5
|
||||
# 1.7.1 had 7:9:5
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@ -331,7 +332,7 @@ AC_CHECK_TOOL(STRIP, strip)
|
||||
ACX_LIBTOOL_C_ONLY
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
# check for types.
|
||||
# Using own tests for int64* because autoconf builtin only give 32bit.
|
||||
@ -992,6 +993,26 @@ case "$enable_ed25519" in
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(ed448, AC_HELP_STRING([--disable-ed448], [Disable ED448 support]))
|
||||
use_ed448="no"
|
||||
case "$enable_ed448" in
|
||||
no)
|
||||
;;
|
||||
*)
|
||||
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
||||
AC_CHECK_DECLS([NID_ED448], [
|
||||
use_ed448="yes"
|
||||
], [ if test "x$enable_ed448" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support ED448 and you used --enable-ed448.])
|
||||
fi ], [AC_INCLUDES_DEFAULT
|
||||
#include <openssl/evp.h>
|
||||
])
|
||||
fi
|
||||
if test $use_ed448 = "yes"; then
|
||||
AC_DEFINE_UNQUOTED([USE_ED448], [1], [Define this to enable ED448 support.])
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(event-api, AC_HELP_STRING([--enable-event-api], [Enable (experimental) pluggable event base libunbound API installed to unbound-event.h]))
|
||||
case "$enable_event_api" in
|
||||
yes)
|
||||
@ -1150,6 +1171,39 @@ AC_CHECK_DECLS([XML_StopParser], [], [], [AC_INCLUDES_DEFAULT
|
||||
#include <expat.h>
|
||||
])
|
||||
|
||||
# hiredis (redis C client for cachedb)
|
||||
AC_ARG_WITH(libhiredis, AC_HELP_STRING([--with-libhiredis=path],
|
||||
[specify explicit path for libhiredis.]),
|
||||
[ ],[ withval="no" ])
|
||||
AC_MSG_CHECKING(for libhiredis)
|
||||
found_libhiredis="no"
|
||||
if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/hiredis/hiredis.h"; then
|
||||
found_libhiredis="yes"
|
||||
dnl assume /usr is in default path.
|
||||
if test "$dir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$dir/include"
|
||||
LDFLAGS="$LDFLAGS -L$dir/lib"
|
||||
fi
|
||||
AC_MSG_RESULT(found in $dir)
|
||||
AC_DEFINE([USE_REDIS], [1], [Define this to use hiredis client.])
|
||||
LIBS="$LIBS -lhiredis"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libhiredis != x_yes; then
|
||||
AC_ERROR([Could not find libhiredis, hiredis.h])
|
||||
fi
|
||||
AC_CHECK_HEADERS([hiredis/hiredis.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_DECLS([redisConnect], [], [], [AC_INCLUDES_DEFAULT
|
||||
#include <hiredis/hiredis.h>
|
||||
])
|
||||
fi
|
||||
|
||||
# set static linking if requested
|
||||
AC_SUBST(staticexe)
|
||||
staticexe=""
|
||||
@ -1752,6 +1806,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
|
||||
/** default port for DNS traffic. */
|
||||
#define UNBOUND_DNS_PORT 53
|
||||
/** default port for DNS over TLS traffic. */
|
||||
#define UNBOUND_DNS_OVER_TLS_PORT 853
|
||||
/** default port for unbound control traffic, registered port with IANA,
|
||||
ub-dns-control 8953/tcp unbound dns nameserver control */
|
||||
#define UNBOUND_CONTROL_PORT 8953
|
||||
|
@ -35,3 +35,6 @@ distribution but may be helpful.
|
||||
instead of SERVFAIL. Contributed by SIDN.
|
||||
* fastrpz.patch: fastrpz support from Farsight Security.
|
||||
* libunbound.so.conf: ltrace.conf file, see ltrace.conf(5), for libunbound.
|
||||
* unbound-querycachedb.py: utility to show data stored in cachedb backend
|
||||
for a particular query name and type. It requires dnspython and (for
|
||||
redis backend) redis Python modules.
|
||||
|
@ -21,7 +21,7 @@ Index: unbound-1.7.0~rc1/Makefile.in
|
||||
@@ -125,7 +127,7 @@ validator/val_sigcrypt.c validator/val_u
|
||||
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
|
||||
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
|
||||
cachedb/cachedb.c respip/respip.c $(CHECKLOCK_SRC) \
|
||||
cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
|
||||
-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
|
||||
+$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
|
||||
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
|
||||
|
77
contrib/unbound/contrib/unbound-querycachedb.py
Normal file
77
contrib/unbound/contrib/unbound-querycachedb.py
Normal file
@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import hashlib
|
||||
import sys
|
||||
import struct
|
||||
import socket
|
||||
import time
|
||||
from optparse import OptionParser
|
||||
|
||||
import dns.message
|
||||
import dns.name
|
||||
import dns.rdataclass
|
||||
import dns.rdatatype
|
||||
|
||||
def _calc_hashkey(qname, secret, qtype):
|
||||
qclass = 'IN' # CLASS is fixed for simplicity
|
||||
hobj = hashlib.sha256()
|
||||
hobj.update(dns.name.from_text(qname).to_wire())
|
||||
hobj.update(struct.pack('HH',
|
||||
socket.htons(dns.rdatatype.from_text(qtype)),
|
||||
socket.htons(dns.rdataclass.from_text(qclass))))
|
||||
hobj.update(secret)
|
||||
return hobj.hexdigest().upper()
|
||||
|
||||
def _redis_get(options, key):
|
||||
import redis
|
||||
return redis.Redis(options.address, int(options.port)).get(key)
|
||||
|
||||
def _dump_value(options, qname, key, value):
|
||||
print(';; query=%s/IN/%s' % (qname, options.qtype))
|
||||
print(';; key=%s' % key)
|
||||
if value is None:
|
||||
print(';; no value')
|
||||
return
|
||||
if len(value) < 16:
|
||||
print(';; broken value, short length: %d' % len(value))
|
||||
return
|
||||
now = int(time.time())
|
||||
timestamp = struct.unpack('!Q', value[-16:-8])[0]
|
||||
expire = struct.unpack('!Q', value[-8:])[0]
|
||||
print(';; Now=%d, TimeStamp=%d, Expire=%d, TTL=%d' %
|
||||
(now, timestamp, expire, max(expire - now, 0)))
|
||||
print(dns.message.from_wire(value[:-16]))
|
||||
|
||||
def main():
|
||||
parser = OptionParser(usage='usage: %prog [options] query_name')
|
||||
parser.add_option("-a", "--address", dest="address", action="store",
|
||||
default='127.0.0.1', help="backend-server address",
|
||||
metavar='ADDRESS')
|
||||
parser.add_option("-b", "--backend", dest="backend", action="store",
|
||||
default='redis', help="backend name",
|
||||
metavar='BACKEND')
|
||||
parser.add_option("-p", "--port", dest="port", action="store",
|
||||
default='6379', help="backend-server port",
|
||||
metavar='PORT')
|
||||
parser.add_option("-s", "--secret", dest="secret", action="store",
|
||||
default='default', help="secret seed", metavar='SECRET')
|
||||
parser.add_option("-t", "--qtype", dest="qtype", action="store",
|
||||
default='A', help="query RR type", metavar='QTYPE')
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) < 1:
|
||||
parser.error('qname is missing')
|
||||
if options.backend == 'redis':
|
||||
get_func = _redis_get
|
||||
else:
|
||||
raise Exception('unknown backend name: %s\n' % options.backend)
|
||||
key = _calc_hashkey(args[0], options.secret, options.qtype)
|
||||
value = get_func(options, key)
|
||||
_dump_value(options, args[0], key, value)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
sys.stderr.write('%s\n' % e)
|
||||
exit(1)
|
@ -706,9 +706,11 @@ daemon_cleanup(struct daemon* daemon)
|
||||
daemon->num = 0;
|
||||
#ifdef USE_DNSTAP
|
||||
dt_delete(daemon->dtenv);
|
||||
daemon->dtenv = NULL;
|
||||
#endif
|
||||
#ifdef USE_DNSCRYPT
|
||||
dnsc_delete(daemon->dnscenv);
|
||||
daemon->dnscenv = NULL;
|
||||
#endif
|
||||
daemon->cfg = NULL;
|
||||
}
|
||||
|
@ -68,6 +68,7 @@
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/mesh.h"
|
||||
#include "services/localzone.h"
|
||||
#include "services/authzone.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/data/dname.h"
|
||||
@ -236,10 +237,15 @@ daemon_remote_create(struct config_file* cfg)
|
||||
|
||||
if (cfg->remote_control_use_cert == 0) {
|
||||
/* No certificates are requested */
|
||||
#if defined(SSL_OP_NO_TLSv1_3)
|
||||
/* in openssl 1.1.1, negotiation code for tls 1.3 does
|
||||
* not allow the unauthenticated aNULL and eNULL ciphers */
|
||||
SSL_CTX_set_options(rc->ctx, SSL_OP_NO_TLSv1_3);
|
||||
#endif
|
||||
#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
|
||||
SSL_CTX_set_security_level(rc->ctx, 0);
|
||||
#endif
|
||||
if(!SSL_CTX_set_cipher_list(rc->ctx, "aNULL, eNULL")) {
|
||||
if(!SSL_CTX_set_cipher_list(rc->ctx, "aNULL:eNULL")) {
|
||||
log_crypto_err("Failed to set aNULL cipher list");
|
||||
daemon_remote_delete(rc);
|
||||
return NULL;
|
||||
@ -1046,6 +1052,10 @@ print_ext(SSL* ssl, struct ub_stats_info* s)
|
||||
(unsigned long)s->svr.ans_bogus)) return 0;
|
||||
if(!ssl_printf(ssl, "num.rrset.bogus"SQ"%lu\n",
|
||||
(unsigned long)s->svr.rrset_bogus)) return 0;
|
||||
if(!ssl_printf(ssl, "num.query.aggressive.NOERROR"SQ"%lu\n",
|
||||
(unsigned long)s->svr.num_neg_cache_noerror)) return 0;
|
||||
if(!ssl_printf(ssl, "num.query.aggressive.NXDOMAIN"SQ"%lu\n",
|
||||
(unsigned long)s->svr.num_neg_cache_nxdomain)) return 0;
|
||||
/* threat detection */
|
||||
if(!ssl_printf(ssl, "unwanted.queries"SQ"%lu\n",
|
||||
(unsigned long)s->svr.unwanted_queries)) return 0;
|
||||
@ -1070,6 +1080,10 @@ print_ext(SSL* ssl, struct ub_stats_info* s)
|
||||
if(!ssl_printf(ssl, "num.query.dnscrypt.replay"SQ"%lu\n",
|
||||
(unsigned long)s->svr.num_query_dnscrypt_replay)) return 0;
|
||||
#endif /* USE_DNSCRYPT */
|
||||
if(!ssl_printf(ssl, "num.query.authzone.up"SQ"%lu\n",
|
||||
(unsigned long)s->svr.num_query_authzone_up)) return 0;
|
||||
if(!ssl_printf(ssl, "num.query.authzone.down"SQ"%lu\n",
|
||||
(unsigned long)s->svr.num_query_authzone_down)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1644,6 +1658,7 @@ zone_del_msg(struct lruhash_entry* e, void* arg)
|
||||
struct reply_info* d = (struct reply_info*)e->data;
|
||||
if(d->ttl > inf->expired) {
|
||||
d->ttl = inf->expired;
|
||||
d->prefetch_ttl = inf->expired;
|
||||
inf->num_msgs++;
|
||||
}
|
||||
}
|
||||
@ -1927,6 +1942,7 @@ parse_delegpt(SSL* ssl, char* args, uint8_t* nm, int allow_names)
|
||||
struct delegpt* dp = delegpt_create_mlc(nm);
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
char* auth_name;
|
||||
if(!dp) {
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
return NULL;
|
||||
@ -1939,7 +1955,7 @@ parse_delegpt(SSL* ssl, char* args, uint8_t* nm, int allow_names)
|
||||
p = skipwhite(p); /* position at next spot */
|
||||
}
|
||||
/* parse address */
|
||||
if(!extstrtoaddr(todo, &addr, &addrlen)) {
|
||||
if(!authextstrtoaddr(todo, &addr, &addrlen, &auth_name)) {
|
||||
if(allow_names) {
|
||||
uint8_t* n = NULL;
|
||||
size_t ln;
|
||||
@ -1967,7 +1983,8 @@ parse_delegpt(SSL* ssl, char* args, uint8_t* nm, int allow_names)
|
||||
}
|
||||
} else {
|
||||
/* add address */
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) {
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
|
||||
auth_name)) {
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
delegpt_free_mlc(dp);
|
||||
return NULL;
|
||||
@ -2527,6 +2544,36 @@ do_list_stubs(SSL* ssl, struct worker* worker)
|
||||
}
|
||||
}
|
||||
|
||||
/** do the list_auth_zones command */
|
||||
static void
|
||||
do_list_auth_zones(SSL* ssl, struct auth_zones* az)
|
||||
{
|
||||
struct auth_zone* z;
|
||||
char buf[257], buf2[256];
|
||||
lock_rw_rdlock(&az->lock);
|
||||
RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
|
||||
lock_rw_rdlock(&z->lock);
|
||||
dname_str(z->name, buf);
|
||||
if(z->zone_expired)
|
||||
snprintf(buf2, sizeof(buf2), "expired");
|
||||
else {
|
||||
uint32_t serial = 0;
|
||||
if(auth_zone_get_serial(z, &serial))
|
||||
snprintf(buf2, sizeof(buf2), "serial %u",
|
||||
(unsigned)serial);
|
||||
else snprintf(buf2, sizeof(buf2), "no serial");
|
||||
}
|
||||
if(!ssl_printf(ssl, "%s\t%s\n", buf, buf2)) {
|
||||
/* failure to print */
|
||||
lock_rw_unlock(&z->lock);
|
||||
lock_rw_unlock(&az->lock);
|
||||
return;
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
lock_rw_unlock(&az->lock);
|
||||
}
|
||||
|
||||
/** do the list_local_zones command */
|
||||
static void
|
||||
do_list_local_zones(SSL* ssl, struct local_zones* zones)
|
||||
@ -2787,6 +2834,9 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
|
||||
} else if(cmdcmp(p, "ip_ratelimit_list", 17)) {
|
||||
do_ip_ratelimit_list(ssl, worker, p+17);
|
||||
return;
|
||||
} else if(cmdcmp(p, "list_auth_zones", 15)) {
|
||||
do_list_auth_zones(ssl, worker->env.auth_zones);
|
||||
return;
|
||||
} else if(cmdcmp(p, "stub_add", 8)) {
|
||||
/* must always distribute this cmd */
|
||||
if(rc) distribute_cmd(rc, ssl, cmd);
|
||||
|
@ -60,7 +60,9 @@
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/authzone.h"
|
||||
#include "validator/val_kcache.h"
|
||||
#include "validator/val_neg.h"
|
||||
|
||||
/** add timers and the values do not overflow or become negative */
|
||||
static void
|
||||
@ -122,6 +124,30 @@ void server_stats_log(struct ub_server_stats* stats, struct worker* worker,
|
||||
(unsigned)worker->env.mesh->stats_jostled);
|
||||
}
|
||||
|
||||
/** Set the neg cache stats. */
|
||||
static void
|
||||
set_neg_cache_stats(struct worker* worker, struct ub_server_stats* svr,
|
||||
int reset)
|
||||
{
|
||||
int m = modstack_find(&worker->env.mesh->mods, "validator");
|
||||
struct val_env* ve;
|
||||
struct val_neg_cache* neg;
|
||||
if(m == -1)
|
||||
return;
|
||||
ve = (struct val_env*)worker->env.modinfo[m];
|
||||
if(!ve->neg_cache)
|
||||
return;
|
||||
neg = ve->neg_cache;
|
||||
lock_basic_lock(&neg->lock);
|
||||
svr->num_neg_cache_noerror = (long long)neg->num_neg_cache_noerror;
|
||||
svr->num_neg_cache_nxdomain = (long long)neg->num_neg_cache_nxdomain;
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
neg->num_neg_cache_noerror = 0;
|
||||
neg->num_neg_cache_nxdomain = 0;
|
||||
}
|
||||
lock_basic_unlock(&neg->lock);
|
||||
}
|
||||
|
||||
/** get rrsets bogus number from validator */
|
||||
static size_t
|
||||
get_rrset_bogus(struct worker* worker, int reset)
|
||||
@ -256,6 +282,25 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
|
||||
s->svr.nonce_cache_count = 0;
|
||||
s->svr.num_query_dnscrypt_replay = 0;
|
||||
#endif /* USE_DNSCRYPT */
|
||||
if(worker->env.auth_zones) {
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
lock_rw_wrlock(&worker->env.auth_zones->lock);
|
||||
} else {
|
||||
lock_rw_rdlock(&worker->env.auth_zones->lock);
|
||||
}
|
||||
s->svr.num_query_authzone_up = (long long)worker->env.
|
||||
auth_zones->num_query_up;
|
||||
s->svr.num_query_authzone_down = (long long)worker->env.
|
||||
auth_zones->num_query_down;
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
worker->env.auth_zones->num_query_up = 0;
|
||||
worker->env.auth_zones->num_query_down = 0;
|
||||
}
|
||||
lock_rw_unlock(&worker->env.auth_zones->lock);
|
||||
}
|
||||
|
||||
/* Set neg cache usage numbers */
|
||||
set_neg_cache_stats(worker, &s->svr, reset);
|
||||
|
||||
/* get tcp accept usage */
|
||||
s->svr.tcp_accept_usage = 0;
|
||||
|
@ -342,7 +342,8 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker)
|
||||
verbose(VERB_QUERY, "request bad, has TC bit on");
|
||||
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||
}
|
||||
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) {
|
||||
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY &&
|
||||
LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_NOTIFY) {
|
||||
verbose(VERB_QUERY, "request unknown opcode %d",
|
||||
LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)));
|
||||
return worker_err_ratelimit(worker, LDNS_RCODE_NOTIMPL);
|
||||
@ -352,7 +353,9 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker)
|
||||
LDNS_QDCOUNT(sldns_buffer_begin(pkt)));
|
||||
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||
}
|
||||
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0) {
|
||||
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0 &&
|
||||
(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 1 ||
|
||||
LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_NOTIFY)) {
|
||||
verbose(VERB_QUERY, "request wrong nr an=%d",
|
||||
LDNS_ANCOUNT(sldns_buffer_begin(pkt)));
|
||||
return worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||
@ -499,6 +502,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
* let validator do that */
|
||||
return 0;
|
||||
case sec_status_bogus:
|
||||
case sec_status_secure_sentinel_fail:
|
||||
/* some rrsets are bogus, reply servfail */
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
@ -655,7 +659,8 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
}
|
||||
}
|
||||
/* check security status of the cached answer */
|
||||
if( rep->security == sec_status_bogus && must_validate) {
|
||||
if(must_validate && (rep->security == sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
/* BAD cached */
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
@ -940,6 +945,66 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer notify queries. These are notifies for authoritative zones,
|
||||
* the reply is an ack that the notify has been received. We need to check
|
||||
* access permission here.
|
||||
* @param w: worker
|
||||
* @param qinfo: query info. Pointer into packet buffer.
|
||||
* @param edns: edns info from query.
|
||||
* @param repinfo: reply info with source address.
|
||||
* @param pkt: packet buffer.
|
||||
*/
|
||||
static void
|
||||
answer_notify(struct worker* w, struct query_info* qinfo,
|
||||
struct edns_data* edns, sldns_buffer* pkt, struct comm_reply* repinfo)
|
||||
{
|
||||
int refused = 0;
|
||||
int rcode = LDNS_RCODE_NOERROR;
|
||||
uint32_t serial = 0;
|
||||
int has_serial;
|
||||
if(!w->env.auth_zones) return;
|
||||
has_serial = auth_zone_parse_notify_serial(pkt, &serial);
|
||||
if(auth_zones_notify(w->env.auth_zones, &w->env, qinfo->qname,
|
||||
qinfo->qname_len, qinfo->qclass, &repinfo->addr,
|
||||
repinfo->addrlen, has_serial, serial, &refused)) {
|
||||
rcode = LDNS_RCODE_NOERROR;
|
||||
} else {
|
||||
if(refused)
|
||||
rcode = LDNS_RCODE_REFUSED;
|
||||
else rcode = LDNS_RCODE_SERVFAIL;
|
||||
}
|
||||
|
||||
if(verbosity >= VERB_DETAIL) {
|
||||
char buf[380];
|
||||
char zname[255+1];
|
||||
char sr[25];
|
||||
dname_str(qinfo->qname, zname);
|
||||
sr[0]=0;
|
||||
if(has_serial)
|
||||
snprintf(sr, sizeof(sr), "serial %u ",
|
||||
(unsigned)serial);
|
||||
if(rcode == LDNS_RCODE_REFUSED)
|
||||
snprintf(buf, sizeof(buf),
|
||||
"refused NOTIFY %sfor %s from", sr, zname);
|
||||
else if(rcode == LDNS_RCODE_SERVFAIL)
|
||||
snprintf(buf, sizeof(buf),
|
||||
"servfail for NOTIFY %sfor %s from", sr, zname);
|
||||
else snprintf(buf, sizeof(buf),
|
||||
"received NOTIFY %sfor %s from", sr, zname);
|
||||
log_addr(VERB_DETAIL, buf, &repinfo->addr, repinfo->addrlen);
|
||||
}
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
edns->opt_list = NULL;
|
||||
error_encode(pkt, rcode, qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(pkt),
|
||||
sldns_buffer_read_u16_at(pkt, 2), edns);
|
||||
LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY);
|
||||
}
|
||||
|
||||
static int
|
||||
deny_refuse(struct comm_point* c, enum acl_access acl,
|
||||
enum acl_access deny, enum acl_access refuse,
|
||||
@ -1238,6 +1303,12 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
|
||||
LDNS_PACKET_NOTIFY) {
|
||||
answer_notify(worker, &qinfo, &edns, c->buffer, repinfo);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
if(local_zones_answer(worker->daemon->local_zones, &worker->env, &qinfo,
|
||||
&edns, c->buffer, worker->scratchpad, repinfo, acladdr->taglist,
|
||||
acladdr->taglen, acladdr->tag_actions,
|
||||
@ -1806,7 +1877,7 @@ struct outbound_entry*
|
||||
worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
|
||||
int want_dnssec, int nocaps, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen, int ssl_upstream,
|
||||
struct module_qstate* q)
|
||||
char* tls_auth_name, struct module_qstate* q)
|
||||
{
|
||||
struct worker* worker = q->env->worker;
|
||||
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
|
||||
@ -1816,7 +1887,7 @@ worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
|
||||
e->qstate = q;
|
||||
e->qsent = outnet_serviced_query(worker->back, qinfo, flags, dnssec,
|
||||
want_dnssec, nocaps, q->env->cfg->tcp_upstream,
|
||||
ssl_upstream, addr, addrlen, zone, zonelen, q,
|
||||
ssl_upstream, tls_auth_name, addr, addrlen, zone, zonelen, q,
|
||||
worker_handle_service_reply, e, worker->back->udp_buff, q->env);
|
||||
if(!e->qsent) {
|
||||
return NULL;
|
||||
@ -1863,7 +1934,8 @@ struct outbound_entry* libworker_send_query(
|
||||
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
|
||||
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
|
||||
int ATTR_UNUSED(ssl_upstream), struct module_qstate* ATTR_UNUSED(q))
|
||||
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
|
||||
struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
|
@ -1,6 +1,143 @@
|
||||
26 April 2018: Wouter
|
||||
- Fix for crash in daemon_cleanup with dnstap during reload,
|
||||
from Saksham Manchanda.
|
||||
- Also that for dnscrypt.
|
||||
- tag for 1.7.1rc1 release.
|
||||
|
||||
25 April 2018: Ralph
|
||||
- Fix memory leak when caching wildcard records for aggressive NSEC use
|
||||
|
||||
24 April 2018: Wouter
|
||||
- Fix contrib/fastrpz.patch for this release.
|
||||
- Fix auth https for libev.
|
||||
|
||||
24 April 2018: Ralph
|
||||
- Added root-key-sentinel support
|
||||
|
||||
23 April 2018: Wouter
|
||||
- makedist uses bz2 for expat code, instead of tar.gz.
|
||||
- Fix #4092: libunbound: use-caps-for-id lacks colon in
|
||||
config_set_option.
|
||||
- auth zone http download stores exact copy of downloaded file,
|
||||
including comments in the file.
|
||||
- Fix sldns parse failure for CDS alternate delete syntax empty hex.
|
||||
- Attempt for auth zone fix; add of callback in mesh gets from
|
||||
callback does not skip callback of result.
|
||||
- Fix cname classification with qname minimisation enabled.
|
||||
- list_auth_zones unbound-control command.
|
||||
|
||||
20 April 2018: Wouter
|
||||
- man page documentation for dns-over-tls forward-addr '#' notation.
|
||||
- removed free from failed parse case.
|
||||
- Fix #4091: Fix that reload of auth-zone does not merge the zonefile
|
||||
with the previous contents.
|
||||
- Delete auth zone when removed from config.
|
||||
|
||||
19 April 2018: Wouter
|
||||
- Can set tls authentication with forward-addr: IP#tls.auth.name
|
||||
And put the public cert bundle in tls-cert-bundle: "ca-bundle.pem".
|
||||
such as forward-addr: 9.9.9.9@853#dns.quad9.net or
|
||||
1.1.1.1@853#cloudflare-dns.com
|
||||
- Fix #658: unbound using TLS in a forwarding configuration does not
|
||||
verify the server's certificate (RFC 8310 support).
|
||||
- For addr with #authname and no @port notation, the default is 853.
|
||||
|
||||
18 April 2018: Wouter
|
||||
- Fix auth-zone retry timer to be on schedule with retry timeout,
|
||||
with backoff. Also time a refresh at the zone expiry.
|
||||
|
||||
17 April 2018: Wouter
|
||||
- auth zone notify work.
|
||||
- allow-notify: config statement for auth-zones.
|
||||
- unit test for allow-notify
|
||||
|
||||
16 April 2018: Wouter
|
||||
- Fix auth zone target lookup iterator.
|
||||
- auth zone notify with prefix
|
||||
- auth zone notify work.
|
||||
|
||||
13 April 2018: Wouter
|
||||
- Fix for max include depth for authzones.
|
||||
- Fix memory free on fail for $INCLUDE in authzone.
|
||||
- Fix that an internal error to look up the wrong rr type for
|
||||
auth zone gets stopped, before trying to send there.
|
||||
- auth zone notify work.
|
||||
|
||||
10 April 2018: Ralph
|
||||
- num.query.aggressive.NOERROR and num.query.aggressive.NXDOMAIN
|
||||
statistics counters.
|
||||
|
||||
10 April 2018: Wouter
|
||||
- documentation for low-rtt and low-rtt-pct.
|
||||
- auth zone notify work.
|
||||
|
||||
9 April 2018: Wouter
|
||||
- Fix that flush_zone sets prefetch ttl expired, so that with
|
||||
serve-expired enabled it'll start prefetching those entries.
|
||||
- num.query.authzone.up and num.query.authzone.down statistics counters.
|
||||
- Fix downstream auth zone, only fallback when auth zone fails to
|
||||
answer and fallback is enabled.
|
||||
- Accept both option names with and without colon for get_option
|
||||
and set_option.
|
||||
- low-rtt and low-rtt-pct in unbound.conf enable the server selection
|
||||
of fast servers for some percentage of the time.
|
||||
|
||||
5 April 2018: Wouter
|
||||
- Combine write of tcp length and tcp query for dns over tls.
|
||||
- nitpick fixes in example.conf.
|
||||
- Fix above stub queries for type NS and useless delegation point.
|
||||
- Fix unbound-control over pipe with openssl 1.1.1, the TLSv1.3
|
||||
tls_choose_sigalg routine does not allow the ciphers for the pipe,
|
||||
so use TLSv1.2.
|
||||
- ED448 support.
|
||||
|
||||
3 April 2018: Wouter
|
||||
- Fix #4043: make test fails due to v6 presentation issue in macOS.
|
||||
- Fix unable to resolve after new WLAN connection, due to auth-zone
|
||||
failing with a forwarder set. Now, auth-zone is only used for
|
||||
answers (not referrals) when a forwarder is set.
|
||||
|
||||
29 March 2018: Ralph
|
||||
- Check "result" in dup_all(), by Florian Obser.
|
||||
|
||||
23 March 2018: Ralph
|
||||
- Fix unbound-control get_option aggressive-nsec
|
||||
|
||||
21 March 2018: Ralph
|
||||
- Do not use cached NSEC records to generate negative answers for
|
||||
domains under DNSSEC Negative Trust Anchors.
|
||||
|
||||
19 March 2018: Wouter
|
||||
- iana port update.
|
||||
|
||||
16 March 2018: Wouter
|
||||
- corrected a minor typo in the changelog.
|
||||
- move htobe64/be64toh portability code to cachedb.c.
|
||||
|
||||
15 March 2018: Wouter
|
||||
- Add --with-libhiredis, unbound support for a new cachedb backend
|
||||
that uses a Redis server as the storage. This implementation
|
||||
depends on the hiredis client library (https://redislabs.com/lp/hiredis/).
|
||||
And unbound should be built with both --enable-cachedb and
|
||||
--with-libhiredis[=PATH] (where $PATH/include/hiredis/hiredis.h
|
||||
should exist). Patch from Jinmei Tatuya (Infoblox).
|
||||
- Fix #3817: core dump happens in libunbound delete, when queued
|
||||
servfail hits deleted message queue.
|
||||
- Create additional tls service interfaces by opening them on other
|
||||
portnumbers and listing the portnumbers as additional-tls-port: nr.
|
||||
|
||||
13 March 2018: Wouter
|
||||
- Fix typo in documentation.
|
||||
- Fix #3736: Fix 0 TTL domains stuck on SERVFAIL unless manually
|
||||
flushed with serve-expired on.
|
||||
|
||||
12 March 2018: Wouter
|
||||
- Added documentation for aggressive-nsec: yes.
|
||||
- tag 1.7.0rc3.
|
||||
- tag 1.7.0rc3. That became the 1.7.0 release on 15 Mar, trunk
|
||||
now has 1.7.1 in development.
|
||||
- Fix #3727: Protocol name is TLS, options have been renamed but
|
||||
documentation is not consistent.
|
||||
- Check IXFR start serial.
|
||||
|
||||
9 March 2018: Wouter
|
||||
- Fix #3598: Fix swig build issue on rhel6 based system.
|
||||
|
@ -1,4 +1,4 @@
|
||||
README for Unbound 1.7.0
|
||||
README for Unbound 1.7.1
|
||||
Copyright 2007 NLnet Labs
|
||||
http://unbound.net
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
# See unbound.conf(5) man page, version 1.7.0.
|
||||
# See unbound.conf(5) man page, version 1.7.1.
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
@ -199,7 +199,7 @@ server:
|
||||
# upstream connections use TCP only (and no UDP), "yes" or "no"
|
||||
# useful for tunneling scenarios, default no.
|
||||
# tcp-upstream: no
|
||||
|
||||
|
||||
# upstream connections also use UDP (even if do-udp is no).
|
||||
# useful if if you want UDP upstream, but don't provide UDP downstream.
|
||||
# udp-upstream-without-downstream: no
|
||||
@ -320,7 +320,7 @@ server:
|
||||
|
||||
# enable to not answer version.server and version.bind queries.
|
||||
# hide-version: no
|
||||
|
||||
|
||||
# enable to not answer trustanchor.unbound queries.
|
||||
# hide-trustanchor: no
|
||||
|
||||
@ -458,6 +458,9 @@ server:
|
||||
|
||||
# trust anchor signaling sends a RFC8145 key tag query after priming.
|
||||
# trust-anchor-signaling: yes
|
||||
|
||||
# Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel)
|
||||
# root-key-sentinel: yes
|
||||
|
||||
# File with DLV trusted keys. Same format as trust-anchor-file.
|
||||
# There can be only one DLV configured, it is trusted from root down.
|
||||
@ -630,7 +633,7 @@ server:
|
||||
# o inform acts like transparent, but logs client IP address
|
||||
# o inform_deny drops queries and logs client IP address
|
||||
# o always_transparent, always_refuse, always_nxdomain, resolve in
|
||||
# that way but ignore local data for that name.
|
||||
# that way but ignore local data for that name
|
||||
# o noview breaks out of that view towards global local-zones.
|
||||
#
|
||||
# defaults are localhost address, reverse for 127.0.0.1 and ::1
|
||||
@ -664,20 +667,23 @@ server:
|
||||
# add a netblock specific override to a localzone, with zone type
|
||||
# local-zone-override: "example.com" 192.0.2.0/24 refuse
|
||||
|
||||
# service clients over SSL (on the TCP sockets), with plain DNS inside
|
||||
# the SSL stream. Give the certificate to use and private key.
|
||||
# service clients over TLS (on the TCP sockets), with plain DNS inside
|
||||
# the TLS stream. Give the certificate to use and private key.
|
||||
# default is "" (disabled). requires restart to take effect.
|
||||
# tls-service-key: "path/to/privatekeyfile.key"
|
||||
# tls-service-pem: "path/to/publiccertfile.pem"
|
||||
# tls-port: 853
|
||||
|
||||
# request upstream over SSL (with plain DNS inside the SSL stream).
|
||||
# request upstream over TLS (with plain DNS inside the TLS stream).
|
||||
# Default is no. Can be turned on and off with unbound-control.
|
||||
# tls-upstream: no
|
||||
|
||||
# Certificates used to authenticate connections made upstream.
|
||||
# tls-cert-bundle: ""
|
||||
|
||||
# Also serve tls on these port numbers (eg. 443, ...), by listing
|
||||
# additional-tls-port: portno for each of the port numbers.
|
||||
|
||||
# DNS64 prefix. Must be specified when DNS64 is use.
|
||||
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
|
||||
# dns64-prefix: 64:ff9b::0/96
|
||||
@ -715,6 +721,12 @@ server:
|
||||
# 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through
|
||||
# ip-ratelimit-factor: 10
|
||||
|
||||
# what is considered a low rtt (ping time for upstream server), in msec
|
||||
# low-rtt: 45
|
||||
# select low rtt this many times out of 1000. 0 means the fast server
|
||||
# select is disabled. prefetches are not sped up.
|
||||
# low-rtt-pct: 0
|
||||
|
||||
# Specific options for ipsecmod. unbound needs to be configured with
|
||||
# --enable-ipsecmod for these to take effect.
|
||||
#
|
||||
@ -823,6 +835,8 @@ remote-control:
|
||||
# has a copy of the root for local usage. The second serves example.org
|
||||
# authoritatively. zonefile: reads from file (and writes to it if you also
|
||||
# download it), master: fetches with AXFR and IXFR, or url to zonefile.
|
||||
# With allow-notify: you can give additional (apart from masters) sources of
|
||||
# notifies.
|
||||
# auth-zone:
|
||||
# name: "."
|
||||
# for-downstream: no
|
||||
@ -851,7 +865,7 @@ remote-control:
|
||||
# name: "viewname"
|
||||
# local-zone: "example.com" redirect
|
||||
# local-data: "example.com A 192.0.2.3"
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
# view-first: no
|
||||
# view:
|
||||
# name: "anotherview"
|
||||
@ -886,3 +900,11 @@ remote-control:
|
||||
# backend: "testframe"
|
||||
# # secret seed string to calculate hashed keys
|
||||
# secret-seed: "default"
|
||||
#
|
||||
# # For "redis" backend:
|
||||
# # redis server's IP address or host name
|
||||
# redis-server-host: 127.0.0.1
|
||||
# # redis server's TCP port
|
||||
# redis-server-port: 6379
|
||||
# # timeout (in ms) for communication with the redis server
|
||||
# redis-timeout: 100
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
# See unbound.conf(5) man page, version 1.7.0.
|
||||
# See unbound.conf(5) man page, version 1.7.1.
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
@ -199,7 +199,7 @@ server:
|
||||
# upstream connections use TCP only (and no UDP), "yes" or "no"
|
||||
# useful for tunneling scenarios, default no.
|
||||
# tcp-upstream: no
|
||||
|
||||
|
||||
# upstream connections also use UDP (even if do-udp is no).
|
||||
# useful if if you want UDP upstream, but don't provide UDP downstream.
|
||||
# udp-upstream-without-downstream: no
|
||||
@ -320,7 +320,7 @@ server:
|
||||
|
||||
# enable to not answer version.server and version.bind queries.
|
||||
# hide-version: no
|
||||
|
||||
|
||||
# enable to not answer trustanchor.unbound queries.
|
||||
# hide-trustanchor: no
|
||||
|
||||
@ -458,6 +458,9 @@ server:
|
||||
|
||||
# trust anchor signaling sends a RFC8145 key tag query after priming.
|
||||
# trust-anchor-signaling: yes
|
||||
|
||||
# Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel)
|
||||
# root-key-sentinel: yes
|
||||
|
||||
# File with DLV trusted keys. Same format as trust-anchor-file.
|
||||
# There can be only one DLV configured, it is trusted from root down.
|
||||
@ -630,7 +633,7 @@ server:
|
||||
# o inform acts like transparent, but logs client IP address
|
||||
# o inform_deny drops queries and logs client IP address
|
||||
# o always_transparent, always_refuse, always_nxdomain, resolve in
|
||||
# that way but ignore local data for that name.
|
||||
# that way but ignore local data for that name
|
||||
# o noview breaks out of that view towards global local-zones.
|
||||
#
|
||||
# defaults are localhost address, reverse for 127.0.0.1 and ::1
|
||||
@ -664,20 +667,23 @@ server:
|
||||
# add a netblock specific override to a localzone, with zone type
|
||||
# local-zone-override: "example.com" 192.0.2.0/24 refuse
|
||||
|
||||
# service clients over SSL (on the TCP sockets), with plain DNS inside
|
||||
# the SSL stream. Give the certificate to use and private key.
|
||||
# service clients over TLS (on the TCP sockets), with plain DNS inside
|
||||
# the TLS stream. Give the certificate to use and private key.
|
||||
# default is "" (disabled). requires restart to take effect.
|
||||
# tls-service-key: "path/to/privatekeyfile.key"
|
||||
# tls-service-pem: "path/to/publiccertfile.pem"
|
||||
# tls-port: 853
|
||||
|
||||
# request upstream over SSL (with plain DNS inside the SSL stream).
|
||||
# request upstream over TLS (with plain DNS inside the TLS stream).
|
||||
# Default is no. Can be turned on and off with unbound-control.
|
||||
# tls-upstream: no
|
||||
|
||||
# Certificates used to authenticate connections made upstream.
|
||||
# tls-cert-bundle: ""
|
||||
|
||||
# Also serve tls on these port numbers (eg. 443, ...), by listing
|
||||
# additional-tls-port: portno for each of the port numbers.
|
||||
|
||||
# DNS64 prefix. Must be specified when DNS64 is use.
|
||||
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
|
||||
# dns64-prefix: 64:ff9b::0/96
|
||||
@ -715,6 +721,12 @@ server:
|
||||
# 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through
|
||||
# ip-ratelimit-factor: 10
|
||||
|
||||
# what is considered a low rtt (ping time for upstream server), in msec
|
||||
# low-rtt: 45
|
||||
# select low rtt this many times out of 1000. 0 means the fast server
|
||||
# select is disabled. prefetches are not sped up.
|
||||
# low-rtt-pct: 0
|
||||
|
||||
# Specific options for ipsecmod. unbound needs to be configured with
|
||||
# --enable-ipsecmod for these to take effect.
|
||||
#
|
||||
@ -823,6 +835,8 @@ remote-control:
|
||||
# has a copy of the root for local usage. The second serves example.org
|
||||
# authoritatively. zonefile: reads from file (and writes to it if you also
|
||||
# download it), master: fetches with AXFR and IXFR, or url to zonefile.
|
||||
# With allow-notify: you can give additional (apart from masters) sources of
|
||||
# notifies.
|
||||
# auth-zone:
|
||||
# name: "."
|
||||
# for-downstream: no
|
||||
@ -851,7 +865,7 @@ remote-control:
|
||||
# name: "viewname"
|
||||
# local-zone: "example.com" redirect
|
||||
# local-data: "example.com A 192.0.2.3"
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
# view-first: no
|
||||
# view:
|
||||
# name: "anotherview"
|
||||
@ -886,3 +900,11 @@ remote-control:
|
||||
# backend: "testframe"
|
||||
# # secret seed string to calculate hashed keys
|
||||
# secret-seed: "default"
|
||||
#
|
||||
# # For "redis" backend:
|
||||
# # redis server's IP address or host name
|
||||
# redis-server-host: 127.0.0.1
|
||||
# # redis server's TCP port
|
||||
# redis-server-port: 6379
|
||||
# # timeout (in ms) for communication with the redis server
|
||||
# redis-timeout: 100
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "libunbound" "3" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "libunbound" "3" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" libunbound.3 -- unbound library functions manual
|
||||
.\"
|
||||
@ -43,7 +43,7 @@
|
||||
.B ub_ctx_zone_remove,
|
||||
.B ub_ctx_data_add,
|
||||
.B ub_ctx_data_remove
|
||||
\- Unbound DNS validating resolver 1.7.0 functions.
|
||||
\- Unbound DNS validating resolver 1.7.1 functions.
|
||||
.SH "SYNOPSIS"
|
||||
.B #include <unbound.h>
|
||||
.LP
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "libunbound" "3" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "libunbound" "3" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" libunbound.3 -- unbound library functions manual
|
||||
.\"
|
||||
@ -43,7 +43,7 @@
|
||||
.B ub_ctx_zone_remove,
|
||||
.B ub_ctx_data_add,
|
||||
.B ub_ctx_data_remove
|
||||
\- Unbound DNS validating resolver 1.7.0 functions.
|
||||
\- Unbound DNS validating resolver 1.7.1 functions.
|
||||
.SH "SYNOPSIS"
|
||||
.B #include <unbound.h>
|
||||
.LP
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-anchor" "8" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "unbound-anchor" "8" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-anchor" "8" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "unbound-anchor" "8" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-checkconf" "8" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "unbound-checkconf" "8" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" unbound-checkconf.8 -- unbound configuration checker manual
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-checkconf" "8" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "unbound-checkconf" "8" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" unbound-checkconf.8 -- unbound configuration checker manual
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-control" "8" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "unbound-control" "8" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" unbound-control.8 -- unbound remote control manual
|
||||
.\"
|
||||
@ -144,6 +144,9 @@ Remove the name, type information from the cache.
|
||||
Remove all information at or below the name from the cache.
|
||||
The rrsets and key entries are removed so that new lookups will be performed.
|
||||
This needs to walk and inspect the entire cache, and is a slow operation.
|
||||
The entries are set to expired in the implementation of this command (so,
|
||||
with serve\-expired enabled, it'll serve that information but schedule a
|
||||
prefetch for new information).
|
||||
.TP
|
||||
.B flush_bogus
|
||||
Remove all bogus data from the cache.
|
||||
@ -286,6 +289,10 @@ estimated qps and qps limit from config. With +a it prints all ips, not
|
||||
just the ratelimited ips, with their estimated qps. The ratelimited
|
||||
ips are dropped before checking the cache.
|
||||
.TP
|
||||
.B list_auth_zones
|
||||
List the auth zones that are configured. Printed one per line with a
|
||||
status, indicating if the zone is expired and current serial number.
|
||||
.TP
|
||||
.B view_list_local_zones \fIview\fR
|
||||
\fIlist_local_zones\fR for given view.
|
||||
.TP
|
||||
@ -598,6 +605,26 @@ 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.
|
||||
.TP
|
||||
.I num.query.authzone.up
|
||||
The number of queries answered from auth\-zone data, upstream queries.
|
||||
These queries would otherwise have been sent (with fallback enabled) to
|
||||
the internet, but are now answered from the auth zone.
|
||||
.TP
|
||||
.I num.query.authzone.down
|
||||
The number of queries for downstream answered from auth\-zone data.
|
||||
These queries are from downstream clients, and have had an answer from
|
||||
the data in the auth zone.
|
||||
.TP
|
||||
.I num.query.aggressive.NOERROR
|
||||
The number of queries answered using cached NSEC records with NODATA RCODE.
|
||||
These queries would otherwise have been sent to the internet, but are now
|
||||
answered using cached data.
|
||||
.TP
|
||||
.I num.query.aggressive.NXDOMAIN
|
||||
The number of queries answered using cached NSEC records with NXDOMAIN RCODE.
|
||||
These queries would otherwise have been sent to the internet, but are now
|
||||
answered using cached data.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I /var/unbound/unbound.conf
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-control" "8" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "unbound-control" "8" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" unbound-control.8 -- unbound remote control manual
|
||||
.\"
|
||||
@ -144,6 +144,9 @@ Remove the name, type information from the cache.
|
||||
Remove all information at or below the name from the cache.
|
||||
The rrsets and key entries are removed so that new lookups will be performed.
|
||||
This needs to walk and inspect the entire cache, and is a slow operation.
|
||||
The entries are set to expired in the implementation of this command (so,
|
||||
with serve\-expired enabled, it'll serve that information but schedule a
|
||||
prefetch for new information).
|
||||
.TP
|
||||
.B flush_bogus
|
||||
Remove all bogus data from the cache.
|
||||
@ -286,6 +289,10 @@ estimated qps and qps limit from config. With +a it prints all ips, not
|
||||
just the ratelimited ips, with their estimated qps. The ratelimited
|
||||
ips are dropped before checking the cache.
|
||||
.TP
|
||||
.B list_auth_zones
|
||||
List the auth zones that are configured. Printed one per line with a
|
||||
status, indicating if the zone is expired and current serial number.
|
||||
.TP
|
||||
.B view_list_local_zones \fIview\fR
|
||||
\fIlist_local_zones\fR for given view.
|
||||
.TP
|
||||
@ -598,6 +605,26 @@ 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.
|
||||
.TP
|
||||
.I num.query.authzone.up
|
||||
The number of queries answered from auth\-zone data, upstream queries.
|
||||
These queries would otherwise have been sent (with fallback enabled) to
|
||||
the internet, but are now answered from the auth zone.
|
||||
.TP
|
||||
.I num.query.authzone.down
|
||||
The number of queries for downstream answered from auth\-zone data.
|
||||
These queries are from downstream clients, and have had an answer from
|
||||
the data in the auth zone.
|
||||
.TP
|
||||
.I num.query.aggressive.NOERROR
|
||||
The number of queries answered using cached NSEC records with NODATA RCODE.
|
||||
These queries would otherwise have been sent to the internet, but are now
|
||||
answered using cached data.
|
||||
.TP
|
||||
.I num.query.aggressive.NXDOMAIN
|
||||
The number of queries answered using cached NSEC records with NXDOMAIN RCODE.
|
||||
These queries would otherwise have been sent to the internet, but are now
|
||||
answered using cached data.
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I @ub_conf_file@
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound\-host" "1" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "unbound\-host" "1" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" unbound-host.1 -- unbound DNS lookup utility
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound\-host" "1" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "unbound\-host" "1" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" unbound-host.1 -- unbound DNS lookup utility
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound" "8" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "unbound" "8" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" unbound.8 -- unbound manual
|
||||
.\"
|
||||
@ -9,7 +9,7 @@
|
||||
.\"
|
||||
.SH "NAME"
|
||||
.B unbound
|
||||
\- Unbound DNS validating resolver 1.7.0.
|
||||
\- Unbound DNS validating resolver 1.7.1.
|
||||
.SH "SYNOPSIS"
|
||||
.B unbound
|
||||
.RB [ \-h ]
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound" "8" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "unbound" "8" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" unbound.8 -- unbound manual
|
||||
.\"
|
||||
@ -9,7 +9,7 @@
|
||||
.\"
|
||||
.SH "NAME"
|
||||
.B unbound
|
||||
\- Unbound DNS validating resolver 1.7.0.
|
||||
\- Unbound DNS validating resolver 1.7.1.
|
||||
.SH "SYNOPSIS"
|
||||
.B unbound
|
||||
.RB [ \-h ]
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound.conf" "5" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "unbound.conf" "5" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" unbound.conf.5 -- unbound.conf manual
|
||||
.\"
|
||||
@ -288,7 +288,7 @@ silently (unless verbosity 3) without the option.
|
||||
.B ip\-transparent: \fI<yes or no>
|
||||
If yes, then use IP_TRANSPARENT socket option on sockets where unbound
|
||||
is listening for incoming traffic. Default no. Allows you to bind to
|
||||
non\-local interfaces. For example for non\-existant IP addresses that
|
||||
non\-local interfaces. For example for non\-existent IP addresses that
|
||||
are going to exist later on, with host failover configuration. This is
|
||||
a lot like interface\-automatic, but that one services all interfaces
|
||||
and with this option you can select which (future) interfaces unbound
|
||||
@ -399,8 +399,8 @@ change anything. Useful for TLS service providers, that want no udp downstream
|
||||
but use udp to fetch data upstream.
|
||||
.TP
|
||||
.B tls\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the upstream queries use SSL only for transport.
|
||||
Default is no. Useful in tunneling scenarios. The SSL contains plain DNS in
|
||||
Enabled or disable whether the upstream queries use TLS only for transport.
|
||||
Default is no. Useful in tunneling scenarios. The TLS contains plain DNS in
|
||||
TCP wireformat. The other server must support this (see
|
||||
\fBtls\-service\-key\fR).
|
||||
.TP
|
||||
@ -409,7 +409,7 @@ Alternate syntax for \fBtls\-upstream\fR. If both are present in the config
|
||||
file the last is used.
|
||||
.TP
|
||||
.B tls\-service\-key: \fI<file>
|
||||
If enabled, the server provider SSL service on its TCP sockets. The clients
|
||||
If enabled, the server provider TLS service on its TCP sockets. The clients
|
||||
have to use tls\-upstream: yes. The file is the private key for the TLS
|
||||
session. The public certificate is in the tls\-service\-pem file. Default
|
||||
is "", turned off. Requires a restart (a reload is not enough) if changed,
|
||||
@ -429,8 +429,8 @@ turned off.
|
||||
Alternate syntax for \fBtls\-service\-pem\fR.
|
||||
.TP
|
||||
.B tls\-port: \fI<number>
|
||||
The port number on which to provide TCP SSL service, default 853, only
|
||||
interfaces configured with that port number as @number get the SSL service.
|
||||
The port number on which to provide TCP TLS service, default 853, only
|
||||
interfaces configured with that port number as @number get the TLS service.
|
||||
.TP
|
||||
.B ssl\-port: \fI<number>
|
||||
Alternate syntax for \fBtls\-port\fR.
|
||||
@ -444,6 +444,11 @@ urls, and also DNS over TLS connections.
|
||||
.B ssl\-cert\-bundle: \fI<file>
|
||||
Alternate syntax for \fBtls\-cert\-bundle\fR.
|
||||
.TP
|
||||
.B additional\-tls\-port: \fI<portnr>
|
||||
List portnumbers as additional\-tls\-port, and when interfaces are defined,
|
||||
eg. with the @port suffix, as this port number, they provide dns over TLS
|
||||
service. Can list multiple, each on a new statement.
|
||||
.TP
|
||||
.B use\-systemd: \fI<yes or no>
|
||||
Enable or disable systemd socket activation.
|
||||
Default is no.
|
||||
@ -728,8 +733,8 @@ This option only has effect when qname-minimisation is enabled. Default is off.
|
||||
.B aggressive\-nsec: \fI<yes or no>
|
||||
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
|
||||
and other denials, using information from previous NXDOMAINs answers.
|
||||
Default is off. It helps to reduce the query rate towards targets that get
|
||||
a very high nonexistant name lookup rate.
|
||||
Default is no. It helps to reduce the query rate towards targets that get
|
||||
a very high nonexistent name lookup rate.
|
||||
.TP
|
||||
.B private\-address: \fI<IP address or subnet>
|
||||
Give IPv4 of IPv6 addresses or classless subnets. These are addresses
|
||||
@ -844,6 +849,9 @@ expanded on start and on reload.
|
||||
.B trust\-anchor\-signaling: \fI<yes or no>
|
||||
Send RFC8145 key tag query after trust anchor priming. Default is on.
|
||||
.TP
|
||||
.B root\-key\-sentinel: \fI<yes or no>
|
||||
Root key trust anchor sentinel. Default is on.
|
||||
.TP
|
||||
.B dlv\-anchor\-file: \fI<filename>
|
||||
This option was used during early days DNSSEC deployment when no parent-side
|
||||
DS record registrations were easily available. Nowadays, it is best to have
|
||||
@ -1304,13 +1312,30 @@ to complete. Default is 10, allowing 1/10 traffic to flow normally.
|
||||
This can make ordinary queries complete (if repeatedly queried for),
|
||||
and enter the cache, whilst also mitigating the traffic flow by the
|
||||
factor given.
|
||||
.TP 5
|
||||
.B low\-rtt: \fI<msec time>
|
||||
Set the time in millisecond that is considere a low ping time for fast
|
||||
server selection with the low\-rtt\-pct option, that turns this on or off.
|
||||
The default is 45 msec, a number from IPv6 quick response documents.
|
||||
.TP 5
|
||||
.B low\-rtt\-pct: \fI<number>
|
||||
Specify how many times out of 1000 to pick the fast server from the low
|
||||
rtt band. 0 turns the feature off. A value of 900 would pick the fast
|
||||
server when such fast servers are available 90 percent of the time, and
|
||||
the remaining time perform normal exploration of random servers.
|
||||
When prefetch is enabled (or serve\-expired), such prefetches are not
|
||||
sped up, because there is no one waiting for it, and it presents a good
|
||||
moment to perform server exploration. The low\-rtt option can be used
|
||||
to specify which servers are picked for fast server selection, servers
|
||||
with a ping roundtrip time below that value are considered.
|
||||
The default for low\-rtt\-pct is 0.
|
||||
.SS "Remote Control Options"
|
||||
In the
|
||||
.B remote\-control:
|
||||
clause are the declarations for the remote control facility. If this is
|
||||
enabled, the \fIunbound\-control\fR(8) utility can be used to send
|
||||
commands to the running unbound server. The server uses these clauses
|
||||
to setup SSLv3 / TLSv1 security for the connection. The
|
||||
to setup TLSv1 security for the connection. The
|
||||
\fIunbound\-control\fR(8) utility also reads the \fBremote\-control\fR
|
||||
section for options. To setup the correct self\-signed certificates use the
|
||||
\fIunbound\-control\-setup\fR(8) utility.
|
||||
@ -1416,7 +1441,7 @@ the servers are unreachable, instead it is tried without this clause.
|
||||
The default is no.
|
||||
.TP
|
||||
.B stub\-tls\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the queries to this stub use SSL for transport.
|
||||
Enabled or disable whether the queries to this stub use TLS for transport.
|
||||
Default is no.
|
||||
.TP
|
||||
.B stub\-ssl\-upstream: \fI<yes or no>
|
||||
@ -1448,6 +1473,13 @@ Name of server to forward to. Is itself resolved before it is used.
|
||||
.B forward\-addr: \fI<IP address>
|
||||
IP address of server to forward to. Can be IP 4 or IP 6.
|
||||
To use a nondefault port for DNS communication append '@' with the port number.
|
||||
If tls is enabled, then you can append a '#' and a name, then it'll check
|
||||
the tls authentication certificates with that name. If you combine
|
||||
the '@' and '#', the '@' comes first.
|
||||
.IP
|
||||
At high verbosity it logs the TLS certificate, with TLS enabled.
|
||||
If you leave out the '#' and auth name from the forward\-addr, any
|
||||
name is accepted. The cert must also match a CA from the tls\-cert\-bundle.
|
||||
.TP
|
||||
.B forward\-first: \fI<yes or no>
|
||||
If enabled, a query is attempted without the forward clause if it fails.
|
||||
@ -1456,7 +1488,7 @@ the servers are unreachable, instead it is tried without this clause.
|
||||
The default is no.
|
||||
.TP
|
||||
.B forward\-tls\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the queries to this forwarder use SSL for transport.
|
||||
Enabled or disable whether the queries to this forwarder use TLS for transport.
|
||||
Default is no.
|
||||
.TP
|
||||
.B forward\-ssl\-upstream: \fI<yes or no>
|
||||
@ -1496,6 +1528,14 @@ If none of the urls work, the masters are tried with IXFR and AXFR.
|
||||
For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
|
||||
to authenticate the connection.
|
||||
.TP
|
||||
.B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
|
||||
With allow\-notify you can specify additional sources of notifies.
|
||||
When notified, the server attempts to first probe and then zone transfer.
|
||||
If the notify is from a master, it first attempts that master. Otherwise
|
||||
other masters are attempted. If there are no masters, but only urls, the
|
||||
file is downloaded when notified. The masters from master: statements are
|
||||
allowed notify by default.
|
||||
.TP
|
||||
.B fallback\-enabled: \fI<yes or no>
|
||||
Default no. If enabled, unbound falls back to querying the internet as
|
||||
a resolver for this zone when lookups fail. For example for DNSSEC
|
||||
@ -1781,15 +1821,42 @@ If it finds a valid answer in the backend, Unbound uses it to respond
|
||||
to the query without performing iterative DNS resolution.
|
||||
If Unbound cannot even find an answer in the backend, it resolves the
|
||||
query as usual, and stores the answer in the backend.
|
||||
.P
|
||||
If Unbound was built with
|
||||
\fB\-\-with\-libhiredis\fR
|
||||
on a system that has installed the hiredis C client library of Redis,
|
||||
then the "redis" backend can be used.
|
||||
This backend communicates with the specified Redis server over a TCP
|
||||
connection to store and retrive cache data.
|
||||
It can be used as a persistent and/or shared cache backend.
|
||||
It should be noted that Unbound never removes data stored in the Redis server,
|
||||
even if some data have expired in terms of DNS TTL or the Redis server has
|
||||
cached too much data;
|
||||
if necessary the Redis server must be configured to limit the cache size,
|
||||
preferably with some kind of least-recently-used eviction policy.
|
||||
This backend uses synchronous communication with the Redis server
|
||||
based on the assumption that the communication is stable and sufficiently
|
||||
fast.
|
||||
The thread waiting for a response from the Redis server cannot handle
|
||||
other DNS queries.
|
||||
Although the backend has the ability to reconnect to the server when
|
||||
the connection is closed unexpectedly and there is a configurable timeout
|
||||
in case the server is overly slow or hangs up, these cases are assumed
|
||||
to be very rare.
|
||||
If connection close or timeout happens too often, Unbound will be
|
||||
effectively unusable with this backend.
|
||||
It's the administrator's responsibility to make the assumption hold.
|
||||
.P
|
||||
The
|
||||
.B cachedb:
|
||||
clause gives custom settings of the cache DB module.
|
||||
.TP
|
||||
.B backend: \fI<backend name>\fR
|
||||
Specify the backend database name.
|
||||
Currently, only the in-memory "testframe" backend is supported.
|
||||
As the name suggests this backend is not of any practical use.
|
||||
This option defaults to "testframe".
|
||||
The default database is the in-memory backend named "testframe", which,
|
||||
as the name suggests, is not of any practical use.
|
||||
Depending on the build-time configuration, "redis" backend may also be
|
||||
used as described above.
|
||||
.TP
|
||||
.B secret-seed: \fI<"secret string">\fR
|
||||
Specify a seed to calculate a hash value from query information.
|
||||
@ -1799,6 +1866,28 @@ operationally.
|
||||
If the backend database is shared by multiple Unbound instances,
|
||||
all instances must use the same secret seed.
|
||||
This option defaults to "default".
|
||||
.P
|
||||
The following
|
||||
.B cachedb
|
||||
otions are specific to the redis backend.
|
||||
.TP
|
||||
.B redis-server-host: \fI<server address or name>\fR
|
||||
The IP (either v6 or v4) address or domain name of the Redis server.
|
||||
In general an IP address should be specified as otherwise Unbound will have to
|
||||
resolve the name of the server every time it establishes a connection
|
||||
to the server.
|
||||
This option defaults to "127.0.0.1".
|
||||
.TP
|
||||
.B redis-server-port: \fI<port number>\fR
|
||||
The TCP port number of the Redis server.
|
||||
This option defaults to 6379.
|
||||
.TP
|
||||
.B redis-timeout: \fI<msec>\fR
|
||||
The period until when Unbound waits for a response from the Redis sever.
|
||||
If this timeout expires Unbound closes the connection, treats it as
|
||||
if the Redis server does not have the requested data, and will try to
|
||||
re-establish a new connection later.
|
||||
This option defaults to 100 milliseconds.
|
||||
.SH "MEMORY CONTROL EXAMPLE"
|
||||
In the example config settings below memory usage is reduced. Some service
|
||||
levels are lower, notable very large data and a high TCP load are no longer
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound.conf" "5" "Mar 15, 2018" "NLnet Labs" "unbound 1.7.0"
|
||||
.TH "unbound.conf" "5" "May 3, 2018" "NLnet Labs" "unbound 1.7.1"
|
||||
.\"
|
||||
.\" unbound.conf.5 -- unbound.conf manual
|
||||
.\"
|
||||
@ -288,7 +288,7 @@ silently (unless verbosity 3) without the option.
|
||||
.B ip\-transparent: \fI<yes or no>
|
||||
If yes, then use IP_TRANSPARENT socket option on sockets where unbound
|
||||
is listening for incoming traffic. Default no. Allows you to bind to
|
||||
non\-local interfaces. For example for non\-existant IP addresses that
|
||||
non\-local interfaces. For example for non\-existent IP addresses that
|
||||
are going to exist later on, with host failover configuration. This is
|
||||
a lot like interface\-automatic, but that one services all interfaces
|
||||
and with this option you can select which (future) interfaces unbound
|
||||
@ -399,8 +399,8 @@ change anything. Useful for TLS service providers, that want no udp downstream
|
||||
but use udp to fetch data upstream.
|
||||
.TP
|
||||
.B tls\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the upstream queries use SSL only for transport.
|
||||
Default is no. Useful in tunneling scenarios. The SSL contains plain DNS in
|
||||
Enabled or disable whether the upstream queries use TLS only for transport.
|
||||
Default is no. Useful in tunneling scenarios. The TLS contains plain DNS in
|
||||
TCP wireformat. The other server must support this (see
|
||||
\fBtls\-service\-key\fR).
|
||||
.TP
|
||||
@ -409,7 +409,7 @@ Alternate syntax for \fBtls\-upstream\fR. If both are present in the config
|
||||
file the last is used.
|
||||
.TP
|
||||
.B tls\-service\-key: \fI<file>
|
||||
If enabled, the server provider SSL service on its TCP sockets. The clients
|
||||
If enabled, the server provider TLS service on its TCP sockets. The clients
|
||||
have to use tls\-upstream: yes. The file is the private key for the TLS
|
||||
session. The public certificate is in the tls\-service\-pem file. Default
|
||||
is "", turned off. Requires a restart (a reload is not enough) if changed,
|
||||
@ -429,8 +429,8 @@ turned off.
|
||||
Alternate syntax for \fBtls\-service\-pem\fR.
|
||||
.TP
|
||||
.B tls\-port: \fI<number>
|
||||
The port number on which to provide TCP SSL service, default 853, only
|
||||
interfaces configured with that port number as @number get the SSL service.
|
||||
The port number on which to provide TCP TLS service, default 853, only
|
||||
interfaces configured with that port number as @number get the TLS service.
|
||||
.TP
|
||||
.B ssl\-port: \fI<number>
|
||||
Alternate syntax for \fBtls\-port\fR.
|
||||
@ -444,6 +444,11 @@ urls, and also DNS over TLS connections.
|
||||
.B ssl\-cert\-bundle: \fI<file>
|
||||
Alternate syntax for \fBtls\-cert\-bundle\fR.
|
||||
.TP
|
||||
.B additional\-tls\-port: \fI<portnr>
|
||||
List portnumbers as additional\-tls\-port, and when interfaces are defined,
|
||||
eg. with the @port suffix, as this port number, they provide dns over TLS
|
||||
service. Can list multiple, each on a new statement.
|
||||
.TP
|
||||
.B use\-systemd: \fI<yes or no>
|
||||
Enable or disable systemd socket activation.
|
||||
Default is no.
|
||||
@ -728,8 +733,8 @@ This option only has effect when qname-minimisation is enabled. Default is off.
|
||||
.B aggressive\-nsec: \fI<yes or no>
|
||||
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
|
||||
and other denials, using information from previous NXDOMAINs answers.
|
||||
Default is off. It helps to reduce the query rate towards targets that get
|
||||
a very high nonexistant name lookup rate.
|
||||
Default is no. It helps to reduce the query rate towards targets that get
|
||||
a very high nonexistent name lookup rate.
|
||||
.TP
|
||||
.B private\-address: \fI<IP address or subnet>
|
||||
Give IPv4 of IPv6 addresses or classless subnets. These are addresses
|
||||
@ -844,6 +849,9 @@ expanded on start and on reload.
|
||||
.B trust\-anchor\-signaling: \fI<yes or no>
|
||||
Send RFC8145 key tag query after trust anchor priming. Default is on.
|
||||
.TP
|
||||
.B root\-key\-sentinel: \fI<yes or no>
|
||||
Root key trust anchor sentinel. Default is on.
|
||||
.TP
|
||||
.B dlv\-anchor\-file: \fI<filename>
|
||||
This option was used during early days DNSSEC deployment when no parent-side
|
||||
DS record registrations were easily available. Nowadays, it is best to have
|
||||
@ -1304,13 +1312,30 @@ to complete. Default is 10, allowing 1/10 traffic to flow normally.
|
||||
This can make ordinary queries complete (if repeatedly queried for),
|
||||
and enter the cache, whilst also mitigating the traffic flow by the
|
||||
factor given.
|
||||
.TP 5
|
||||
.B low\-rtt: \fI<msec time>
|
||||
Set the time in millisecond that is considere a low ping time for fast
|
||||
server selection with the low\-rtt\-pct option, that turns this on or off.
|
||||
The default is 45 msec, a number from IPv6 quick response documents.
|
||||
.TP 5
|
||||
.B low\-rtt\-pct: \fI<number>
|
||||
Specify how many times out of 1000 to pick the fast server from the low
|
||||
rtt band. 0 turns the feature off. A value of 900 would pick the fast
|
||||
server when such fast servers are available 90 percent of the time, and
|
||||
the remaining time perform normal exploration of random servers.
|
||||
When prefetch is enabled (or serve\-expired), such prefetches are not
|
||||
sped up, because there is no one waiting for it, and it presents a good
|
||||
moment to perform server exploration. The low\-rtt option can be used
|
||||
to specify which servers are picked for fast server selection, servers
|
||||
with a ping roundtrip time below that value are considered.
|
||||
The default for low\-rtt\-pct is 0.
|
||||
.SS "Remote Control Options"
|
||||
In the
|
||||
.B remote\-control:
|
||||
clause are the declarations for the remote control facility. If this is
|
||||
enabled, the \fIunbound\-control\fR(8) utility can be used to send
|
||||
commands to the running unbound server. The server uses these clauses
|
||||
to setup SSLv3 / TLSv1 security for the connection. The
|
||||
to setup TLSv1 security for the connection. The
|
||||
\fIunbound\-control\fR(8) utility also reads the \fBremote\-control\fR
|
||||
section for options. To setup the correct self\-signed certificates use the
|
||||
\fIunbound\-control\-setup\fR(8) utility.
|
||||
@ -1416,7 +1441,7 @@ the servers are unreachable, instead it is tried without this clause.
|
||||
The default is no.
|
||||
.TP
|
||||
.B stub\-tls\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the queries to this stub use SSL for transport.
|
||||
Enabled or disable whether the queries to this stub use TLS for transport.
|
||||
Default is no.
|
||||
.TP
|
||||
.B stub\-ssl\-upstream: \fI<yes or no>
|
||||
@ -1448,6 +1473,13 @@ Name of server to forward to. Is itself resolved before it is used.
|
||||
.B forward\-addr: \fI<IP address>
|
||||
IP address of server to forward to. Can be IP 4 or IP 6.
|
||||
To use a nondefault port for DNS communication append '@' with the port number.
|
||||
If tls is enabled, then you can append a '#' and a name, then it'll check
|
||||
the tls authentication certificates with that name. If you combine
|
||||
the '@' and '#', the '@' comes first.
|
||||
.IP
|
||||
At high verbosity it logs the TLS certificate, with TLS enabled.
|
||||
If you leave out the '#' and auth name from the forward\-addr, any
|
||||
name is accepted. The cert must also match a CA from the tls\-cert\-bundle.
|
||||
.TP
|
||||
.B forward\-first: \fI<yes or no>
|
||||
If enabled, a query is attempted without the forward clause if it fails.
|
||||
@ -1456,7 +1488,7 @@ the servers are unreachable, instead it is tried without this clause.
|
||||
The default is no.
|
||||
.TP
|
||||
.B forward\-tls\-upstream: \fI<yes or no>
|
||||
Enabled or disable whether the queries to this forwarder use SSL for transport.
|
||||
Enabled or disable whether the queries to this forwarder use TLS for transport.
|
||||
Default is no.
|
||||
.TP
|
||||
.B forward\-ssl\-upstream: \fI<yes or no>
|
||||
@ -1496,6 +1528,14 @@ If none of the urls work, the masters are tried with IXFR and AXFR.
|
||||
For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
|
||||
to authenticate the connection.
|
||||
.TP
|
||||
.B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
|
||||
With allow\-notify you can specify additional sources of notifies.
|
||||
When notified, the server attempts to first probe and then zone transfer.
|
||||
If the notify is from a master, it first attempts that master. Otherwise
|
||||
other masters are attempted. If there are no masters, but only urls, the
|
||||
file is downloaded when notified. The masters from master: statements are
|
||||
allowed notify by default.
|
||||
.TP
|
||||
.B fallback\-enabled: \fI<yes or no>
|
||||
Default no. If enabled, unbound falls back to querying the internet as
|
||||
a resolver for this zone when lookups fail. For example for DNSSEC
|
||||
@ -1781,15 +1821,42 @@ If it finds a valid answer in the backend, Unbound uses it to respond
|
||||
to the query without performing iterative DNS resolution.
|
||||
If Unbound cannot even find an answer in the backend, it resolves the
|
||||
query as usual, and stores the answer in the backend.
|
||||
.P
|
||||
If Unbound was built with
|
||||
\fB\-\-with\-libhiredis\fR
|
||||
on a system that has installed the hiredis C client library of Redis,
|
||||
then the "redis" backend can be used.
|
||||
This backend communicates with the specified Redis server over a TCP
|
||||
connection to store and retrive cache data.
|
||||
It can be used as a persistent and/or shared cache backend.
|
||||
It should be noted that Unbound never removes data stored in the Redis server,
|
||||
even if some data have expired in terms of DNS TTL or the Redis server has
|
||||
cached too much data;
|
||||
if necessary the Redis server must be configured to limit the cache size,
|
||||
preferably with some kind of least-recently-used eviction policy.
|
||||
This backend uses synchronous communication with the Redis server
|
||||
based on the assumption that the communication is stable and sufficiently
|
||||
fast.
|
||||
The thread waiting for a response from the Redis server cannot handle
|
||||
other DNS queries.
|
||||
Although the backend has the ability to reconnect to the server when
|
||||
the connection is closed unexpectedly and there is a configurable timeout
|
||||
in case the server is overly slow or hangs up, these cases are assumed
|
||||
to be very rare.
|
||||
If connection close or timeout happens too often, Unbound will be
|
||||
effectively unusable with this backend.
|
||||
It's the administrator's responsibility to make the assumption hold.
|
||||
.P
|
||||
The
|
||||
.B cachedb:
|
||||
clause gives custom settings of the cache DB module.
|
||||
.TP
|
||||
.B backend: \fI<backend name>\fR
|
||||
Specify the backend database name.
|
||||
Currently, only the in-memory "testframe" backend is supported.
|
||||
As the name suggests this backend is not of any practical use.
|
||||
This option defaults to "testframe".
|
||||
The default database is the in-memory backend named "testframe", which,
|
||||
as the name suggests, is not of any practical use.
|
||||
Depending on the build-time configuration, "redis" backend may also be
|
||||
used as described above.
|
||||
.TP
|
||||
.B secret-seed: \fI<"secret string">\fR
|
||||
Specify a seed to calculate a hash value from query information.
|
||||
@ -1799,6 +1866,28 @@ operationally.
|
||||
If the backend database is shared by multiple Unbound instances,
|
||||
all instances must use the same secret seed.
|
||||
This option defaults to "default".
|
||||
.P
|
||||
The following
|
||||
.B cachedb
|
||||
otions are specific to the redis backend.
|
||||
.TP
|
||||
.B redis-server-host: \fI<server address or name>\fR
|
||||
The IP (either v6 or v4) address or domain name of the Redis server.
|
||||
In general an IP address should be specified as otherwise Unbound will have to
|
||||
resolve the name of the server every time it establishes a connection
|
||||
to the server.
|
||||
This option defaults to "127.0.0.1".
|
||||
.TP
|
||||
.B redis-server-port: \fI<port number>\fR
|
||||
The TCP port number of the Redis server.
|
||||
This option defaults to 6379.
|
||||
.TP
|
||||
.B redis-timeout: \fI<msec>\fR
|
||||
The period until when Unbound waits for a response from the Redis sever.
|
||||
If this timeout expires Unbound closes the connection, treats it as
|
||||
if the Redis server does not have the requested data, and will try to
|
||||
re-establish a new connection later.
|
||||
This option defaults to 100 milliseconds.
|
||||
.SH "MEMORY CONTROL EXAMPLE"
|
||||
In the example config settings below memory usage is reduced. Some service
|
||||
levels are lower, notable very large data and a high TCP load are no longer
|
||||
|
@ -84,7 +84,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
|
||||
}
|
||||
for(a = dp->target_list; a; a = a->next_target) {
|
||||
if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen,
|
||||
a->bogus, a->lame))
|
||||
a->bogus, a->lame, a->tls_auth_name))
|
||||
return NULL;
|
||||
}
|
||||
return copy;
|
||||
@ -176,13 +176,13 @@ delegpt_add_target(struct delegpt* dp, struct regional* region,
|
||||
if(ns->got4 && ns->got6)
|
||||
ns->resolved = 1;
|
||||
}
|
||||
return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame);
|
||||
return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
delegpt_add_addr(struct delegpt* dp, struct regional* region,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus,
|
||||
uint8_t lame)
|
||||
uint8_t lame, char* tls_auth_name)
|
||||
{
|
||||
struct delegpt_addr* a;
|
||||
log_assert(!dp->dp_type_mlc);
|
||||
@ -210,6 +210,13 @@ delegpt_add_addr(struct delegpt* dp, struct regional* region,
|
||||
a->bogus = bogus;
|
||||
a->lame = lame;
|
||||
a->dnsseclame = 0;
|
||||
if(tls_auth_name) {
|
||||
a->tls_auth_name = regional_strdup(region, tls_auth_name);
|
||||
if(!a->tls_auth_name)
|
||||
return 0;
|
||||
} else {
|
||||
a->tls_auth_name = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -276,11 +283,16 @@ void delegpt_log(enum verbosity_value v, struct delegpt* dp)
|
||||
(ns->done_pside6?" PSIDE_AAAA":""));
|
||||
}
|
||||
for(a = dp->target_list; a; a = a->next_target) {
|
||||
char s[128];
|
||||
const char* str = " ";
|
||||
if(a->bogus && a->lame) str = " BOGUS ADDR_LAME ";
|
||||
else if(a->bogus) str = " BOGUS ";
|
||||
else if(a->lame) str = " ADDR_LAME ";
|
||||
log_addr(VERB_ALGO, str, &a->addr, a->addrlen);
|
||||
if(a->tls_auth_name)
|
||||
snprintf(s, sizeof(s), "%s[%s]", str,
|
||||
a->tls_auth_name);
|
||||
else snprintf(s, sizeof(s), "%s", str);
|
||||
log_addr(VERB_ALGO, s, &a->addr, a->addrlen);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -539,6 +551,7 @@ void delegpt_free_mlc(struct delegpt* dp)
|
||||
a = dp->target_list;
|
||||
while(a) {
|
||||
na = a->next_target;
|
||||
free(a->tls_auth_name);
|
||||
free(a);
|
||||
a = na;
|
||||
}
|
||||
@ -585,7 +598,7 @@ int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame)
|
||||
}
|
||||
|
||||
int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame)
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name)
|
||||
{
|
||||
struct delegpt_addr* a;
|
||||
log_assert(dp->dp_type_mlc);
|
||||
@ -612,6 +625,15 @@ int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
|
||||
a->bogus = bogus;
|
||||
a->lame = lame;
|
||||
a->dnsseclame = 0;
|
||||
if(tls_auth_name) {
|
||||
a->tls_auth_name = strdup(tls_auth_name);
|
||||
if(!a->tls_auth_name) {
|
||||
free(a);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
a->tls_auth_name = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -632,7 +654,7 @@ int delegpt_add_target_mlc(struct delegpt* dp, uint8_t* name, size_t namelen,
|
||||
if(ns->got4 && ns->got6)
|
||||
ns->resolved = 1;
|
||||
}
|
||||
return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame);
|
||||
return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame, NULL);
|
||||
}
|
||||
|
||||
size_t delegpt_get_mem(struct delegpt* dp)
|
||||
|
@ -151,6 +151,8 @@ struct delegpt_addr {
|
||||
* option is useful to mark the address dnsseclame.
|
||||
* This value is not copied in addr-copy and dp-copy. */
|
||||
uint8_t dnsseclame;
|
||||
/** the TLS authentication name, (if not NULL) to use. */
|
||||
char* tls_auth_name;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -259,11 +261,12 @@ int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
|
||||
* @param addrlen: the length of addr.
|
||||
* @param bogus: if address is bogus.
|
||||
* @param lame: if address is lame.
|
||||
* @param tls_auth_name: TLS authentication name (or NULL).
|
||||
* @return false on error.
|
||||
*/
|
||||
int delegpt_add_addr(struct delegpt* dp, struct regional* regional,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t bogus, uint8_t lame);
|
||||
uint8_t bogus, uint8_t lame, char* tls_auth_name);
|
||||
|
||||
/**
|
||||
* Find NS record in name list of delegation point.
|
||||
@ -394,10 +397,11 @@ int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame);
|
||||
* @param addrlen: the length of addr.
|
||||
* @param bogus: if address is bogus.
|
||||
* @param lame: if address is lame.
|
||||
* @param tls_auth_name: TLS authentication name (or NULL).
|
||||
* @return false on error.
|
||||
*/
|
||||
int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame);
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name);
|
||||
|
||||
/**
|
||||
* Add target address to the delegation point.
|
||||
|
@ -231,14 +231,16 @@ read_fwds_addr(struct config_stub* s, struct delegpt* dp)
|
||||
struct config_strlist* p;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
char* tls_auth_name;
|
||||
for(p = s->addrs; p; p = p->next) {
|
||||
log_assert(p->str);
|
||||
if(!extstrtoaddr(p->str, &addr, &addrlen)) {
|
||||
if(!authextstrtoaddr(p->str, &addr, &addrlen, &tls_auth_name)) {
|
||||
log_err("cannot parse forward %s ip address: '%s'",
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) {
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
|
||||
tls_auth_name)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
@ -244,14 +244,16 @@ read_stubs_addr(struct config_stub* s, struct delegpt* dp)
|
||||
struct config_strlist* p;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
char* auth_name;
|
||||
for(p = s->addrs; p; p = p->next) {
|
||||
log_assert(p->str);
|
||||
if(!extstrtoaddr(p->str, &addr, &addrlen)) {
|
||||
if(!authextstrtoaddr(p->str, &addr, &addrlen, &auth_name)) {
|
||||
log_err("cannot parse stub %s ip address: '%s'",
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) {
|
||||
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
|
||||
auth_name)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
@ -312,9 +312,9 @@ static int
|
||||
iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, time_t now,
|
||||
struct delegpt* dp, int* selected_rtt, int open_target,
|
||||
struct sock_list* blacklist)
|
||||
struct sock_list* blacklist, time_t prefetch)
|
||||
{
|
||||
int got_num = 0, low_rtt = 0, swap_to_front;
|
||||
int got_num = 0, low_rtt = 0, swap_to_front, rtt_band = RTT_BAND;
|
||||
struct delegpt_addr* a, *n, *prev=NULL;
|
||||
|
||||
/* fillup sel_rtt and find best rtt in the bunch */
|
||||
@ -329,6 +329,16 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
return 0 to force the caller to fetch more */
|
||||
}
|
||||
|
||||
if(env->cfg->low_rtt_pct != 0 && prefetch == 0 &&
|
||||
low_rtt < env->cfg->low_rtt &&
|
||||
ub_random_max(env->rnd, 1000) < env->cfg->low_rtt_pct) {
|
||||
/* the query is not prefetch, but for a downstream client,
|
||||
* there is a low_rtt (fast) server. We choose that x% of the
|
||||
* time */
|
||||
/* pick rtt numbers from 0..LOWBAND_RTT */
|
||||
rtt_band = env->cfg->low_rtt - low_rtt;
|
||||
}
|
||||
|
||||
got_num = 0;
|
||||
a = dp->result_list;
|
||||
while(a) {
|
||||
@ -340,10 +350,10 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
|
||||
}
|
||||
/* classify the server address and determine what to do */
|
||||
swap_to_front = 0;
|
||||
if(a->sel_rtt >= low_rtt && a->sel_rtt - low_rtt <= RTT_BAND) {
|
||||
if(a->sel_rtt >= low_rtt && a->sel_rtt - low_rtt <= rtt_band) {
|
||||
got_num++;
|
||||
swap_to_front = 1;
|
||||
} else if(a->sel_rtt<low_rtt && low_rtt-a->sel_rtt<=RTT_BAND) {
|
||||
} else if(a->sel_rtt<low_rtt && low_rtt-a->sel_rtt<=rtt_band) {
|
||||
got_num++;
|
||||
swap_to_front = 1;
|
||||
}
|
||||
@ -400,13 +410,14 @@ struct delegpt_addr*
|
||||
iter_server_selection(struct iter_env* iter_env,
|
||||
struct module_env* env, struct delegpt* dp,
|
||||
uint8_t* name, size_t namelen, uint16_t qtype, int* dnssec_lame,
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist)
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist,
|
||||
time_t prefetch)
|
||||
{
|
||||
int sel;
|
||||
int selrtt;
|
||||
struct delegpt_addr* a, *prev;
|
||||
int num = iter_filter_order(iter_env, env, name, namelen, qtype,
|
||||
*env->now, dp, &selrtt, open_target, blacklist);
|
||||
*env->now, dp, &selrtt, open_target, blacklist, prefetch);
|
||||
|
||||
if(num == 0)
|
||||
return NULL;
|
||||
@ -625,7 +636,7 @@ iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
||||
}
|
||||
|
||||
int
|
||||
iter_indicates_dnssec_fwd(struct module_env* env, struct query_info *qinfo)
|
||||
iter_qname_indicates_dnssec(struct module_env* env, struct query_info *qinfo)
|
||||
{
|
||||
struct trust_anchor* a;
|
||||
if(!env || !env->anchors || !qinfo || !qinfo->qname)
|
||||
|
@ -87,13 +87,18 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
|
||||
* @param open_target: number of currently outstanding target queries.
|
||||
* If we wait for these, perhaps more server addresses become available.
|
||||
* @param blacklist: the IP blacklist to use.
|
||||
* @param prefetch: if not 0, prefetch is in use for this query.
|
||||
* This means the query can have different timing, because prefetch is
|
||||
* not waited upon by the downstream client, and thus a good time to
|
||||
* perform exploration of other targets.
|
||||
* @return best target or NULL if no target.
|
||||
* if not null, that target is removed from the result list in the dp.
|
||||
*/
|
||||
struct delegpt_addr* iter_server_selection(struct iter_env* iter_env,
|
||||
struct module_env* env, struct delegpt* dp, uint8_t* name,
|
||||
size_t namelen, uint16_t qtype, int* dnssec_lame,
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist);
|
||||
int* chase_to_rd, int open_target, struct sock_list* blacklist,
|
||||
time_t prefetch);
|
||||
|
||||
/**
|
||||
* Allocate dns_msg from parsed msg, in regional.
|
||||
@ -174,15 +179,14 @@ int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
||||
struct delegpt* dp);
|
||||
|
||||
/**
|
||||
* See if qname has DNSSEC needs in the forwarding case. This is true if
|
||||
* there is a trust anchor above it. Whether there is an insecure delegation
|
||||
* to the data is unknown, but CD-retry is needed.
|
||||
* See if qname has DNSSEC needs. This is true if there is a trust anchor above
|
||||
* it. Whether there is an insecure delegation to the data is unknown.
|
||||
* @param env: environment with anchors.
|
||||
* @param qinfo: query name and class.
|
||||
* @return true if trust anchor above qname, false if no anchor or insecure
|
||||
* point above qname.
|
||||
*/
|
||||
int iter_indicates_dnssec_fwd(struct module_env* env,
|
||||
int iter_qname_indicates_dnssec(struct module_env* env,
|
||||
struct query_info *qinfo);
|
||||
|
||||
/**
|
||||
|
@ -1206,7 +1206,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->qchase.qname_len, iq->qchase.qtype,
|
||||
iq->qchase.qclass, qstate->query_flags,
|
||||
qstate->region, qstate->env->scratch, 0);
|
||||
if(!msg && qstate->env->neg_cache) {
|
||||
if(!msg && qstate->env->neg_cache &&
|
||||
iter_qname_indicates_dnssec(qstate->env, &iq->qchase)) {
|
||||
/* lookup in negative cache; may result in
|
||||
* NOERROR/NODATA or NXDOMAIN answers that need validation */
|
||||
msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase,
|
||||
@ -1298,7 +1299,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
delnamelen = iq->qchase.qname_len;
|
||||
}
|
||||
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue ||
|
||||
(iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway)) {
|
||||
(iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway
|
||||
&& can_have_last_resort(qstate->env, delname, delnamelen, iq->qchase.qclass))) {
|
||||
/* remove first label from delname, root goes to hints,
|
||||
* but only to fetch glue, not for qtype=DS. */
|
||||
/* also when prefetching an NS record, fetch it again from
|
||||
@ -1414,6 +1416,12 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
*/
|
||||
if(iter_dp_is_useless(&qstate->qinfo, qstate->query_flags,
|
||||
iq->dp)) {
|
||||
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass)) {
|
||||
verbose(VERB_ALGO, "useless dp "
|
||||
"but cannot go up, servfail");
|
||||
return error_response(qstate, id,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(dname_is_root(iq->dp->name)) {
|
||||
/* use safety belt */
|
||||
verbose(VERB_QUERY, "Cache has root NS but "
|
||||
@ -1791,7 +1799,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
for(a = p->target_list; a; a=a->next_target) {
|
||||
(void)delegpt_add_addr(iq->dp, qstate->region,
|
||||
&a->addr, a->addrlen, a->bogus,
|
||||
a->lame);
|
||||
a->lame, a->tls_auth_name);
|
||||
}
|
||||
}
|
||||
iq->dp->has_parent_side_NS = 1;
|
||||
@ -2160,11 +2168,18 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
log_dns_msg("msg from auth zone",
|
||||
&iq->response->qinfo, iq->response->rep);
|
||||
}
|
||||
iq->num_current_queries++;
|
||||
iq->chase_to_rd = 0;
|
||||
iq->dnssec_lame_query = 0;
|
||||
iq->auth_zone_response = 1;
|
||||
return next_state(iq, QUERY_RESP_STATE);
|
||||
if((iq->chase_flags&BIT_RD) && !(iq->response->rep->flags&BIT_AA)) {
|
||||
verbose(VERB_ALGO, "forwarder, ignoring referral from auth zone");
|
||||
} else {
|
||||
lock_rw_wrlock(&qstate->env->auth_zones->lock);
|
||||
qstate->env->auth_zones->num_query_up++;
|
||||
lock_rw_unlock(&qstate->env->auth_zones->lock);
|
||||
iq->num_current_queries++;
|
||||
iq->chase_to_rd = 0;
|
||||
iq->dnssec_lame_query = 0;
|
||||
iq->auth_zone_response = 1;
|
||||
return next_state(iq, QUERY_RESP_STATE);
|
||||
}
|
||||
}
|
||||
iq->auth_zone_response = 0;
|
||||
if(auth_fallback == 0) {
|
||||
@ -2253,7 +2268,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
target = iter_server_selection(ie, qstate->env, iq->dp,
|
||||
iq->dp->name, iq->dp->namelen, iq->qchase.qtype,
|
||||
&iq->dnssec_lame_query, &iq->chase_to_rd,
|
||||
iq->num_target_queries, qstate->blacklist);
|
||||
iq->num_target_queries, qstate->blacklist,
|
||||
qstate->prefetch_leeway);
|
||||
|
||||
/* If no usable target was selected... */
|
||||
if(!target) {
|
||||
@ -2366,12 +2382,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* (blacklist nonempty) and no trust-anchors are configured
|
||||
* above the qname or on the first attempt when dnssec is on */
|
||||
EDNS_DO| ((iq->chase_to_rd||(iq->chase_flags&BIT_RD)!=0)&&
|
||||
!qstate->blacklist&&(!iter_indicates_dnssec_fwd(qstate->env,
|
||||
!qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env,
|
||||
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
|
||||
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
|
||||
ie, iq), &target->addr, target->addrlen,
|
||||
iq->dp->name, iq->dp->namelen,
|
||||
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream), qstate);
|
||||
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
|
||||
target->tls_auth_name, qstate);
|
||||
if(!outq) {
|
||||
log_addr(VERB_DETAIL, "error sending query to auth server",
|
||||
&target->addr, target->addrlen);
|
||||
@ -2440,9 +2457,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
type = response_type_from_server(
|
||||
(int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd),
|
||||
iq->response, &iq->qchase, iq->dp);
|
||||
iq->response, &iq->qinfo_out, iq->dp);
|
||||
iq->chase_to_rd = 0;
|
||||
if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD)) {
|
||||
if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD) &&
|
||||
!iq->auth_zone_response) {
|
||||
/* When forwarding (RD bit is set), we handle referrals
|
||||
* differently. No queries should be sent elsewhere */
|
||||
type = RESPONSE_TYPE_ANSWER;
|
||||
|
@ -365,6 +365,7 @@ libworker_dobg(void* arg)
|
||||
|
||||
/* cleanup */
|
||||
m = UB_LIBCMD_QUIT;
|
||||
w->want_quit = 1;
|
||||
tube_remove_bg_listen(w->ctx->qq_pipe);
|
||||
tube_remove_bg_write(w->ctx->rr_pipe);
|
||||
libworker_delete(w);
|
||||
@ -512,7 +513,8 @@ libworker_enter_result(struct ub_result* res, sldns_buffer* buf,
|
||||
res->nxdomain = 1;
|
||||
if(msg_security == sec_status_secure)
|
||||
res->secure = 1;
|
||||
if(msg_security == sec_status_bogus)
|
||||
if(msg_security == sec_status_bogus ||
|
||||
msg_security == sec_status_secure_sentinel_fail)
|
||||
res->bogus = 1;
|
||||
}
|
||||
|
||||
@ -713,6 +715,10 @@ add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt,
|
||||
uint8_t* msg = NULL;
|
||||
uint32_t len = 0;
|
||||
|
||||
if(w->want_quit) {
|
||||
context_query_delete(q);
|
||||
return;
|
||||
}
|
||||
/* serialize and delete unneeded q */
|
||||
if(w->is_bg_thread) {
|
||||
lock_basic_lock(&w->ctx->cfglock);
|
||||
@ -841,7 +847,8 @@ void libworker_alloc_cleanup(void* arg)
|
||||
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int ssl_upstream, struct module_qstate* q)
|
||||
size_t zonelen, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q)
|
||||
{
|
||||
struct libworker* w = (struct libworker*)q->env->worker;
|
||||
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
|
||||
@ -851,8 +858,8 @@ struct outbound_entry* libworker_send_query(struct query_info* qinfo,
|
||||
e->qstate = q;
|
||||
e->qsent = outnet_serviced_query(w->back, qinfo, flags, dnssec,
|
||||
want_dnssec, nocaps, q->env->cfg->tcp_upstream, ssl_upstream,
|
||||
addr, addrlen, zone, zonelen, q, libworker_handle_service_reply,
|
||||
e, w->back->udp_buff, q->env);
|
||||
tls_auth_name, addr, addrlen, zone, zonelen, q,
|
||||
libworker_handle_service_reply, e, w->back->udp_buff, q->env);
|
||||
if(!e->qsent) {
|
||||
return NULL;
|
||||
}
|
||||
@ -972,7 +979,8 @@ struct outbound_entry* worker_send_query(struct query_info* ATTR_UNUSED(qinfo),
|
||||
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
|
||||
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen),
|
||||
int ATTR_UNUSED(ssl_upstream), struct module_qstate* ATTR_UNUSED(q))
|
||||
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
|
||||
struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
|
@ -75,6 +75,8 @@ struct libworker {
|
||||
int is_bg;
|
||||
/** is this a bg worker that is threaded (not forked)? */
|
||||
int is_bg_thread;
|
||||
/** want to quit, stop handling new content */
|
||||
int want_quit;
|
||||
|
||||
/** copy of the module environment with worker local entries. */
|
||||
struct module_env* env;
|
||||
|
@ -747,6 +747,16 @@ struct ub_server_stats {
|
||||
long long num_query_dnscrypt_replay;
|
||||
/** number of dnscrypt nonces cache entries */
|
||||
long long nonce_cache_count;
|
||||
/** number of queries for unbound's auth_zones, upstream query */
|
||||
long long num_query_authzone_up;
|
||||
/** number of queries for unbound's auth_zones, downstream answers */
|
||||
long long num_query_authzone_down;
|
||||
/** number of times neg cache records were used to generate NOERROR
|
||||
* responses. */
|
||||
long long num_neg_cache_noerror;
|
||||
/** number of times neg cache records were used to generate NXDOMAIN
|
||||
* responses. */
|
||||
long long num_neg_cache_nxdomain;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -63,6 +63,8 @@ struct query_info;
|
||||
* @param zone: delegation point name.
|
||||
* @param zonelen: length of zone name wireformat dname.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param tls_auth_name: if ssl_upstream, use this name with TLS
|
||||
* authentication.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
@ -70,7 +72,8 @@ struct query_info;
|
||||
struct outbound_entry* libworker_send_query(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int ssl_upstream, struct module_qstate* q);
|
||||
size_t zonelen, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q);
|
||||
|
||||
/** process incoming replies from the network */
|
||||
int libworker_handle_reply(struct comm_point* c, void* arg, int error,
|
||||
@ -115,6 +118,8 @@ void worker_sighandler(int sig, void* arg);
|
||||
* @param zone: wireformat dname of the zone.
|
||||
* @param zonelen: length of zone name.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param tls_auth_name: if ssl_upstream, use this name with TLS
|
||||
* authentication.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
@ -122,7 +127,8 @@ void worker_sighandler(int sig, void* arg);
|
||||
struct outbound_entry* worker_send_query(struct query_info* qinfo,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int ssl_upstream, struct module_qstate* q);
|
||||
size_t zonelen, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q);
|
||||
|
||||
/**
|
||||
* process control messages from the main thread. Frees the control
|
||||
|
@ -86,13 +86,21 @@
|
||||
#define AUTH_HTTP_PORT 80
|
||||
/* auth https port number */
|
||||
#define AUTH_HTTPS_PORT 443
|
||||
/* max depth for nested $INCLUDEs */
|
||||
#define MAX_INCLUDE_DEPTH 10
|
||||
|
||||
/** pick up nextprobe task to start waiting to perform transfer actions */
|
||||
static void xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
|
||||
int failure);
|
||||
int failure, int lookup_only);
|
||||
/** move to sending the probe packets, next if fails. task_probe */
|
||||
static void xfr_probe_send_or_end(struct auth_xfer* xfr,
|
||||
struct module_env* env);
|
||||
/** pick up probe task with specified(or NULL) destination first,
|
||||
* or transfer task if nothing to probe, or false if already in progress */
|
||||
static int xfr_start_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
struct auth_master* spec);
|
||||
/** delete xfer structure (not its tree entry) */
|
||||
static void auth_xfer_delete(struct auth_xfer* xfr);
|
||||
|
||||
/** create new dns_msg */
|
||||
static struct dns_msg*
|
||||
@ -1437,11 +1445,13 @@ az_remove_rr_decompress(struct auth_zone* z, uint8_t* pkt, size_t pktlen,
|
||||
* @param state: parse state with $ORIGIN, $TTL and 'prev-dname' and so on,
|
||||
* that is kept between includes.
|
||||
* The lineno is set at 1 and then increased by the function.
|
||||
* @param fname: file name.
|
||||
* @param depth: recursion depth for includes
|
||||
* returns false on failure, has printed an error message
|
||||
*/
|
||||
static int
|
||||
az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
|
||||
struct sldns_file_parse_state* state)
|
||||
struct sldns_file_parse_state* state, char* fname, int depth)
|
||||
{
|
||||
size_t rr_len, dname_len;
|
||||
int status;
|
||||
@ -1459,6 +1469,11 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
|
||||
FILE* inc;
|
||||
int lineno_orig = state->lineno;
|
||||
char* incfile = (char*)rr + 8;
|
||||
if(depth > MAX_INCLUDE_DEPTH) {
|
||||
log_err("%s:%d max include depth"
|
||||
"exceeded", fname, state->lineno);
|
||||
return 0;
|
||||
}
|
||||
/* skip spaces */
|
||||
while(*incfile == ' ' || *incfile == '\t')
|
||||
incfile++;
|
||||
@ -1480,11 +1495,12 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
|
||||
}
|
||||
/* recurse read that file now */
|
||||
if(!az_parse_file(z, inc, rr, rrbuflen,
|
||||
state)) {
|
||||
state, incfile, depth+1)) {
|
||||
log_err("%s:%d cannot parse include "
|
||||
"file %s", z->zonefile,
|
||||
"file %s", fname,
|
||||
lineno_orig, incfile);
|
||||
fclose(inc);
|
||||
free(incfile);
|
||||
return 0;
|
||||
}
|
||||
fclose(inc);
|
||||
@ -1496,7 +1512,7 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
|
||||
continue;
|
||||
}
|
||||
if(status != 0) {
|
||||
log_err("parse error %s %d:%d: %s", z->zonefile,
|
||||
log_err("parse error %s %d:%d: %s", fname,
|
||||
state->lineno, LDNS_WIREPARSE_OFFSET(status),
|
||||
sldns_get_errorstr_parse(status));
|
||||
return 0;
|
||||
@ -1511,7 +1527,7 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
|
||||
sldns_wire2str_type_buf(sldns_wirerr_get_type(rr,
|
||||
rr_len, dname_len), buf, sizeof(buf));
|
||||
log_err("%s:%d cannot insert RR of type %s",
|
||||
z->zonefile, state->lineno, buf);
|
||||
fname, state->lineno, buf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1546,6 +1562,11 @@ auth_zone_read_zonefile(struct auth_zone* z)
|
||||
free(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* clear the data tree */
|
||||
traverse_postorder(&z->data, auth_data_del, NULL);
|
||||
rbtree_init(&z->data, &auth_data_cmp);
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
/* default TTL to 3600 */
|
||||
state.default_ttl = 3600;
|
||||
@ -1555,7 +1576,7 @@ auth_zone_read_zonefile(struct auth_zone* z)
|
||||
state.origin_len = z->namelen;
|
||||
}
|
||||
/* parse the (toplevel) file */
|
||||
if(!az_parse_file(z, in, rr, sizeof(rr), &state)) {
|
||||
if(!az_parse_file(z, in, rr, sizeof(rr), &state, z->zonefile, 0)) {
|
||||
char* n = sldns_wire2str_dname(z->name, z->namelen);
|
||||
log_err("error parsing zonefile %s for %s",
|
||||
z->zonefile, n?n:"error");
|
||||
@ -1569,9 +1590,9 @@ auth_zone_read_zonefile(struct auth_zone* z)
|
||||
|
||||
/** write buffer to file and check return codes */
|
||||
static int
|
||||
write_out(FILE* out, const char* str)
|
||||
write_out(FILE* out, const char* str, size_t len)
|
||||
{
|
||||
size_t r, len = strlen(str);
|
||||
size_t r;
|
||||
if(len == 0)
|
||||
return 1;
|
||||
r = fwrite(str, 1, len, out);
|
||||
@ -1634,7 +1655,7 @@ auth_zone_write_rrset(struct auth_zone* z, struct auth_data* node,
|
||||
verbose(VERB_ALGO, "failed to rr2str rr %d", (int)i);
|
||||
continue;
|
||||
}
|
||||
if(!write_out(out, buf))
|
||||
if(!write_out(out, buf, strlen(buf)))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -1703,6 +1724,24 @@ auth_zones_read_zones(struct auth_zones* az)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** find serial number of zone or false if none */
|
||||
int
|
||||
auth_zone_get_serial(struct auth_zone* z, uint32_t* serial)
|
||||
{
|
||||
struct auth_data* apex;
|
||||
struct auth_rrset* soa;
|
||||
struct packed_rrset_data* d;
|
||||
apex = az_find_name(z, z->name, z->namelen);
|
||||
if(!apex) return 0;
|
||||
soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA);
|
||||
if(!soa || soa->data->count==0)
|
||||
return 0; /* no RRset or no RRs in rrset */
|
||||
if(soa->data->rr_len[0] < 2+4*5) return 0; /* SOA too short */
|
||||
d = soa->data;
|
||||
*serial = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-20));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Find auth_zone SOA and populate the values in xfr(soa values). */
|
||||
static int
|
||||
xfr_find_soa(struct auth_zone* z, struct auth_xfer* xfr)
|
||||
@ -1808,6 +1847,7 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
|
||||
lock_rw_unlock(&az->lock);
|
||||
|
||||
/* set options */
|
||||
z->zone_deleted = 0;
|
||||
if(!auth_zone_set_zonefile(z, c->zonefile)) {
|
||||
if(x) {
|
||||
lock_basic_unlock(&x->lock);
|
||||
@ -1840,10 +1880,65 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** set all auth zones deleted, then in auth_zones_cfg, it marks them
|
||||
* as nondeleted (if they are still in the config), and then later
|
||||
* we can find deleted zones */
|
||||
static void
|
||||
az_setall_deleted(struct auth_zones* az)
|
||||
{
|
||||
struct auth_zone* z;
|
||||
lock_rw_wrlock(&az->lock);
|
||||
RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
|
||||
lock_rw_wrlock(&z->lock);
|
||||
z->zone_deleted = 1;
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
lock_rw_unlock(&az->lock);
|
||||
}
|
||||
|
||||
/** find zones that are marked deleted and delete them.
|
||||
* This is called from apply_cfg, and there are no threads and no
|
||||
* workers, so the xfr can just be deleted. */
|
||||
static void
|
||||
az_delete_deleted_zones(struct auth_zones* az)
|
||||
{
|
||||
struct auth_zone* z;
|
||||
struct auth_zone* delete_list = NULL, *next;
|
||||
struct auth_xfer* xfr;
|
||||
lock_rw_wrlock(&az->lock);
|
||||
RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
|
||||
lock_rw_wrlock(&z->lock);
|
||||
if(z->zone_deleted) {
|
||||
/* we cannot alter the rbtree right now, but
|
||||
* we can put it on a linked list and then
|
||||
* delete it */
|
||||
z->delete_next = delete_list;
|
||||
delete_list = z;
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
/* now we are out of the tree loop and we can loop and delete
|
||||
* the zones */
|
||||
z = delete_list;
|
||||
while(z) {
|
||||
next = z->delete_next;
|
||||
xfr = auth_xfer_find(az, z->name, z->namelen, z->dclass);
|
||||
if(xfr) {
|
||||
(void)rbtree_delete(&az->xtree, &xfr->node);
|
||||
auth_xfer_delete(xfr);
|
||||
}
|
||||
(void)rbtree_delete(&az->ztree, &z->node);
|
||||
auth_zone_delete(z);
|
||||
z = next;
|
||||
}
|
||||
lock_rw_unlock(&az->lock);
|
||||
}
|
||||
|
||||
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||
int setup)
|
||||
{
|
||||
struct config_auth* p;
|
||||
az_setall_deleted(az);
|
||||
for(p = cfg->auths; p; p = p->next) {
|
||||
if(!p->name || p->name[0] == 0) {
|
||||
log_warn("auth-zone without a name, skipped");
|
||||
@ -1854,6 +1949,7 @@ int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
az_delete_deleted_zones(az);
|
||||
if(!auth_zones_read_zones(az))
|
||||
return 0;
|
||||
if(setup) {
|
||||
@ -1937,6 +2033,7 @@ auth_xfer_delete(struct auth_xfer* xfr)
|
||||
}
|
||||
free(xfr->task_transfer);
|
||||
}
|
||||
auth_free_masters(xfr->allow_notify_list);
|
||||
free(xfr);
|
||||
}
|
||||
|
||||
@ -3153,10 +3250,13 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env,
|
||||
/* answer it from zone z */
|
||||
r = auth_zone_generate_answer(z, qinfo, temp, &msg, &fallback);
|
||||
lock_rw_unlock(&z->lock);
|
||||
if(fallback) {
|
||||
if(!r && fallback) {
|
||||
/* fallback to regular answering (recursive) */
|
||||
return 0;
|
||||
}
|
||||
lock_rw_wrlock(&az->lock);
|
||||
az->num_query_down++;
|
||||
lock_rw_unlock(&az->lock);
|
||||
|
||||
/* encode answer */
|
||||
if(!r)
|
||||
@ -3186,6 +3286,187 @@ int auth_zones_can_fallback(struct auth_zones* az, uint8_t* nm, size_t nmlen,
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
auth_zone_parse_notify_serial(sldns_buffer* pkt, uint32_t *serial)
|
||||
{
|
||||
struct query_info q;
|
||||
uint16_t rdlen;
|
||||
memset(&q, 0, sizeof(q));
|
||||
sldns_buffer_set_position(pkt, 0);
|
||||
if(!query_info_parse(&q, pkt)) return 0;
|
||||
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) == 0) return 0;
|
||||
/* skip name of RR in answer section */
|
||||
if(sldns_buffer_remaining(pkt) < 1) return 0;
|
||||
if(pkt_dname_len(pkt) == 0) return 0;
|
||||
/* check type */
|
||||
if(sldns_buffer_remaining(pkt) < 10 /* type,class,ttl,rdatalen*/)
|
||||
return 0;
|
||||
if(sldns_buffer_read_u16(pkt) != LDNS_RR_TYPE_SOA) return 0;
|
||||
sldns_buffer_skip(pkt, 2); /* class */
|
||||
sldns_buffer_skip(pkt, 4); /* ttl */
|
||||
rdlen = sldns_buffer_read_u16(pkt); /* rdatalen */
|
||||
if(sldns_buffer_remaining(pkt) < rdlen) return 0;
|
||||
if(rdlen < 22) return 0; /* bad soa length */
|
||||
sldns_buffer_skip(pkt, (ssize_t)(rdlen-20));
|
||||
*serial = sldns_buffer_read_u32(pkt);
|
||||
/* return true when has serial in answer section */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** see if addr appears in the list */
|
||||
static int
|
||||
addr_in_list(struct auth_addr* list, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
struct auth_addr* p;
|
||||
for(p=list; p; p=p->next) {
|
||||
if(sockaddr_cmp_addr(addr, addrlen, &p->addr, p->addrlen)==0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** check if an address matches a master specification (or one of its
|
||||
* addresses in the addr list) */
|
||||
static int
|
||||
addr_matches_master(struct auth_master* master, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, struct auth_master** fromhost)
|
||||
{
|
||||
struct sockaddr_storage a;
|
||||
socklen_t alen = 0;
|
||||
int net = 0;
|
||||
if(addr_in_list(master->list, addr, addrlen)) {
|
||||
*fromhost = master;
|
||||
return 1;
|
||||
}
|
||||
/* compare address (but not port number, that is the destination
|
||||
* port of the master, the port number of the received notify is
|
||||
* allowed to by any port on that master) */
|
||||
if(extstrtoaddr(master->host, &a, &alen) &&
|
||||
sockaddr_cmp_addr(addr, addrlen, &a, alen)==0) {
|
||||
*fromhost = master;
|
||||
return 1;
|
||||
}
|
||||
/* prefixes, addr/len, like 10.0.0.0/8 */
|
||||
/* not http and has a / and there is one / */
|
||||
if(master->allow_notify && !master->http &&
|
||||
strchr(master->host, '/') != NULL &&
|
||||
strchr(master->host, '/') == strrchr(master->host, '/') &&
|
||||
netblockstrtoaddr(master->host, UNBOUND_DNS_PORT, &a, &alen,
|
||||
&net) && alen == addrlen) {
|
||||
if(addr_in_common(addr, (addr_is_ip6(addr, addrlen)?128:32),
|
||||
&a, net, alen) >= net) {
|
||||
*fromhost = NULL; /* prefix does not have destination
|
||||
to send the probe or transfer with */
|
||||
return 1; /* matches the netblock */
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** check access list for notifies */
|
||||
static int
|
||||
az_xfr_allowed_notify(struct auth_xfer* xfr, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, struct auth_master** fromhost)
|
||||
{
|
||||
struct auth_master* p;
|
||||
for(p=xfr->allow_notify_list; p; p=p->next) {
|
||||
if(addr_matches_master(p, addr, addrlen, fromhost)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** see if the serial means the zone has to be updated, i.e. the serial
|
||||
* is newer than the zone serial, or we have no zone */
|
||||
static int
|
||||
xfr_serial_means_update(struct auth_xfer* xfr, uint32_t serial)
|
||||
{
|
||||
if(!xfr->have_zone)
|
||||
return 1; /* no zone, anything is better */
|
||||
if(xfr->zone_expired)
|
||||
return 1; /* expired, the sent serial is better than expired
|
||||
data */
|
||||
if(compare_serial(xfr->serial, serial) < 0)
|
||||
return 1; /* our serial is smaller than the sent serial,
|
||||
the data is newer, fetch it */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** note notify serial, updates the notify information in the xfr struct */
|
||||
static void
|
||||
xfr_note_notify_serial(struct auth_xfer* xfr, int has_serial, uint32_t serial)
|
||||
{
|
||||
if(xfr->notify_received && xfr->notify_has_serial && has_serial) {
|
||||
/* see if this serial is newer */
|
||||
if(compare_serial(xfr->notify_serial, serial) < 0)
|
||||
xfr->notify_serial = serial;
|
||||
} else if(xfr->notify_received && xfr->notify_has_serial &&
|
||||
!has_serial) {
|
||||
/* remove serial, we have notify without serial */
|
||||
xfr->notify_has_serial = 0;
|
||||
xfr->notify_serial = 0;
|
||||
} else if(xfr->notify_received && !xfr->notify_has_serial) {
|
||||
/* we already have notify without serial, keep it
|
||||
* that way; no serial check when current operation
|
||||
* is done */
|
||||
} else {
|
||||
xfr->notify_received = 1;
|
||||
xfr->notify_has_serial = has_serial;
|
||||
xfr->notify_serial = serial;
|
||||
}
|
||||
}
|
||||
|
||||
/** process a notify serial, start new probe or note serial. xfr is locked */
|
||||
static void
|
||||
xfr_process_notify(struct auth_xfer* xfr, struct module_env* env,
|
||||
int has_serial, uint32_t serial, struct auth_master* fromhost)
|
||||
{
|
||||
/* if the serial of notify is older than we have, don't fetch
|
||||
* a zone, we already have it */
|
||||
if(has_serial && !xfr_serial_means_update(xfr, serial))
|
||||
return;
|
||||
/* start new probe with this addr src, or note serial */
|
||||
if(!xfr_start_probe(xfr, env, fromhost)) {
|
||||
/* not started because already in progress, note the serial */
|
||||
xfr_note_notify_serial(xfr, has_serial, serial);
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
}
|
||||
}
|
||||
|
||||
int auth_zones_notify(struct auth_zones* az, struct module_env* env,
|
||||
uint8_t* nm, size_t nmlen, uint16_t dclass,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int has_serial,
|
||||
uint32_t serial, int* refused)
|
||||
{
|
||||
struct auth_xfer* xfr;
|
||||
struct auth_master* fromhost = NULL;
|
||||
/* see which zone this is */
|
||||
lock_rw_rdlock(&az->lock);
|
||||
xfr = auth_xfer_find(az, nm, nmlen, dclass);
|
||||
if(!xfr) {
|
||||
lock_rw_unlock(&az->lock);
|
||||
/* no such zone, refuse the notify */
|
||||
*refused = 1;
|
||||
return 0;
|
||||
}
|
||||
lock_basic_lock(&xfr->lock);
|
||||
lock_rw_unlock(&az->lock);
|
||||
|
||||
/* check access list for notifies */
|
||||
if(!az_xfr_allowed_notify(xfr, addr, addrlen, &fromhost)) {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
/* notify not allowed, refuse the notify */
|
||||
*refused = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* process the notify */
|
||||
xfr_process_notify(xfr, env, has_serial, serial, fromhost);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** set a zone expired */
|
||||
static void
|
||||
auth_xfer_set_expired(struct auth_xfer* xfr, struct module_env* env,
|
||||
@ -3239,6 +3520,93 @@ xfr_masterlist_free_addrs(struct auth_master* list)
|
||||
}
|
||||
}
|
||||
|
||||
/** copy a list of auth_addrs */
|
||||
static struct auth_addr*
|
||||
auth_addr_list_copy(struct auth_addr* source)
|
||||
{
|
||||
struct auth_addr* list = NULL, *last = NULL;
|
||||
struct auth_addr* p;
|
||||
for(p=source; p; p=p->next) {
|
||||
struct auth_addr* a = (struct auth_addr*)memdup(p, sizeof(*p));
|
||||
if(!a) {
|
||||
log_err("malloc failure");
|
||||
auth_free_master_addrs(list);
|
||||
return NULL;
|
||||
}
|
||||
a->next = NULL;
|
||||
if(last) last->next = a;
|
||||
if(!list) list = a;
|
||||
last = a;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/** copy a master to a new structure, NULL on alloc failure */
|
||||
static struct auth_master*
|
||||
auth_master_copy(struct auth_master* o)
|
||||
{
|
||||
struct auth_master* m;
|
||||
if(!o) return NULL;
|
||||
m = (struct auth_master*)memdup(o, sizeof(*o));
|
||||
if(!m) {
|
||||
log_err("malloc failure");
|
||||
return NULL;
|
||||
}
|
||||
m->next = NULL;
|
||||
if(m->host) {
|
||||
m->host = strdup(m->host);
|
||||
if(!m->host) {
|
||||
free(m);
|
||||
log_err("malloc failure");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(m->file) {
|
||||
m->file = strdup(m->file);
|
||||
if(!m->file) {
|
||||
free(m->host);
|
||||
free(m);
|
||||
log_err("malloc failure");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(m->list) {
|
||||
m->list = auth_addr_list_copy(m->list);
|
||||
if(!m->list) {
|
||||
free(m->file);
|
||||
free(m->host);
|
||||
free(m);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/** copy the master addresses from the task_probe lookups to the allow_notify
|
||||
* list of masters */
|
||||
static void
|
||||
probe_copy_masters_for_allow_notify(struct auth_xfer* xfr)
|
||||
{
|
||||
struct auth_master* list = NULL, *last = NULL;
|
||||
struct auth_master* p;
|
||||
/* build up new list with copies */
|
||||
for(p = xfr->task_probe->masters; p; p=p->next) {
|
||||
struct auth_master* m = auth_master_copy(p);
|
||||
if(!m) {
|
||||
auth_free_masters(list);
|
||||
/* failed because of malloc failure, use old list */
|
||||
return;
|
||||
}
|
||||
m->next = NULL;
|
||||
if(last) last->next = m;
|
||||
if(!list) list = m;
|
||||
last = m;
|
||||
}
|
||||
/* success, replace list */
|
||||
auth_free_masters(xfr->allow_notify_list);
|
||||
xfr->allow_notify_list = list;
|
||||
}
|
||||
|
||||
/** start the lookups for task_transfer */
|
||||
static void
|
||||
xfr_transfer_start_lookups(struct auth_xfer* xfr)
|
||||
@ -3400,11 +3768,19 @@ xfr_transfer_nextmaster(struct auth_xfer* xfr)
|
||||
if(xfr->task_transfer->scan_specific) {
|
||||
xfr->task_transfer->scan_specific = NULL;
|
||||
xfr->task_transfer->scan_target = xfr->task_transfer->masters;
|
||||
if(xfr->task_transfer->scan_target && xfr->task_transfer->
|
||||
scan_target->list)
|
||||
xfr->task_transfer->scan_addr =
|
||||
xfr->task_transfer->scan_target->list;
|
||||
return;
|
||||
}
|
||||
if(!xfr->task_transfer->scan_target)
|
||||
return;
|
||||
xfr->task_transfer->scan_target = xfr->task_transfer->scan_target->next;
|
||||
if(xfr->task_transfer->scan_target && xfr->task_transfer->
|
||||
scan_target->list)
|
||||
xfr->task_transfer->scan_addr =
|
||||
xfr->task_transfer->scan_target->list;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3422,11 +3798,19 @@ xfr_probe_nextmaster(struct auth_xfer* xfr)
|
||||
if(xfr->task_probe->scan_specific) {
|
||||
xfr->task_probe->scan_specific = NULL;
|
||||
xfr->task_probe->scan_target = xfr->task_probe->masters;
|
||||
if(xfr->task_probe->scan_target && xfr->task_probe->
|
||||
scan_target->list)
|
||||
xfr->task_probe->scan_addr =
|
||||
xfr->task_probe->scan_target->list;
|
||||
return;
|
||||
}
|
||||
if(!xfr->task_probe->scan_target)
|
||||
return;
|
||||
xfr->task_probe->scan_target = xfr->task_probe->scan_target->next;
|
||||
if(xfr->task_probe->scan_target && xfr->task_probe->
|
||||
scan_target->list)
|
||||
xfr->task_probe->scan_addr =
|
||||
xfr->task_probe->scan_target->list;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3581,22 +3965,6 @@ check_packet_ok(sldns_buffer* pkt, uint16_t qtype, struct auth_xfer* xfr,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** see if the serial means the zone has to be updated, i.e. the serial
|
||||
* is newer than the zone serial, or we have no zone */
|
||||
static int
|
||||
xfr_serial_means_update(struct auth_xfer* xfr, uint32_t serial)
|
||||
{
|
||||
if(!xfr->have_zone)
|
||||
return 1; /* no zone, anything is better */
|
||||
if(xfr->zone_expired)
|
||||
return 1; /* expired, the sent serial is better than expired
|
||||
data */
|
||||
if(compare_serial(xfr->serial, serial) < 0)
|
||||
return 1; /* our serial is smaller than the sent serial,
|
||||
the data is newer, fetch it */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** read one line from chunks into buffer at current position */
|
||||
static int
|
||||
chunkline_get_line(struct auth_chunk** chunk, size_t* chunk_pos,
|
||||
@ -3870,6 +4238,11 @@ chunkline_newline_removal(sldns_buffer* buf)
|
||||
size_t i, end=sldns_buffer_limit(buf);
|
||||
for(i=0; i<end; i++) {
|
||||
char c = (char)sldns_buffer_read_u8_at(buf, i);
|
||||
if(c == '\n' && i==end-1) {
|
||||
sldns_buffer_write_u8_at(buf, i, 0);
|
||||
sldns_buffer_set_limit(buf, end-1);
|
||||
return;
|
||||
}
|
||||
if(c == '\n')
|
||||
sldns_buffer_write_u8_at(buf, i, (uint8_t)' ');
|
||||
}
|
||||
@ -4032,6 +4405,56 @@ log_rrlist_position(const char* label, struct auth_chunk* rr_chunk,
|
||||
str, typestr);
|
||||
}
|
||||
|
||||
/** check that start serial is OK for ixfr. we are at rr_counter == 0,
|
||||
* and we are going to check rr_counter == 1 (has to be type SOA) serial */
|
||||
static int
|
||||
ixfr_start_serial(struct auth_chunk* rr_chunk, int rr_num, size_t rr_pos,
|
||||
uint8_t* rr_dname, uint16_t rr_type, uint16_t rr_class,
|
||||
uint32_t rr_ttl, uint16_t rr_rdlen, uint8_t* rr_rdata,
|
||||
size_t rr_nextpos, uint32_t transfer_serial, uint32_t xfr_serial)
|
||||
{
|
||||
uint32_t startserial;
|
||||
/* move forward on RR */
|
||||
chunk_rrlist_gonext(&rr_chunk, &rr_num, &rr_pos, rr_nextpos);
|
||||
if(chunk_rrlist_end(rr_chunk, rr_num)) {
|
||||
/* no second SOA */
|
||||
verbose(VERB_OPS, "IXFR has no second SOA record");
|
||||
return 0;
|
||||
}
|
||||
if(!chunk_rrlist_get_current(rr_chunk, rr_num, rr_pos,
|
||||
&rr_dname, &rr_type, &rr_class, &rr_ttl, &rr_rdlen,
|
||||
&rr_rdata, &rr_nextpos)) {
|
||||
verbose(VERB_OPS, "IXFR cannot parse second SOA record");
|
||||
/* failed to parse RR */
|
||||
return 0;
|
||||
}
|
||||
if(rr_type != LDNS_RR_TYPE_SOA) {
|
||||
verbose(VERB_OPS, "IXFR second record is not type SOA");
|
||||
return 0;
|
||||
}
|
||||
if(rr_rdlen < 22) {
|
||||
verbose(VERB_OPS, "IXFR, second SOA has short rdlength");
|
||||
return 0; /* bad SOA rdlen */
|
||||
}
|
||||
startserial = sldns_read_uint32(rr_rdata+rr_rdlen-20);
|
||||
if(startserial == transfer_serial) {
|
||||
/* empty AXFR, not an IXFR */
|
||||
verbose(VERB_OPS, "IXFR second serial same as first");
|
||||
return 0;
|
||||
}
|
||||
if(startserial != xfr_serial) {
|
||||
/* wrong start serial, it does not match the serial in
|
||||
* memory */
|
||||
verbose(VERB_OPS, "IXFR is from serial %u to %u but %u "
|
||||
"in memory, rejecting the zone transfer",
|
||||
(unsigned)startserial, (unsigned)transfer_serial,
|
||||
(unsigned)xfr_serial);
|
||||
return 0;
|
||||
}
|
||||
/* everything OK in second SOA serial */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** apply IXFR to zone in memory. z is locked. false on failure(mallocfail) */
|
||||
static int
|
||||
apply_ixfr(struct auth_xfer* xfr, struct auth_zone* z,
|
||||
@ -4078,6 +4501,13 @@ apply_ixfr(struct auth_xfer* xfr, struct auth_zone* z,
|
||||
have_transfer_serial = 1;
|
||||
transfer_serial = serial;
|
||||
delmode = 1; /* gets negated below */
|
||||
/* check second RR before going any further */
|
||||
if(!ixfr_start_serial(rr_chunk, rr_num, rr_pos,
|
||||
rr_dname, rr_type, rr_class, rr_ttl,
|
||||
rr_rdlen, rr_rdata, rr_nextpos,
|
||||
transfer_serial, xfr->serial)) {
|
||||
return 0;
|
||||
}
|
||||
} else if(transfer_serial == serial) {
|
||||
have_transfer_serial++;
|
||||
if(rr_counter == 1) {
|
||||
@ -4308,6 +4738,28 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** write http chunks to zonefile to create downloaded file */
|
||||
static int
|
||||
auth_zone_write_chunks(struct auth_xfer* xfr, const char* fname)
|
||||
{
|
||||
FILE* out;
|
||||
struct auth_chunk* p;
|
||||
out = fopen(fname, "w");
|
||||
if(!out) {
|
||||
log_err("could not open %s: %s", fname, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
for(p = xfr->task_transfer->chunks_first; p ; p = p->next) {
|
||||
if(!write_out(out, (char*)p->data, p->len)) {
|
||||
log_err("could not write http download to %s", fname);
|
||||
fclose(out);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fclose(out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** write to zonefile after zone has been updated */
|
||||
static void
|
||||
xfr_write_after_update(struct auth_xfer* xfr, struct module_env* env)
|
||||
@ -4346,7 +4798,13 @@ xfr_write_after_update(struct auth_xfer* xfr, struct module_env* env)
|
||||
}
|
||||
snprintf(tmpfile, sizeof(tmpfile), "%s.tmp%u", z->zonefile,
|
||||
(unsigned)getpid());
|
||||
if(!auth_zone_write_file(z, tmpfile)) {
|
||||
if(xfr->task_transfer->master->http) {
|
||||
/* use the stored chunk list to write them */
|
||||
if(!auth_zone_write_chunks(xfr, tmpfile)) {
|
||||
unlink(tmpfile);
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
} else if(!auth_zone_write_file(z, tmpfile)) {
|
||||
unlink(tmpfile);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return;
|
||||
@ -4465,6 +4923,9 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env)
|
||||
/* not needed, host is in IP addr format */
|
||||
return 0;
|
||||
}
|
||||
if(master->allow_notify)
|
||||
return 0; /* allow-notifies are not transferred from, no
|
||||
lookup is needed */
|
||||
|
||||
/* use mesh_new_callback to probe for non-addr hosts,
|
||||
* and then wait for them to be looked up (in cache, or query) */
|
||||
@ -4519,6 +4980,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
||||
socklen_t addrlen = 0;
|
||||
struct auth_master* master = xfr->task_transfer->master;
|
||||
if(!master) return 0;
|
||||
if(master->allow_notify) return 0; /* only for notify */
|
||||
|
||||
/* get master addr */
|
||||
if(xfr->task_transfer->scan_addr) {
|
||||
@ -4623,7 +5085,7 @@ xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
xfr_transfer_disown(xfr);
|
||||
|
||||
/* pick up the nextprobe task and wait */
|
||||
xfr_set_timeout(xfr, env, 1);
|
||||
xfr_set_timeout(xfr, env, 1, 0);
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
}
|
||||
|
||||
@ -4635,6 +5097,8 @@ xfr_master_add_addrs(struct auth_master* m, struct ub_packed_rrset_key* rrset,
|
||||
size_t i;
|
||||
struct packed_rrset_data* data;
|
||||
if(!m || !rrset) return;
|
||||
if(rrtype != LDNS_RR_TYPE_A && rrtype != LDNS_RR_TYPE_AAAA)
|
||||
return;
|
||||
data = (struct packed_rrset_data*)rrset->entry.data;
|
||||
for(i=0; i<data->count; i++) {
|
||||
struct auth_addr* a;
|
||||
@ -5056,8 +5520,30 @@ process_list_end_transfer(struct auth_xfer* xfr, struct module_env* env)
|
||||
/* we fetched the zone, move to wait task */
|
||||
xfr_transfer_disown(xfr);
|
||||
|
||||
/* pick up the nextprobe task and wait (normail wait time) */
|
||||
xfr_set_timeout(xfr, env, 0);
|
||||
if(xfr->notify_received && (!xfr->notify_has_serial ||
|
||||
(xfr->notify_has_serial &&
|
||||
xfr_serial_means_update(xfr, xfr->notify_serial)))) {
|
||||
uint32_t sr = xfr->notify_serial;
|
||||
int has_sr = xfr->notify_has_serial;
|
||||
/* we received a notify while probe/transfer was
|
||||
* in progress. start a new probe and transfer */
|
||||
xfr->notify_received = 0;
|
||||
xfr->notify_has_serial = 0;
|
||||
xfr->notify_serial = 0;
|
||||
if(!xfr_start_probe(xfr, env, NULL)) {
|
||||
/* if we couldn't start it, already in
|
||||
* progress; restore notify serial,
|
||||
* while xfr still locked */
|
||||
xfr->notify_received = 1;
|
||||
xfr->notify_has_serial = has_sr;
|
||||
xfr->notify_serial = sr;
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
/* pick up the nextprobe task and wait (normail wait time) */
|
||||
xfr_set_timeout(xfr, env, 0, 0);
|
||||
}
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return;
|
||||
}
|
||||
@ -5248,6 +5734,9 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
/* pick master */
|
||||
struct auth_master* master = xfr_probe_current_master(xfr);
|
||||
if(!master) return 0;
|
||||
if(master->allow_notify) return 0; /* only for notify */
|
||||
if(master->http) return 0; /* only masters get SOA UDP probe,
|
||||
not urls, if those are in this list */
|
||||
|
||||
/* get master addr */
|
||||
if(xfr->task_probe->scan_addr) {
|
||||
@ -5400,7 +5889,7 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
|
||||
if(xfr->have_zone)
|
||||
xfr->lease_time = *env->now;
|
||||
if(xfr->task_nextprobe->worker == NULL)
|
||||
xfr_set_timeout(xfr, env, 0);
|
||||
xfr_set_timeout(xfr, env, 0, 0);
|
||||
}
|
||||
/* other tasks are running, we don't do this anymore */
|
||||
xfr_probe_disown(xfr);
|
||||
@ -5445,6 +5934,11 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
|
||||
/* not needed, host is in IP addr format */
|
||||
return 0;
|
||||
}
|
||||
if(master->allow_notify && !master->http &&
|
||||
strchr(master->host, '/') != NULL &&
|
||||
strchr(master->host, '/') == strrchr(master->host, '/')) {
|
||||
return 0; /* is IP/prefix format, not something to look up */
|
||||
}
|
||||
|
||||
/* use mesh_new_callback to probe for non-addr hosts,
|
||||
* and then wait for them to be looked up (in cache, or query) */
|
||||
@ -5507,6 +6001,17 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
}
|
||||
xfr_probe_move_to_next_lookup(xfr, env);
|
||||
}
|
||||
/* probe of list has ended. Create or refresh the list of of
|
||||
* allow_notify addrs */
|
||||
probe_copy_masters_for_allow_notify(xfr);
|
||||
if(xfr->task_probe->only_lookup) {
|
||||
/* only wanted lookups for copy, stop probe and start wait */
|
||||
xfr->task_probe->only_lookup = 0;
|
||||
xfr_probe_disown(xfr);
|
||||
xfr_set_timeout(xfr, env, 0, 0);
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
/* send probe packets */
|
||||
while(!xfr_probe_end_of_list(xfr)) {
|
||||
@ -5524,7 +6029,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
xfr_probe_disown(xfr);
|
||||
|
||||
/* pick up the nextprobe task and wait */
|
||||
xfr_set_timeout(xfr, env, 1);
|
||||
xfr_set_timeout(xfr, env, 1, 0);
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
}
|
||||
|
||||
@ -5611,19 +6116,45 @@ auth_xfer_timer(void* arg)
|
||||
|
||||
xfr_nextprobe_disown(xfr);
|
||||
|
||||
if(!xfr_start_probe(xfr, env, NULL)) {
|
||||
/* not started because already in progress */
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
}
|
||||
}
|
||||
|
||||
/** return true if there are probe (SOA UDP query) targets in the master list*/
|
||||
static int
|
||||
have_probe_targets(struct auth_master* list)
|
||||
{
|
||||
struct auth_master* p;
|
||||
for(p=list; p; p = p->next) {
|
||||
if(!p->allow_notify && p->host)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** start task_probe if possible, if no masters for probe start task_transfer
|
||||
* returns true if task has been started, and false if the task is already
|
||||
* in progress. */
|
||||
static int
|
||||
xfr_start_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
struct auth_master* spec)
|
||||
{
|
||||
/* see if we need to start a probe (or maybe it is already in
|
||||
* progress (due to notify)) */
|
||||
if(xfr->task_probe->worker == NULL) {
|
||||
if(xfr->task_probe->masters == NULL) {
|
||||
if(!have_probe_targets(xfr->task_probe->masters) &&
|
||||
!(xfr->task_probe->only_lookup &&
|
||||
xfr->task_probe->masters != NULL)) {
|
||||
/* useless to pick up task_probe, no masters to
|
||||
* probe. Instead attempt to pick up task transfer */
|
||||
if(xfr->task_transfer->worker == NULL) {
|
||||
xfr_start_transfer(xfr, env, NULL);
|
||||
} else {
|
||||
/* task transfer already in progress */
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
xfr_start_transfer(xfr, env, spec);
|
||||
return 1;
|
||||
}
|
||||
return;
|
||||
/* task transfer already in progress */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* pick up the probe task ourselves */
|
||||
@ -5632,15 +6163,17 @@ auth_xfer_timer(void* arg)
|
||||
xfr->task_probe->cp = NULL;
|
||||
|
||||
/* start the task */
|
||||
/* this was a timeout, so no specific first master to scan */
|
||||
xfr_probe_start_list(xfr, NULL);
|
||||
/* if this was a timeout, no specific first master to scan */
|
||||
/* otherwise, spec is nonNULL the notified master, scan
|
||||
* first and also transfer first from it */
|
||||
xfr_probe_start_list(xfr, spec);
|
||||
/* setup to start the lookup of hostnames of masters afresh */
|
||||
xfr_probe_start_lookups(xfr);
|
||||
/* send the probe packet or next send, or end task */
|
||||
xfr_probe_send_or_end(xfr, env);
|
||||
} else {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** for task_nextprobe.
|
||||
@ -5648,10 +6181,11 @@ auth_xfer_timer(void* arg)
|
||||
* @param xfr: task structure
|
||||
* @param env: module environment, with worker and time.
|
||||
* @param failure: set true if timer should be set for failure retry.
|
||||
* @param lookup_only: only perform lookups when timer done, 0 sec timeout
|
||||
*/
|
||||
static void
|
||||
xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
|
||||
int failure)
|
||||
int failure, int lookup_only)
|
||||
{
|
||||
struct timeval tv;
|
||||
log_assert(xfr->task_nextprobe != NULL);
|
||||
@ -5661,7 +6195,7 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
|
||||
* but if expiry is sooner, use that one.
|
||||
* after a failure, use the retry timer instead. */
|
||||
xfr->task_nextprobe->next_probe = *env->now;
|
||||
if(xfr->lease_time)
|
||||
if(xfr->lease_time && !failure)
|
||||
xfr->task_nextprobe->next_probe = xfr->lease_time;
|
||||
|
||||
if(!failure) {
|
||||
@ -5684,6 +6218,12 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
|
||||
if(failure)
|
||||
xfr->task_nextprobe->next_probe +=
|
||||
xfr->task_nextprobe->backoff;
|
||||
/* put the timer exactly on expiry, if possible */
|
||||
if(xfr->lease_time && xfr->lease_time+xfr->expiry <
|
||||
xfr->task_nextprobe->next_probe &&
|
||||
xfr->lease_time+xfr->expiry > *env->now)
|
||||
xfr->task_nextprobe->next_probe =
|
||||
xfr->lease_time+xfr->expiry;
|
||||
} else {
|
||||
xfr->task_nextprobe->next_probe +=
|
||||
xfr->task_nextprobe->backoff;
|
||||
@ -5708,6 +6248,13 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
|
||||
tv.tv_sec = xfr->task_nextprobe->next_probe -
|
||||
*(xfr->task_nextprobe->env->now);
|
||||
else tv.tv_sec = 0;
|
||||
if(tv.tv_sec != 0 && lookup_only && xfr->task_probe->masters) {
|
||||
/* don't lookup_only, if lookup timeout is 0 anyway,
|
||||
* or if we don't have masters to lookup */
|
||||
tv.tv_sec = 0;
|
||||
if(xfr->task_probe && xfr->task_probe->worker == NULL)
|
||||
xfr->task_probe->only_lookup = 1;
|
||||
}
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
dname_str(xfr->name, zname);
|
||||
@ -5731,8 +6278,9 @@ auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env)
|
||||
* notes the start time when the data was acquired */
|
||||
if(x->have_zone)
|
||||
x->lease_time = *env->now;
|
||||
if(x->task_nextprobe && x->task_nextprobe->worker == NULL)
|
||||
xfr_set_timeout(x, env, 0);
|
||||
if(x->task_nextprobe && x->task_nextprobe->worker == NULL) {
|
||||
xfr_set_timeout(x, env, 0, 1);
|
||||
}
|
||||
lock_basic_unlock(&x->lock);
|
||||
}
|
||||
lock_rw_unlock(&az->lock);
|
||||
@ -5889,7 +6437,7 @@ static char*
|
||||
dup_all(char* str)
|
||||
{
|
||||
char* result = strdup(str);
|
||||
if(!str) {
|
||||
if(!result) {
|
||||
log_err("malloc failure");
|
||||
return NULL;
|
||||
}
|
||||
@ -6006,6 +6554,15 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c,
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for(p = c->allow_notify; p; p = p->next) {
|
||||
m = auth_master_new(&list);
|
||||
m->allow_notify = 1;
|
||||
m->host = strdup(p->str);
|
||||
if(!m->host) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,10 @@ struct auth_zones {
|
||||
rbtree_type xtree;
|
||||
/** do we have downstream enabled */
|
||||
int have_downstream;
|
||||
/** number of queries upstream */
|
||||
size_t num_query_up;
|
||||
/** number of queries downstream */
|
||||
size_t num_query_down;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -122,6 +126,10 @@ struct auth_zone {
|
||||
/** for upstream: this zone answers queries that unbound intends to
|
||||
* send upstream. */
|
||||
int for_upstream;
|
||||
/** zone has been deleted */
|
||||
int zone_deleted;
|
||||
/** deletelist pointer, unused normally except during delete */
|
||||
struct auth_zone* delete_next;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -214,8 +222,14 @@ struct auth_xfer {
|
||||
* Hold the lock to access this member (and the serial).
|
||||
*/
|
||||
int notify_received;
|
||||
/** true if the notify_received has a serial number */
|
||||
int notify_has_serial;
|
||||
/** serial number of the notify */
|
||||
uint32_t notify_serial;
|
||||
/** the list of masters for checking notifies. This list is
|
||||
* empty on start, and a copy of the list from the probe_task when
|
||||
* it is done looking them up. */
|
||||
struct auth_master* allow_notify_list;
|
||||
|
||||
/* protected by the lock on the structure, information about
|
||||
* the loaded authority zone. */
|
||||
@ -292,6 +306,9 @@ struct auth_probe {
|
||||
struct auth_master* lookup_target;
|
||||
/** are we looking up A or AAAA, first A, then AAAA (if ip6 enabled) */
|
||||
int lookup_aaaa;
|
||||
/** we only want to do lookups for making config work (for notify),
|
||||
* don't proceed with UDP SOA probe queries */
|
||||
int only_lookup;
|
||||
|
||||
/** once notified, or the timeout has been reached. a scan starts. */
|
||||
/** the scan specific target (notify source), or NULL if none */
|
||||
@ -400,6 +417,9 @@ struct auth_master {
|
||||
int http;
|
||||
/** use IXFR for this master */
|
||||
int ixfr;
|
||||
/** this is an allow notify member, the master can send notifies
|
||||
* to us, but we don't send SOA probes, or zone transfer from it */
|
||||
int allow_notify;
|
||||
/** use ssl for channel */
|
||||
int ssl;
|
||||
/** the port number (for urls) */
|
||||
@ -541,9 +561,39 @@ int auth_zone_set_fallback(struct auth_zone* z, char* fallbackstr);
|
||||
int auth_zones_can_fallback(struct auth_zones* az, uint8_t* nm, size_t nmlen,
|
||||
uint16_t dclass);
|
||||
|
||||
/** process notify for auth zones.
|
||||
* first checks the access list. Then processes the notify. This starts
|
||||
* the probe sequence or it notes the serial number (if any)
|
||||
* @param az: auth zones structure.
|
||||
* @param env: module env of the worker that is handling the notify. it will
|
||||
* pick up the task probe (or transfer), unless already in progress by
|
||||
* another worker.
|
||||
* @param nm: name of the zone. Uncompressed. from query.
|
||||
* @param nmlen: length of name.
|
||||
* @param dclass: class of zone.
|
||||
* @param addr: source address of notify
|
||||
* @param addrlen: length of addr.
|
||||
* @param has_serial: if true, the notify has a serial attached.
|
||||
* @param serial: the serial number, if has_serial is true.
|
||||
* @param refused: is set to true on failure to note refused access.
|
||||
* @return fail on failures (refused is false) and when access is
|
||||
* denied (refused is true). True when processed.
|
||||
*/
|
||||
int auth_zones_notify(struct auth_zones* az, struct module_env* env,
|
||||
uint8_t* nm, size_t nmlen, uint16_t dclass,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int has_serial,
|
||||
uint32_t serial, int* refused);
|
||||
|
||||
/** process notify packet and read serial number from SOA.
|
||||
* returns 0 if no soa record in the notify */
|
||||
int auth_zone_parse_notify_serial(struct sldns_buffer* pkt, uint32_t *serial);
|
||||
|
||||
/** read auth zone from zonefile. caller must lock zone. false on failure */
|
||||
int auth_zone_read_zonefile(struct auth_zone* z);
|
||||
|
||||
/** find serial number of zone or false if none (no SOA record) */
|
||||
int auth_zone_get_serial(struct auth_zone* z, uint32_t* serial);
|
||||
|
||||
/** compare auth_zones for sorted rbtree */
|
||||
int auth_zone_cmp(const void* z1, const void* z2);
|
||||
|
||||
|
48
contrib/unbound/services/cache/dns.c
vendored
48
contrib/unbound/services/cache/dns.c
vendored
@ -108,6 +108,48 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
||||
}
|
||||
}
|
||||
|
||||
/** delete message from message cache */
|
||||
static void
|
||||
msg_cache_remove(struct module_env* env, uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags)
|
||||
{
|
||||
struct query_info k;
|
||||
hashvalue_type h;
|
||||
|
||||
k.qname = qname;
|
||||
k.qname_len = qnamelen;
|
||||
k.qtype = qtype;
|
||||
k.qclass = qclass;
|
||||
k.local_alias = NULL;
|
||||
h = query_info_hash(&k, flags);
|
||||
slabhash_remove(env->msg_cache, h, &k);
|
||||
}
|
||||
|
||||
/** remove servfail msg cache entry */
|
||||
static void
|
||||
msg_del_servfail(struct module_env* env, struct query_info* qinfo,
|
||||
uint32_t flags)
|
||||
{
|
||||
struct msgreply_entry* e;
|
||||
/* see if the entry is servfail, and then remove it, so that
|
||||
* lookups move from the cacheresponse stage to the recursionresponse
|
||||
* stage */
|
||||
e = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len,
|
||||
qinfo->qtype, qinfo->qclass, flags, 0, 0);
|
||||
if(!e) return;
|
||||
/* we don't check for the ttl here, also expired servfail entries
|
||||
* are removed. If the user uses serve-expired, they would still be
|
||||
* used to answer from cache */
|
||||
if(FLAGS_GET_RCODE(((struct reply_info*)e->entry.data)->flags)
|
||||
!= LDNS_RCODE_SERVFAIL) {
|
||||
lock_rw_unlock(&e->entry.lock);
|
||||
return;
|
||||
}
|
||||
lock_rw_unlock(&e->entry.lock);
|
||||
msg_cache_remove(env, qinfo->qname, qinfo->qname_len, qinfo->qtype,
|
||||
qinfo->qclass, flags);
|
||||
}
|
||||
|
||||
void
|
||||
dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||
hashvalue_type hash, struct reply_info* rep, time_t leeway, int pside,
|
||||
@ -132,6 +174,12 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||
* which could be useful for delegation information */
|
||||
verbose(VERB_ALGO, "TTL 0: dropped msg from cache");
|
||||
free(rep);
|
||||
/* if the message is SERVFAIL in cache, remove that SERVFAIL,
|
||||
* so that the TTL 0 response can be returned for future
|
||||
* responses (i.e. don't get answered by the servfail from
|
||||
* cache, but instead go to recursion to get this TTL0
|
||||
* response). */
|
||||
msg_del_servfail(env, qinfo, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
|
2
contrib/unbound/services/cache/rrset.c
vendored
2
contrib/unbound/services/cache/rrset.c
vendored
@ -255,9 +255,11 @@ void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache,
|
||||
wc_dname[1] = (uint8_t)'*';
|
||||
memmove(wc_dname+2, ce, ce_len);
|
||||
|
||||
free(rrset->rk.dname);
|
||||
rrset->rk.dname_len = ce_len + 2;
|
||||
rrset->rk.dname = (uint8_t*)memdup(wc_dname, rrset->rk.dname_len);
|
||||
if(!rrset->rk.dname) {
|
||||
alloc_special_release(alloc, rrset);
|
||||
log_err("memdup failure in rrset_cache_update_wildcard");
|
||||
return;
|
||||
}
|
||||
|
@ -1056,6 +1056,26 @@ set_recvpktinfo(int s, int family)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** see if interface is ssl, its port number == the ssl port number */
|
||||
static int
|
||||
if_is_ssl(const char* ifname, const char* port, int ssl_port,
|
||||
struct config_strlist* additional_tls_port)
|
||||
{
|
||||
struct config_strlist* s;
|
||||
char* p = strchr(ifname, '@');
|
||||
if(!p && atoi(port) == ssl_port)
|
||||
return 1;
|
||||
if(p && atoi(p+1) == ssl_port)
|
||||
return 1;
|
||||
for(s = additional_tls_port; s; s = s->next) {
|
||||
if(p && atoi(p+1) == atoi(s->str))
|
||||
return 1;
|
||||
if(!p && atoi(port) == atoi(s->str))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for ports_open. Creates one interface (or NULL for default).
|
||||
* @param ifname: The interface ip address.
|
||||
@ -1069,6 +1089,7 @@ set_recvpktinfo(int s, int family)
|
||||
* @param rcv: receive buffer size for UDP
|
||||
* @param snd: send buffer size for UDP
|
||||
* @param ssl_port: ssl service port number
|
||||
* @param additional_tls_port: list of additional ssl service port numbers.
|
||||
* @param reuseport: try to set SO_REUSEPORT if nonNULL and true.
|
||||
* set to false on exit if reuseport failed due to no kernel support.
|
||||
* @param transparent: set IP_TRANSPARENT socket option.
|
||||
@ -1081,8 +1102,10 @@ set_recvpktinfo(int s, int family)
|
||||
static int
|
||||
ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
struct addrinfo *hints, const char* port, struct listen_port** list,
|
||||
size_t rcv, size_t snd, int ssl_port, int* reuseport, int transparent,
|
||||
int tcp_mss, int freebind, int use_systemd, int dnscrypt_port)
|
||||
size_t rcv, size_t snd, int ssl_port,
|
||||
struct config_strlist* additional_tls_port, int* reuseport,
|
||||
int transparent, int tcp_mss, int freebind, int use_systemd,
|
||||
int dnscrypt_port)
|
||||
{
|
||||
int s, noip6=0;
|
||||
#ifdef USE_DNSCRYPT
|
||||
@ -1146,9 +1169,8 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
}
|
||||
}
|
||||
if(do_tcp) {
|
||||
int is_ssl = ((strchr(ifname, '@') &&
|
||||
atoi(strchr(ifname, '@')+1) == ssl_port) ||
|
||||
(!strchr(ifname, '@') && atoi(port) == ssl_port));
|
||||
int is_ssl = if_is_ssl(ifname, port, ssl_port,
|
||||
additional_tls_port);
|
||||
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
|
||||
&noip6, 0, 0, reuseport, transparent, tcp_mss,
|
||||
freebind, use_systemd)) == -1) {
|
||||
@ -1334,8 +1356,8 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
do_auto, cfg->do_udp, do_tcp,
|
||||
&hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->ssl_port, cfg->additional_tls_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
@ -1348,8 +1370,8 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
do_auto, cfg->do_udp, do_tcp,
|
||||
&hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->ssl_port, cfg->additional_tls_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
@ -1364,8 +1386,8 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
|
||||
do_tcp, &hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->ssl_port, cfg->additional_tls_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
@ -1378,8 +1400,8 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
if(!ports_create_if(cfg->ifs[i], 0, cfg->do_udp,
|
||||
do_tcp, &hints, portbuf, &list,
|
||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||
cfg->ssl_port, reuseport,
|
||||
cfg->ip_transparent,
|
||||
cfg->ssl_port, cfg->additional_tls_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
listening_ports_free(list);
|
||||
|
@ -736,7 +736,8 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
comm_point_drop_reply(&rep->query_reply);
|
||||
mesh->num_reply_addrs--;
|
||||
}
|
||||
for(cb=mstate->cb_list; cb; cb=cb->next) {
|
||||
while((cb = mstate->cb_list)!=NULL) {
|
||||
mstate->cb_list = cb->next;
|
||||
fptr_ok(fptr_whitelist_mesh_cb(cb->cb));
|
||||
(*cb->cb)(cb->cb_arg, LDNS_RCODE_SERVFAIL, NULL,
|
||||
sec_status_unchecked, NULL);
|
||||
@ -974,7 +975,8 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
else secure = 0;
|
||||
if(!rep && rcode == LDNS_RCODE_NOERROR)
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(!rcode && rep->security == sec_status_bogus) {
|
||||
if(!rcode && (rep->security == sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
if(!(reason = errinf_to_str(&m->s)))
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
}
|
||||
@ -1040,7 +1042,8 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
/* examine security status */
|
||||
if(m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
|
||||
m->s.env->cfg->ignore_cd) && rep &&
|
||||
rep->security <= sec_status_bogus) {
|
||||
(rep->security <= sec_status_bogus ||
|
||||
rep->security == sec_status_secure_sentinel_fail)) {
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(m->s.env->cfg->stat_extended)
|
||||
m->s.env->mesh->ans_bogus++;
|
||||
@ -1167,7 +1170,13 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
}
|
||||
}
|
||||
mstate->replies_sent = 1;
|
||||
for(c = mstate->cb_list; c; c = c->next) {
|
||||
while((c = mstate->cb_list) != NULL) {
|
||||
/* take this cb off the list; so that the list can be
|
||||
* changed, eg. by adds from the callback routine */
|
||||
mstate->cb_list = c->next;
|
||||
if(!mstate->reply_list && !mstate->cb_list &&
|
||||
mstate->super_set.count == 0)
|
||||
mstate->s.env->mesh->num_detached_states++;
|
||||
mesh_do_callback(mstate, mstate->s.return_rcode, rep, c);
|
||||
}
|
||||
}
|
||||
|
@ -364,6 +364,20 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
|
||||
#endif
|
||||
pend->c->ssl_shake_state = comm_ssl_shake_write;
|
||||
#ifdef HAVE_SSL_SET1_HOST
|
||||
if(w->tls_auth_name) {
|
||||
SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
|
||||
/* setting the hostname makes openssl verify the
|
||||
* host name in the x509 certificate in the
|
||||
* SSL connection*/
|
||||
if(!SSL_set1_host(pend->c->ssl, w->tls_auth_name)) {
|
||||
log_err("SSL_set1_host failed");
|
||||
pend->c->fd = s;
|
||||
comm_point_close(pend->c);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_SSL_SET1_HOST */
|
||||
}
|
||||
w->pkt = NULL;
|
||||
w->next_waiting = (void*)pend;
|
||||
@ -851,6 +865,7 @@ serviced_node_del(rbnode_type* node, void* ATTR_UNUSED(arg))
|
||||
struct service_callback* p = sq->cblist, *np;
|
||||
free(sq->qbuf);
|
||||
free(sq->zone);
|
||||
free(sq->tls_auth_name);
|
||||
edns_opt_list_free(sq->opt_list);
|
||||
while(p) {
|
||||
np = p->next;
|
||||
@ -1284,6 +1299,7 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
|
||||
w->cb = callback;
|
||||
w->cb_arg = callback_arg;
|
||||
w->ssl_upstream = sq->ssl_upstream;
|
||||
w->tls_auth_name = sq->tls_auth_name;
|
||||
#ifndef S_SPLINT_S
|
||||
tv.tv_sec = timeout;
|
||||
tv.tv_usec = 0;
|
||||
@ -1357,8 +1373,8 @@ lookup_serviced(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
||||
static struct serviced_query*
|
||||
serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
||||
int want_dnssec, int nocaps, int tcp_upstream, int ssl_upstream,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int qtype, struct edns_option* opt_list)
|
||||
char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, int qtype, struct edns_option* opt_list)
|
||||
{
|
||||
struct serviced_query* sq = (struct serviced_query*)malloc(sizeof(*sq));
|
||||
#ifdef UNBOUND_DEBUG
|
||||
@ -1386,12 +1402,24 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
||||
sq->nocaps = nocaps;
|
||||
sq->tcp_upstream = tcp_upstream;
|
||||
sq->ssl_upstream = ssl_upstream;
|
||||
if(tls_auth_name) {
|
||||
sq->tls_auth_name = strdup(tls_auth_name);
|
||||
if(!sq->tls_auth_name) {
|
||||
free(sq->zone);
|
||||
free(sq->qbuf);
|
||||
free(sq);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
sq->tls_auth_name = NULL;
|
||||
}
|
||||
memcpy(&sq->addr, addr, addrlen);
|
||||
sq->addrlen = addrlen;
|
||||
sq->opt_list = NULL;
|
||||
if(opt_list) {
|
||||
sq->opt_list = edns_opt_copy_alloc(opt_list);
|
||||
if(!sq->opt_list) {
|
||||
free(sq->tls_auth_name);
|
||||
free(sq->zone);
|
||||
free(sq->qbuf);
|
||||
free(sq);
|
||||
@ -2055,7 +2083,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
||||
struct serviced_query*
|
||||
outnet_serviced_query(struct outside_network* outnet,
|
||||
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
|
||||
int nocaps, int tcp_upstream, int ssl_upstream,
|
||||
int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* qstate,
|
||||
comm_point_callback_type* callback, void* callback_arg, sldns_buffer* buff,
|
||||
@ -2078,8 +2106,9 @@ outnet_serviced_query(struct outside_network* outnet,
|
||||
if(!sq) {
|
||||
/* make new serviced query entry */
|
||||
sq = serviced_create(outnet, buff, dnssec, want_dnssec, nocaps,
|
||||
tcp_upstream, ssl_upstream, addr, addrlen, zone,
|
||||
zonelen, (int)qinfo->qtype, qstate->edns_opts_back_out);
|
||||
tcp_upstream, ssl_upstream, tls_auth_name, addr,
|
||||
addrlen, zone, zonelen, (int)qinfo->qtype,
|
||||
qstate->edns_opts_back_out);
|
||||
if(!sq) {
|
||||
free(cb);
|
||||
return NULL;
|
||||
|
@ -290,6 +290,8 @@ struct waiting_tcp {
|
||||
void* cb_arg;
|
||||
/** if it uses ssl upstream */
|
||||
int ssl_upstream;
|
||||
/** ref to the tls_auth_name from the serviced_query */
|
||||
char* tls_auth_name;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -332,6 +334,9 @@ struct serviced_query {
|
||||
int nocaps;
|
||||
/** tcp upstream used, use tcp, or ssl_upstream for SSL */
|
||||
int tcp_upstream, ssl_upstream;
|
||||
/** the name of the tls authentication name, eg. 'ns.example.com'
|
||||
* or NULL */
|
||||
char* tls_auth_name;
|
||||
/** where to send it */
|
||||
struct sockaddr_storage addr;
|
||||
/** length of addr field in use. */
|
||||
@ -484,6 +489,8 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
|
||||
* @param nocaps: ignore use_caps_for_id and use unperturbed qname.
|
||||
* @param tcp_upstream: use TCP for upstream queries.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param tls_auth_name: when ssl_upstream is true, use this name to check
|
||||
* the server's peer certificate.
|
||||
* @param addr: to which server to send the query.
|
||||
* @param addrlen: length of addr.
|
||||
* @param zone: name of the zone of the delegation point. wireformat dname.
|
||||
@ -501,7 +508,7 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
|
||||
*/
|
||||
struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
|
||||
int nocaps, int tcp_upstream, int ssl_upstream,
|
||||
int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* qstate,
|
||||
comm_point_callback_type* callback, void* callback_arg,
|
||||
|
@ -89,6 +89,14 @@ sldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
|
||||
return 256;
|
||||
case LDNS_ECDSAP384SHA384:
|
||||
return 384;
|
||||
#endif
|
||||
#ifdef USE_ED25519
|
||||
case LDNS_ED25519:
|
||||
return 256;
|
||||
#endif
|
||||
#ifdef USE_ED448
|
||||
case LDNS_ED448:
|
||||
return 456;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
@ -409,6 +417,27 @@ sldns_ed255192pkey_raw(const unsigned char* key, size_t keylen)
|
||||
}
|
||||
#endif /* USE_ED25519 */
|
||||
|
||||
#ifdef USE_ED448
|
||||
EVP_PKEY*
|
||||
sldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
|
||||
{
|
||||
/* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
|
||||
uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
|
||||
0x71, 0x03, 0x3a, 0x00};
|
||||
int pre_len = 12;
|
||||
uint8_t buf[256];
|
||||
EVP_PKEY *evp_key;
|
||||
/* pp gets modified by d2i() */
|
||||
const unsigned char* pp = (unsigned char*)buf;
|
||||
if(keylen != 57 || keylen + pre_len > sizeof(buf))
|
||||
return NULL; /* wrong length */
|
||||
memmove(buf, pre, pre_len);
|
||||
memmove(buf+pre_len, key, keylen);
|
||||
evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
|
||||
return evp_key;
|
||||
}
|
||||
#endif /* USE_ED448 */
|
||||
|
||||
int
|
||||
sldns_digest_evp(unsigned char* data, unsigned int len, unsigned char* dest,
|
||||
const EVP_MD* md)
|
||||
|
@ -101,6 +101,15 @@ RSA *sldns_key_buf2rsa_raw(unsigned char* key, size_t len);
|
||||
*/
|
||||
EVP_PKEY* sldns_ed255192pkey_raw(const unsigned char* key, size_t len);
|
||||
|
||||
/**
|
||||
* Converts a holding buffer with key material to EVP PKEY in openssl.
|
||||
* Only available if ldns was compiled with ED448.
|
||||
* \param[in] key the uncompressed wireformat of the key.
|
||||
* \param[in] len length of key data
|
||||
* \return the key or NULL on error.
|
||||
*/
|
||||
EVP_PKEY* sldns_ed4482pkey_raw(const unsigned char* key, size_t len);
|
||||
|
||||
/**
|
||||
* Utility function to calculate hash using generic EVP_MD pointer.
|
||||
* \param[in] data the data to hash.
|
||||
|
@ -1225,6 +1225,17 @@ int sldns_str2wire_b32_ext_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
||||
/** see if the string ends, or ends in whitespace */
|
||||
static int
|
||||
sldns_is_last_of_string(const char* str)
|
||||
{
|
||||
if(*str == 0) return 1;
|
||||
while(isspace((unsigned char)*str))
|
||||
str++;
|
||||
if(*str == 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sldns_str2wire_hex_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
{
|
||||
const char* s = str;
|
||||
@ -1234,7 +1245,7 @@ int sldns_str2wire_hex_buf(const char* str, uint8_t* rd, size_t* len)
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
if(dlen == 0 && *s == '0' && *(s+1) == 0) {
|
||||
if(dlen == 0 && *s == '0' && sldns_is_last_of_string(s+1)) {
|
||||
*len = 0;
|
||||
return LDNS_WIREPARSE_ERR_OK;
|
||||
}
|
||||
|
@ -142,6 +142,7 @@ usage(void)
|
||||
printf(" ratelimit_list [+a] list ratelimited domains\n");
|
||||
printf(" ip_ratelimit_list [+a] list ratelimited ip addresses\n");
|
||||
printf(" +a list all, also not ratelimited\n");
|
||||
printf(" list_auth_zones list auth zones\n");
|
||||
printf(" view_list_local_zones view list local-zones in view\n");
|
||||
printf(" view_list_local_data view list local-data RRs in view\n");
|
||||
printf(" view_local_zone view name type add local-zone in view\n");
|
||||
@ -349,6 +350,8 @@ static void print_extended(struct ub_stats_info* s)
|
||||
PR_UL("num.answer.secure", s->svr.ans_secure);
|
||||
PR_UL("num.answer.bogus", s->svr.ans_bogus);
|
||||
PR_UL("num.rrset.bogus", s->svr.rrset_bogus);
|
||||
PR_UL("num.query.aggressive.NOERROR", s->svr.num_neg_cache_noerror);
|
||||
PR_UL("num.query.aggressive.NXDOMAIN", s->svr.num_neg_cache_nxdomain);
|
||||
/* threat detection */
|
||||
PR_UL("unwanted.queries", s->svr.unwanted_queries);
|
||||
PR_UL("unwanted.replies", s->svr.unwanted_replies);
|
||||
@ -366,6 +369,8 @@ static void print_extended(struct ub_stats_info* s)
|
||||
PR_UL("num.query.dnscrypt.replay",
|
||||
s->svr.num_query_dnscrypt_replay);
|
||||
#endif /* USE_DNSCRYPT */
|
||||
PR_UL("num.query.authzone.up", s->svr.num_query_authzone_up);
|
||||
PR_UL("num.query.authzone.down", s->svr.num_query_authzone_down);
|
||||
}
|
||||
|
||||
/** print statistics out of memory structures */
|
||||
@ -476,10 +481,15 @@ setup_ctx(struct config_file* cfg)
|
||||
free(c_cert);
|
||||
} else {
|
||||
/* Use ciphers that don't require authentication */
|
||||
#if defined(SSL_OP_NO_TLSv1_3)
|
||||
/* in openssl 1.1.1, negotiation code for tls 1.3 does
|
||||
* not allow the unauthenticated aNULL and eNULL ciphers */
|
||||
SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3);
|
||||
#endif
|
||||
#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
|
||||
SSL_CTX_set_security_level(ctx, 0);
|
||||
#endif
|
||||
if(!SSL_CTX_set_cipher_list(ctx, "aNULL, eNULL"))
|
||||
if(!SSL_CTX_set_cipher_list(ctx, "aNULL:eNULL"))
|
||||
ssl_err("Error setting NULL cipher!");
|
||||
}
|
||||
return ctx;
|
||||
|
@ -105,7 +105,7 @@ struct outbound_entry* worker_send_query(
|
||||
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
|
||||
struct module_qstate* ATTR_UNUSED(q))
|
||||
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
@ -137,7 +137,7 @@ struct outbound_entry* libworker_send_query(
|
||||
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream),
|
||||
struct module_qstate* ATTR_UNUSED(q))
|
||||
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
|
@ -106,7 +106,7 @@ config_create(void)
|
||||
cfg->outgoing_tcp_mss = 0;
|
||||
cfg->ssl_service_key = NULL;
|
||||
cfg->ssl_service_pem = NULL;
|
||||
cfg->ssl_port = 853;
|
||||
cfg->ssl_port = UNBOUND_DNS_OVER_TLS_PORT;
|
||||
cfg->ssl_upstream = 0;
|
||||
cfg->tls_cert_bundle = NULL;
|
||||
cfg->use_syslog = 1;
|
||||
@ -161,6 +161,8 @@ config_create(void)
|
||||
if(!(cfg->logfile = strdup(""))) goto error_exit;
|
||||
if(!(cfg->pidfile = strdup(PIDFILE))) goto error_exit;
|
||||
if(!(cfg->target_fetch_policy = strdup("3 2 1 0 0"))) goto error_exit;
|
||||
cfg->low_rtt_pct = 0;
|
||||
cfg->low_rtt = 45;
|
||||
cfg->donotqueryaddrs = NULL;
|
||||
cfg->donotquery_localhost = 1;
|
||||
cfg->root_hints = NULL;
|
||||
@ -211,6 +213,7 @@ config_create(void)
|
||||
cfg->trust_anchor_list = NULL;
|
||||
cfg->trusted_keys_file_list = NULL;
|
||||
cfg->trust_anchor_signaling = 1;
|
||||
cfg->root_key_sentinel = 1;
|
||||
cfg->dlv_anchor_file = NULL;
|
||||
cfg->dlv_anchor_list = NULL;
|
||||
cfg->domain_insecure = NULL;
|
||||
@ -386,6 +389,12 @@ struct config_file* config_create_forlib(void)
|
||||
int config_set_option(struct config_file* cfg, const char* opt,
|
||||
const char* val)
|
||||
{
|
||||
char buf[64];
|
||||
if(!opt) return 0;
|
||||
if(opt[strlen(opt)-1] != ':' && strlen(opt)+2<sizeof(buf)) {
|
||||
snprintf(buf, sizeof(buf), "%s:", opt);
|
||||
opt = buf;
|
||||
}
|
||||
S_NUMBER_OR_ZERO("verbosity:", verbosity)
|
||||
else if(strcmp(opt, "statistics-interval:") == 0) {
|
||||
if(strcmp(val, "0") == 0 || strcmp(val, "") == 0)
|
||||
@ -446,6 +455,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_STR("ssl-service-pem:", ssl_service_pem)
|
||||
else S_NUMBER_NONZERO("ssl-port:", ssl_port)
|
||||
else S_STR("tls-cert-bundle:", tls_cert_bundle)
|
||||
else S_STRLIST("additional-tls-port:", additional_tls_port)
|
||||
else S_YNO("interface-automatic:", if_automatic)
|
||||
else S_YNO("use-systemd:", use_systemd)
|
||||
else S_YNO("do-daemonize:", do_daemonize)
|
||||
@ -500,7 +510,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_YNO("harden-below-nxdomain:", harden_below_nxdomain)
|
||||
else S_YNO("harden-referral-path:", harden_referral_path)
|
||||
else S_YNO("harden-algo-downgrade:", harden_algo_downgrade)
|
||||
else S_YNO("use-caps-for-id", use_caps_bits_for_id)
|
||||
else S_YNO("use-caps-for-id:", use_caps_bits_for_id)
|
||||
else S_STRLIST("caps-whitelist:", caps_whitelist)
|
||||
else S_SIZET_OR_ZERO("unwanted-reply-threshold:", unwanted_threshold)
|
||||
else S_STRLIST("private-address:", private_address)
|
||||
@ -512,6 +522,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_STRLIST("trust-anchor:", trust_anchor_list)
|
||||
else S_STRLIST("trusted-keys-file:", trusted_keys_file_list)
|
||||
else S_YNO("trust-anchor-signaling:", trust_anchor_signaling)
|
||||
else S_YNO("root-key-sentinel:", root_key_sentinel)
|
||||
else S_STR("dlv-anchor-file:", dlv_anchor_file)
|
||||
else S_STRLIST("dlv-anchor:", dlv_anchor_list)
|
||||
else S_STRLIST("domain-insecure:", domain_insecure)
|
||||
@ -606,6 +617,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_POW2("ratelimit-slabs:", ratelimit_slabs)
|
||||
else S_NUMBER_OR_ZERO("ip-ratelimit-factor:", ip_ratelimit_factor)
|
||||
else S_NUMBER_OR_ZERO("ratelimit-factor:", ratelimit_factor)
|
||||
else S_NUMBER_OR_ZERO("low-rtt:", low_rtt)
|
||||
else S_NUMBER_OR_ZERO("low-rtt-pct:", low_rtt_pct)
|
||||
else S_YNO("qname-minimisation:", qname_minimisation)
|
||||
else S_YNO("qname-minimisation-strict:", qname_minimisation_strict)
|
||||
#ifdef USE_IPSECMOD
|
||||
@ -800,8 +813,13 @@ int
|
||||
config_get_option(struct config_file* cfg, const char* opt,
|
||||
void (*func)(char*,void*), void* arg)
|
||||
{
|
||||
char buf[1024];
|
||||
char buf[1024], nopt[64];
|
||||
size_t len = sizeof(buf);
|
||||
if(opt && opt[strlen(opt)-1] == ':' && strlen(opt)<sizeof(nopt)) {
|
||||
memmove(nopt, opt, strlen(opt));
|
||||
nopt[strlen(opt)-1] = 0;
|
||||
opt = nopt;
|
||||
}
|
||||
fptr_ok(fptr_whitelist_print_func(func));
|
||||
O_DEC(opt, "verbosity", verbosity)
|
||||
else O_DEC(opt, "statistics-interval", stat_interval)
|
||||
@ -856,6 +874,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_STR(opt, "ssl-service-pem", ssl_service_pem)
|
||||
else O_DEC(opt, "ssl-port", ssl_port)
|
||||
else O_STR(opt, "tls-cert-bundle", tls_cert_bundle)
|
||||
else O_LST(opt, "additional-tls-port", additional_tls_port)
|
||||
else O_YNO(opt, "use-systemd", use_systemd)
|
||||
else O_YNO(opt, "do-daemonize", do_daemonize)
|
||||
else O_STR(opt, "chroot", chrootdir)
|
||||
@ -888,7 +907,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_YNO(opt, "val-clean-additional", val_clean_additional)
|
||||
else O_DEC(opt, "val-log-level", val_log_level)
|
||||
else O_YNO(opt, "val-permissive-mode", val_permissive_mode)
|
||||
else O_YNO(opt, "aggressive-nsec:", aggressive_nsec)
|
||||
else O_YNO(opt, "aggressive-nsec", aggressive_nsec)
|
||||
else O_YNO(opt, "ignore-cd-flag", ignore_cd)
|
||||
else O_YNO(opt, "serve-expired", serve_expired)
|
||||
else O_STR(opt, "val-nsec3-keysize-iterations",val_nsec3_key_iterations)
|
||||
@ -915,6 +934,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_LST(opt, "trust-anchor", trust_anchor_list)
|
||||
else O_LST(opt, "trusted-keys-file", trusted_keys_file_list)
|
||||
else O_YNO(opt, "trust-anchor-signaling", trust_anchor_signaling)
|
||||
else O_YNO(opt, "root-key-sentinel", root_key_sentinel)
|
||||
else O_LST(opt, "dlv-anchor", dlv_anchor_list)
|
||||
else O_LST(opt, "control-interface", control_ifs)
|
||||
else O_LST(opt, "domain-insecure", domain_insecure)
|
||||
@ -980,6 +1000,8 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_LS2(opt, "ratelimit-below-domain", ratelimit_below_domain)
|
||||
else O_DEC(opt, "ip-ratelimit-factor", ip_ratelimit_factor)
|
||||
else O_DEC(opt, "ratelimit-factor", ratelimit_factor)
|
||||
else O_DEC(opt, "low-rtt", low_rtt)
|
||||
else O_DEC(opt, "low-rtt-pct", low_rtt_pct)
|
||||
else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min)
|
||||
else O_DEC(opt, "val-sig-skew-max", val_sig_skew_max)
|
||||
else O_YNO(opt, "qname-minimisation", qname_minimisation)
|
||||
@ -1178,6 +1200,7 @@ config_delauth(struct config_auth* p)
|
||||
free(p->name);
|
||||
config_delstrlist(p->masters);
|
||||
config_delstrlist(p->urls);
|
||||
config_delstrlist(p->allow_notify);
|
||||
free(p->zonefile);
|
||||
free(p);
|
||||
}
|
||||
@ -1274,6 +1297,7 @@ config_delete(struct config_file* cfg)
|
||||
free(cfg->ssl_service_key);
|
||||
free(cfg->ssl_service_pem);
|
||||
free(cfg->tls_cert_bundle);
|
||||
config_delstrlist(cfg->additional_tls_port);
|
||||
free(cfg->log_identity);
|
||||
config_del_strarray(cfg->ifs, cfg->num_ifs);
|
||||
config_del_strarray(cfg->out_ifs, cfg->num_out_ifs);
|
||||
|
@ -102,6 +102,8 @@ struct config_file {
|
||||
int ssl_upstream;
|
||||
/** cert bundle for outgoing connections */
|
||||
char* tls_cert_bundle;
|
||||
/** additional tls ports */
|
||||
struct config_strlist* additional_tls_port;
|
||||
|
||||
/** outgoing port range number of ports (per thread) */
|
||||
int outgoing_num_ports;
|
||||
@ -141,6 +143,10 @@ struct config_file {
|
||||
|
||||
/** the target fetch policy for the iterator */
|
||||
char* target_fetch_policy;
|
||||
/** percent*10, how many times in 1000 to pick low rtt destinations */
|
||||
int low_rtt_pct;
|
||||
/** what time in msec is a low rtt destination */
|
||||
int low_rtt;
|
||||
|
||||
/** automatic interface for incoming messages. Uses ipv6 remapping,
|
||||
* and recvmsg/sendmsg ancillary data to detect interfaces, boolean */
|
||||
@ -285,6 +291,8 @@ struct config_file {
|
||||
struct config_strlist* domain_insecure;
|
||||
/** send key tag query */
|
||||
int trust_anchor_signaling;
|
||||
/** enable root key sentinel */
|
||||
int root_key_sentinel;
|
||||
|
||||
/** if not 0, this value is the validation date for RRSIGs */
|
||||
int32_t val_date_override;
|
||||
@ -507,6 +515,14 @@ struct config_file {
|
||||
char* cachedb_backend;
|
||||
/** secret seed for hash key calculation */
|
||||
char* cachedb_secret;
|
||||
#ifdef USE_REDIS
|
||||
/** redis server's IP address or host name */
|
||||
char* redis_server_host;
|
||||
/** redis server's TCP port */
|
||||
int redis_server_port;
|
||||
/** timeout (in ms) for communication with the redis server */
|
||||
int redis_timeout;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -549,6 +565,8 @@ struct config_auth {
|
||||
struct config_strlist* masters;
|
||||
/** list of urls */
|
||||
struct config_strlist* urls;
|
||||
/** list of allow-notify */
|
||||
struct config_strlist* allow_notify;
|
||||
/** zonefile (or NULL) */
|
||||
char* zonefile;
|
||||
/** provide downstream answers */
|
||||
|
@ -239,6 +239,8 @@ ssl-port{COLON} { YDVAR(1, VAR_SSL_PORT) }
|
||||
tls-port{COLON} { YDVAR(1, VAR_SSL_PORT) }
|
||||
ssl-cert-bundle{COLON} { YDVAR(1, VAR_TLS_CERT_BUNDLE) }
|
||||
tls-cert-bundle{COLON} { YDVAR(1, VAR_TLS_CERT_BUNDLE) }
|
||||
additional-ssl-port{COLON} { YDVAR(1, VAR_ADDITIONAL_TLS_PORT) }
|
||||
additional-tls-port{COLON} { YDVAR(1, VAR_ADDITIONAL_TLS_PORT) }
|
||||
use-systemd{COLON} { YDVAR(1, VAR_USE_SYSTEMD) }
|
||||
do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) }
|
||||
interface{COLON} { YDVAR(1, VAR_INTERFACE) }
|
||||
@ -307,6 +309,7 @@ auth-zone{COLON} { YDVAR(0, VAR_AUTH_ZONE) }
|
||||
zonefile{COLON} { YDVAR(1, VAR_ZONEFILE) }
|
||||
master{COLON} { YDVAR(1, VAR_MASTER) }
|
||||
url{COLON} { YDVAR(1, VAR_URL) }
|
||||
allow-notify{COLON} { YDVAR(1, VAR_ALLOW_NOTIFY) }
|
||||
for-downstream{COLON} { YDVAR(1, VAR_FOR_DOWNSTREAM) }
|
||||
for-upstream{COLON} { YDVAR(1, VAR_FOR_UPSTREAM) }
|
||||
fallback-enabled{COLON} { YDVAR(1, VAR_FALLBACK_ENABLED) }
|
||||
@ -334,6 +337,7 @@ auto-trust-anchor-file{COLON} { YDVAR(1, VAR_AUTO_TRUST_ANCHOR_FILE) }
|
||||
trusted-keys-file{COLON} { YDVAR(1, VAR_TRUSTED_KEYS_FILE) }
|
||||
trust-anchor{COLON} { YDVAR(1, VAR_TRUST_ANCHOR) }
|
||||
trust-anchor-signaling{COLON} { YDVAR(1, VAR_TRUST_ANCHOR_SIGNALING) }
|
||||
root-key-sentinel{COLON} { YDVAR(1, VAR_ROOT_KEY_SENTINEL) }
|
||||
val-override-date{COLON} { YDVAR(1, VAR_VAL_OVERRIDE_DATE) }
|
||||
val-sig-skew-min{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MIN) }
|
||||
val-sig-skew-max{COLON} { YDVAR(1, VAR_VAL_SIG_SKEW_MAX) }
|
||||
@ -424,6 +428,8 @@ ratelimit-for-domain{COLON} { YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) }
|
||||
ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) }
|
||||
ip-ratelimit-factor{COLON} { YDVAR(1, VAR_IP_RATELIMIT_FACTOR) }
|
||||
ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) }
|
||||
low-rtt{COLON} { YDVAR(1, VAR_LOW_RTT) }
|
||||
low-rtt-pct{COLON} { YDVAR(1, VAR_LOW_RTT_PCT) }
|
||||
response-ip-tag{COLON} { YDVAR(2, VAR_RESPONSE_IP_TAG) }
|
||||
response-ip{COLON} { YDVAR(2, VAR_RESPONSE_IP) }
|
||||
response-ip-data{COLON} { YDVAR(2, VAR_RESPONSE_IP_DATA) }
|
||||
@ -449,6 +455,9 @@ ipsecmod-strict{COLON} { YDVAR(1, VAR_IPSECMOD_STRICT) }
|
||||
cachedb{COLON} { YDVAR(0, VAR_CACHEDB) }
|
||||
backend{COLON} { YDVAR(1, VAR_CACHEDB_BACKEND) }
|
||||
secret-seed{COLON} { YDVAR(1, VAR_CACHEDB_SECRETSEED) }
|
||||
redis-server-host{COLON} { YDVAR(1, VAR_CACHEDB_REDISHOST) }
|
||||
redis-server-port{COLON} { YDVAR(1, VAR_CACHEDB_REDISPORT) }
|
||||
redis-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) }
|
||||
udp-upstream-without-downstream{COLON} { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) }
|
||||
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
|
||||
|
||||
|
@ -142,6 +142,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_FAKE_DSA VAR_FAKE_SHA1
|
||||
%token VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR VAR_TRUST_ANCHOR_SIGNALING
|
||||
%token VAR_AGGRESSIVE_NSEC VAR_USE_SYSTEMD VAR_SHM_ENABLE VAR_SHM_KEY
|
||||
%token VAR_ROOT_KEY_SENTINEL
|
||||
%token VAR_DNSCRYPT VAR_DNSCRYPT_ENABLE VAR_DNSCRYPT_PORT VAR_DNSCRYPT_PROVIDER
|
||||
%token VAR_DNSCRYPT_SECRET_KEY VAR_DNSCRYPT_PROVIDER_CERT
|
||||
%token VAR_DNSCRYPT_PROVIDER_CERT_ROTATED
|
||||
@ -152,9 +153,11 @@ extern struct config_parser_state* cfg_parser;
|
||||
%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
|
||||
%token VAR_CACHEDB_REDISHOST VAR_CACHEDB_REDISPORT VAR_CACHEDB_REDISTIMEOUT
|
||||
%token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM
|
||||
%token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM
|
||||
%token VAR_FALLBACK_ENABLED
|
||||
%token VAR_FALLBACK_ENABLED VAR_ADDITIONAL_TLS_PORT VAR_LOW_RTT VAR_LOW_RTT_PCT
|
||||
%token VAR_ALLOW_NOTIFY
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
@ -240,11 +243,13 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_response_ip_tag | server_response_ip | server_response_ip_data |
|
||||
server_shm_enable | server_shm_key | server_fake_sha1 |
|
||||
server_hide_trustanchor | server_trust_anchor_signaling |
|
||||
server_root_key_sentinel |
|
||||
server_ipsecmod_enabled | server_ipsecmod_hook |
|
||||
server_ipsecmod_ignore_bogus | server_ipsecmod_max_ttl |
|
||||
server_ipsecmod_whitelist | server_ipsecmod_strict |
|
||||
server_udp_upstream_without_downstream | server_aggressive_nsec |
|
||||
server_tls_cert_bundle
|
||||
server_tls_cert_bundle | server_additional_tls_port | server_low_rtt |
|
||||
server_low_rtt_pct
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
{
|
||||
@ -318,7 +323,8 @@ authstart: VAR_AUTH_ZONE
|
||||
contents_auth: contents_auth content_auth
|
||||
| ;
|
||||
content_auth: auth_name | auth_zonefile | auth_master | auth_url |
|
||||
auth_for_downstream | auth_for_upstream | auth_fallback_enabled
|
||||
auth_for_downstream | auth_for_upstream | auth_fallback_enabled |
|
||||
auth_allow_notify
|
||||
;
|
||||
server_num_threads: VAR_NUM_THREADS STRING_ARG
|
||||
{
|
||||
@ -682,6 +688,14 @@ server_tls_cert_bundle: VAR_TLS_CERT_BUNDLE STRING_ARG
|
||||
cfg_parser->cfg->tls_cert_bundle = $2;
|
||||
}
|
||||
;
|
||||
server_additional_tls_port: VAR_ADDITIONAL_TLS_PORT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_additional_tls_port:%s)\n", $2));
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->additional_tls_port,
|
||||
$2))
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
server_use_systemd: VAR_USE_SYSTEMD STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_use_systemd:%s)\n", $2));
|
||||
@ -859,6 +873,17 @@ server_trust_anchor_signaling: VAR_TRUST_ANCHOR_SIGNALING STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_root_key_sentinel: VAR_ROOT_KEY_SENTINEL STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_root_key_sentinel:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else
|
||||
cfg_parser->cfg->root_key_sentinel =
|
||||
(strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_domain_insecure: VAR_DOMAIN_INSECURE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_domain_insecure:%s)\n", $2));
|
||||
@ -1851,6 +1876,24 @@ server_ratelimit_factor: VAR_RATELIMIT_FACTOR STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_low_rtt: VAR_LOW_RTT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_low_rtt:%s)\n", $2));
|
||||
if(atoi($2) == 0 && strcmp($2, "0") != 0)
|
||||
yyerror("number expected");
|
||||
else cfg_parser->cfg->low_rtt = atoi($2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_low_rtt_pct: VAR_LOW_RTT_PCT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_low_rtt_pct:%s)\n", $2));
|
||||
if(atoi($2) == 0 && strcmp($2, "0") != 0)
|
||||
yyerror("number expected");
|
||||
else cfg_parser->cfg->low_rtt_pct = atoi($2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_qname_minimisation: VAR_QNAME_MINIMISATION STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_qname_minimisation:%s)\n", $2));
|
||||
@ -2072,6 +2115,14 @@ auth_url: VAR_URL STRING_ARG
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
auth_allow_notify: VAR_ALLOW_NOTIFY STRING_ARG
|
||||
{
|
||||
OUTYY(("P(allow-notify:%s)\n", $2));
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->auths->allow_notify,
|
||||
$2))
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
auth_for_downstream: VAR_FOR_DOWNSTREAM STRING_ARG
|
||||
{
|
||||
OUTYY(("P(for-downstream:%s)\n", $2));
|
||||
@ -2551,7 +2602,8 @@ cachedbstart: VAR_CACHEDB
|
||||
;
|
||||
contents_cachedb: contents_cachedb content_cachedb
|
||||
| ;
|
||||
content_cachedb: cachedb_backend_name | cachedb_secret_seed
|
||||
content_cachedb: cachedb_backend_name | cachedb_secret_seed |
|
||||
redis_server_host | redis_server_port | redis_timeout
|
||||
;
|
||||
cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG
|
||||
{
|
||||
@ -2582,6 +2634,46 @@ cachedb_secret_seed: VAR_CACHEDB_SECRETSEED STRING_ARG
|
||||
#endif
|
||||
}
|
||||
;
|
||||
redis_server_host: VAR_CACHEDB_REDISHOST STRING_ARG
|
||||
{
|
||||
#if defined(USE_CACHEDB) && defined(USE_REDIS)
|
||||
OUTYY(("P(redis_server_host:%s)\n", $2));
|
||||
free(cfg_parser->cfg->redis_server_host);
|
||||
cfg_parser->cfg->redis_server_host = $2;
|
||||
#else
|
||||
OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
|
||||
free($2);
|
||||
#endif
|
||||
}
|
||||
;
|
||||
redis_server_port: VAR_CACHEDB_REDISPORT STRING_ARG
|
||||
{
|
||||
#if defined(USE_CACHEDB) && defined(USE_REDIS)
|
||||
int port;
|
||||
OUTYY(("P(redis_server_port:%s)\n", $2));
|
||||
port = atoi($2);
|
||||
if(port == 0 || port < 0 || port > 65535)
|
||||
yyerror("valid redis server port number expected");
|
||||
else cfg_parser->cfg->redis_server_port = port;
|
||||
#else
|
||||
OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
|
||||
#endif
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
redis_timeout: VAR_CACHEDB_REDISTIMEOUT STRING_ARG
|
||||
{
|
||||
#if defined(USE_CACHEDB) && defined(USE_REDIS)
|
||||
OUTYY(("P(redis_timeout:%s)\n", $2));
|
||||
if(atoi($2) == 0)
|
||||
yyerror("redis timeout value expected");
|
||||
else cfg_parser->cfg->redis_timeout = atoi($2);
|
||||
#else
|
||||
OUTYY(("P(Compiled without cachedb or redis, ignoring)\n"));
|
||||
#endif
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
%%
|
||||
|
||||
/* parse helper routines could be here */
|
||||
|
@ -523,6 +523,29 @@ dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs)
|
||||
return lastdiff;
|
||||
}
|
||||
|
||||
int
|
||||
dname_lab_startswith(uint8_t* label, char* prefix, char** endptr)
|
||||
{
|
||||
size_t plen = strlen(prefix);
|
||||
size_t orig_plen = plen;
|
||||
size_t lablen = (size_t)*label;
|
||||
if(plen > lablen)
|
||||
return 0;
|
||||
label++;
|
||||
while(plen--) {
|
||||
if(*prefix != tolower((unsigned char)*label)) {
|
||||
return 0;
|
||||
}
|
||||
prefix++; label++;
|
||||
}
|
||||
if(orig_plen < lablen)
|
||||
*endptr = (char *)label;
|
||||
else
|
||||
/* prefix length == label length */
|
||||
*endptr = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
dname_buffer_write(sldns_buffer* pkt, uint8_t* dname)
|
||||
{
|
||||
|
@ -185,6 +185,17 @@ int dname_count_size_labels(uint8_t* dname, size_t* size);
|
||||
*/
|
||||
int dname_lab_cmp(uint8_t* d1, int labs1, uint8_t* d2, int labs2, int* mlabs);
|
||||
|
||||
/**
|
||||
* Check if labels starts with given prefix
|
||||
* @param label: dname label
|
||||
* @param prefix: the string to match label with, null terminated.
|
||||
* @param endptr: pointer to location in label after prefix, only if return
|
||||
* value is 1. NULL if nothing in the label after the prefix, i.e. prefix
|
||||
* and label are the same.
|
||||
* @return: 1 if label starts with prefix, else 0
|
||||
*/
|
||||
int dname_lab_startswith(uint8_t* label, char* prefix, char** endptr);
|
||||
|
||||
/**
|
||||
* See if domain name d1 is a strict subdomain of d2.
|
||||
* That is a subdomain, but not equal.
|
||||
|
@ -1028,6 +1028,32 @@ parse_extract_edns(struct msg_parse* msg, struct edns_data* edns,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** skip RR in packet */
|
||||
static int
|
||||
skip_pkt_rr(sldns_buffer* pkt)
|
||||
{
|
||||
if(sldns_buffer_remaining(pkt) < 1) return 0;
|
||||
if(!pkt_dname_len(pkt))
|
||||
return 0;
|
||||
if(sldns_buffer_remaining(pkt) < 4) return 0;
|
||||
sldns_buffer_skip(pkt, 4); /* type and class */
|
||||
if(!skip_ttl_rdata(pkt))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** skip RRs from packet */
|
||||
static int
|
||||
skip_pkt_rrs(sldns_buffer* pkt, int num)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<num; i++) {
|
||||
if(!skip_pkt_rr(pkt))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
parse_edns_from_pkt(sldns_buffer* pkt, struct edns_data* edns,
|
||||
struct regional* region)
|
||||
@ -1035,8 +1061,12 @@ parse_edns_from_pkt(sldns_buffer* pkt, struct edns_data* edns,
|
||||
size_t rdata_len;
|
||||
uint8_t* rdata_ptr;
|
||||
log_assert(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) == 1);
|
||||
log_assert(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) == 0);
|
||||
log_assert(LDNS_NSCOUNT(sldns_buffer_begin(pkt)) == 0);
|
||||
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) != 0 ||
|
||||
LDNS_NSCOUNT(sldns_buffer_begin(pkt)) != 0) {
|
||||
if(!skip_pkt_rrs(pkt, ((int)LDNS_ANCOUNT(sldns_buffer_begin(pkt)))+
|
||||
((int)LDNS_NSCOUNT(sldns_buffer_begin(pkt)))))
|
||||
return 0;
|
||||
}
|
||||
/* check edns section is present */
|
||||
if(LDNS_ARCOUNT(sldns_buffer_begin(pkt)) > 1) {
|
||||
return LDNS_RCODE_FORMERR;
|
||||
|
@ -534,8 +534,9 @@ query_info_parse(struct query_info* m, sldns_buffer* query)
|
||||
/* minimum size: header + \0 + qtype + qclass */
|
||||
if(sldns_buffer_limit(query) < LDNS_HEADER_SIZE + 5)
|
||||
return 0;
|
||||
if(LDNS_OPCODE_WIRE(q) != LDNS_PACKET_QUERY ||
|
||||
LDNS_QDCOUNT(q) != 1 || sldns_buffer_position(query) != 0)
|
||||
if((LDNS_OPCODE_WIRE(q) != LDNS_PACKET_QUERY && LDNS_OPCODE_WIRE(q) !=
|
||||
LDNS_PACKET_NOTIFY) || LDNS_QDCOUNT(q) != 1 ||
|
||||
sldns_buffer_position(query) != 0)
|
||||
return 0;
|
||||
sldns_buffer_skip(query, LDNS_HEADER_SIZE);
|
||||
m->qname = sldns_buffer_current(query);
|
||||
|
@ -253,6 +253,7 @@ sec_status_to_string(enum sec_status s)
|
||||
case sec_status_bogus: return "sec_status_bogus";
|
||||
case sec_status_indeterminate: return "sec_status_indeterminate";
|
||||
case sec_status_insecure: return "sec_status_insecure";
|
||||
case sec_status_secure_sentinel_fail: return "sec_status_secure_sentinel_fail";
|
||||
case sec_status_secure: return "sec_status_secure";
|
||||
}
|
||||
return "unknown_sec_status_value";
|
||||
|
@ -187,6 +187,10 @@ enum sec_status {
|
||||
* insecure. Generally this means that this RRset is below a trust
|
||||
* anchor, but also below a verified, insecure delegation. */
|
||||
sec_status_insecure,
|
||||
/** SECURE_SENTINEL_FAIL means that the object (RRset or message)
|
||||
* validated according to local policy but did not succeed in the root
|
||||
* KSK sentinel test (draft-ietf-dnsop-kskroll-sentinel). */
|
||||
sec_status_secure_sentinel_fail,
|
||||
/** SECURE means that the object (RRset or message) validated
|
||||
* according to local policy. */
|
||||
sec_status_secure
|
||||
|
@ -311,7 +311,8 @@ int
|
||||
fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
|
||||
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
|
||||
int nocaps, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, int ssl_upstream, struct module_qstate* q))
|
||||
uint8_t* zone, size_t zonelen, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q))
|
||||
{
|
||||
if(fptr == &worker_send_query) return 1;
|
||||
else if(fptr == &libworker_send_query) return 1;
|
||||
|
@ -212,7 +212,8 @@ int fptr_whitelist_hash_markdelfunc(lruhash_markdelfunc_type fptr);
|
||||
int fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
|
||||
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
|
||||
int nocaps, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, int ssl_upstream, struct module_qstate* q));
|
||||
uint8_t* zone, size_t zonelen, int ssl_upstream, char* tls_auth_name,
|
||||
struct module_qstate* q));
|
||||
|
||||
/**
|
||||
* Check function pointer whitelist for module_env detach_subs callback values.
|
||||
|
@ -4890,6 +4890,7 @@
|
||||
9006,
|
||||
9007,
|
||||
9009,
|
||||
9011,
|
||||
9020,
|
||||
9021,
|
||||
9022,
|
||||
|
@ -338,6 +338,8 @@ struct module_env {
|
||||
* @param zone: delegation point name.
|
||||
* @param zonelen: length of zone name.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param tls_auth_name: if ssl_upstream, use this name with TLS
|
||||
* authentication.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent. Or returns an outbound entry with qsent and qstate set.
|
||||
@ -348,7 +350,7 @@ struct module_env {
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, int ssl_upstream,
|
||||
struct module_qstate* q);
|
||||
char* tls_auth_name, struct module_qstate* q);
|
||||
|
||||
/**
|
||||
* Detach-subqueries.
|
||||
|
@ -241,7 +241,8 @@ ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
|
||||
int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
|
||||
socklen_t* addrlen, int* net)
|
||||
{
|
||||
char* s = NULL;
|
||||
char buf[64];
|
||||
char* s;
|
||||
*net = (str_is_ip6(str)?128:32);
|
||||
if((s=strchr(str, '/'))) {
|
||||
if(atoi(s+1) > *net) {
|
||||
@ -253,24 +254,65 @@ int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
|
||||
log_err("cannot parse netblock: '%s'", str);
|
||||
return 0;
|
||||
}
|
||||
if(!(s = strdup(str))) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
*strchr(s, '/') = '\0';
|
||||
strlcpy(buf, str, sizeof(buf));
|
||||
s = strchr(buf, '/');
|
||||
if(s) *s = 0;
|
||||
s = buf;
|
||||
}
|
||||
if(!ipstrtoaddr(s?s:str, port, addr, addrlen)) {
|
||||
free(s);
|
||||
log_err("cannot parse ip address: '%s'", str);
|
||||
return 0;
|
||||
}
|
||||
if(s) {
|
||||
free(s);
|
||||
addr_mask(addr, *addrlen, *net);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int authextstrtoaddr(char* str, struct sockaddr_storage* addr,
|
||||
socklen_t* addrlen, char** auth_name)
|
||||
{
|
||||
char* s;
|
||||
int port = UNBOUND_DNS_PORT;
|
||||
if((s=strchr(str, '@'))) {
|
||||
char buf[MAX_ADDR_STRLEN];
|
||||
size_t len = (size_t)(s-str);
|
||||
char* hash = strchr(s+1, '#');
|
||||
if(hash) {
|
||||
*auth_name = hash+1;
|
||||
} else {
|
||||
*auth_name = NULL;
|
||||
}
|
||||
if(len >= MAX_ADDR_STRLEN) {
|
||||
return 0;
|
||||
}
|
||||
(void)strlcpy(buf, str, sizeof(buf));
|
||||
buf[len] = 0;
|
||||
port = atoi(s+1);
|
||||
if(port == 0) {
|
||||
if(!hash && strcmp(s+1,"0")!=0)
|
||||
return 0;
|
||||
if(hash && strncmp(s+1,"0#",2)!=0)
|
||||
return 0;
|
||||
}
|
||||
return ipstrtoaddr(buf, port, addr, addrlen);
|
||||
}
|
||||
if((s=strchr(str, '#'))) {
|
||||
char buf[MAX_ADDR_STRLEN];
|
||||
size_t len = (size_t)(s-str);
|
||||
if(len >= MAX_ADDR_STRLEN) {
|
||||
return 0;
|
||||
}
|
||||
(void)strlcpy(buf, str, sizeof(buf));
|
||||
buf[len] = 0;
|
||||
port = UNBOUND_DNS_OVER_TLS_PORT;
|
||||
*auth_name = s+1;
|
||||
return ipstrtoaddr(buf, port, addr, addrlen);
|
||||
}
|
||||
*auth_name = NULL;
|
||||
return ipstrtoaddr(str, port, addr, addrlen);
|
||||
}
|
||||
|
||||
/** store port number into sockaddr structure */
|
||||
void
|
||||
sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen, int port)
|
||||
|
@ -190,7 +190,7 @@ int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
|
||||
|
||||
/**
|
||||
* Convert ip netblock (ip/netsize) string and port to sockaddr.
|
||||
* *SLOW*, does a malloc internally to avoid writing over 'ip' string.
|
||||
* performs a copy internally to avoid writing over 'ip' string.
|
||||
* @param ip: ip4 or ip6 address string.
|
||||
* @param port: port number, host format.
|
||||
* @param addr: where to store sockaddr.
|
||||
@ -201,6 +201,20 @@ int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
|
||||
int netblockstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
|
||||
socklen_t* addrlen, int* net);
|
||||
|
||||
/**
|
||||
* Convert address string, with "@port" appendix, to sockaddr.
|
||||
* It can also have an "#tls-auth-name" appendix (after the port).
|
||||
* The returned tls-auth-name string is a pointer into the input string.
|
||||
* Uses DNS port by default.
|
||||
* @param str: the string
|
||||
* @param addr: where to store sockaddr.
|
||||
* @param addrlen: length of stored sockaddr is returned.
|
||||
* @param auth_name: returned pointer to tls_auth_name, or NULL if none.
|
||||
* @return 0 on error.
|
||||
*/
|
||||
int authextstrtoaddr(char* str, struct sockaddr_storage* addr,
|
||||
socklen_t* addrlen, char** auth_name);
|
||||
|
||||
/**
|
||||
* Store port number into sockaddr structure
|
||||
* @param addr: sockaddr structure, ip4 or ip6.
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "sldns/pkthdr.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/str2wire.h"
|
||||
#include "dnstap/dnstap.h"
|
||||
#include "dnscrypt/dnscrypt.h"
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
@ -1209,9 +1210,24 @@ ssl_handle_write(struct comm_point* c)
|
||||
if(c->tcp_byte_count < sizeof(uint16_t)) {
|
||||
uint16_t len = htons(sldns_buffer_limit(c->buffer));
|
||||
ERR_clear_error();
|
||||
r = SSL_write(c->ssl,
|
||||
(void*)(((uint8_t*)&len)+c->tcp_byte_count),
|
||||
(int)(sizeof(uint16_t)-c->tcp_byte_count));
|
||||
if(sizeof(uint16_t)+sldns_buffer_remaining(c->buffer) <
|
||||
LDNS_RR_BUF_SIZE) {
|
||||
/* combine the tcp length and the query for write,
|
||||
* this emulates writev */
|
||||
uint8_t buf[LDNS_RR_BUF_SIZE];
|
||||
memmove(buf, &len, sizeof(uint16_t));
|
||||
memmove(buf+sizeof(uint16_t),
|
||||
sldns_buffer_current(c->buffer),
|
||||
sldns_buffer_remaining(c->buffer));
|
||||
r = SSL_write(c->ssl, (void*)(buf+c->tcp_byte_count),
|
||||
(int)(sizeof(uint16_t)+
|
||||
sldns_buffer_remaining(c->buffer)
|
||||
- c->tcp_byte_count));
|
||||
} else {
|
||||
r = SSL_write(c->ssl,
|
||||
(void*)(((uint8_t*)&len)+c->tcp_byte_count),
|
||||
(int)(sizeof(uint16_t)-c->tcp_byte_count));
|
||||
}
|
||||
if(r <= 0) {
|
||||
int want = SSL_get_error(c->ssl, r);
|
||||
if(want == SSL_ERROR_ZERO_RETURN) {
|
||||
|
@ -454,8 +454,9 @@ int tube_setup_bg_write(struct tube* tube, struct comm_base* base)
|
||||
|
||||
int tube_queue_item(struct tube* tube, uint8_t* msg, size_t len)
|
||||
{
|
||||
struct tube_res_list* item =
|
||||
(struct tube_res_list*)malloc(sizeof(*item));
|
||||
struct tube_res_list* item;
|
||||
if(!tube || !tube->res_com) return 0;
|
||||
item = (struct tube_res_list*)malloc(sizeof(*item));
|
||||
if(!item) {
|
||||
free(msg);
|
||||
log_err("out of memory for async answer");
|
||||
@ -687,8 +688,9 @@ int tube_setup_bg_write(struct tube* ATTR_UNUSED(tube),
|
||||
|
||||
int tube_queue_item(struct tube* tube, uint8_t* msg, size_t len)
|
||||
{
|
||||
struct tube_res_list* item =
|
||||
(struct tube_res_list*)malloc(sizeof(*item));
|
||||
struct tube_res_list* item;
|
||||
if(!tube) return 0;
|
||||
item = (struct tube_res_list*)malloc(sizeof(*item));
|
||||
verbose(VERB_ALGO, "tube queue_item len %d", (int)len);
|
||||
if(!item) {
|
||||
free(msg);
|
||||
|
@ -95,6 +95,7 @@ UB_EV_BITS_CB(comm_timer_callback)
|
||||
UB_EV_BITS_CB(comm_signal_callback)
|
||||
UB_EV_BITS_CB(comm_point_local_handle_callback)
|
||||
UB_EV_BITS_CB(comm_point_raw_handle_callback)
|
||||
UB_EV_BITS_CB(comm_point_http_handle_callback)
|
||||
UB_EV_BITS_CB(tube_handle_signal)
|
||||
UB_EV_BITS_CB(comm_base_handle_slow_accept)
|
||||
|
||||
@ -116,12 +117,17 @@ static void (*NATIVE_BITS_CB(void (*cb)(int, short, void*)))(int, short, void*)
|
||||
return my_comm_point_local_handle_callback;
|
||||
else if(cb == comm_point_raw_handle_callback)
|
||||
return my_comm_point_raw_handle_callback;
|
||||
else if(cb == comm_point_http_handle_callback)
|
||||
return my_comm_point_http_handle_callback;
|
||||
else if(cb == tube_handle_signal)
|
||||
return my_tube_handle_signal;
|
||||
else if(cb == comm_base_handle_slow_accept)
|
||||
return my_comm_base_handle_slow_accept;
|
||||
else
|
||||
else {
|
||||
log_assert(0); /* this NULL callback pointer should not happen,
|
||||
we should have the necessary routine listed above */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define NATIVE_BITS(b) (b)
|
||||
|
@ -1309,3 +1309,44 @@ anchor_list_keytags(struct trust_anchor* ta, uint16_t* list, size_t num)
|
||||
qsort(list, ret, sizeof(*list), keytag_compare);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
anchor_has_keytag(struct val_anchors* anchors, uint8_t* name, int namelabs,
|
||||
size_t namelen, uint16_t dclass, uint16_t keytag)
|
||||
{
|
||||
uint16_t* taglist;
|
||||
uint16_t* tl;
|
||||
size_t numtag, i;
|
||||
struct trust_anchor* anchor = anchor_find(anchors,
|
||||
name, namelabs, namelen, dclass);
|
||||
if(!anchor)
|
||||
return 0;
|
||||
if(!anchor->numDS && !anchor->numDNSKEY) {
|
||||
lock_basic_unlock(&anchor->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
taglist = calloc(anchor->numDS + anchor->numDNSKEY, sizeof(*taglist));
|
||||
if(!taglist) {
|
||||
lock_basic_unlock(&anchor->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
numtag = anchor_list_keytags(anchor, taglist,
|
||||
anchor->numDS+anchor->numDNSKEY);
|
||||
lock_basic_unlock(&anchor->lock);
|
||||
if(!numtag) {
|
||||
free(taglist);
|
||||
return 0;
|
||||
}
|
||||
tl = taglist;
|
||||
for(i=0; i<numtag; i++) {
|
||||
if(*tl == keytag) {
|
||||
free(taglist);
|
||||
return 1;
|
||||
}
|
||||
tl++;
|
||||
}
|
||||
free(taglist);
|
||||
return 0;
|
||||
}
|
||||
|
@ -227,4 +227,19 @@ void anchors_delete_insecure(struct val_anchors* anchors, uint16_t c,
|
||||
*/
|
||||
size_t anchor_list_keytags(struct trust_anchor* ta, uint16_t* list, size_t num);
|
||||
|
||||
/**
|
||||
* Check if there is a trust anchor for given zone with this keytag.
|
||||
*
|
||||
* @param anchors: anchor storage
|
||||
* @param name: name of trust anchor (wireformat)
|
||||
* @param namelabs: labels in name
|
||||
* @param namelen: length of name
|
||||
* @param dclass: class of trust anchor
|
||||
* @param keytag: keytag
|
||||
* @return 1 if there is a trust anchor in the trustachor store for this zone
|
||||
* and keytag, else 0.
|
||||
*/
|
||||
int anchor_has_keytag(struct val_anchors* anchors, uint8_t* name, int namelabs,
|
||||
size_t namelen, uint16_t dclass, uint16_t keytag);
|
||||
|
||||
#endif /* VALIDATOR_VAL_ANCHOR_H */
|
||||
|
@ -1515,6 +1515,10 @@ val_neg_getmsg(struct val_neg_cache* neg, struct query_info* qinfo,
|
||||
return NULL;
|
||||
if(addsoa && !add_soa(rrset_cache, now, region, msg, NULL))
|
||||
return NULL;
|
||||
|
||||
lock_basic_lock(&neg->lock);
|
||||
neg->num_neg_cache_noerror++;
|
||||
lock_basic_unlock(&neg->lock);
|
||||
return msg;
|
||||
} else if(nsec && val_nsec_proves_name_error(nsec, qinfo->qname)) {
|
||||
if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len,
|
||||
@ -1578,7 +1582,7 @@ val_neg_getmsg(struct val_neg_cache* neg, struct query_info* qinfo,
|
||||
rcode = LDNS_RCODE_NXDOMAIN;
|
||||
else if(!nsec_proves_nodata(wcrr, &wc_qinfo,
|
||||
&nodata_wc) || nodata_wc)
|
||||
/* &nodata_wc shoudn't be set, wc_qinfo
|
||||
/* &nodata_wc shouldn't be set, wc_qinfo
|
||||
* already contains wildcard domain. */
|
||||
/* NSEC doesn't prove anything for
|
||||
* wildcard. */
|
||||
@ -1595,6 +1599,14 @@ val_neg_getmsg(struct val_neg_cache* neg, struct query_info* qinfo,
|
||||
if(addsoa && !add_soa(rrset_cache, now, region, msg, NULL))
|
||||
return NULL;
|
||||
|
||||
/* Increment statistic counters */
|
||||
lock_basic_lock(&neg->lock);
|
||||
if(rcode == LDNS_RCODE_NOERROR)
|
||||
neg->num_neg_cache_noerror++;
|
||||
else if(rcode == LDNS_RCODE_NXDOMAIN)
|
||||
neg->num_neg_cache_nxdomain++;
|
||||
lock_basic_unlock(&neg->lock);
|
||||
|
||||
FLAGS_SET_RCODE(msg->rep->flags, rcode);
|
||||
return msg;
|
||||
}
|
||||
|
@ -80,6 +80,12 @@ struct val_neg_cache {
|
||||
size_t max;
|
||||
/** max nsec3 iterations allowed */
|
||||
size_t nsec3_max_iter;
|
||||
/** number of times neg cache records were used to generate NOERROR
|
||||
* responses. */
|
||||
size_t num_neg_cache_noerror;
|
||||
/** number of times neg cache records were used to generate NXDOMAIN
|
||||
* responses. */
|
||||
size_t num_neg_cache_nxdomain;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -231,7 +231,10 @@ dnskey_algo_id_is_supported(int id)
|
||||
#ifdef USE_ED25519
|
||||
case LDNS_ED25519:
|
||||
#endif
|
||||
#if (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) || defined(USE_ECDSA)
|
||||
#ifdef USE_ED448
|
||||
case LDNS_ED448:
|
||||
#endif
|
||||
#if (defined(HAVE_EVP_SHA256) && defined(USE_SHA2)) || (defined(HAVE_EVP_SHA512) && defined(USE_SHA2)) || defined(USE_ECDSA) || defined(USE_ED25519) || defined(USE_ED448)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
@ -569,6 +572,17 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
|
||||
*digest_type = NULL;
|
||||
break;
|
||||
#endif /* USE_ED25519 */
|
||||
#ifdef USE_ED448
|
||||
case LDNS_ED448:
|
||||
*evp_key = sldns_ed4482pkey_raw(key, keylen);
|
||||
if(!*evp_key) {
|
||||
verbose(VERB_QUERY, "verify: "
|
||||
"sldns_ed4482pkey_raw failed");
|
||||
return 0;
|
||||
}
|
||||
*digest_type = NULL;
|
||||
break;
|
||||
#endif /* USE_ED448 */
|
||||
default:
|
||||
verbose(VERB_QUERY, "verify: unknown algorithm %d",
|
||||
algo);
|
||||
|
@ -40,6 +40,7 @@
|
||||
* According to RFC 4034.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <ctype.h>
|
||||
#include "validator/validator.h"
|
||||
#include "validator/val_anchor.h"
|
||||
#include "validator/val_kcache.h"
|
||||
@ -477,6 +478,31 @@ generate_keytag_query(struct module_qstate* qstate, int id,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get keytag as uint16_t from string
|
||||
*
|
||||
* @param start: start of string containing keytag
|
||||
* @param keytag: pointer where to store the extracted keytag
|
||||
* @return: 1 if keytag was extracted, else 0.
|
||||
*/
|
||||
static int
|
||||
sentinel_get_keytag(char* start, uint16_t* keytag) {
|
||||
char* keytag_str;
|
||||
char* e = NULL;
|
||||
keytag_str = calloc(1, SENTINEL_KEYTAG_LEN + 1 /* null byte */);
|
||||
if(!keytag_str)
|
||||
return 0;
|
||||
memmove(keytag_str, start, SENTINEL_KEYTAG_LEN);
|
||||
keytag_str[SENTINEL_KEYTAG_LEN] = '\0';
|
||||
*keytag = (uint16_t)strtol(keytag_str, &e, 10);
|
||||
if(!e || *e != '\0') {
|
||||
free(keytag_str);
|
||||
return 0;
|
||||
}
|
||||
free(keytag_str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prime trust anchor for use.
|
||||
* Generate and dispatch a priming query for the given trust anchor.
|
||||
@ -2223,6 +2249,34 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
|
||||
vq->orig_msg->rep->security = sec_status_indeterminate;
|
||||
}
|
||||
|
||||
if(vq->orig_msg->rep->security == sec_status_secure &&
|
||||
qstate->env->cfg->root_key_sentinel &&
|
||||
(qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
|
||||
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)) {
|
||||
char* keytag_start;
|
||||
uint16_t keytag;
|
||||
if(*qstate->qinfo.qname == strlen(SENTINEL_IS) +
|
||||
SENTINEL_KEYTAG_LEN &&
|
||||
dname_lab_startswith(qstate->qinfo.qname, SENTINEL_IS,
|
||||
&keytag_start)) {
|
||||
if(sentinel_get_keytag(keytag_start, &keytag) &&
|
||||
!anchor_has_keytag(qstate->env->anchors,
|
||||
(uint8_t*)"", 1, 0, vq->qchase.qclass, keytag)) {
|
||||
vq->orig_msg->rep->security =
|
||||
sec_status_secure_sentinel_fail;
|
||||
}
|
||||
} else if(*qstate->qinfo.qname == strlen(SENTINEL_NOT) +
|
||||
SENTINEL_KEYTAG_LEN &&
|
||||
dname_lab_startswith(qstate->qinfo.qname, SENTINEL_NOT,
|
||||
&keytag_start)) {
|
||||
if(sentinel_get_keytag(keytag_start, &keytag) &&
|
||||
anchor_has_keytag(qstate->env->anchors,
|
||||
(uint8_t*)"", 1, 0, vq->qchase.qclass, keytag)) {
|
||||
vq->orig_msg->rep->security =
|
||||
sec_status_secure_sentinel_fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* store results in cache */
|
||||
if(qstate->query_flags&BIT_RD) {
|
||||
/* if secure, this will override cache anyway, no need
|
||||
|
@ -67,6 +67,13 @@ struct config_strlist;
|
||||
/** max number of query restarts, number of IPs to probe */
|
||||
#define VAL_MAX_RESTART_COUNT 5
|
||||
|
||||
/** Root key sentinel is ta preamble */
|
||||
#define SENTINEL_IS "root-key-sentinel-is-ta-"
|
||||
/** Root key sentinel is not ta preamble */
|
||||
#define SENTINEL_NOT "root-key-sentinel-not-ta-"
|
||||
/** Root key sentinal keytag length */
|
||||
#define SENTINEL_KEYTAG_LEN 5
|
||||
|
||||
/**
|
||||
* Global state for the validator.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user