Compare commits

..
Author SHA1 Message Date
Willem Toorop 2ffc17e826 Shumon's invalid query type EDE return 2024-07-25 19:29:09 -07:00
355 changed files with 6311 additions and 51544 deletions
+3 -61
View File
@@ -161,44 +161,13 @@ jobs:
test_windows: "yes"
config: "no"
make: "no"
- name: FreeBSD
os: ubuntu-latest
config: "no"
make: "no"
with_cross_platform_action: "yes"
cross_platform_os: "freebsd"
cross_platform_arch: "x86-64"
cross_platform_version: "14.1"
cross_platform_config: "--enable-debug --disable-flto --with-libevent --disable-static"
- name: OpenBSD
os: ubuntu-latest
config: "no"
make: "no"
with_cross_platform_action: "yes"
cross_platform_os: "openbsd"
cross_platform_arch: "x86-64"
cross_platform_version: "7.5"
cross_platform_config: "--enable-debug --disable-flto --with-libevent --disable-static"
- name: NetBSD
os: ubuntu-latest
config: "no"
make: "no"
with_cross_platform_action: "yes"
cross_platform_os: "netbsd"
cross_platform_arch: "x86-64"
cross_platform_version: "10.0"
cross_platform_config: "--enable-debug --disable-flto --with-libevent --disable-static"
steps:
- uses: actions/checkout@v4
with:
submodules: false
persist-credentials: false
- name: test_windows
if: ${{ matrix.test_windows == 'yes' }}
env:
LIBEXPAT_FNAME: expat-2.7.0
LIBEXPAT_VERSION_DIR: R_2_7_0
shell: bash
run: |
export unboundpath=`pwd`
@@ -241,9 +210,9 @@ jobs:
cd ..
mkdir expat
echo "curl expat"
curl -L -k -s -S -o $LIBEXPAT_FNAME.tar.gz https://github.com/libexpat/libexpat/releases/download/$LIBEXPAT_VERSION_DIR/$LIBEXPAT_FNAME.tar.gz
tar xzf $LIBEXPAT_FNAME.tar.gz
cd $LIBEXPAT_FNAME
curl -L -k -s -S -o expat-2.2.10.tar.gz https://github.com/libexpat/libexpat/releases/download/R_2_2_10/expat-2.2.10.tar.gz
tar xzf expat-2.2.10.tar.gz
cd expat-2.2.10
echo "./configure SHELL=/usr/bin/bash CONFIG_SHELL=/usr/bin/bash --prefix=\"$prepath/expat\" --exec-prefix=\"$prepath/expat\" --bindir=\"$prepath/expat/bin\" --includedir=\"$prepath/expat/include\" --mandir=\"$prepath/expat/man\" --libdir=\"$prepath/expat/lib\""
./configure SHELL=/usr/bin/bash CONFIG_SHELL=/usr/bin/bash --prefix="$prepath/expat" --exec-prefix="$prepath/expat" --bindir="$prepath/expat/bin" --includedir="$prepath/expat/include" --mandir="$prepath/expat/man" --libdir="$prepath/expat/lib"
# fixup SHELL is treated specially, but SHELZZ is not by make.
@@ -362,33 +331,6 @@ jobs:
echo "::group::make install"
make install
echo "::endgroup::"
- name: cross-platform-action on ${{ matrix.cross_platform_os }} ${{ matrix.cross_platform_version }}
if: ${{ matrix.with_cross_platform_action == 'yes' }}
uses: cross-platform-actions/action@v0.25.0
env:
CROSS_PLATFORM_OS: ${{ matrix.cross_platform_os }}
with:
environment_variables: CROSS_PLATFORM_OS
operating_system: ${{ matrix.cross_platform_os }}
architecture: ${{ matrix.cross_platform_arch }}
version: ${{ matrix.cross_platform_version }}
shell: bash
memory: 4G
cpu_count: 2
run: |
set -e -x
if test "$CROSS_PLATFORM_OS" = "freebsd"; then sudo pkg install -y openssl libevent expat; fi
if test "$CROSS_PLATFORM_OS" = "openbsd"; then sudo pkg_add libevent; fi
if test "$CROSS_PLATFORM_OS" = "netbsd"; then sudo pkgin -y install libevent; fi
echo "::group::configure"
./configure ${{ matrix.cross_platform_config }}
echo "::endgroup::"
echo "::group::make"
make
echo "::endgroup::"
echo "::group::make test"
make test
echo "::endgroup::"
- name: install libevent
if: ${{ matrix.install_libevent == 'yes' }}
run: sudo apt-get install libevent-dev
-2
View File
@@ -13,8 +13,6 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: configure
run: ./configure --enable-debug
- name: make
-1
View File
@@ -36,7 +36,6 @@
/asynclook
/delayer
/dohclient
/doqclient
/lock-verify
/memstats
/perf
+567 -837
View File
File diff suppressed because it is too large Load Diff
-70
View File
@@ -1,70 +0,0 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_build_date_epoch.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_BUILD_DATE_EPOCH(VARIABLE[, FORMAT[, ACTION-IF-FAIL]])
#
# DESCRIPTION
#
# Sets VARIABLE to a string representing the current time. It is
# formatted according to FORMAT if specified, otherwise it is formatted as
# the number of seconds (excluding leap seconds) since the UNIX epoch (01
# Jan 1970 00:00:00 UTC).
#
# If the SOURCE_DATE_EPOCH environment variable is set, it uses the value
# of that variable instead of the current time. See
# https://reproducible-builds.org/specs/source-date-epoch). If
# SOURCE_DATE_EPOCH is set but cannot be properly interpreted as a UNIX
# timestamp, then execute ACTION-IF-FAIL if specified, otherwise error.
#
# VARIABLE is AC_SUBST-ed.
#
# LICENSE
#
# Copyright (c) 2016 Eric Bavier <bavier@member.fsf.org>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 2
AC_DEFUN([AX_BUILD_DATE_EPOCH],
[dnl
AC_MSG_CHECKING([for build time])
ax_date_fmt="m4_default($2,%s)"
AS_IF([test x"$SOURCE_DATE_EPOCH" = x],
[$1=`date "+$ax_date_fmt"`],
[ax_build_date=`date -u -d "@$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null \
|| date -u -r "$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null`
AS_IF([test x"$ax_build_date" = x],
[m4_ifval([$3],
[$3],
[AC_MSG_ERROR([malformed SOURCE_DATE_EPOCH])])],
[$1=$ax_build_date])])
AC_MSG_RESULT([$$1])
])dnl AX_BUILD_DATE_EPOCH
+3 -7
View File
@@ -47,7 +47,6 @@
#include "util/regional.h"
#include "util/net_help.h"
#include "util/config_file.h"
#include "util/data/dname.h"
#include "util/data/msgreply.h"
#include "util/data/msgencode.h"
#include "services/cache/dns.h"
@@ -342,7 +341,6 @@ calc_hash(struct query_info* qinfo, struct module_env* env, char* buf,
/* copy the hash info into the clear buffer */
if(clen + qinfo->qname_len < sizeof(clear)) {
memmove(clear+clen, qinfo->qname, qinfo->qname_len);
query_dname_tolower(clear+clen);
clen += qinfo->qname_len;
}
if(clen + 4 < sizeof(clear)) {
@@ -623,9 +621,6 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
}
verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
adjust_msg_ttl(qstate->return_msg, adjust);
if(qstate->env->cfg->aggressive_nsec) {
limit_nsec_ttl(qstate->return_msg);
}
/* Similar to the unbound worker, if serve-expired is enabled and
* the msg would be considered to be expired, mark the state so a
@@ -757,8 +752,7 @@ cachedb_intcache_store(struct module_qstate* qstate, int msg_expired)
}
(void)dns_cache_store(qstate->env, &qstate->qinfo,
qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0,
qstate->region, store_flags, qstate->qstarttime,
qstate->is_valrec);
qstate->region, store_flags, qstate->qstarttime);
if(serve_expired && msg_expired) {
if(qstate->env->cfg->serve_expired_client_timeout) {
/* No expired response from the query state, the
@@ -834,6 +828,8 @@ cachedb_handle_query(struct module_qstate* qstate,
/* In case we have expired data but there is a client timer for expired
* answers, pass execution to next module in order to try updating the
* data first.
* TODO: this needs revisit. The expired data stored from cachedb has
* 0 TTL which is picked up by iterator later when looking in the cache.
*/
if(qstate->env->cfg->serve_expired && msg_expired) {
qstate->return_msg = NULL;
+68 -323
View File
@@ -46,62 +46,24 @@
#include "cachedb/cachedb.h"
#include "util/alloc.h"
#include "util/config_file.h"
#include "util/locks.h"
#include "util/timeval_func.h"
#include "sldns/sbuffer.h"
#ifdef USE_REDIS
#include "hiredis/hiredis.h"
struct redis_moddata {
/* thread-specific redis contexts */
redisContext** ctxs;
redisContext** replica_ctxs;
/* number of ctx entries */
int numctxs;
/* server's IP address or host name */
const char* server_host;
const char* replica_server_host;
/* server's TCP port */
int server_port;
int replica_server_port;
/* server's unix path, or "", NULL if unused */
const char* server_path;
const char* replica_server_path;
/* server's AUTH password, or "", NULL if unused */
const char* server_password;
const char* replica_server_password;
/* timeout for commands */
struct timeval command_timeout;
struct timeval replica_command_timeout;
/* timeout for connection setup */
struct timeval connect_timeout;
struct timeval replica_connect_timeout;
/* the reconnect interval time. */
struct timeval reconnect_interval;
struct timeval replica_reconnect_interval;
/* reconnect attempts, 0 if connected, counts up failed reconnects. */
int reconnect_attempts;
int replica_reconnect_attempts;
/* Lock on reconnect_wait time. */
lock_basic_type wait_lock;
lock_basic_type replica_wait_lock;
/* reconnect wait time, wait until it has passed before reconnect. */
struct timeval reconnect_wait;
struct timeval replica_reconnect_wait;
/* the redis logical database to use */
int logical_db;
int replica_logical_db;
/* if the SET with EX command is supported */
int set_with_ex_available;
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 */
const char* server_path; /* server's unix path, or "", NULL if unused */
const char* server_password; /* server's AUTH password, or "", NULL if unused */
struct timeval timeout; /* timeout for connection setup and commands */
int logical_db; /* the redis logical database to use */
};
/** The limit on the number of redis connect attempts. After failure if
* the number is exceeded, the reconnects are throttled by the wait time. */
#define REDIS_RECONNECT_ATTEMPT_LIMIT 3
static redisReply* redis_command(struct module_env*, struct cachedb_env*,
const char*, const uint8_t*, size_t, int);
const char*, const uint8_t*, size_t);
static void
moddata_clean(struct redis_moddata** moddata) {
@@ -115,139 +77,63 @@ moddata_clean(struct redis_moddata** moddata) {
}
free((*moddata)->ctxs);
}
if((*moddata)->replica_ctxs) {
int i;
for(i = 0; i < (*moddata)->numctxs; i++) {
if((*moddata)->replica_ctxs[i])
redisFree((*moddata)->replica_ctxs[i]);
}
free((*moddata)->replica_ctxs);
}
lock_basic_destroy(&(*moddata)->wait_lock);
lock_basic_destroy(&(*moddata)->replica_wait_lock);
free(*moddata);
*moddata = NULL;
}
static redisContext*
redis_connect(const char* host, int port, const char* path,
const char* password, int logical_db,
const struct timeval connect_timeout,
const struct timeval command_timeout,
const struct timeval* reconnect_interval,
int* reconnect_attempts,
struct timeval* reconnect_wait,
lock_basic_type* wait_lock,
struct timeval* now_tv,
const char* infostr)
redis_connect(const struct redis_moddata* moddata)
{
struct timeval now_val;
redisContext* ctx;
/* See if the redis server is down, and reconnect has to wait. */
if(*reconnect_attempts > REDIS_RECONNECT_ATTEMPT_LIMIT) {
/* Acquire lock to look at timeval, the integer has atomic
* integrity. */
struct timeval wait_tv;
if(now_tv) {
now_val = *now_tv;
} else {
if(gettimeofday(&now_val, NULL) < 0)
log_err("redis: gettimeofday: %s",
strerror(errno));
}
lock_basic_lock(wait_lock);
wait_tv = *reconnect_wait;
lock_basic_unlock(wait_lock);
if(timeval_smaller(&now_val, &wait_tv)) {
verbose(VERB_ALGO, "redis %sdown, reconnect wait",
infostr);
return NULL;
}
}
if(path && path[0]!=0) {
ctx = redisConnectUnixWithTimeout(path, connect_timeout);
if(moddata->server_path && moddata->server_path[0]!=0) {
ctx = redisConnectUnixWithTimeout(moddata->server_path,
moddata->timeout);
} else {
ctx = redisConnectWithTimeout(host, port, connect_timeout);
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 %sserver: %s", infostr, errstr);
log_err("failed to connect to redis server: %s", errstr);
goto fail;
}
if(redisSetTimeout(ctx, command_timeout) != REDIS_OK) {
log_err("failed to set redis %stimeout, %s", infostr, ctx->errstr);
if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) {
log_err("failed to set redis timeout");
goto fail;
}
if(password && password[0]!=0) {
if(moddata->server_password && moddata->server_password[0]!=0) {
redisReply* rep;
rep = redisCommand(ctx, "AUTH %s", password);
rep = redisCommand(ctx, "AUTH %s", moddata->server_password);
if(!rep || rep->type == REDIS_REPLY_ERROR) {
log_err("failed to authenticate %swith password", infostr);
log_err("failed to authenticate with password");
freeReplyObject(rep);
goto fail;
}
freeReplyObject(rep);
}
if(logical_db > 0) {
if(moddata->logical_db > 0) {
redisReply* rep;
rep = redisCommand(ctx, "SELECT %d", logical_db);
rep = redisCommand(ctx, "SELECT %d", moddata->logical_db);
if(!rep || rep->type == REDIS_REPLY_ERROR) {
log_err("failed %sto set logical database (%d)",
infostr, logical_db);
log_err("failed to set logical database (%d)",
moddata->logical_db);
freeReplyObject(rep);
goto fail;
}
freeReplyObject(rep);
}
*reconnect_attempts = 0;
if(verbosity >= VERB_OPS) {
char port_str[6+1];
port_str[0] = ' ';
(void)snprintf(port_str+1, sizeof(port_str)-1, "%d", port);
verbose(VERB_OPS, "Connection to Redis %sestablished (%s%s)",
infostr,
path&&path[0]!=0?path:host,
path&&path[0]!=0?"":port_str);
}
verbose(VERB_OPS, "Connection to Redis established");
return ctx;
fail:
if(ctx)
redisFree(ctx);
(*reconnect_attempts)++;
if(*reconnect_attempts > REDIS_RECONNECT_ATTEMPT_LIMIT) {
/* Wait for the reconnect interval before trying again. */
struct timeval tv;
if(now_tv) {
now_val = *now_tv;
} else {
if(gettimeofday(&now_val, NULL) < 0)
log_err("redis: gettimeofday: %s",
strerror(errno));
}
tv = now_val;
timeval_add(&tv, reconnect_interval);
lock_basic_lock(wait_lock);
*reconnect_wait = tv;
lock_basic_unlock(wait_lock);
verbose(VERB_ALGO, "redis %sreconnect wait until %d.%6.6d",
infostr, (int)tv.tv_sec, (int)tv.tv_usec);
}
return NULL;
}
static void
set_timeout(struct timeval* timeout, int value, int explicit_value)
{
int v = explicit_value != 0 ? explicit_value : value;
timeout->tv_sec = v / 1000;
timeout->tv_usec = (v % 1000) * 1000;
}
static int
redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
{
@@ -261,120 +147,42 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
log_err("out of memory");
goto fail;
}
lock_basic_init(&moddata->wait_lock);
lock_protect(&moddata->wait_lock, &moddata->reconnect_wait,
sizeof(moddata->reconnect_wait));
lock_basic_init(&moddata->replica_wait_lock);
lock_protect(&moddata->replica_wait_lock,
&moddata->replica_reconnect_wait,
sizeof(moddata->replica_reconnect_wait));
moddata->numctxs = env->cfg->num_threads;
/* note: server_host and similar string configuration options are
* shallow references to configured strings; we don't have to free them
* in this module. */
moddata->server_host = env->cfg->redis_server_host;
moddata->replica_server_host = env->cfg->redis_replica_server_host;
moddata->server_port = env->cfg->redis_server_port;
moddata->replica_server_port = env->cfg->redis_replica_server_port;
moddata->server_path = env->cfg->redis_server_path;
moddata->replica_server_path = env->cfg->redis_replica_server_path;
moddata->server_password = env->cfg->redis_server_password;
moddata->replica_server_password = env->cfg->redis_replica_server_password;
set_timeout(&moddata->command_timeout,
env->cfg->redis_timeout,
env->cfg->redis_command_timeout);
set_timeout(&moddata->replica_command_timeout,
env->cfg->redis_replica_timeout,
env->cfg->redis_replica_command_timeout);
set_timeout(&moddata->connect_timeout,
env->cfg->redis_timeout,
env->cfg->redis_connect_timeout);
set_timeout(&moddata->replica_connect_timeout,
env->cfg->redis_replica_timeout,
env->cfg->redis_replica_connect_timeout);
set_timeout(&moddata->reconnect_interval, 1000, 0);
set_timeout(&moddata->replica_reconnect_interval, 1000, 0);
moddata->logical_db = env->cfg->redis_logical_db;
moddata->replica_logical_db = env->cfg->redis_replica_logical_db;
moddata->ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*));
if(!moddata->ctxs) {
log_err("out of memory");
goto fail;
}
if((moddata->replica_server_host && moddata->replica_server_host[0]!=0)
|| (moddata->replica_server_path && moddata->replica_server_path[0]!=0)) {
/* There is a replica configured, allocate ctxs */
moddata->replica_ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*));
if(!moddata->replica_ctxs) {
log_err("out of memory");
goto fail;
}
}
/* 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->server_path = env->cfg->redis_server_path;
moddata->server_password = env->cfg->redis_server_password;
moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000;
moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000;
moddata->logical_db = env->cfg->redis_logical_db;
for(i = 0; i < moddata->numctxs; i++) {
redisContext* ctx = redis_connect(
moddata->server_host,
moddata->server_port,
moddata->server_path,
moddata->server_password,
moddata->logical_db,
moddata->connect_timeout,
moddata->command_timeout,
&moddata->reconnect_interval,
&moddata->reconnect_attempts,
&moddata->reconnect_wait,
&moddata->wait_lock,
env->now_tv,
"");
redisContext* ctx = redis_connect(moddata);
if(!ctx) {
log_err("redis_init: failed to init redis "
"(for thread %d)", i);
/* And continue, the context can be established
* later, just like after a disconnect. */
log_err("redis_init: failed to init redis");
goto fail;
}
moddata->ctxs[i] = ctx;
}
if(moddata->replica_ctxs) {
for(i = 0; i < moddata->numctxs; i++) {
redisContext* ctx = redis_connect(
moddata->replica_server_host,
moddata->replica_server_port,
moddata->replica_server_path,
moddata->replica_server_password,
moddata->replica_logical_db,
moddata->replica_connect_timeout,
moddata->replica_command_timeout,
&moddata->replica_reconnect_interval,
&moddata->replica_reconnect_attempts,
&moddata->replica_reconnect_wait,
&moddata->replica_wait_lock,
env->now_tv,
"replica ");
if(!ctx) {
log_err("redis_init: failed to init redis "
"replica (for thread %d)", i);
/* And continue, the context can be established
* later, just like after a disconnect. */
}
moddata->replica_ctxs[i] = ctx;
}
}
cachedb_env->backend_data = moddata;
if(env->cfg->redis_expire_records &&
moddata->ctxs[env->alloc->thread_num] != NULL) {
if(env->cfg->redis_expire_records) {
redisReply* rep = NULL;
int redis_reply_type = 0;
/** check if set with ex command is supported */
/** check if setex command is supported */
rep = redis_command(env, cachedb_env,
"SET __UNBOUND_REDIS_CHECK__ none EX 1", NULL, 0, 1);
"SETEX __UNBOUND_REDIS_CHECK__ 1 none", NULL, 0);
if(!rep) {
/** init failed, no response from redis server*/
goto set_with_ex_fail;
log_err("redis_init: failed to init redis, the "
"redis-expire-records option requires the SETEX command "
"(redis >= 2.0.0)");
goto fail;
}
redis_reply_type = rep->type;
freeReplyObject(rep);
@@ -382,18 +190,15 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
case REDIS_REPLY_STATUS:
break;
default:
/** init failed, set_with_ex command not supported */
goto set_with_ex_fail;
/** init failed, setex command not supported */
log_err("redis_init: failed to init redis, the "
"redis-expire-records option requires the SETEX command "
"(redis >= 2.0.0)");
goto fail;
}
moddata->set_with_ex_available = 1;
}
return 1;
set_with_ex_fail:
log_err("redis_init: failure during redis_init, the "
"redis-expire-records option requires the SET with EX command "
"(redis >= 2.6.12)");
return 1;
fail:
moddata_clean(&moddata);
return 0;
@@ -424,9 +229,9 @@ redis_deinit(struct module_env* env, struct cachedb_env* cachedb_env)
*/
static redisReply*
redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
const char* command, const uint8_t* data, size_t data_len, int write)
const char* command, const uint8_t* data, size_t data_len)
{
redisContext* ctx, **ctx_selector;
redisContext* ctx;
redisReply* rep;
struct redis_moddata* d = (struct redis_moddata*)
cachedb_env->backend_data;
@@ -437,50 +242,17 @@ redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
* assumption throughout the unbound architecture, so we simply assert
* it. */
log_assert(env->alloc->thread_num < d->numctxs);
ctx_selector = !write && d->replica_ctxs
?d->replica_ctxs
:d->ctxs;
ctx = ctx_selector[env->alloc->thread_num];
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) {
if(!write && d->replica_ctxs) {
ctx = redis_connect(
d->replica_server_host,
d->replica_server_port,
d->replica_server_path,
d->replica_server_password,
d->replica_logical_db,
d->replica_connect_timeout,
d->replica_command_timeout,
&d->replica_reconnect_interval,
&d->replica_reconnect_attempts,
&d->replica_reconnect_wait,
&d->replica_wait_lock,
env->now_tv,
"replica ");
} else {
ctx = redis_connect(
d->server_host,
d->server_port,
d->server_path,
d->server_password,
d->logical_db,
d->connect_timeout,
d->command_timeout,
&d->reconnect_interval,
&d->reconnect_attempts,
&d->reconnect_wait,
&d->wait_lock,
env->now_tv,
"");
}
ctx_selector[env->alloc->thread_num] = ctx;
ctx = redis_connect(d);
d->ctxs[env->alloc->thread_num] = ctx;
}
if(!ctx) return NULL;
if(!ctx)
return NULL;
/* Send the command and get a reply, synchronously. */
rep = (redisReply*)redisCommand(ctx, command, data, data_len);
@@ -490,7 +262,7 @@ redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
log_err("redis_command: failed to receive a reply, "
"closing connection: %s", ctx->errstr);
redisFree(ctx);
ctx_selector[env->alloc->thread_num] = NULL;
d->ctxs[env->alloc->thread_num] = NULL;
return NULL;
}
@@ -508,14 +280,7 @@ redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
char* key, struct sldns_buffer* result_buffer)
{
redisReply* rep;
/* Supported commands:
* - "GET " + key
*/
#define REDIS_LOOKUP_MAX_BUF_LEN \
4 /* "GET " */ \
+(CACHEDB_HASHSIZE/8)*2 /* key hash */ \
+ 1 /* \0 */
char cmdbuf[REDIS_LOOKUP_MAX_BUF_LEN];
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+1]; /* "GET " + key */
int n;
int ret = 0;
@@ -527,7 +292,7 @@ redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
return 0;
}
rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0, 0);
rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0);
if(!rep)
return 0;
switch(rep->type) {
@@ -564,45 +329,26 @@ redis_store(struct module_env* env, struct cachedb_env* cachedb_env,
{
redisReply* rep;
int n;
struct redis_moddata* moddata = (struct redis_moddata*)
cachedb_env->backend_data;
int set_ttl = (moddata->set_with_ex_available &&
env->cfg->redis_expire_records &&
int set_ttl = (env->cfg->redis_expire_records &&
(!env->cfg->serve_expired || env->cfg->serve_expired_ttl > 0));
/* Supported commands:
* - "SET " + key + " %b"
* - "SET " + key + " %b EX " + ttl
* older redis 2.0.0 was "SETEX " + key + " " + ttl + " %b"
* - "EXPIRE " + key + " 0"
* - "SETEX " + key + " " + ttl + " %b"
*/
#define REDIS_STORE_MAX_BUF_LEN \
7 /* "EXPIRE " */ \
+(CACHEDB_HASHSIZE/8)*2 /* key hash */ \
+ 7 /* " %b EX " */ \
+ 20 /* ttl (uint64_t) */ \
+ 1 /* \0 */
char cmdbuf[REDIS_STORE_MAX_BUF_LEN];
char cmdbuf[6+(CACHEDB_HASHSIZE/8)*2+11+3+1];
if (!set_ttl) {
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);
} else if(ttl == 0) {
/* use the EXPIRE command, SET with EX 0 is an invalid time. */
/* Replies with REDIS_REPLY_INTEGER of 1. */
verbose(VERB_ALGO, "redis_store expire %s (%d bytes)",
key, (int)data_len);
n = snprintf(cmdbuf, sizeof(cmdbuf), "EXPIRE %s 0", key);
data = NULL;
data_len = 0;
} else {
/* add expired ttl time to redis ttl to avoid premature eviction of key */
ttl += env->cfg->serve_expired_ttl;
verbose(VERB_ALGO, "redis_store %s (%d bytes) with ttl %u",
key, (int)data_len, (unsigned)(uint32_t)ttl);
key, (int)data_len, (uint32_t)ttl);
/* build command to set to a binary safe string */
n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b EX %u", key,
(unsigned)(uint32_t)ttl);
n = snprintf(cmdbuf, sizeof(cmdbuf), "SETEX %s %u %%b", key,
(uint32_t)ttl);
}
@@ -611,12 +357,11 @@ redis_store(struct module_env* env, struct cachedb_env* cachedb_env,
return;
}
rep = redis_command(env, cachedb_env, cmdbuf, data, data_len, 1);
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 &&
rep->type != REDIS_REPLY_INTEGER) {
rep->type != REDIS_REPLY_ERROR) {
log_err("redis_store: unexpected type of reply (%d)",
rep->type);
}
+3 -3
View File
@@ -57,7 +57,7 @@ int getnameinfo(const struct sockaddr *sa, size_t ATTR_UNUSED(salen), char *host
}
if (host != NULL) {
if ((flags & NI_NUMERICHOST)) {
if (flags & NI_NUMERICHOST) {
if (strlcpy(host, inet_ntoa(sin->sin_addr),
hostlen) >= hostlen)
return (EAI_MEMORY);
@@ -168,7 +168,7 @@ getaddrinfo(const char *hostname, const char *servname,
port = 0;
}
if (hints && (hints->ai_flags & AI_PASSIVE)) {
if (hints && hints->ai_flags & AI_PASSIVE) {
addr = htonl(0x00000000);
if (hostname && inet_aton(hostname, &in) != 0)
addr = in.s_addr;
@@ -193,7 +193,7 @@ getaddrinfo(const char *hostname, const char *servname,
}
/* Don't try DNS if AI_NUMERICHOST is set */
if (hints && (hints->ai_flags & AI_NUMERICHOST))
if (hints && hints->ai_flags & AI_NUMERICHOST)
return (EAI_NONAME);
hp = gethostbyname(hostname);
+4
View File
@@ -5,8 +5,12 @@
#undef malloc
#include <sys/types.h>
#ifndef USE_WINSOCK
void *malloc ();
#else
/* provide a prototype */
void *malloc (size_t n);
#endif
/* Allocate an N-byte block of memory from the heap.
If N is zero, allocate a 1-byte block. */
+3 -122
View File
@@ -1,8 +1,5 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* apply the fallthrough attribute. */
#undef ATTR_FALLTHROUGH
/* apply the noreturn attribute to a function that exits the program */
#undef ATTR_NORETURN
@@ -60,9 +57,6 @@
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Whether the C compiler accepts the "fallthrough" attribute */
#undef HAVE_ATTR_FALLTHROUGH
/* Whether the C compiler accepts the "format" attribute */
#undef HAVE_ATTR_FORMAT
@@ -129,14 +123,6 @@
and to 0 if you don't. */
#undef HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW
/* Define to 1 if you have the declaration of `ngtcp2_conn_server_new', and to
0 if you don't. */
#undef HAVE_DECL_NGTCP2_CONN_SERVER_NEW
/* Define to 1 if you have the declaration of `ngtcp2_crypto_encrypt_cb', and
to 0 if you don't. */
#undef HAVE_DECL_NGTCP2_CRYPTO_ENCRYPT_CB
/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
don't. */
#undef HAVE_DECL_NID_ED25519
@@ -173,10 +159,6 @@
0 if you don't. */
#undef HAVE_DECL_SSL_CTX_SET_ECDH_AUTO
/* Define to 1 if you have the declaration of `SSL_CTX_set_tmp_ecdh', and to 0
if you don't. */
#undef HAVE_DECL_SSL_CTX_SET_TMP_ECDH
/* Define to 1 if you have the declaration of `strlcat', and to 0 if you
don't. */
#undef HAVE_DECL_STRLCAT
@@ -382,9 +364,6 @@
/* Define if we have LibreSSL */
#undef HAVE_LIBRESSL
/* If we have atomic_store */
#undef HAVE_LINK_ATOMIC_STORE
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
#undef HAVE_LINUX_NET_TSTAMP_H
@@ -436,71 +415,6 @@
/* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */
#undef HAVE_NGHTTP2_NGHTTP2_H
/* Define this to use ngtcp2. */
#undef HAVE_NGTCP2
/* Define to 1 if you have the `ngtcp2_ccerr_default' function. */
#undef HAVE_NGTCP2_CCERR_DEFAULT
/* Define to 1 if you have the `ngtcp2_conn_encode_0rtt_transport_params'
function. */
#undef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS
/* Define to 1 if you have the `ngtcp2_conn_get_max_local_streams_uni'
function. */
#undef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI
/* Define to 1 if you have the `ngtcp2_conn_get_num_scid' function. */
#undef HAVE_NGTCP2_CONN_GET_NUM_SCID
/* Define to 1 if you have the `ngtcp2_conn_in_closing_period' function. */
#undef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD
/* Define to 1 if you have the `ngtcp2_conn_in_draining_period' function. */
#undef HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD
/* Define if ngtcp2_conn_shutdown_stream has 4 arguments. */
#undef HAVE_NGTCP2_CONN_SHUTDOWN_STREAM4
/* Define to 1 if you have the `ngtcp2_conn_tls_early_data_rejected' function.
*/
#undef HAVE_NGTCP2_CONN_TLS_EARLY_DATA_REJECTED
/* Define to 1 if you have the `ngtcp2_crypto_encrypt_cb' function. */
#undef HAVE_NGTCP2_CRYPTO_ENCRYPT_CB
/* Define to 1 if you have the
`ngtcp2_crypto_quictls_configure_client_context' function. */
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
/* Define to 1 if you have the
`ngtcp2_crypto_quictls_configure_server_context' function. */
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
/* Define to 1 if you have the
`ngtcp2_crypto_quictls_from_ossl_encryption_level' function. */
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
/* Define to 1 if you have the `ngtcp2_crypto_quictls_init' function. */
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_INIT
/* Define to 1 if the system has the type `ngtcp2_encryption_level'. */
#undef HAVE_NGTCP2_ENCRYPTION_LEVEL
/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_openssl.h> header file.
*/
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H
/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_ossl.h> header file. */
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_OSSL_H
/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_quictls.h> header file.
*/
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H
/* Define to 1 if you have the <ngtcp2/ngtcp2.h> header file. */
#undef HAVE_NGTCP2_NGTCP2_H
/* Use libnss for crypto */
#undef HAVE_NSS
@@ -655,6 +569,9 @@
function. */
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
/* Define to 1 if you have the `SSL_CTX_set_tmp_ecdh' function. */
#undef HAVE_SSL_CTX_SET_TMP_ECDH
/* Define to 1 if you have the `SSL_get0_alpn_selected' function. */
#undef HAVE_SSL_GET0_ALPN_SELECTED
@@ -664,18 +581,12 @@
/* Define to 1 if you have the `SSL_get1_peer_certificate' function. */
#undef HAVE_SSL_GET1_PEER_CERTIFICATE
/* Define to 1 if you have the `SSL_is_quic' function. */
#undef HAVE_SSL_IS_QUIC
/* Define to 1 if you have the `SSL_set1_host' function. */
#undef HAVE_SSL_SET1_HOST
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define to 1 if you have the <stdatomic.h> header file. */
#undef HAVE_STDATOMIC_H
/* Define to 1 if you have the <stdbool.h> header file. */
#undef HAVE_STDBOOL_H
@@ -712,23 +623,6 @@
/* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */
#undef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST
/* Define to 1 if `tokenlen' is a member of `struct ngtcp2_pkt_hd'. */
#undef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN
/* Define to 1 if `max_tx_udp_payload_size' is a member of `struct
ngtcp2_settings'. */
#undef HAVE_STRUCT_NGTCP2_SETTINGS_MAX_TX_UDP_PAYLOAD_SIZE
/* Define to 1 if `tokenlen' is a member of `struct ngtcp2_settings'. */
#undef HAVE_STRUCT_NGTCP2_SETTINGS_TOKENLEN
/* Define to 1 if `original_dcid_present' is a member of `struct
ngtcp2_transport_params'. */
#undef HAVE_STRUCT_NGTCP2_TRANSPORT_PARAMS_ORIGINAL_DCID_PRESENT
/* Define to 1 if the system has the type `struct ngtcp2_version_cid'. */
#undef HAVE_STRUCT_NGTCP2_VERSION_CID
/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */
#undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
@@ -1030,9 +924,6 @@
/* Define this to enable client TCP Fast Open. */
#undef USE_MSG_FASTOPEN
/* Define this to use ngtcp2_crypto_ossl. */
#undef USE_NGTCP2_CRYPTO_OSSL
/* Define this to enable client TCP Fast Open. */
#undef USE_OSX_MSG_FASTOPEN
@@ -1599,10 +1490,6 @@ struct sockaddr_storage;
# define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__)
# define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__)
# define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__)
# define strdup(s) unbound_stat_strdup_log(s, __FILE__, __LINE__, __func__)
#ifdef HAVE_REALLOCARRAY
# define reallocarray(p,n,s) unbound_stat_reallocarray_log(p, n, s, __FILE__, __LINE__, __func__)
#endif
void *unbound_stat_malloc(size_t size);
void *unbound_stat_calloc(size_t nmemb, size_t size);
void unbound_stat_free(void *ptr);
@@ -1615,10 +1502,6 @@ void unbound_stat_free_log(void *ptr, const char* file, int line,
const char* func);
void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
int line, const char* func);
void *unbound_stat_reallocarray_log(void *ptr, size_t nmemb, size_t size,
const char* file, int line, const char* func);
char *unbound_stat_strdup_log(const char *s, const char* file, int line,
const char* func);
#elif defined(UNBOUND_ALLOC_LITE)
# include "util/alloc.h"
#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */
@@ -1629,8 +1512,6 @@ char *unbound_stat_strdup_log(const char *s, const char* file, int line,
#define UNBOUND_DNS_OVER_TLS_PORT 853
/** default port for DNS over HTTPS traffic. */
#define UNBOUND_DNS_OVER_HTTPS_PORT 443
/** default port for DNS over QUIC traffic. */
#define UNBOUND_DNS_OVER_QUIC_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
Vendored
+26 -768
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.71 for unbound 1.24.0.
# Generated by GNU Autoconf 2.71 for unbound 1.20.1.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
#
@@ -622,8 +622,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
PACKAGE_VERSION='1.24.0'
PACKAGE_STRING='unbound 1.24.0'
PACKAGE_VERSION='1.20.1'
PACKAGE_STRING='unbound 1.20.1'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
PACKAGE_URL=''
@@ -685,9 +685,7 @@ opt_dnstap_socket_path
ENABLE_DNSTAP
PROTOBUFC_LIBS
PROTOBUFC_CFLAGS
PROTOC_GEN_C
PROTOC_C
PROTOC
UBSYMS
EXTRALINK
COMMON_OBJ_ALL_SYMBOLS
@@ -714,7 +712,6 @@ SSLLIB
HAVE_SSL
PC_CRYPTO_DEPENDENCY
CONFIG_DATE
SOURCE_DATE_EPOCH
GCC_DOCKER_LINTFLAGS
NETBSD_LINTFLAGS
PYUNBOUND_UNINSTALL
@@ -924,7 +921,6 @@ with_libevent
with_libexpat
with_libhiredis
with_libnghttp2
with_libngtcp2
enable_static_exe
enable_fully_static
enable_lock_checks
@@ -962,7 +958,6 @@ SYSTEMD_LIBS
SYSTEMD_DAEMON_CFLAGS
SYSTEMD_DAEMON_LIBS
PYTHON_VERSION
SOURCE_DATE_EPOCH
PROTOBUFC_CFLAGS
PROTOBUFC_LIBS'
@@ -1513,7 +1508,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.24.0 to adapt to many kinds of systems.
\`configure' configures unbound 1.20.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1579,7 +1574,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of unbound 1.24.0:";;
short | recursive ) echo "Configuration of unbound 1.20.1:";;
esac
cat <<\_ACEOF
@@ -1714,7 +1709,6 @@ Optional Packages:
--with-libexpat=path specify explicit path for libexpat.
--with-libhiredis=path specify explicit path for libhiredis.
--with-libnghttp2=path specify explicit path for libnghttp2.
--with-libngtcp2=path specify explicit path for libngtcp2, for QUIC.
--with-dnstap-socket-path=pathname
set default dnstap socket path
--with-protobuf-c=path Path where protobuf-c is installed, for dnstap
@@ -1756,10 +1750,6 @@ Some influential environment variables:
The installed Python version to use, for example '2.3'. This
string will be appended to the Python interpreter canonical
name.
SOURCE_DATE_EPOCH
If it is set, it uses the value of that variable instead of the
current time as the build timestamp. The format is a unix
timestamp. This enables reproducible build output.
PROTOBUFC_CFLAGS
C compiler flags for PROTOBUFC, overriding pkg-config
PROTOBUFC_LIBS
@@ -1832,7 +1822,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
unbound configure 1.24.0
unbound configure 1.20.1
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2489,7 +2479,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.24.0, which was
It was created by unbound $as_me 1.20.1, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -3251,13 +3241,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=24
UNBOUND_VERSION_MINOR=20
UNBOUND_VERSION_MICRO=0
UNBOUND_VERSION_MICRO=1
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=33
LIBUNBOUND_REVISION=28
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -3352,12 +3342,7 @@ LIBUNBOUND_AGE=1
# 1.19.2 had 9:25:1
# 1.19.3 had 9:26:1
# 1.20.0 had 9:27:1
# 1.21.0 had 9:28:1
# 1.21.1 had 9:29:1
# 1.22.0 had 9:30:1
# 1.23.0 had 9:31:1
# 1.23.1 had 9:32:1
# 1.24.0 had 9:33:1
# 1.20.1 had 9:28:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -6991,10 +6976,6 @@ printf "%s\n" "#define HAVE_ATTR_WEAK 1" >>confdefs.h
printf "%s\n" "#define ATTR_WEAK __attribute__((weak))" >>confdefs.h
else
printf "%s\n" "#define ATTR_WEAK /**/" >>confdefs.h
fi
@@ -7042,79 +7023,6 @@ printf "%s\n" "#define HAVE_ATTR_NORETURN 1" >>confdefs.h
printf "%s\n" "#define ATTR_NORETURN __attribute__((__noreturn__))" >>confdefs.h
else
printf "%s\n" "#define ATTR_NORETURN /**/" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"fallthrough\" attribute" >&5
printf %s "checking whether the C compiler (${CC-cc}) accepts the \"fallthrough\" attribute... " >&6; }
BAKCFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
if test ${ac_cv_c_fallthrough_attribute+y}
then :
printf %s "(cached) " >&6
else $as_nop
ac_cv_c_fallthrough_attribute=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdio.h>
void f(int x) {
int y = 0;
switch(x) {
case 1:
y = 1;
__attribute__((fallthrough));
/* fallthrough */
case 2:
y++;
break;
case 3:
y = 3;
break;
}
printf("%d", y);
}
int
main (void)
{
f(1);
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
ac_cv_c_fallthrough_attribute="yes"
else $as_nop
ac_cv_c_fallthrough_attribute="no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
CFLAGS="$BAKCFLAGS"
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_fallthrough_attribute" >&5
printf "%s\n" "$ac_cv_c_fallthrough_attribute" >&6; }
if test $ac_cv_c_fallthrough_attribute = yes; then
printf "%s\n" "#define HAVE_ATTR_FALLTHROUGH 1" >>confdefs.h
printf "%s\n" "#define ATTR_FALLTHROUGH __attribute__((fallthrough));" >>confdefs.h
else
printf "%s\n" "#define ATTR_FALLTHROUGH /**/" >>confdefs.h
fi
@@ -16104,14 +16012,6 @@ then :
fi
ac_fn_c_check_header_compile "$LINENO" "stdatomic.h" "ac_cv_header_stdatomic_h" "$ac_includes_default
"
if test "x$ac_cv_header_stdatomic_h" = xyes
then :
printf "%s\n" "#define HAVE_STDATOMIC_H 1" >>confdefs.h
fi
# check for types.
# Using own tests for int64* because autoconf builtin only give 32bit.
@@ -19912,26 +19812,7 @@ if test "`uname`" = "Linux"; then
GCC_DOCKER_LINTFLAGS='-syntax'
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build time" >&5
printf %s "checking for build time... " >&6; }
ax_date_fmt="%Y%m%d"
if test x"$SOURCE_DATE_EPOCH" = x
then :
CONFIG_DATE=`date "+$ax_date_fmt"`
else $as_nop
ax_build_date=`date -u -d "@$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null \
|| date -u -r "$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null`
if test x"$ax_build_date" = x
then :
as_fn_error $? "malformed SOURCE_DATE_EPOCH" "$LINENO" 5
else $as_nop
CONFIG_DATE=$ax_build_date
fi
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CONFIG_DATE" >&5
printf "%s\n" "$CONFIG_DATE" >&6; }
CONFIG_DATE=`date +%Y%m%d`
# Checks for libraries.
@@ -20820,6 +20701,12 @@ then :
printf "%s\n" "#define HAVE_BIO_SET_CALLBACK_EX 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "SSL_CTX_set_tmp_ecdh" "ac_cv_func_SSL_CTX_set_tmp_ecdh"
if test "x$ac_cv_func_SSL_CTX_set_tmp_ecdh" = xyes
then :
printf "%s\n" "#define HAVE_SSL_CTX_SET_TMP_ECDH 1" >>confdefs.h
fi
# these check_funcs need -lssl
@@ -20978,34 +20865,6 @@ else $as_nop
ac_have_decl=0
fi
printf "%s\n" "#define HAVE_DECL_SSL_CTX_SET_ECDH_AUTO $ac_have_decl" >>confdefs.h
ac_fn_check_decl "$LINENO" "SSL_CTX_set_tmp_ecdh" "ac_cv_have_decl_SSL_CTX_set_tmp_ecdh" "
$ac_includes_default
#ifdef HAVE_OPENSSL_ERR_H
#include <openssl/err.h>
#endif
#ifdef HAVE_OPENSSL_RAND_H
#include <openssl/rand.h>
#endif
#ifdef HAVE_OPENSSL_CONF_H
#include <openssl/conf.h>
#endif
#ifdef HAVE_OPENSSL_ENGINE_H
#include <openssl/engine.h>
#endif
#include <openssl/ssl.h>
#include <openssl/evp.h>
" "$ac_c_undeclared_builtin_options" "CFLAGS"
if test "x$ac_cv_have_decl_SSL_CTX_set_tmp_ecdh" = xyes
then :
ac_have_decl=1
else $as_nop
ac_have_decl=0
fi
printf "%s\n" "#define HAVE_DECL_SSL_CTX_SET_TMP_ECDH $ac_have_decl" >>confdefs.h
if test "$ac_cv_func_HMAC_Init_ex" = "yes"; then
@@ -22267,423 +22126,6 @@ printf "%s\n" "#define HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW $ac_have_decl" >>con
fi
# ngtcp2
# Check whether --with-libngtcp2 was given.
if test ${with_libngtcp2+y}
then :
withval=$with_libngtcp2;
else $as_nop
withval="no"
fi
found_libngtcp2="no"
if test x_$withval = x_yes -o x_$withval != x_no; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libngtcp2" >&5
printf %s "checking for libngtcp2... " >&6; }
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/ngtcp2/ngtcp2.h"; then
found_libngtcp2="yes"
if test "$dir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$dir/include"
LDFLAGS="$LDFLAGS -L$dir/lib"
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
printf "%s\n" "found in $dir" >&6; }
printf "%s\n" "#define HAVE_NGTCP2 1" >>confdefs.h
LIBS="$LIBS -lngtcp2"
break;
fi
done
if test x_$found_libngtcp2 != x_yes; then
as_fn_error $? "Could not find libngtcp2, ngtcp2.h" "$LINENO" 5
fi
ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2.h" "ac_cv_header_ngtcp2_ngtcp2_h" "$ac_includes_default
"
if test "x$ac_cv_header_ngtcp2_ngtcp2_h" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_NGTCP2_H 1" >>confdefs.h
fi
ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2_crypto_ossl.h" "ac_cv_header_ngtcp2_ngtcp2_crypto_ossl_h" "$ac_includes_default
"
if test "x$ac_cv_header_ngtcp2_ngtcp2_crypto_ossl_h" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_NGTCP2_CRYPTO_OSSL_H 1" >>confdefs.h
fi
ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2_crypto_openssl.h" "ac_cv_header_ngtcp2_ngtcp2_crypto_openssl_h" "$ac_includes_default
"
if test "x$ac_cv_header_ngtcp2_ngtcp2_crypto_openssl_h" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H 1" >>confdefs.h
fi
ac_fn_c_check_header_compile "$LINENO" "ngtcp2/ngtcp2_crypto_quictls.h" "ac_cv_header_ngtcp2_ngtcp2_crypto_quictls_h" "$ac_includes_default
"
if test "x$ac_cv_header_ngtcp2_ngtcp2_crypto_quictls_h" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H 1" >>confdefs.h
fi
ac_fn_check_decl "$LINENO" "ngtcp2_conn_server_new" "ac_cv_have_decl_ngtcp2_conn_server_new" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
" "$ac_c_undeclared_builtin_options" "CFLAGS"
if test "x$ac_cv_have_decl_ngtcp2_conn_server_new" = xyes
then :
ac_have_decl=1
else $as_nop
ac_have_decl=0
fi
printf "%s\n" "#define HAVE_DECL_NGTCP2_CONN_SERVER_NEW $ac_have_decl" >>confdefs.h
ac_fn_check_decl "$LINENO" "ngtcp2_crypto_encrypt_cb" "ac_cv_have_decl_ngtcp2_crypto_encrypt_cb" "$ac_includes_default
#include <ngtcp2/ngtcp2_crypto.h>
" "$ac_c_undeclared_builtin_options" "CFLAGS"
if test "x$ac_cv_have_decl_ngtcp2_crypto_encrypt_cb" = xyes
then :
ac_have_decl=1
else $as_nop
ac_have_decl=0
fi
printf "%s\n" "#define HAVE_DECL_NGTCP2_CRYPTO_ENCRYPT_CB $ac_have_decl" >>confdefs.h
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_ossl" >&5
printf %s "checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_ossl... " >&6; }
if test ${ac_cv_lib_ngtcp2_crypto_ossl_ngtcp2_crypto_encrypt_cb+y}
then :
printf %s "(cached) " >&6
else $as_nop
ac_check_lib_save_LIBS=$LIBS
LIBS="-lngtcp2_crypto_ossl $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
char ngtcp2_crypto_encrypt_cb ();
int
main (void)
{
return ngtcp2_crypto_encrypt_cb ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
ac_cv_lib_ngtcp2_crypto_ossl_ngtcp2_crypto_encrypt_cb=yes
else $as_nop
ac_cv_lib_ngtcp2_crypto_ossl_ngtcp2_crypto_encrypt_cb=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ngtcp2_crypto_ossl_ngtcp2_crypto_encrypt_cb" >&5
printf "%s\n" "$ac_cv_lib_ngtcp2_crypto_ossl_ngtcp2_crypto_encrypt_cb" >&6; }
if test "x$ac_cv_lib_ngtcp2_crypto_ossl_ngtcp2_crypto_encrypt_cb" = xyes
then :
LIBS="$LIBS -lngtcp2_crypto_ossl"
printf "%s\n" "#define USE_NGTCP2_CRYPTO_OSSL 1" >>confdefs.h
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_openssl" >&5
printf %s "checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_openssl... " >&6; }
if test ${ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb+y}
then :
printf %s "(cached) " >&6
else $as_nop
ac_check_lib_save_LIBS=$LIBS
LIBS="-lngtcp2_crypto_openssl $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
char ngtcp2_crypto_encrypt_cb ();
int
main (void)
{
return ngtcp2_crypto_encrypt_cb ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb=yes
else $as_nop
ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb" >&5
printf "%s\n" "$ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb" >&6; }
if test "x$ac_cv_lib_ngtcp2_crypto_openssl_ngtcp2_crypto_encrypt_cb" = xyes
then :
LIBS="$LIBS -lngtcp2_crypto_openssl"
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_quictls" >&5
printf %s "checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_quictls... " >&6; }
if test ${ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb+y}
then :
printf %s "(cached) " >&6
else $as_nop
ac_check_lib_save_LIBS=$LIBS
LIBS="-lngtcp2_crypto_quictls $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
char ngtcp2_crypto_encrypt_cb ();
int
main (void)
{
return ngtcp2_crypto_encrypt_cb ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb=yes
else $as_nop
ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb" >&5
printf "%s\n" "$ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb" >&6; }
if test "x$ac_cv_lib_ngtcp2_crypto_quictls_ngtcp2_crypto_encrypt_cb" = xyes
then :
LIBS="$LIBS -lngtcp2_crypto_quictls"
fi
fi
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_crypto_encrypt_cb" "ac_cv_func_ngtcp2_crypto_encrypt_cb"
if test "x$ac_cv_func_ngtcp2_crypto_encrypt_cb" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CRYPTO_ENCRYPT_CB 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_ccerr_default" "ac_cv_func_ngtcp2_ccerr_default"
if test "x$ac_cv_func_ngtcp2_ccerr_default" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CCERR_DEFAULT 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_conn_in_closing_period" "ac_cv_func_ngtcp2_conn_in_closing_period"
if test "x$ac_cv_func_ngtcp2_conn_in_closing_period" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_conn_in_draining_period" "ac_cv_func_ngtcp2_conn_in_draining_period"
if test "x$ac_cv_func_ngtcp2_conn_in_draining_period" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_conn_get_max_local_streams_uni" "ac_cv_func_ngtcp2_conn_get_max_local_streams_uni"
if test "x$ac_cv_func_ngtcp2_conn_get_max_local_streams_uni" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_crypto_quictls_from_ossl_encryption_level" "ac_cv_func_ngtcp2_crypto_quictls_from_ossl_encryption_level"
if test "x$ac_cv_func_ngtcp2_crypto_quictls_from_ossl_encryption_level" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_crypto_quictls_configure_server_context" "ac_cv_func_ngtcp2_crypto_quictls_configure_server_context"
if test "x$ac_cv_func_ngtcp2_crypto_quictls_configure_server_context" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_crypto_quictls_configure_client_context" "ac_cv_func_ngtcp2_crypto_quictls_configure_client_context"
if test "x$ac_cv_func_ngtcp2_crypto_quictls_configure_client_context" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_crypto_quictls_init" "ac_cv_func_ngtcp2_crypto_quictls_init"
if test "x$ac_cv_func_ngtcp2_crypto_quictls_init" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CRYPTO_QUICTLS_INIT 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_conn_get_num_scid" "ac_cv_func_ngtcp2_conn_get_num_scid"
if test "x$ac_cv_func_ngtcp2_conn_get_num_scid" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CONN_GET_NUM_SCID 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_conn_tls_early_data_rejected" "ac_cv_func_ngtcp2_conn_tls_early_data_rejected"
if test "x$ac_cv_func_ngtcp2_conn_tls_early_data_rejected" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CONN_TLS_EARLY_DATA_REJECTED 1" >>confdefs.h
fi
ac_fn_c_check_func "$LINENO" "ngtcp2_conn_encode_0rtt_transport_params" "ac_cv_func_ngtcp2_conn_encode_0rtt_transport_params"
if test "x$ac_cv_func_ngtcp2_conn_encode_0rtt_transport_params" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS 1" >>confdefs.h
fi
# these check_funcs need -lssl
BAKLIBS="$LIBS"
LIBS="-lssl $LIBS"
for ac_func in SSL_is_quic
do :
ac_fn_c_check_func "$LINENO" "SSL_is_quic" "ac_cv_func_SSL_is_quic"
if test "x$ac_cv_func_SSL_is_quic" = xyes
then :
printf "%s\n" "#define HAVE_SSL_IS_QUIC 1" >>confdefs.h
else $as_nop
as_fn_error $? "No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2." "$LINENO" 5
fi
done
LIBS="$BAKLIBS"
ac_fn_c_check_type "$LINENO" "struct ngtcp2_version_cid" "ac_cv_type_struct_ngtcp2_version_cid" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
"
if test "x$ac_cv_type_struct_ngtcp2_version_cid" = xyes
then :
printf "%s\n" "#define HAVE_STRUCT_NGTCP2_VERSION_CID 1" >>confdefs.h
fi
ac_fn_c_check_type "$LINENO" "ngtcp2_encryption_level" "ac_cv_type_ngtcp2_encryption_level" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
"
if test "x$ac_cv_type_ngtcp2_encryption_level" = xyes
then :
printf "%s\n" "#define HAVE_NGTCP2_ENCRYPTION_LEVEL 1" >>confdefs.h
fi
ac_fn_c_check_member "$LINENO" "struct ngtcp2_pkt_hd" "tokenlen" "ac_cv_member_struct_ngtcp2_pkt_hd_tokenlen" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
"
if test "x$ac_cv_member_struct_ngtcp2_pkt_hd_tokenlen" = xyes
then :
printf "%s\n" "#define HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN 1" >>confdefs.h
fi
ac_fn_c_check_member "$LINENO" "struct ngtcp2_settings" "tokenlen" "ac_cv_member_struct_ngtcp2_settings_tokenlen" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
"
if test "x$ac_cv_member_struct_ngtcp2_settings_tokenlen" = xyes
then :
printf "%s\n" "#define HAVE_STRUCT_NGTCP2_SETTINGS_TOKENLEN 1" >>confdefs.h
fi
ac_fn_c_check_member "$LINENO" "struct ngtcp2_settings" "max_tx_udp_payload_size" "ac_cv_member_struct_ngtcp2_settings_max_tx_udp_payload_size" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
"
if test "x$ac_cv_member_struct_ngtcp2_settings_max_tx_udp_payload_size" = xyes
then :
printf "%s\n" "#define HAVE_STRUCT_NGTCP2_SETTINGS_MAX_TX_UDP_PAYLOAD_SIZE 1" >>confdefs.h
fi
ac_fn_c_check_member "$LINENO" "struct ngtcp2_transport_params" "original_dcid_present" "ac_cv_member_struct_ngtcp2_transport_params_original_dcid_present" "$ac_includes_default
#include <ngtcp2/ngtcp2.h>
"
if test "x$ac_cv_member_struct_ngtcp2_transport_params_original_dcid_present" = xyes
then :
printf "%s\n" "#define HAVE_STRUCT_NGTCP2_TRANSPORT_PARAMS_ORIGINAL_DCID_PRESENT 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ngtcp2_conn_shutdown_stream has 4 arguments" >&5
printf %s "checking whether ngtcp2_conn_shutdown_stream has 4 arguments... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
#include <ngtcp2/ngtcp2.h>
int
main (void)
{
(void)ngtcp2_conn_shutdown_stream(NULL, 0, 0, 0);
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
printf "%s\n" "#define HAVE_NGTCP2_CONN_SHUTDOWN_STREAM4 1" >>confdefs.h
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
# set static linking for uninstalled libraries if requested
staticexe=""
@@ -23626,48 +23068,6 @@ if echo $host_os | grep darwin8 > /dev/null; then
printf "%s\n" "#define DARWIN_BROKEN_SETREUID 1" >>confdefs.h
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for atomic_store" >&5
printf %s "checking for atomic_store... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
#ifdef HAVE_STDATOMIC_H
#include <stdatomic.h>
#endif
int
main (void)
{
int newvar = 5, var = 0;
atomic_store((_Atomic int*)&var, newvar);
newvar = 0;
/* condition to use the variables. */
if(var == newvar) return 1;
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
printf "%s\n" "#define HAVE_LINK_ATOMIC_STORE 1" >>confdefs.h
else $as_nop
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
ac_fn_check_decl "$LINENO" "inet_pton" "ac_cv_have_decl_inet_pton" "
$ac_includes_default
#ifdef HAVE_NETINET_IN_H
@@ -24309,12 +23709,10 @@ if test x_$enable_lock_checks = x_yes; then
UBSYMS="-export-symbols clubsyms.def"
cp ${srcdir}/libunbound/ubsyms.def clubsyms.def
echo lock_protect >> clubsyms.def
echo lock_protect_place >> clubsyms.def
echo lock_unprotect >> clubsyms.def
echo lock_get_mem >> clubsyms.def
echo checklock_start >> clubsyms.def
echo checklock_stop >> clubsyms.def
echo checklock_set_output_name >> clubsyms.def
echo checklock_lock >> clubsyms.def
echo checklock_unlock >> clubsyms.def
echo checklock_init >> clubsyms.def
@@ -24344,55 +23742,7 @@ fi
if test "x$opt_dnstap" != "xno"; then
# Extract the first word of "protoc", so it can be a program name with args.
set dummy protoc; ac_word=$2
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_path_PROTOC+y}
then :
printf %s "(cached) " >&6
else $as_nop
case $PROTOC in
[\\/]* | ?:[\\/]*)
ac_cv_path_PROTOC="$PROTOC" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
case $as_dir in #(((
'') as_dir=./ ;;
*/) ;;
*) as_dir=$as_dir/ ;;
esac
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
ac_cv_path_PROTOC="$as_dir$ac_word$ac_exec_ext"
printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
PROTOC=$ac_cv_path_PROTOC
if test -n "$PROTOC"; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PROTOC" >&5
printf "%s\n" "$PROTOC" >&6; }
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi
# 'protoc-c' is deprecated. We use 'protoc' instead. If it can not be
# found, try 'protoc-c'.
if test -z "$PROTOC"; then
# Extract the first word of "protoc-c", so it can be a program name with args.
# Extract the first word of "protoc-c", so it can be a program name with args.
set dummy protoc-c; ac_word=$2
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
@@ -24437,83 +23787,9 @@ printf "%s\n" "no" >&6; }
fi
else
PROTOC_C="$PROTOC"
fi
if test -z "$PROTOC_C"; then
as_fn_error $? "The protoc or protoc-c program was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c to provide protoc or protoc-c" "$LINENO" 5
fi
# Check for protoc-gen-c plugin
# Extract the first word of "protoc-gen-c", so it can be a program name with args.
set dummy protoc-gen-c; ac_word=$2
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
printf %s "checking for $ac_word... " >&6; }
if test ${ac_cv_path_PROTOC_GEN_C+y}
then :
printf %s "(cached) " >&6
else $as_nop
case $PROTOC_GEN_C in
[\\/]* | ?:[\\/]*)
ac_cv_path_PROTOC_GEN_C="$PROTOC_GEN_C" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
case $as_dir in #(((
'') as_dir=./ ;;
*/) ;;
*) as_dir=$as_dir/ ;;
esac
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
ac_cv_path_PROTOC_GEN_C="$as_dir$ac_word$ac_exec_ext"
printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
;;
esac
fi
PROTOC_GEN_C=$ac_cv_path_PROTOC_GEN_C
if test -n "$PROTOC_GEN_C"; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PROTOC_GEN_C" >&5
printf "%s\n" "$PROTOC_GEN_C" >&6; }
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
fi
if test -z "$PROTOC_GEN_C"; then
as_fn_error $? "The protoc-gen-c plugin was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c-compiler to provide protoc-gen-c" "$LINENO" 5
fi
# Test that protoc-gen-c actually works
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if protoc-gen-c plugin works" >&5
printf %s "checking if protoc-gen-c plugin works... " >&6; }
cat > conftest.proto << EOF
syntax = "proto2";
message TestMessage {
optional string test_field = 1;
}
EOF
if $PROTOC_C --c_out=. conftest.proto >/dev/null 2>&1; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
rm -f conftest.proto conftest.pb-c.c conftest.pb-c.h
else
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
rm -f conftest.proto conftest.pb-c.c conftest.pb-c.h
as_fn_error $? "The protoc-gen-c plugin is not working properly. Please ensure protobuf-c-compiler is properly installed" "$LINENO" 5
fi
if test -z "$PROTOC_C"; then
as_fn_error $? "The protoc-c program was not found. Please install protobuf-c!" "$LINENO" 5
fi
# Check whether --with-protobuf-c was given.
if test ${with_protobuf_c+y}
@@ -25291,27 +24567,9 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 10240" >>confdefs.h
version=1.24.0
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build time" >&5
printf %s "checking for build time... " >&6; }
ax_date_fmt="%b %e, %Y"
if test x"$SOURCE_DATE_EPOCH" = x
then :
date=`date "+$ax_date_fmt"`
else $as_nop
ax_build_date=`date -u -d "@$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null \
|| date -u -r "$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null`
if test x"$ax_build_date" = x
then :
as_fn_error $? "malformed SOURCE_DATE_EPOCH" "$LINENO" 5
else $as_nop
date=$ax_build_date
fi
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $date" >&5
printf "%s\n" "$date" >&6; }
version=1.20.1
date=`date +'%b %e, %Y'`
ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service"
@@ -25821,7 +25079,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.24.0, which was
This file was extended by unbound $as_me 1.20.1, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -25889,7 +25147,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
unbound config.status 1.24.0
unbound config.status 1.20.1
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
+8 -163
View File
@@ -2,7 +2,6 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.56])
sinclude(acx_nlnetlabs.m4)
sinclude(ax_build_date_epoch.m4)
sinclude(ax_pthread.m4)
sinclude(acx_python.m4)
sinclude(ax_pkg_swig.m4)
@@ -11,15 +10,15 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[24])
m4_define([VERSION_MICRO],[0])
m4_define([VERSION_MINOR],[20])
m4_define([VERSION_MICRO],[1])
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=33
LIBUNBOUND_REVISION=28
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@@ -114,12 +113,7 @@ LIBUNBOUND_AGE=1
# 1.19.2 had 9:25:1
# 1.19.3 had 9:26:1
# 1.20.0 had 9:27:1
# 1.21.0 had 9:28:1
# 1.21.1 had 9:29:1
# 1.22.0 had 9:30:1
# 1.23.0 had 9:31:1
# 1.23.1 had 9:32:1
# 1.24.0 had 9:33:1
# 1.20.1 had 9:28:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@@ -345,8 +339,6 @@ AC_MSG_RESULT($ac_cv_c_weak_attribute)
if test $ac_cv_c_weak_attribute = yes; then
AC_DEFINE(HAVE_ATTR_WEAK, 1, [Whether the C compiler accepts the "weak" attribute])
AC_DEFINE(ATTR_WEAK, [__attribute__((weak))], [apply the weak attribute to a symbol])
else
AC_DEFINE(ATTR_WEAK,[], [apply the weak attribute to a symbol])
fi
])dnl End of CHECK_WEAK_ATTRIBUTE
@@ -368,54 +360,11 @@ AC_MSG_RESULT($ac_cv_c_noreturn_attribute)
if test $ac_cv_c_noreturn_attribute = yes; then
AC_DEFINE(HAVE_ATTR_NORETURN, 1, [Whether the C compiler accepts the "noreturn" attribute])
AC_DEFINE(ATTR_NORETURN, [__attribute__((__noreturn__))], [apply the noreturn attribute to a function that exits the program])
else
AC_DEFINE(ATTR_NORETURN,[], [apply the noreturn attribute to a function that exits the program])
fi
])dnl End of CHECK_NORETURN_ATTRIBUTE
CHECK_NORETURN_ATTRIBUTE
AC_DEFUN([CHECK_FALLTHROUGH_ATTRIBUTE],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "fallthrough" attribute)
BAKCFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Werror"
AC_CACHE_VAL(ac_cv_c_fallthrough_attribute,
[ac_cv_c_fallthrough_attribute=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h>
void f(int x) {
int y = 0;
switch(x) {
case 1:
y = 1;
__attribute__((fallthrough));
/* fallthrough */
case 2:
y++;
break;
case 3:
y = 3;
break;
}
printf("%d", y);
}
]], [[
f(1);
]])],[ac_cv_c_fallthrough_attribute="yes"],[ac_cv_c_fallthrough_attribute="no"])
])
CFLAGS="$BAKCFLAGS"
AC_MSG_RESULT($ac_cv_c_fallthrough_attribute)
if test $ac_cv_c_fallthrough_attribute = yes; then
AC_DEFINE(HAVE_ATTR_FALLTHROUGH, 1, [Whether the C compiler accepts the "fallthrough" attribute])
AC_DEFINE(ATTR_FALLTHROUGH, [__attribute__((fallthrough));], [apply the fallthrough attribute.])
else
AC_DEFINE(ATTR_FALLTHROUGH,[], [apply the fallthrough attribute.])
fi
])dnl End of CHECK_FALLTHROUGH_ATTRIBUTE
CHECK_FALLTHROUGH_ATTRIBUTE
if test "$srcdir" != "."; then
CPPFLAGS="$CPPFLAGS -I$srcdir"
fi
@@ -526,7 +475,6 @@ AC_CHECK_HEADERS([netioapi.h],,, [AC_INCLUDES_DEFAULT
# Check for Linux timestamping headers
AC_CHECK_HEADERS([linux/net_tstamp.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_HEADERS([stdatomic.h],,, [AC_INCLUDES_DEFAULT])
# check for types.
# Using own tests for int64* because autoconf builtin only give 32bit.
@@ -912,8 +860,7 @@ if test "`uname`" = "Linux"; then
GCC_DOCKER_LINTFLAGS='-syntax'
AC_SUBST(GCC_DOCKER_LINTFLAGS)
fi
AX_BUILD_DATE_EPOCH(CONFIG_DATE, [%Y%m%d])
AC_ARG_VAR(SOURCE_DATE_EPOCH, [If it is set, it uses the value of that variable instead of the current time as the build timestamp. The format is a unix timestamp. This enables reproducible build output.])
CONFIG_DATE=`date +%Y%m%d`
AC_SUBST(CONFIG_DATE)
# Checks for libraries.
@@ -997,7 +944,7 @@ else
AC_MSG_RESULT([no])
fi
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h openssl/param_build.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex SSL_CTX_set_tmp_ecdh])
# these check_funcs need -lssl
BAKLIBS="$LIBS"
@@ -1005,7 +952,7 @@ LIBS="-lssl $LIBS"
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb SSL_get0_alpn_selected SSL_CTX_set_alpn_protos SSL_get1_peer_certificate])
LIBS="$BAKLIBS"
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto,SSL_CTX_set_tmp_ecdh], [], [], [
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
AC_INCLUDES_DEFAULT
#ifdef HAVE_OPENSSL_ERR_H
#include <openssl/err.h>
@@ -1585,76 +1532,6 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
])
fi
# ngtcp2
AC_ARG_WITH(libngtcp2, AS_HELP_STRING([--with-libngtcp2=path],[specify explicit path for libngtcp2, for QUIC.]),
[ ],[ withval="no" ])
found_libngtcp2="no"
if test x_$withval = x_yes -o x_$withval != x_no; then
AC_MSG_CHECKING(for libngtcp2)
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/ngtcp2/ngtcp2.h"; then
found_libngtcp2="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([HAVE_NGTCP2], [1], [Define this to use ngtcp2.])
LIBS="$LIBS -lngtcp2"
break;
fi
done
if test x_$found_libngtcp2 != x_yes; then
AC_MSG_ERROR([Could not find libngtcp2, ngtcp2.h])
fi
AC_CHECK_HEADERS([ngtcp2/ngtcp2.h ngtcp2/ngtcp2_crypto_ossl.h ngtcp2/ngtcp2_crypto_openssl.h ngtcp2/ngtcp2_crypto_quictls.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_DECLS([ngtcp2_conn_server_new], [], [], [AC_INCLUDES_DEFAULT
#include <ngtcp2/ngtcp2.h>
])
AC_CHECK_DECLS([ngtcp2_crypto_encrypt_cb], [], [], [AC_INCLUDES_DEFAULT
#include <ngtcp2/ngtcp2_crypto.h>
])
AC_CHECK_LIB([ngtcp2_crypto_ossl], [ngtcp2_crypto_encrypt_cb], [
LIBS="$LIBS -lngtcp2_crypto_ossl"
AC_DEFINE(USE_NGTCP2_CRYPTO_OSSL, 1, [Define this to use ngtcp2_crypto_ossl.])
], [
AC_CHECK_LIB([ngtcp2_crypto_openssl], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_openssl" ], [
AC_CHECK_LIB([ngtcp2_crypto_quictls], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_quictls" ])
])
])
AC_CHECK_FUNCS([ngtcp2_crypto_encrypt_cb ngtcp2_ccerr_default ngtcp2_conn_in_closing_period ngtcp2_conn_in_draining_period ngtcp2_conn_get_max_local_streams_uni ngtcp2_crypto_quictls_from_ossl_encryption_level ngtcp2_crypto_quictls_configure_server_context ngtcp2_crypto_quictls_configure_client_context ngtcp2_crypto_quictls_init ngtcp2_conn_get_num_scid ngtcp2_conn_tls_early_data_rejected ngtcp2_conn_encode_0rtt_transport_params])
# these check_funcs need -lssl
BAKLIBS="$LIBS"
LIBS="-lssl $LIBS"
AC_CHECK_FUNCS([SSL_is_quic], [], [AC_MSG_ERROR([No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2.])])
LIBS="$BAKLIBS"
AC_CHECK_TYPES([struct ngtcp2_version_cid, ngtcp2_encryption_level],,,[AC_INCLUDES_DEFAULT
#include <ngtcp2/ngtcp2.h>
])
AC_CHECK_MEMBERS([struct ngtcp2_pkt_hd.tokenlen, struct ngtcp2_settings.tokenlen, struct ngtcp2_settings.max_tx_udp_payload_size, struct ngtcp2_transport_params.original_dcid_present],,,[AC_INCLUDES_DEFAULT
#include <ngtcp2/ngtcp2.h>
])
AC_MSG_CHECKING([whether ngtcp2_conn_shutdown_stream has 4 arguments])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
#include <ngtcp2/ngtcp2.h>
],[
(void)ngtcp2_conn_shutdown_stream(NULL, 0, 0, 0);
])],[
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_NGTCP2_CONN_SHUTDOWN_STREAM4, 1, [Define if ngtcp2_conn_shutdown_stream has 4 arguments.])
],[
AC_MSG_RESULT(no)
])
fi
# set static linking for uninstalled libraries if requested
AC_SUBST(staticexe)
staticexe=""
@@ -1832,25 +1709,6 @@ AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
if echo $host_os | grep darwin8 > /dev/null; then
AC_DEFINE(DARWIN_BROKEN_SETREUID, 1, [Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work])
fi
AC_MSG_CHECKING([for atomic_store])
AC_LINK_IFELSE([AC_LANG_PROGRAM(AC_INCLUDES_DEFAULT [[
#ifdef HAVE_STDATOMIC_H
#include <stdatomic.h>
#endif
]], [[
int newvar = 5, var = 0;
atomic_store((_Atomic int*)&var, newvar);
newvar = 0;
/* condition to use the variables. */
if(var == newvar) return 1;
]])], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_LINK_ATOMIC_STORE, 1, [If we have atomic_store])
], [
AC_MSG_RESULT([no])
])
AC_CHECK_DECLS([inet_pton,inet_ntop], [], [], [
AC_INCLUDES_DEFAULT
#ifdef HAVE_NETINET_IN_H
@@ -1989,12 +1847,10 @@ if test x_$enable_lock_checks = x_yes; then
UBSYMS="-export-symbols clubsyms.def"
cp ${srcdir}/libunbound/ubsyms.def clubsyms.def
echo lock_protect >> clubsyms.def
echo lock_protect_place >> clubsyms.def
echo lock_unprotect >> clubsyms.def
echo lock_get_mem >> clubsyms.def
echo checklock_start >> clubsyms.def
echo checklock_stop >> clubsyms.def
echo checklock_set_output_name >> clubsyms.def
echo checklock_lock >> clubsyms.def
echo checklock_unlock >> clubsyms.def
echo checklock_init >> clubsyms.def
@@ -2428,10 +2284,6 @@ struct sockaddr_storage;
# define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__)
# define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__)
# define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__)
# define strdup(s) unbound_stat_strdup_log(s, __FILE__, __LINE__, __func__)
#ifdef HAVE_REALLOCARRAY
# define reallocarray(p,n,s) unbound_stat_reallocarray_log(p, n, s, __FILE__, __LINE__, __func__)
#endif
void *unbound_stat_malloc(size_t size);
void *unbound_stat_calloc(size_t nmemb, size_t size);
void unbound_stat_free(void *ptr);
@@ -2444,10 +2296,6 @@ void unbound_stat_free_log(void *ptr, const char* file, int line,
const char* func);
void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
int line, const char* func);
void *unbound_stat_reallocarray_log(void *ptr, size_t nmemb, size_t size,
const char* file, int line, const char* func);
char *unbound_stat_strdup_log(const char *s, const char* file, int line,
const char* func);
#elif defined(UNBOUND_ALLOC_LITE)
# include "util/alloc.h"
#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */
@@ -2458,8 +2306,6 @@ char *unbound_stat_strdup_log(const char *s, const char* file, int line,
#define UNBOUND_DNS_OVER_TLS_PORT 853
/** default port for DNS over HTTPS traffic. */
#define UNBOUND_DNS_OVER_HTTPS_PORT 443
/** default port for DNS over QUIC traffic. */
#define UNBOUND_DNS_OVER_QUIC_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
@@ -2471,8 +2317,7 @@ char *unbound_stat_strdup_log(const char *s, const char* file, int line,
dnl if we build from source tree, the man pages need @date@ and @version@
dnl if this is a distro tarball, that was already done by makedist.sh
AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO])
AX_BUILD_DATE_EPOCH(date, [[%b %e, %Y]])
AC_SUBST(date)
AC_SUBST(date, [`date +'%b %e, %Y'`])
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service])
AC_CONFIG_HEADERS([config.h])
+1 -1
View File
@@ -236,7 +236,7 @@ index 54006940..768fe202 100644
+ /* see if the failure did get (parent-lame) info */
+ if(!cache_fill_missing(super->env,
+ super_iq->qchase.qclass, super->region,
+ super_iq->dp, 0))
+ super_iq->dp))
+ log_err("ASN-AAAA-filter: out of memory adding missing");
+ dpns->resolved = 1; /* mark as failed */
+ }
+4 -7
View File
@@ -1,24 +1,21 @@
#!/usr/bin/env bash
LIBEXPAT_FNAME=expat-2.7.0
LIBEXPAT_VERSION_DIR=R_2_7_0
echo "Downloading Expat"
if ! curl -L -k -s -o $LIBEXPAT_FNAME.tar.gz https://github.com/libexpat/libexpat/releases/download/$LIBEXPAT_VERSION_DIR/$LIBEXPAT_FNAME.tar.gz;
if ! curl -L -k -s -o expat-2.2.9.tar.gz https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.gz;
then
echo "Failed to download Expat"
exit 1
fi
echo "Unpacking Expat"
rm -rf ./$LIBEXPAT_FNAME
if ! tar -xf $LIBEXPAT_FNAME.tar.gz;
rm -rf ./expat-2.2.9
if ! tar -xf expat-2.2.9.tar.gz;
then
echo "Failed to unpack Expat"
exit 1
fi
cd $LIBEXPAT_FNAME || exit 1
cd expat-2.2.9 || exit 1
echo "Configuring Expat"
if ! ./configure --build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" --prefix="$ANDROID_PREFIX"; then
+7 -11
View File
@@ -1,32 +1,28 @@
#!/usr/bin/env bash
LIBEXPAT_FNAME=expat-2.7.0
LIBEXPAT_VERSION_DIR=R_2_7_0
echo "Downloading Expat"
if ! curl -L -k -s -o $LIBEXPAT_FNAME.tar.gz https://github.com/libexpat/libexpat/releases/download/$LIBEXPAT_VERSION_DIR/$LIBEXPAT_FNAME.tar.gz;
if ! curl -L -k -s -o expat-2.2.9.tar.gz https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.gz;
then
echo "Failed to download Expat"
exit 1
fi
echo "Unpacking Expat"
rm -rf ./$LIBEXPAT_FNAME
if ! tar -xf $LIBEXPAT_FNAME.tar.gz;
rm -rf ./expat-2.2.9
if ! tar -xf expat-2.2.9.tar.gz;
then
echo "Failed to unpack Expat"
exit 1
fi
cd $LIBEXPAT_FNAME || exit 1
cd expat-2.2.9 || exit 1
export PKG_CONFIG_PATH="$IOS_PREFIX/lib/pkgconfig"
echo "Configuring Expat"
if ! ./configure --without-tests \
--build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \
--prefix="$IOS_PREFIX" ;
then
if ! ./configure \
--build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \
--prefix="$IOS_PREFIX" ; then
echo "Error: Failed to configure Expat"
cat config.log
exit 1
-6
View File
@@ -38,17 +38,11 @@
; - `LockPersonality=yes` locks down the personality system call so that the
; kernel execution domain may not be changed from the default.
;
; - With /etc/systemd/network/*.network a setting to make sure the network
; is not considered online too early, can reduce network unreachable
; errors on server start:
; [Link]
; RequiredForOnline=routable
;
[Unit]
Description=Validating, recursive, and caching DNS resolver
Documentation=man:unbound(8)
After=network-online.target
Wants=network-online.target
Before=nss-lookup.target
[Install]
+13 -17
View File
@@ -221,9 +221,7 @@ acl_interface_insert(struct acl_list* acl_interface,
struct sockaddr_storage* addr, socklen_t addrlen,
enum acl_access control)
{
struct acl_addr* node = acl_find_or_create(acl_interface, addr, addrlen, control);
node->is_interface = 1;
return node;
return acl_find_or_create(acl_interface, addr, addrlen, control);
}
/** apply acl_tag string */
@@ -553,6 +551,17 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
return 1;
}
int
acl_interface_compare(const void* k1, const void* k2)
{
struct addr_tree_node* n1 = (struct addr_tree_node*)k1;
struct addr_tree_node* n2 = (struct addr_tree_node*)k2;
return sockaddr_cmp(&n1->addr, n1->addrlen, &n2->addr,
n2->addrlen);
/* We don't care about comparing node->net. All addresses in the
* acl_interface tree have either 32 (ipv4) or 128 (ipv6). */
}
void
acl_interface_init(struct acl_list* acl_interface)
{
@@ -807,23 +816,10 @@ log_acl_action(const char* action, struct sockaddr_storage* addr,
addr_to_str(&acladdr->node.addr, acladdr->node.addrlen,
n, sizeof(n));
verbose(VERB_ALGO, "%s query from %s port %d because of "
"%s/%d %s%s", action, a, (int)port, n,
acladdr->node.net,
acladdr->is_interface?"(ACL on interface IP) ":"",
"%s/%d %s", action, a, (int)port, n, acladdr->node.net,
acl_access_to_str(acl));
} else {
verbose(VERB_ALGO, "%s query from %s port %d", action, a,
(int)port);
}
}
void acl_list_swap_tree(struct acl_list* acl, struct acl_list* data)
{
/* swap tree and region */
rbtree_type oldtree = acl->tree;
struct regional* oldregion = acl->region;
acl->tree = data->tree;
acl->region = data->region;
data->tree = oldtree;
data->region = oldregion;
}
+3 -10
View File
@@ -107,8 +107,6 @@ struct acl_addr {
struct config_strlist** tag_datas;
/** size of the tag_datas array */
size_t tag_datas_size;
/* If the acl node is for an interface */
int is_interface;
/* view element, NULL if none */
struct view* view;
};
@@ -149,6 +147,9 @@ acl_interface_insert(struct acl_list* acl_interface,
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
struct views* v);
/** compare ACL interface "addr_tree" nodes (+port) */
int acl_interface_compare(const void* k1, const void* k2);
/**
* Initialise (also clean) the acl_interface struct.
* @param acl_interface: where to store.
@@ -201,12 +202,4 @@ const char* acl_access_to_str(enum acl_access acl);
void log_acl_action(const char* action, struct sockaddr_storage* addr,
socklen_t addrlen, enum acl_access acl, struct acl_addr* acladdr);
/**
* Swap internal tree with preallocated entries.
* @param acl: the acl structure.
* @param data: the data structure used to take elements from. This contains
* the old elements on return.
*/
void acl_list_swap_tree(struct acl_list* acl, struct acl_list* data);
#endif /* DAEMON_ACL_LIST_H */
+107 -236
View File
@@ -62,231 +62,84 @@
#include "sldns/wire2str.h"
#include "sldns/str2wire.h"
static void spool_txt_printf(struct config_strlist_head* txt,
const char* format, ...) ATTR_FORMAT(printf, 2, 3);
/** Append to strlist at end, and log error if out of memory. */
static void
spool_txt_string(struct config_strlist_head* txt, char* str)
{
if(!cfg_strlist_append(txt, strdup(str))) {
log_err("out of memory in spool text");
}
}
/** Spool txt to spool list. */
static void
spool_txt_vmsg(struct config_strlist_head* txt, const char* format,
va_list args)
{
char msg[65535];
vsnprintf(msg, sizeof(msg), format, args);
spool_txt_string(txt, msg);
}
/** Print item to spool list. On alloc failure the list is as before. */
static void
spool_txt_printf(struct config_strlist_head* txt, const char* format, ...)
{
va_list args;
va_start(args, format);
spool_txt_vmsg(txt, format, args);
va_end(args);
}
/** dump one rrset zonefile line */
static void
dump_rrset_line(struct config_strlist_head* txt, struct ub_packed_rrset_key* k,
time_t now, size_t i)
static int
dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
{
char s[65535];
if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
spool_txt_string(txt, "BADRR\n");
return;
return ssl_printf(ssl, "BADRR\n");
}
spool_txt_string(txt, s);
return ssl_printf(ssl, "%s", s);
}
/** dump rrset key and data info */
static void
dump_rrset(struct config_strlist_head* txt, struct ub_packed_rrset_key* k,
static int
dump_rrset(RES* ssl, struct ub_packed_rrset_key* k,
struct packed_rrset_data* d, time_t now)
{
size_t i;
/* rd lock held by caller */
if(!k || !d) return;
if(k->id == 0) return; /* deleted */
if(d->ttl < now) return; /* expired */
if(!k || !d) return 1;
if(k->id == 0) return 1; /* deleted */
if(d->ttl < now) return 1; /* expired */
/* meta line */
spool_txt_printf(txt, ";rrset%s " ARG_LL "d %u %u %d %d\n",
if(!ssl_printf(ssl, ";rrset%s " ARG_LL "d %u %u %d %d\n",
(k->rk.flags & PACKED_RRSET_NSEC_AT_APEX)?" nsec_apex":"",
(long long)(d->ttl - now),
(unsigned)d->count, (unsigned)d->rrsig_count,
(int)d->trust, (int)d->security
);
))
return 0;
for(i=0; i<d->count + d->rrsig_count; i++) {
dump_rrset_line(txt, k, now, i);
}
}
/** Spool strlist to the output. */
static int
spool_strlist(RES* ssl, struct config_strlist* list)
{
struct config_strlist* s;
for(s=list; s; s=s->next) {
if(!ssl_printf(ssl, "%s", s->str))
if(!dump_rrset_line(ssl, k, now, i))
return 0;
}
return 1;
}
/** dump lruhash cache and call callback for every item. */
/** dump lruhash rrset cache */
static int
dump_lruhash(struct lruhash* table,
void (*func)(struct lruhash_entry*, struct config_strlist_head*, void*),
RES* ssl, void* arg)
dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now)
{
int just_started = 1;
int not_done = 1;
hashvalue_type hash;
size_t num = 0; /* number of entries processed. */
size_t max = 2; /* number of entries after which it unlocks. */
struct config_strlist_head txt; /* Text strings spooled. */
memset(&txt, 0, sizeof(txt));
while(not_done) {
size_t i; /* hash bin. */
/* Process a number of items. */
num = 0;
lock_quick_lock(&table->lock);
if(just_started) {
i = 0;
} else {
i = hash&table->size_mask;
}
while(num < max) {
/* Process bin. */
int found = 0;
size_t num_bin = 0;
struct lruhash_bin* bin = &table->array[i];
struct lruhash_entry* e;
lock_quick_lock(&bin->lock);
for(e = bin->overflow_list; e; e = e->overflow_next) {
/* Entry e is locked by the func. */
func(e, &txt, arg);
num_bin++;
}
lock_quick_unlock(&bin->lock);
/* This addition of bin number of entries may take
* it over the max. */
num += num_bin;
/* Move to next bin. */
/* Find one with an entry, with a hash value, so we
* can continue from the hash value. The hash value
* can be indexed also if the array changes size. */
i++;
while(i < table->size) {
bin = &table->array[i];
lock_quick_lock(&bin->lock);
if(bin->overflow_list) {
hash = bin->overflow_list->hash;
lock_quick_unlock(&bin->lock);
found = 1;
just_started = 0;
break;
}
lock_quick_unlock(&bin->lock);
i++;
}
if(!found) {
not_done = 0;
break;
}
}
lock_quick_unlock(&table->lock);
/* Print the spooled items, that are collected while the
* locks are locked. The print happens while they are not
* locked. */
if(txt.first) {
if(!spool_strlist(ssl, txt.first)) {
config_delstrlist(txt.first);
return 0;
}
config_delstrlist(txt.first);
memset(&txt, 0, sizeof(txt));
}
}
/* Print the final spooled items. */
if(txt.first) {
if(!spool_strlist(ssl, txt.first)) {
config_delstrlist(txt.first);
struct lruhash_entry* e;
/* lruhash already locked by caller */
/* walk in order of lru; best first */
for(e=h->lru_start; e; e = e->lru_next) {
lock_rw_rdlock(&e->lock);
if(!dump_rrset(ssl, (struct ub_packed_rrset_key*)e->key,
(struct packed_rrset_data*)e->data, now)) {
lock_rw_unlock(&e->lock);
return 0;
}
config_delstrlist(txt.first);
lock_rw_unlock(&e->lock);
}
return 1;
}
/** dump slabhash cache and call callback for every item. */
static int
dump_slabhash(struct slabhash* sh,
void (*func)(struct lruhash_entry*, struct config_strlist_head*, void*),
RES* ssl, void* arg)
{
/* Process a number of items at a time, then unlock the cache,
* so that ordinary processing can continue. Keep an iteration marker
* to continue the loop. That means the cache can change, items
* could be inserted and deleted. And, for example, the hash table
* can grow. */
size_t slab;
for(slab=0; slab<sh->size; slab++) {
if(!dump_lruhash(sh->array[slab], func, ssl, arg))
return 0;
}
return 1;
}
/** Struct for dump information. */
struct dump_info {
/** The worker. */
struct worker* worker;
/** The printout connection. */
RES* ssl;
};
/** Dump the rrset cache entry */
static void
dump_rrset_entry(struct lruhash_entry* e, struct config_strlist_head* txt,
void* arg)
{
struct dump_info* dump_info = (struct dump_info*)arg;
lock_rw_rdlock(&e->lock);
dump_rrset(txt, (struct ub_packed_rrset_key*)e->key,
(struct packed_rrset_data*)e->data,
*dump_info->worker->env.now);
lock_rw_unlock(&e->lock);
}
/** dump rrset cache */
static int
dump_rrset_cache(RES* ssl, struct worker* worker)
{
struct rrset_cache* r = worker->env.rrset_cache;
struct dump_info dump_info;
dump_info.worker = worker;
dump_info.ssl = ssl;
size_t slab;
if(!ssl_printf(ssl, "START_RRSET_CACHE\n")) return 0;
if(!dump_slabhash(&r->table, &dump_rrset_entry, ssl, &dump_info))
return 0;
for(slab=0; slab<r->table.size; slab++) {
lock_quick_lock(&r->table.array[slab]->lock);
if(!dump_rrset_lruhash(ssl, r->table.array[slab],
*worker->env.now)) {
lock_quick_unlock(&r->table.array[slab]->lock);
return 0;
}
lock_quick_unlock(&r->table.array[slab]->lock);
}
return ssl_printf(ssl, "END_RRSET_CACHE\n");
}
/** dump message to rrset reference */
static void
dump_msg_ref(struct config_strlist_head* txt, struct ub_packed_rrset_key* k)
static int
dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
{
char* nm, *tp, *cl;
nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
@@ -296,25 +149,30 @@ dump_msg_ref(struct config_strlist_head* txt, struct ub_packed_rrset_key* k)
free(nm);
free(tp);
free(cl);
spool_txt_string(txt, "BADREF\n");
return;
return ssl_printf(ssl, "BADREF\n");
}
if(!ssl_printf(ssl, "%s %s %s %d\n", nm, cl, tp, (int)k->rk.flags)) {
free(nm);
free(tp);
free(cl);
return 0;
}
spool_txt_printf(txt, "%s %s %s %d\n", nm, cl, tp, (int)k->rk.flags);
free(nm);
free(tp);
free(cl);
return 1;
}
/** dump message entry */
static void
dump_msg(struct config_strlist_head* txt, struct query_info* k,
struct reply_info* d, time_t now)
static int
dump_msg(RES* ssl, struct query_info* k, struct reply_info* d, time_t now)
{
size_t i;
char* nm, *tp, *cl;
if(!k || !d) return;
if(d->ttl < now) return; /* expired */
if(!k || !d) return 1;
if(d->ttl < now) return 1; /* expired */
nm = sldns_wire2str_dname(k->qname, k->qname_len);
tp = sldns_wire2str_type(k->qtype);
cl = sldns_wire2str_class(k->qclass);
@@ -322,35 +180,45 @@ dump_msg(struct config_strlist_head* txt, struct query_info* k,
free(nm);
free(tp);
free(cl);
return; /* skip this entry */
return 1; /* skip this entry */
}
if(!rrset_array_lock(d->ref, d->rrset_count, now)) {
/* rrsets have timed out or do not exist */
free(nm);
free(tp);
free(cl);
return; /* skip this entry */
return 1; /* skip this entry */
}
/* meta line */
spool_txt_printf(txt,
"msg %s %s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
nm, cl, tp,
(int)d->flags, (int)d->qdcount,
(long long)(d->ttl-now), (int)d->security,
(unsigned)d->an_numrrsets,
(unsigned)d->ns_numrrsets,
(unsigned)d->ar_numrrsets,
(int)d->reason_bogus,
d->reason_bogus_str?d->reason_bogus_str:"");
if(!ssl_printf(ssl, "msg %s %s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
nm, cl, tp,
(int)d->flags, (int)d->qdcount,
(long long)(d->ttl-now), (int)d->security,
(unsigned)d->an_numrrsets,
(unsigned)d->ns_numrrsets,
(unsigned)d->ar_numrrsets,
(int)d->reason_bogus,
d->reason_bogus_str?d->reason_bogus_str:"")) {
free(nm);
free(tp);
free(cl);
rrset_array_unlock(d->ref, d->rrset_count);
return 0;
}
free(nm);
free(tp);
free(cl);
for(i=0; i<d->rrset_count; i++) {
dump_msg_ref(txt, d->rrsets[i]);
if(!dump_msg_ref(ssl, d->rrsets[i])) {
rrset_array_unlock(d->ref, d->rrset_count);
return 0;
}
}
rrset_array_unlock(d->ref, d->rrset_count);
return 1;
}
/** copy msg to worker pad */
@@ -379,40 +247,49 @@ copy_msg(struct regional* region, struct lruhash_entry* e,
return (*k)->qname != NULL;
}
/** Dump the msg entry. */
static void
dump_msg_entry(struct lruhash_entry* e, struct config_strlist_head* txt,
void* arg)
/** dump lruhash msg cache */
static int
dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h)
{
struct dump_info* dump_info = (struct dump_info*)arg;
struct lruhash_entry* e;
struct query_info* k;
struct reply_info* d;
regional_free_all(dump_info->worker->scratchpad);
/* Make copy of rrset in worker buffer. */
lock_rw_rdlock(&e->lock);
if(!copy_msg(dump_info->worker->scratchpad, e, &k, &d)) {
/* lruhash already locked by caller */
/* walk in order of lru; best first */
for(e=h->lru_start; e; e = e->lru_next) {
regional_free_all(worker->scratchpad);
lock_rw_rdlock(&e->lock);
/* make copy of rrset in worker buffer */
if(!copy_msg(worker->scratchpad, e, &k, &d)) {
lock_rw_unlock(&e->lock);
return 0;
}
lock_rw_unlock(&e->lock);
log_err("out of memory in dump_msg_entry");
return;
/* release lock so we can lookup the rrset references
* in the rrset cache */
if(!dump_msg(ssl, k, d, *worker->env.now)) {
return 0;
}
}
lock_rw_unlock(&e->lock);
/* Release lock so we can lookup the rrset references
* in the rrset cache. */
dump_msg(txt, k, d, *dump_info->worker->env.now);
return 1;
}
/** dump msg cache */
static int
dump_msg_cache(RES* ssl, struct worker* worker)
{
struct dump_info dump_info;
dump_info.worker = worker;
dump_info.ssl = ssl;
struct slabhash* sh = worker->env.msg_cache;
size_t slab;
if(!ssl_printf(ssl, "START_MSG_CACHE\n")) return 0;
if(!dump_slabhash(worker->env.msg_cache, &dump_msg_entry, ssl,
&dump_info))
return 0;
for(slab=0; slab<sh->size; slab++) {
lock_quick_lock(&sh->array[slab]->lock);
if(!dump_msg_lruhash(ssl, worker, sh->array[slab])) {
lock_quick_unlock(&sh->array[slab]->lock);
return 0;
}
lock_quick_unlock(&sh->array[slab]->lock);
}
return ssl_printf(ssl, "END_MSG_CACHE\n");
}
@@ -815,7 +692,7 @@ load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
return 1; /* skip this one, not all references satisfied */
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags,
*worker->env.now, 1)) {
*worker->env.now)) {
log_warn("error out of memory");
return 0;
}
@@ -934,18 +811,12 @@ print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg)
struct ub_packed_rrset_key* k = msg->rep->rrsets[i];
struct packed_rrset_data* d =
(struct packed_rrset_data*)k->entry.data;
struct config_strlist_head txt;
memset(&txt, 0, sizeof(txt));
if(d->security == sec_status_bogus) {
if(!ssl_printf(ssl, "Address is BOGUS:\n"))
return;
}
dump_rrset(&txt, k, d, 0);
if(!spool_strlist(ssl, txt.first)) {
config_delstrlist(txt.first);
if(!dump_rrset(ssl, k, d, 0))
return;
}
config_delstrlist(txt.first);
}
delegpt_count_ns(dp, &n_ns, &n_miss);
delegpt_count_addr(dp, &n_addr, &n_res, &n_avail);
@@ -965,7 +836,7 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
struct delegpt* dp;
struct dns_msg* msg;
struct regional* region = worker->scratchpad;
char b[LDNS_MAX_DOMAINLEN];
char b[260];
struct query_info qinfo;
struct iter_hints_stub* stub;
int nolock = 0;
+17 -44
View File
@@ -323,7 +323,8 @@ daemon_init(void)
return daemon;
}
int setup_acl_for_ports(struct acl_list* list, struct listen_port* port_list)
static int setup_acl_for_ports(struct acl_list* list,
struct listen_port* port_list)
{
struct acl_addr* acl_node;
for(; port_list; port_list=port_list->next) {
@@ -556,12 +557,6 @@ daemon_create_workers(struct daemon* daemon)
fatal_exit("out of memory during daemon init");
numport = daemon_get_shufport(daemon, shufport);
verbose(VERB_ALGO, "total of %d outgoing ports available", numport);
#ifdef HAVE_NGTCP2
daemon->doq_table = doq_table_create(daemon->cfg, daemon->rand);
if(!daemon->doq_table)
fatal_exit("could not create doq_table: out of memory");
#endif
daemon->num = (daemon->cfg->num_threads?daemon->cfg->num_threads:1);
if(daemon->reuseport && (int)daemon->num < (int)daemon->num_ports) {
@@ -716,16 +711,16 @@ daemon_fork(struct daemon* daemon)
#endif
log_assert(daemon);
if(!(daemon->env->views = views_create()))
if(!(daemon->views = views_create()))
fatal_exit("Could not create views: out of memory");
/* create individual views and their localzone/data trees */
if(!views_apply_cfg(daemon->env->views, daemon->cfg))
if(!views_apply_cfg(daemon->views, daemon->cfg))
fatal_exit("Could not set up views");
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->env->views))
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
fatal_exit("Could not setup access control list");
if(!acl_interface_apply_cfg(daemon->acl_interface, daemon->cfg,
daemon->env->views))
daemon->views))
fatal_exit("Could not setup interface control list");
if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
fatal_exit("Could not setup TCP connection limits");
@@ -740,14 +735,6 @@ daemon_fork(struct daemon* daemon)
"dnscrypt support");
#endif
}
if(daemon->cfg->cookie_secret_file &&
daemon->cfg->cookie_secret_file[0]) {
if(!(daemon->cookie_secrets = cookie_secrets_create()))
fatal_exit("Could not create cookie_secrets: out of memory");
if(!cookie_secrets_apply_cfg(daemon->cookie_secrets,
daemon->cfg->cookie_secret_file))
fatal_exit("Could not setup cookie_secrets");
}
/* create global local_zones */
if(!(daemon->local_zones = local_zones_create()))
fatal_exit("Could not create local zones: out of memory");
@@ -761,15 +748,15 @@ daemon_fork(struct daemon* daemon)
fatal_exit("Could not set root or stub hints");
/* process raw response-ip configuration data */
if(!(daemon->env->respip_set = respip_set_create()))
if(!(daemon->respip_set = respip_set_create()))
fatal_exit("Could not create response IP set");
if(!respip_global_apply_cfg(daemon->env->respip_set, daemon->cfg))
if(!respip_global_apply_cfg(daemon->respip_set, daemon->cfg))
fatal_exit("Could not set up response IP set");
if(!respip_views_apply_cfg(daemon->env->views, daemon->cfg,
if(!respip_views_apply_cfg(daemon->views, daemon->cfg,
&have_view_respip_cfg))
fatal_exit("Could not set up per-view response IP sets");
daemon->use_response_ip = !respip_set_is_empty(
daemon->env->respip_set) || have_view_respip_cfg;
daemon->use_response_ip = !respip_set_is_empty(daemon->respip_set) ||
have_view_respip_cfg;
/* setup modules */
daemon_setup_modules(daemon);
@@ -885,18 +872,14 @@ daemon_cleanup(struct daemon* daemon)
daemon->env->hints = NULL;
local_zones_delete(daemon->local_zones);
daemon->local_zones = NULL;
respip_set_delete(daemon->env->respip_set);
daemon->env->respip_set = NULL;
views_delete(daemon->env->views);
daemon->env->views = NULL;
respip_set_delete(daemon->respip_set);
daemon->respip_set = NULL;
views_delete(daemon->views);
daemon->views = NULL;
if(daemon->env->auth_zones)
auth_zones_cleanup(daemon->env->auth_zones);
/* key cache is cleared by module deinit during next daemon_fork() */
daemon_remote_clear(daemon->rc);
if(daemon->fast_reload_thread)
fast_reload_thread_stop(daemon->fast_reload_thread);
if(daemon->fast_reload_printq_list)
fast_reload_printq_list_delete(daemon->fast_reload_printq_list);
for(i=0; i<daemon->num; i++)
worker_delete(daemon->workers[i]);
free(daemon->workers);
@@ -915,10 +898,6 @@ daemon_cleanup(struct daemon* daemon)
#ifdef USE_DNSCRYPT
dnsc_delete(daemon->dnscenv);
daemon->dnscenv = NULL;
#endif
#ifdef HAVE_NGTCP2
doq_table_delete(daemon->doq_table);
daemon->doq_table = NULL;
#endif
daemon->cfg = NULL;
}
@@ -950,20 +929,14 @@ daemon_delete(struct daemon* daemon)
acl_list_delete(daemon->acl);
acl_list_delete(daemon->acl_interface);
tcl_list_delete(daemon->tcl);
cookie_secrets_delete(daemon->cookie_secrets);
listen_desetup_locks();
free(daemon->chroot);
free(daemon->pidfile);
free(daemon->cfgfile);
free(daemon->env);
#ifdef HAVE_SSL
listen_sslctx_delete_ticket_keys();
SSL_CTX_free((SSL_CTX*)daemon->listen_dot_sslctx);
SSL_CTX_free((SSL_CTX*)daemon->listen_doh_sslctx);
SSL_CTX_free((SSL_CTX*)daemon->connect_dot_sslctx);
#endif
#ifdef HAVE_NGTCP2
SSL_CTX_free((SSL_CTX*)daemon->listen_quic_sslctx);
SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx);
SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx);
#endif
free(daemon);
/* lex cleanup */
+6 -35
View File
@@ -58,10 +58,6 @@ struct ub_randstate;
struct daemon_remote;
struct respip_set;
struct shm_main_info;
struct doq_table;
struct cookie_secrets;
struct fast_reload_thread;
struct fast_reload_printq;
#include "dnstap/dnstap_config.h"
#ifdef USE_DNSTAP
@@ -99,14 +95,8 @@ struct daemon {
struct listen_port* rc_ports;
/** remote control connections management (for first worker) */
struct daemon_remote* rc;
/** ssl context for listening to dnstcp over ssl */
void* listen_dot_sslctx;
/** ssl context for connecting to dnstcp over ssl */
void* connect_dot_sslctx;
/** ssl context for listening to DoH */
void* listen_doh_sslctx;
/** ssl context for listening to quic */
void* listen_quic_sslctx;
/** ssl context for listening to dnstcp over ssl, and connecting ssl */
void* listen_sslctx, *connect_sslctx;
/** num threads allocated */
int num;
/** num threads allocated in the previous config or 0 at first */
@@ -139,11 +129,15 @@ struct daemon {
struct timeval time_last_stat;
/** time when daemon started */
struct timeval time_boot;
/** views structure containing view tree */
struct views* views;
#ifdef USE_DNSTAP
/** the dnstap environment master value, copied and changed by threads*/
struct dt_env* dtenv;
#endif
struct shm_main_info* shm_info;
/** response-ip set with associated actions and tags. */
struct respip_set* respip_set;
/** some response-ip tags or actions are configured if true */
int use_response_ip;
/** some RPZ policies are configured */
@@ -152,23 +146,8 @@ struct daemon {
/** the dnscrypt environment */
struct dnsc_env* dnscenv;
#endif
/** the doq connection table */
struct doq_table* doq_table;
/** reuse existing cache on reload if other conditions allow it. */
int reuse_cache;
/** the EDNS cookie secrets from the cookie-secret-file */
struct cookie_secrets* cookie_secrets;
/** the fast reload thread, or NULL */
struct fast_reload_thread* fast_reload_thread;
/** the fast reload printq list */
struct fast_reload_printq* fast_reload_printq_list;
/** the fast reload option to drop mesh queries, true if so. */
int fast_reload_drop_mesh;
/** for fast reload, if the tcl, tcp connection limits, has
* changes for workers */
int fast_reload_tcl_has_changes;
/** config file name */
char* cfgfile;
};
/**
@@ -221,12 +200,4 @@ void daemon_delete(struct daemon* daemon);
*/
void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg);
/**
* Setup acl list to have entries for the port list.
* @param list: the acl interface
* @param port_list: list of open ports, or none.
* @return false on failure
*/
int setup_acl_for_ports(struct acl_list* list, struct listen_port* port_list);
#endif /* DAEMON_H */
+39 -4722
View File
File diff suppressed because it is too large Load Diff
-167
View File
@@ -48,7 +48,6 @@
#ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#endif
#include "util/locks.h"
struct config_file;
struct listen_list;
struct listen_port;
@@ -56,7 +55,6 @@ struct worker;
struct comm_reply;
struct comm_point;
struct daemon_remote;
struct config_strlist_head;
/** number of milliseconds timeout on incoming remote control handshake */
#define REMOTE_CONTROL_TCP_TIMEOUT 120000
@@ -120,137 +118,6 @@ struct remote_stream {
};
typedef struct remote_stream RES;
/**
* Notification status. This is exchanged between the fast reload thread
* and the server thread, over the commpair sockets.
*/
enum fast_reload_notification {
/** nothing, not used */
fast_reload_notification_none = 0,
/** the fast reload thread is done */
fast_reload_notification_done = 1,
/** the fast reload thread is done but with an error, it failed */
fast_reload_notification_done_error = 2,
/** the fast reload thread is told to exit by the server thread.
* Sent on server quit while the reload is running. */
fast_reload_notification_exit = 3,
/** the fast reload thread has exited, after being told to exit */
fast_reload_notification_exited = 4,
/** the fast reload thread has information to print out */
fast_reload_notification_printout = 5,
/** stop as part of the reload the thread and other threads */
fast_reload_notification_reload_stop = 6,
/** ack the stop as part of the reload, and also ack start */
fast_reload_notification_reload_ack = 7,
/** resume from stop as part of the reload */
fast_reload_notification_reload_start = 8,
/** the fast reload thread wants the mainthread to poll workers,
* after the reload, sent when nopause is used */
fast_reload_notification_reload_nopause_poll = 9
};
/**
* Fast reload printout queue. Contains a list of strings, that need to be
* printed over the file descriptor.
*/
struct fast_reload_printq {
/** if this item is in a list, the previous and next */
struct fast_reload_printq *prev, *next;
/** if this item is in a list, it is true. */
int in_list;
/** list of strings to printout */
struct config_strlist_head* to_print;
/** the current item to print. It is malloced. NULL if none. */
char* client_item;
/** The length, strlen, of the client_item, that has to be sent. */
int client_len;
/** The number of bytes sent of client_item. */
int client_byte_count;
/** the comm point for the client connection, the remote control
* client. */
struct comm_point* client_cp;
/** the remote control connection to print output to. */
struct remote_stream remote;
/** the worker that the event is added in */
struct worker* worker;
};
/**
* Fast reload auth zone change. Keeps track if an auth zone was removed,
* added or changed. This is needed because workers can have events for
* dealing with auth zones, like transfers, and those have to be removed
* too, not just the auth zone structure from the tree. */
struct fast_reload_auth_change {
/** next in the list of auth zone changes. */
struct fast_reload_auth_change* next;
/** the zone in the old config */
struct auth_zone* old_z;
/** the zone in the new config */
struct auth_zone* new_z;
/** if the zone was deleted */
int is_deleted;
/** if the zone was added */
int is_added;
/** if the zone has been changed */
int is_changed;
};
/**
* Fast reload thread structure
*/
struct fast_reload_thread {
/** the thread number for the dtio thread,
* must be first to cast thread arg to int* in checklock code. */
int threadnum;
/** communication socket pair, that sends commands */
int commpair[2];
/** thread id, of the io thread */
ub_thread_type tid;
/** if the io processing has started */
int started;
/** if the thread has to quit */
int need_to_quit;
/** verbosity of the fast_reload command, the number of +v options */
int fr_verb;
/** option to not pause threads during reload */
int fr_nopause;
/** option to drop mesh queries */
int fr_drop_mesh;
/** the event that listens on the remote service worker to the
* commpair, it receives content from the fast reload thread. */
void* service_event;
/** if the event that listens on the remote service worker has
* been added to the comm base. */
int service_event_is_added;
/** the service event can read a cmd, nonblocking, so it can
* save the partial read cmd here */
uint32_t service_read_cmd;
/** the number of bytes in service_read_cmd */
int service_read_cmd_count;
/** the worker that the service_event is added in */
struct worker* worker;
/** the printout of output to the remote client. */
struct fast_reload_printq *printq;
/** lock on fr_output, to stop race when both remote control thread
* and fast reload thread use fr_output list. */
lock_basic_type fr_output_lock;
/** list of strings, that the fast reload thread produces that have
* to be printed. The remote control thread can pick them up with
* the lock. */
struct config_strlist_head* fr_output;
/** communication socket pair, to respond to the reload request */
int commreload[2];
/** the list of auth zone changes. */
struct fast_reload_auth_change* auth_zone_change_list;
/** the old tree of auth zones, to lookup. */
struct auth_zones* old_auth_zones;
};
/**
* Create new remote control state for the daemon.
* @param cfg: config file with key file settings.
@@ -336,38 +203,4 @@ int ssl_printf(RES* ssl, const char* format, ...)
int ssl_read_line(RES* ssl, char* buf, size_t max);
#endif /* HAVE_SSL */
/**
* Start fast reload thread
* @param ssl: the RES connection to print to.
* @param worker: the remote servicing worker.
* @param s: the rc_state that is servicing the remote control connection to
* the remote control client. It needs to be moved away to stay connected
* while the fast reload is running.
* @param fr_verb: verbosity to print output at. 0 is nothing, 1 is some
* and 2 is more detail.
* @param fr_nopause: option to not pause threads during reload.
* @param fr_drop_mesh: option to drop mesh queries.
*/
void fast_reload_thread_start(RES* ssl, struct worker* worker,
struct rc_state* s, int fr_verb, int fr_nopause, int fr_drop_mesh);
/**
* Stop fast reload thread
* @param fast_reload_thread: the thread struct.
*/
void fast_reload_thread_stop(struct fast_reload_thread* fast_reload_thread);
/** fast reload thread commands to remote service thread event callback */
void fast_reload_service_cb(int fd, short bits, void* arg);
/** fast reload callback for the remote control client connection */
int fast_reload_client_callback(struct comm_point* c, void* arg, int err,
struct comm_reply* rep);
/** fast reload printq delete list */
void fast_reload_printq_list_delete(struct fast_reload_printq* list);
/** Pick up per worker changes after a fast reload. */
void fast_reload_worker_pickup_changes(struct worker* worker);
#endif /* DAEMON_REMOTE_H */
+17 -31
View File
@@ -273,7 +273,6 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
/* add in the values from the mesh */
s->svr.ans_secure += (long long)worker->env.mesh->ans_secure;
s->svr.ans_bogus += (long long)worker->env.mesh->ans_bogus;
s->svr.val_ops += (long long)worker->env.mesh->val_ops;
s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata;
s->svr.ans_expired += (long long)worker->env.mesh->ans_expired;
for(i=0; i<UB_STATS_RCODE_NUM; i++)
@@ -282,12 +281,6 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr.rpz_action[i] += (long long)worker->env.mesh->rpz_action[i];
timehist_export(worker->env.mesh->histogram, s->svr.hist,
NUM_BUCKETS_HIST);
s->svr.num_queries_discard_timeout +=
(long long)worker->env.mesh->num_queries_discard_timeout;
s->svr.num_queries_wait_limit +=
(long long)worker->env.mesh->num_queries_wait_limit;
s->svr.num_dns_error_reports +=
(long long)worker->env.mesh->num_dns_error_reports;
/* values from outside network */
s->svr.unwanted_replies = (long long)worker->back->unwanted_replies;
s->svr.qtcp_outgoing = (long long)worker->back->num_tcp_outgoing;
@@ -332,8 +325,20 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr.num_query_dnscrypt_replay = 0;
#endif /* USE_DNSCRYPT */
if(worker->env.auth_zones) {
s->svr.num_query_authzone_up += (long long)worker->env.mesh->num_query_authzone_up;
s->svr.num_query_authzone_down += (long long)worker->env.mesh->num_query_authzone_down;
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);
}
s->svr.mem_stream_wait =
(long long)tcp_req_info_get_stream_buffer_size();
@@ -341,12 +346,6 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
(long long)http2_get_query_buffer_size();
s->svr.mem_http2_response_buffer =
(long long)http2_get_response_buffer_size();
#ifdef HAVE_NGTCP2
s->svr.mem_quic = (long long)doq_table_quic_size_get(
worker->daemon->doq_table);
#else
s->svr.mem_quic = 0;
#endif /* HAVE_NGTCP2 */
/* Set neg cache usage numbers */
set_neg_cache_stats(worker, &s->svr, reset);
@@ -446,15 +445,9 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.num_queries_cookie_valid += a->svr.num_queries_cookie_valid;
total->svr.num_queries_cookie_client += a->svr.num_queries_cookie_client;
total->svr.num_queries_cookie_invalid += a->svr.num_queries_cookie_invalid;
total->svr.num_queries_discard_timeout +=
a->svr.num_queries_discard_timeout;
total->svr.num_queries_wait_limit += a->svr.num_queries_wait_limit;
total->svr.num_dns_error_reports += a->svr.num_dns_error_reports;
total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
total->svr.num_queries_prefetch += a->svr.num_queries_prefetch;
total->svr.num_queries_timed_out += a->svr.num_queries_timed_out;
total->svr.num_query_authzone_up += a->svr.num_query_authzone_up;
total->svr.num_query_authzone_down += a->svr.num_query_authzone_down;
if (total->svr.max_query_time_us < a->svr.max_query_time_us)
total->svr.max_query_time_us = a->svr.max_query_time_us;
total->svr.sum_query_list_size += a->svr.sum_query_list_size;
@@ -462,9 +455,9 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
#ifdef USE_DNSCRYPT
total->svr.num_query_dnscrypt_crypted += a->svr.num_query_dnscrypt_crypted;
total->svr.num_query_dnscrypt_cert += a->svr.num_query_dnscrypt_cert;
total->svr.num_query_dnscrypt_cleartext +=
total->svr.num_query_dnscrypt_cleartext += \
a->svr.num_query_dnscrypt_cleartext;
total->svr.num_query_dnscrypt_crypted_malformed +=
total->svr.num_query_dnscrypt_crypted_malformed += \
a->svr.num_query_dnscrypt_crypted_malformed;
#endif /* USE_DNSCRYPT */
/* the max size reached is upped to higher of both */
@@ -481,7 +474,6 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.qtls += a->svr.qtls;
total->svr.qtls_resume += a->svr.qtls_resume;
total->svr.qhttps += a->svr.qhttps;
total->svr.qquic += a->svr.qquic;
total->svr.qipv6 += a->svr.qipv6;
total->svr.qbit_QR += a->svr.qbit_QR;
total->svr.qbit_AA += a->svr.qbit_AA;
@@ -496,7 +488,6 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.ans_rcode_nodata += a->svr.ans_rcode_nodata;
total->svr.ans_secure += a->svr.ans_secure;
total->svr.ans_bogus += a->svr.ans_bogus;
total->svr.val_ops += a->svr.val_ops;
total->svr.unwanted_replies += a->svr.unwanted_replies;
total->svr.unwanted_queries += a->svr.unwanted_queries;
total->svr.tcp_accept_usage += a->svr.tcp_accept_usage;
@@ -542,8 +533,7 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
else stats->qclass_big++;
stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++;
if(c->type != comm_udp) {
if(c->type != comm_doq)
stats->qtcp++;
stats->qtcp++;
if(c->ssl != NULL) {
stats->qtls++;
#ifdef HAVE_SSL
@@ -552,10 +542,6 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
#endif
if(c->type == comm_http)
stats->qhttps++;
#ifdef HAVE_NGTCP2
else if(c->type == comm_doq)
stats->qquic++;
#endif
}
}
if(repinfo && addr_is_ip6(&repinfo->remote_addr, repinfo->remote_addrlen))
+31 -62
View File
@@ -174,7 +174,7 @@ static void
checkrlimits(struct config_file* cfg)
{
#ifndef S_SPLINT_S
#if defined(HAVE_GETRLIMIT) && !defined(unbound_testbound)
#ifdef HAVE_GETRLIMIT
/* list has number of ports to listen to, ifs number addresses */
int list = ((cfg->do_udp?1:0) + (cfg->do_tcp?1 +
(int)cfg->incoming_num_tcp:0));
@@ -463,62 +463,6 @@ detach(void)
#endif /* HAVE_DAEMON */
}
#ifdef HAVE_SSL
/* setup a listening ssl context, fatal_exit() on any failure */
static void
setup_listen_sslctx(void** ctx, int is_dot, int is_doh, struct config_file* cfg)
{
if(!(*ctx = listen_sslctx_create(
cfg->ssl_service_key, cfg->ssl_service_pem, NULL,
cfg->tls_ciphers, cfg->tls_ciphersuites,
(cfg->tls_session_ticket_keys.first &&
cfg->tls_session_ticket_keys.first->str[0] != 0),
is_dot, is_doh))) {
fatal_exit("could not set up listen SSL_CTX");
}
}
#endif /* HAVE_SSL */
/* setups the needed ssl contexts, fatal_exit() on any failure */
static void
setup_sslctxs(struct daemon* daemon, struct config_file* cfg)
{
#ifdef HAVE_SSL
if(!(daemon->rc = daemon_remote_create(cfg)))
fatal_exit("could not set up remote-control");
if(cfg->ssl_service_key && cfg->ssl_service_key[0]) {
/* setup the session keys; the callback to use them will be
* attached to each sslctx separately */
if(cfg->tls_session_ticket_keys.first &&
cfg->tls_session_ticket_keys.first->str[0] != 0) {
if(!listen_sslctx_setup_ticket_keys(
cfg->tls_session_ticket_keys.first)) {
fatal_exit("could not set session ticket SSL_CTX");
}
}
(void)setup_listen_sslctx(&daemon->listen_dot_sslctx, 1, 0, cfg);
#ifdef HAVE_NGHTTP2_NGHTTP2_H
if(cfg_has_https(cfg)) {
(void)setup_listen_sslctx(&daemon->listen_doh_sslctx, 0, 1, cfg);
}
#endif
#ifdef HAVE_NGTCP2
if(cfg_has_quic(cfg)) {
if(!(daemon->listen_quic_sslctx = quic_sslctx_create(
cfg->ssl_service_key, cfg->ssl_service_pem, NULL))) {
fatal_exit("could not set up quic SSL_CTX");
}
}
#endif /* HAVE_NGTCP2 */
}
if(!(daemon->connect_dot_sslctx = connect_sslctx_create(NULL, NULL,
cfg->tls_cert_bundle, cfg->tls_win_cert)))
fatal_exit("could not set up connect SSL_CTX");
#else /* HAVE_SSL */
(void)daemon;(void)cfg;
#endif /* HAVE_SSL */
}
/** daemonize, drop user privileges and chroot if needed */
static void
perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
@@ -545,7 +489,36 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
#endif
/* read ssl keys while superuser and outside chroot */
(void)setup_sslctxs(daemon, cfg);
#ifdef HAVE_SSL
if(!(daemon->rc = daemon_remote_create(cfg)))
fatal_exit("could not set up remote-control");
if(cfg->ssl_service_key && cfg->ssl_service_key[0]) {
if(!(daemon->listen_sslctx = listen_sslctx_create(
cfg->ssl_service_key, cfg->ssl_service_pem, NULL)))
fatal_exit("could not set up listen SSL_CTX");
if(cfg->tls_ciphers && cfg->tls_ciphers[0]) {
if (!SSL_CTX_set_cipher_list(daemon->listen_sslctx, cfg->tls_ciphers)) {
fatal_exit("failed to set tls-cipher %s", cfg->tls_ciphers);
}
}
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
if(cfg->tls_ciphersuites && cfg->tls_ciphersuites[0]) {
if (!SSL_CTX_set_ciphersuites(daemon->listen_sslctx, cfg->tls_ciphersuites)) {
fatal_exit("failed to set tls-ciphersuites %s", cfg->tls_ciphersuites);
}
}
#endif
if(cfg->tls_session_ticket_keys.first &&
cfg->tls_session_ticket_keys.first->str[0] != 0) {
if(!listen_sslctx_setup_ticket_keys(daemon->listen_sslctx, cfg->tls_session_ticket_keys.first)) {
fatal_exit("could not set session ticket SSL_CTX");
}
}
}
if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL,
cfg->tls_cert_bundle, cfg->tls_win_cert)))
fatal_exit("could not set up connect SSL_CTX");
#endif
/* init syslog (as root) if needed, before daemonize, otherwise
* a fork error could not be printed since daemonize closed stderr.*/
@@ -708,9 +681,6 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
* it would succeed on SIGHUP as well */
if(!cfg->use_syslog)
log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
daemon->cfgfile = strdup(*cfgfile);
if(!daemon->cfgfile)
fatal_exit("out of memory in daemon cfgfile strdup");
}
/**
@@ -745,7 +715,6 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pi
"the commandline to see more errors, "
"or unbound-checkconf", cfgfile);
log_warn("Continuing with default config settings");
config_auto_slab_values(cfg);
}
apply_settings(daemon, cfg, cmdline_verbose, debug_mode);
if(!done_setup)
+216 -310
View File
@@ -160,11 +160,9 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
+ sizeof(worker->rndstate)
+ regional_get_mem(worker->scratchpad)
+ sizeof(*worker->env.scratch_buffer)
+ sldns_buffer_capacity(worker->env.scratch_buffer);
if(worker->daemon->env->fwds)
log_info("forwards=%u", (unsigned)forwards_get_mem(worker->env.fwds));
if(worker->daemon->env->hints)
log_info("hints=%u", (unsigned)hints_get_mem(worker->env.hints));
+ sldns_buffer_capacity(worker->env.scratch_buffer)
+ forwards_get_mem(worker->env.fwds)
+ hints_get_mem(worker->env.hints);
if(worker->thread_num == 0)
me += acl_list_get_mem(worker->daemon->acl);
if(cur_serv) {
@@ -371,84 +369,6 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker,
return;
}
/**
* Send fast-reload acknowledgement to the mainthread in one byte.
* This signals that this worker has received the previous command.
* The worker is waiting if that is after a reload_stop command.
* Or the worker has briefly processed the event itself, and in doing so
* released data pointers to old config, after a reload_poll command.
*/
static void
worker_send_reload_ack(struct worker* worker)
{
/* If this is clipped to 8 bits because thread_num>255, then that
* is not a problem, the receiver counts the number of bytes received.
* The number is informative only. */
uint8_t c = (uint8_t)worker->thread_num;
ssize_t ret;
while(1) {
ret = send(worker->daemon->fast_reload_thread->commreload[1],
(void*)&c, 1, 0);
if(ret == -1) {
if(
#ifndef USE_WINSOCK
errno == EINTR || errno == EAGAIN
# ifdef EWOULDBLOCK
|| errno == EWOULDBLOCK
# endif
#else
WSAGetLastError() == WSAEINTR ||
WSAGetLastError() == WSAEINPROGRESS ||
WSAGetLastError() == WSAEWOULDBLOCK
#endif
)
continue; /* Try again. */
log_err("worker reload ack reply: send failed: %s",
sock_strerror(errno));
break;
}
break;
}
}
/** stop and wait to resume the worker */
static void
worker_stop_and_wait(struct worker* worker)
{
uint8_t* buf = NULL;
uint32_t len = 0, cmd;
worker_send_reload_ack(worker);
/* wait for reload */
if(!tube_read_msg(worker->cmd, &buf, &len, 0)) {
log_err("worker reload read reply failed");
return;
}
if(len != sizeof(uint32_t)) {
log_err("worker reload reply, bad control msg length %d",
(int)len);
free(buf);
return;
}
cmd = sldns_read_uint32(buf);
free(buf);
if(cmd == worker_cmd_quit) {
/* quit anyway */
verbose(VERB_ALGO, "reload reply, control cmd quit");
comm_base_exit(worker->base);
return;
}
if(cmd != worker_cmd_reload_start) {
log_err("worker reload reply, wrong reply command");
}
if(worker->daemon->fast_reload_drop_mesh) {
verbose(VERB_ALGO, "worker: drop mesh queries after reload");
mesh_delete_all(worker->env.mesh);
}
fast_reload_worker_pickup_changes(worker);
worker_send_reload_ack(worker);
verbose(VERB_ALGO, "worker resume after reload");
}
void
worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), uint8_t* msg,
size_t len, int error, void* arg)
@@ -484,15 +404,6 @@ worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), uint8_t* msg,
verbose(VERB_ALGO, "got control cmd remote");
daemon_remote_exec(worker);
break;
case worker_cmd_reload_stop:
verbose(VERB_ALGO, "got control cmd reload_stop");
worker_stop_and_wait(worker);
break;
case worker_cmd_reload_poll:
verbose(VERB_ALGO, "got control cmd reload_poll");
fast_reload_worker_pickup_changes(worker);
worker_send_reload_ack(worker);
break;
default:
log_err("bad command %d", (int)cmd);
break;
@@ -687,8 +598,7 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
return 1;
if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo,
alias_rrset, 0, worker->scratchpad, az, NULL,
worker->env.views, worker->env.respip_set))
alias_rrset, 0, worker->scratchpad, az, NULL))
return 0;
/* xxx_deny actions mean dropping the reply, unless the original reply
@@ -749,18 +659,22 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
if(rep->ttl < timenow) {
/* Check if we need to serve expired now */
if(worker->env.cfg->serve_expired &&
/* if serve-expired-client-timeout is set, serve
* an expired record without attempting recursion
* if the serve_expired_norec_ttl is set for the record
* as we know that recursion is currently failing. */
(!worker->env.cfg->serve_expired_client_timeout ||
timenow < rep->serve_expired_norec_ttl)
!worker->env.cfg->serve_expired_client_timeout
#ifdef USE_CACHEDB
&& !(worker->env.cachedb_enabled &&
worker->env.cfg->cachedb_check_when_serve_expired)
#endif
) {
if(!reply_info_can_answer_expired(rep, timenow))
if(worker->env.cfg->serve_expired_ttl &&
rep->serve_expired_ttl < timenow)
return 0;
/* Ignore expired failure answers */
if(FLAGS_GET_RCODE(rep->flags) !=
LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(rep->flags) !=
LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(rep->flags) !=
LDNS_RCODE_YXDOMAIN)
return 0;
if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
return 0;
@@ -849,8 +763,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
} else if(partial_rep &&
!respip_merge_cname(partial_rep, qinfo, rep, cinfo,
must_validate, &encode_rep, worker->scratchpad,
worker->env.auth_zones, worker->env.views,
worker->env.respip_set)) {
worker->env.auth_zones)) {
goto bail_out;
}
if(encode_rep != rep) {
@@ -1171,7 +1084,7 @@ answer_notify(struct worker* w, struct query_info* qinfo,
if(verbosity >= VERB_DETAIL) {
char buf[380];
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
char sr[25];
dname_str(qinfo->qname, zname);
sr[0]=0;
@@ -1198,6 +1111,172 @@ answer_notify(struct worker* w, struct query_info* qinfo,
LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY);
}
static int
make_ede_error(struct comm_point* c, struct worker* worker,
struct comm_reply* repinfo, int rcode, int16_t ede_code,
int ede, struct check_request_result* check_result)
{
size_t opt_rr_mark;
if(worker->stats.extended)
worker->stats.unwanted_queries++;
worker_check_request(c->buffer, worker, check_result);
if(check_result->value != 0) {
if(check_result->value != -1) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
check_result->value);
return 1;
}
comm_point_drop_reply(repinfo);
return 0;
}
/* worker_check_request() above guarantees that the buffer contains at
* least a header and that qdcount == 1
*/
log_assert(sldns_buffer_limit(c->buffer) >= LDNS_HEADER_SIZE
&& LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) == 1);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE); /* skip header */
/* check additional section is present and that we respond with EDEs */
if(LDNS_ARCOUNT(sldns_buffer_begin(c->buffer)) != 1
|| !ede) {
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), rcode);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
if (!query_dname_len(c->buffer)) {
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
/* space available for query type and class? */
if (sldns_buffer_remaining(c->buffer) < 2 * sizeof(uint16_t)) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), rcode);
sldns_buffer_skip(c->buffer, (ssize_t)sizeof(uint16_t)); /* skip qtype */
sldns_buffer_skip(c->buffer, (ssize_t)sizeof(uint16_t)); /* skip qclass */
/* The OPT RR to be returned should come directly after
* the query, so mark this spot.
*/
opt_rr_mark = sldns_buffer_position(c->buffer);
/* Skip through the RR records */
if(LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)) != 0 ||
LDNS_NSCOUNT(sldns_buffer_begin(c->buffer)) != 0) {
if(!skip_pkt_rrs(c->buffer,
((int)LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)))+
((int)LDNS_NSCOUNT(sldns_buffer_begin(c->buffer))))) {
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
}
}
/* Do we have a valid OPT RR here? If not return rcode (could be a valid TSIG or something so no FORMERR) */
/* domain name must be the root of length 1. */
if(sldns_buffer_remaining(c->buffer) < 1 || *sldns_buffer_current(c->buffer) != 0) {
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
} else {
sldns_buffer_skip(c->buffer, 1); /* skip root label */
}
if(sldns_buffer_remaining(c->buffer) < 2 ||
sldns_buffer_read_u16(c->buffer) != LDNS_RR_TYPE_OPT) {
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
}
/* Write OPT RR directly after the query,
* so without the (possibly skipped) Answer and NS RRs
*/
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_clear(c->buffer); /* reset write limit */
sldns_buffer_set_position(c->buffer, opt_rr_mark);
/* Check if OPT record can be written
* 17 == root label (1) + RR type (2) + UDP Size (2)
* + Fields (4) + rdata len (2) + EDE Option code (2)
* + EDE Option length (2) + EDE info-code (2)
*/
if (sldns_buffer_available(c->buffer, 17) == 0) {
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_flip(c->buffer);
return 1;
}
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 1);
/* root label */
sldns_buffer_write_u8(c->buffer, 0);
sldns_buffer_write_u16(c->buffer, LDNS_RR_TYPE_OPT);
sldns_buffer_write_u16(c->buffer, EDNS_ADVERTISED_SIZE);
/* write OPT Record TTL Field */
sldns_buffer_write_u32(c->buffer, 0);
/* write rdata len: EDE option + length + info-code */
sldns_buffer_write_u16(c->buffer, 6);
/* write OPTIONS; add EDE option code */
sldns_buffer_write_u16(c->buffer, LDNS_EDNS_EDE);
/* write single EDE option length (for just 1 info-code) */
sldns_buffer_write_u16(c->buffer, 2);
/* write single EDE info-code */
sldns_buffer_write_u16(c->buffer, ede_code);
sldns_buffer_flip(c->buffer);
verbose(VERB_ALGO, "attached EDE code: %d", ede_code);
return 1;
}
static int
deny_refuse(struct comm_point* c, enum acl_access acl,
enum acl_access deny, enum acl_access refuse,
@@ -1216,174 +1295,14 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
worker->stats.unwanted_queries++;
return 0;
} else if(acl == refuse) {
size_t opt_rr_mark;
if(verbosity >= VERB_ALGO) {
log_acl_action("refused", &repinfo->client_addr,
repinfo->client_addrlen, acl, acladdr);
log_buf(VERB_ALGO, "refuse", c->buffer);
}
if(worker->stats.extended)
worker->stats.unwanted_queries++;
worker_check_request(c->buffer, worker, check_result);
if(check_result->value != 0) {
if(check_result->value != -1) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
check_result->value);
return 1;
}
comm_point_drop_reply(repinfo);
return 0;
}
/* worker_check_request() above guarantees that the buffer contains at
* least a header and that qdcount == 1
*/
log_assert(sldns_buffer_limit(c->buffer) >= LDNS_HEADER_SIZE
&& LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) == 1);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE); /* skip header */
/* check additional section is present and that we respond with EDEs */
if(LDNS_ARCOUNT(sldns_buffer_begin(c->buffer)) != 1
|| !ede) {
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_REFUSED);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
if (!query_dname_len(c->buffer)) {
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
/* space available for query type and class? */
if (sldns_buffer_remaining(c->buffer) < 2 * sizeof(uint16_t)) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_REFUSED);
sldns_buffer_skip(c->buffer, (ssize_t)sizeof(uint16_t)); /* skip qtype */
sldns_buffer_skip(c->buffer, (ssize_t)sizeof(uint16_t)); /* skip qclass */
/* The OPT RR to be returned should come directly after
* the query, so mark this spot.
*/
opt_rr_mark = sldns_buffer_position(c->buffer);
/* Skip through the RR records */
if(LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)) != 0 ||
LDNS_NSCOUNT(sldns_buffer_begin(c->buffer)) != 0) {
if(!skip_pkt_rrs(c->buffer,
((int)LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)))+
((int)LDNS_NSCOUNT(sldns_buffer_begin(c->buffer))))) {
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
}
}
/* Do we have a valid OPT RR here? If not return REFUSED (could be a valid TSIG or something so no FORMERR) */
/* domain name must be the root of length 1. */
if(sldns_buffer_remaining(c->buffer) < 1 || *sldns_buffer_current(c->buffer) != 0) {
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
} else {
sldns_buffer_skip(c->buffer, 1); /* skip root label */
}
if(sldns_buffer_remaining(c->buffer) < 2 ||
sldns_buffer_read_u16(c->buffer) != LDNS_RR_TYPE_OPT) {
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
}
/* Write OPT RR directly after the query,
* so without the (possibly skipped) Answer and NS RRs
*/
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_clear(c->buffer); /* reset write limit */
sldns_buffer_set_position(c->buffer, opt_rr_mark);
/* Check if OPT record can be written
* 17 == root label (1) + RR type (2) + UDP Size (2)
* + Fields (4) + rdata len (2) + EDE Option code (2)
* + EDE Option length (2) + EDE info-code (2)
*/
if (sldns_buffer_available(c->buffer, 17) == 0) {
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_flip(c->buffer);
return 1;
}
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 1);
/* root label */
sldns_buffer_write_u8(c->buffer, 0);
sldns_buffer_write_u16(c->buffer, LDNS_RR_TYPE_OPT);
sldns_buffer_write_u16(c->buffer, EDNS_ADVERTISED_SIZE);
/* write OPT Record TTL Field */
sldns_buffer_write_u32(c->buffer, 0);
/* write rdata len: EDE option + length + info-code */
sldns_buffer_write_u16(c->buffer, 6);
/* write OPTIONS; add EDE option code */
sldns_buffer_write_u16(c->buffer, LDNS_EDNS_EDE);
/* write single EDE option length (for just 1 info-code) */
sldns_buffer_write_u16(c->buffer, 2);
/* write single EDE info-code */
sldns_buffer_write_u16(c->buffer, LDNS_EDE_PROHIBITED);
sldns_buffer_flip(c->buffer);
verbose(VERB_ALGO, "attached EDE code: %d", LDNS_EDE_PROHIBITED);
return 1;
return make_ede_error(c, worker, repinfo, LDNS_RCODE_REFUSED,
LDNS_EDE_PROHIBITED, ede, check_result);
}
return -1;
}
@@ -1502,7 +1421,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
return 0;
}
if(c->dnscrypt && !repinfo->is_dnscrypted) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[LDNS_MAX_DOMAINLEN+1];
/* Check if this is unencrypted and asking for certs */
worker_check_request(c->buffer, worker, &check_result);
if(check_result.value != 0) {
@@ -1639,6 +1558,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
qinfo.qtype == LDNS_RR_TYPE_MAILA ||
qinfo.qtype == LDNS_RR_TYPE_MAILB ||
(qinfo.qtype >= 128 && qinfo.qtype <= 248)) {
size_t opt_rr_mark;
verbose(VERB_ALGO, "worker request: formerror for meta-type.");
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
repinfo->client_addrlen);
@@ -1646,20 +1567,17 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
comm_point_drop_reply(repinfo);
return 0;
}
sldns_buffer_rewind(c->buffer);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
if(worker->stats.extended) {
worker->stats.qtype[qinfo.qtype]++;
if (make_ede_error(c, worker, repinfo, LDNS_RCODE_FORMERR,
LDNS_EDE_INVALID_QUERY_TYPE,
worker->env.cfg->ede, &check_result)) {
goto send_reply;
}
goto send_reply;
return 0;
}
if((ret=parse_edns_from_query_pkt(
c->buffer, &edns, worker->env.cfg, c, repinfo,
(worker->env.now ? *worker->env.now : time(NULL)),
worker->scratchpad,
worker->daemon->cookie_secrets)) != 0) {
worker->scratchpad)) != 0) {
struct edns_data reply_edns;
verbose(VERB_ALGO, "worker parse edns: formerror.");
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
@@ -1707,7 +1625,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
repinfo->client_addrlen, edns.cookie_valid,
c->buffer)) {
worker->stats.num_queries_ip_ratelimited++;
regional_free_all(worker->scratchpad);
comm_point_drop_reply(repinfo);
return 0;
}
@@ -1819,9 +1736,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
goto send_reply;
}
if(worker->env.auth_zones &&
auth_zones_downstream_answer(worker->env.auth_zones,
&worker->env, &qinfo, &edns, repinfo, c->buffer,
worker->scratchpad)) {
auth_zones_answer(worker->env.auth_zones, &worker->env,
&qinfo, &edns, repinfo, c->buffer, worker->scratchpad)) {
regional_free_all(worker->scratchpad);
if(sldns_buffer_limit(c->buffer) == 0) {
comm_point_drop_reply(repinfo);
@@ -1874,11 +1790,20 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
/* If we've found a local alias, replace the qname with the alias
* target before resolving it. */
if(qinfo.local_alias) {
if(!local_alias_shallow_copy_qname(qinfo.local_alias, &qinfo.qname,
&qinfo.qname_len)) {
struct ub_packed_rrset_key* rrset = qinfo.local_alias->rrset;
struct packed_rrset_data* d = rrset->entry.data;
/* Sanity check: our current implementation only supports
* a single CNAME RRset as a local alias. */
if(qinfo.local_alias->next ||
rrset->rk.type != htons(LDNS_RR_TYPE_CNAME) ||
d->count != 1) {
log_err("assumption failure: unexpected local alias");
regional_free_all(worker->scratchpad);
return 0; /* drop it */
}
qinfo.qname = d->rr_data[0] + 2;
qinfo.qname_len = d->rr_len[0] - 2;
}
/* If we may apply IP-based actions to the answer, build the client
@@ -1895,7 +1820,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
cinfo_tmp.tag_datas = acladdr->tag_datas;
cinfo_tmp.tag_datas_size = acladdr->tag_datas_size;
cinfo_tmp.view = acladdr->view;
cinfo_tmp.view_name = NULL;
cinfo_tmp.respip_set = worker->daemon->respip_set;
cinfo = &cinfo_tmp;
}
@@ -1927,10 +1852,10 @@ lookup_cache:
* its qname must be that used for cache
* lookup. */
if((worker->env.cfg->prefetch &&
rep->prefetch_ttl <= *worker->env.now) ||
*worker->env.now >= rep->prefetch_ttl) ||
(worker->env.cfg->serve_expired &&
rep->ttl < *worker->env.now &&
!(*worker->env.now < rep->serve_expired_norec_ttl))) {
*worker->env.now > rep->ttl)) {
time_t leeway = rep->ttl - *worker->env.now;
if(rep->ttl < *worker->env.now)
leeway = 0;
@@ -2048,13 +1973,13 @@ send_reply_rc:
&repinfo->client_addr, repinfo->client_addrlen,
tv, 1, c->buffer,
(worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr:NULL),
c->type, c->ssl);
c->type);
} else {
log_reply_info(NO_VERBOSE, &qinfo,
&repinfo->client_addr, repinfo->client_addrlen,
tv, 1, c->buffer,
(worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr:NULL),
c->type, c->ssl);
c->type);
}
}
#ifdef USE_DNSCRYPT
@@ -2255,11 +2180,8 @@ worker_init(struct worker* worker, struct config_file *cfg,
: cfg->tcp_idle_timeout,
cfg->harden_large_queries, cfg->http_max_streams,
cfg->http_endpoint, cfg->http_notls_downstream,
worker->daemon->tcl, worker->daemon->listen_dot_sslctx,
worker->daemon->listen_doh_sslctx,
worker->daemon->listen_quic_sslctx,
dtenv, worker->daemon->doq_table, worker->env.rnd,
cfg, worker_handle_request, worker);
worker->daemon->tcl, worker->daemon->listen_sslctx,
dtenv, worker_handle_request, worker);
if(!worker->front) {
log_err("could not create listening sockets");
worker_delete(worker);
@@ -2274,7 +2196,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
cfg->unwanted_threshold, cfg->outgoing_tcp_mss,
&worker_alloc_cleanup, worker,
cfg->do_udp || cfg->udp_upstream_without_downstream,
worker->daemon->connect_dot_sslctx, cfg->delay_close,
worker->daemon->connect_sslctx, cfg->delay_close,
cfg->tls_use_sni, dtenv, cfg->udp_connect,
cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout,
cfg->tcp_auth_query_timeout);
@@ -2593,19 +2515,3 @@ void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
log_assert(0);
}
#endif
#ifdef HAVE_NGTCP2
void doq_client_event_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
#ifdef HAVE_NGTCP2
void doq_client_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
+1 -7
View File
@@ -72,13 +72,7 @@ enum worker_commands {
/** obtain statistics without statsclear */
worker_cmd_stats_noreset,
/** execute remote control command */
worker_cmd_remote,
/** for fast-reload, perform stop */
worker_cmd_reload_stop,
/** for fast-reload, start again */
worker_cmd_reload_start,
/** for fast-reload, poll to make sure worker has released data */
worker_cmd_reload_poll
worker_cmd_remote
};
/**
+4 -8
View File
@@ -631,7 +631,7 @@ handle_event_moddone(struct module_qstate* qstate, int id)
/* When an AAAA query completes check if we want to perform DNS64
* synthesis. We skip queries with DNSSEC enabled (!CD) and
* ones generated by us to retrieve the A/PTR record to use for
* ones generated by us to retrive the A/PTR record to use for
* synth. */
int could_synth =
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA &&
@@ -657,9 +657,8 @@ handle_event_moddone(struct module_qstate* qstate, int id)
qstate->return_msg->rep &&
!dns_cache_store(
qstate->env, &qstate->qinfo, qstate->return_msg->rep,
0, qstate->prefetch_leeway, 0, NULL,
qstate->query_flags, qstate->qstarttime,
qstate->is_valrec))
0, 0, 0, NULL,
qstate->query_flags, qstate->qstarttime))
log_err("out of memory");
/* do nothing */
@@ -702,7 +701,6 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
iq->state = DNS64_NEW_QUERY;
iq->started_no_cache_store = qstate->no_cache_store;
qstate->no_cache_store = 1;
ATTR_FALLTHROUGH
/* fallthrough */
case module_event_pass:
qstate->ext_state[id] = handle_event_pass(qstate, id);
@@ -848,7 +846,6 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
*/
cp = construct_reply_info_base(super->region, rep->flags, rep->qdcount,
rep->ttl, rep->prefetch_ttl, rep->serve_expired_ttl,
rep->serve_expired_norec_ttl,
rep->an_numrrsets, rep->ns_numrrsets, rep->ar_numrrsets,
rep->rrset_count, rep->security, LDNS_EDE_NONE);
if(!cp)
@@ -1009,8 +1006,7 @@ dns64_inform_super(struct module_qstate* qstate, int id,
/* Store the generated response in cache. */
if ( (!super_dq || !super_dq->started_no_cache_store) &&
!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
0, super->prefetch_leeway, 0, NULL, super->query_flags,
qstate->qstarttime, qstate->is_valrec))
0, 0, 0, NULL, super->query_flags, qstate->qstarttime))
log_err("out of memory");
}
+10 -22
View File
@@ -192,11 +192,8 @@ static void
dt_apply_identity(struct dt_env *env, struct config_file *cfg)
{
char buf[MAXHOSTNAMELEN+1];
if (!cfg->dnstap_send_identity) {
free(env->identity);
env->identity = NULL;
if (!cfg->dnstap_send_identity)
return;
}
free(env->identity);
if (cfg->dnstap_identity == NULL || cfg->dnstap_identity[0] == 0) {
if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
@@ -218,11 +215,8 @@ dt_apply_identity(struct dt_env *env, struct config_file *cfg)
static void
dt_apply_version(struct dt_env *env, struct config_file *cfg)
{
if (!cfg->dnstap_send_version) {
free(env->version);
env->version = NULL;
if (!cfg->dnstap_send_version)
return;
}
free(env->version);
if (cfg->dnstap_version == NULL || cfg->dnstap_version[0] == 0)
env->version = strdup(PACKAGE_STRING);
@@ -236,8 +230,13 @@ dt_apply_version(struct dt_env *env, struct config_file *cfg)
}
void
dt_apply_logcfg(struct dt_env *env, struct config_file *cfg)
dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
{
if (!cfg->dnstap)
return;
dt_apply_identity(env, cfg);
dt_apply_version(env, cfg);
if ((env->log_resolver_query_messages = (unsigned int)
cfg->dnstap_log_resolver_query_messages))
{
@@ -276,17 +275,6 @@ dt_apply_logcfg(struct dt_env *env, struct config_file *cfg)
lock_basic_unlock(&env->sample_lock);
}
void
dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
{
if (!cfg->dnstap)
return;
dt_apply_identity(env, cfg);
dt_apply_version(env, cfg);
dt_apply_logcfg(env, cfg);
}
int
dt_init(struct dt_env *env, struct comm_base* base)
{
@@ -542,7 +530,7 @@ dt_msg_send_outside_query(struct dt_env *env,
qflags = sldns_buffer_read_u16_at(qmsg, 2);
/* type */
if ((qflags & BIT_RD)) {
if (qflags & BIT_RD) {
if (!env->log_forwarder_query_messages)
return;
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY);
@@ -599,7 +587,7 @@ dt_msg_send_outside_response(struct dt_env *env,
qflags = ntohs(qflags);
/* type */
if ((qflags & BIT_RD)) {
if (qflags & BIT_RD) {
if (!env->log_forwarder_response_messages)
return;
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE);
-7
View File
@@ -106,13 +106,6 @@ dt_create(struct config_file* cfg);
void
dt_apply_cfg(struct dt_env *env, struct config_file *cfg);
/**
* Apply config settings for log enable for message types.
* @param env: dnstap environment object.
* @param cfg: new config settings.
*/
void dt_apply_logcfg(struct dt_env *env, struct config_file *cfg);
/**
* Initialize per-worker state in dnstap environment object.
* @param env: dnstap environment object to initialize, created with dt_create().
+4 -35
View File
@@ -18,41 +18,10 @@ AC_DEFUN([dt_DNSTAP],
[opt_dnstap_socket_path="$1"])
if test "x$opt_dnstap" != "xno"; then
AC_PATH_PROG([PROTOC], [protoc])
# 'protoc-c' is deprecated. We use 'protoc' instead. If it can not be
# found, try 'protoc-c'.
if test -z "$PROTOC"; then
AC_PATH_PROG([PROTOC_C], [protoc-c])
else
PROTOC_C="$PROTOC"
fi
if test -z "$PROTOC_C"; then
AC_MSG_ERROR([[The protoc or protoc-c program was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c to provide protoc or protoc-c]])
fi
# Check for protoc-gen-c plugin
AC_PATH_PROG([PROTOC_GEN_C], [protoc-gen-c])
if test -z "$PROTOC_GEN_C"; then
AC_MSG_ERROR([[The protoc-gen-c plugin was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c-compiler to provide protoc-gen-c]])
fi
# Test that protoc-gen-c actually works
AC_MSG_CHECKING([if protoc-gen-c plugin works])
cat > conftest.proto << EOF
syntax = "proto2";
message TestMessage {
optional string test_field = 1;
}
EOF
if $PROTOC_C --c_out=. conftest.proto >/dev/null 2>&1; then
AC_MSG_RESULT([yes])
rm -f conftest.proto conftest.pb-c.c conftest.pb-c.h
else
AC_MSG_RESULT([no])
rm -f conftest.proto conftest.pb-c.c conftest.pb-c.h
AC_MSG_ERROR([[The protoc-gen-c plugin is not working properly. Please ensure protobuf-c-compiler is properly installed]])
fi
AC_PATH_PROG([PROTOC_C], [protoc-c])
if test -z "$PROTOC_C"; then
AC_MSG_ERROR([The protoc-c program was not found. Please install protobuf-c!])
fi
AC_ARG_WITH([protobuf-c],
AS_HELP_STRING([--with-protobuf-c=path], [Path where protobuf-c is installed, for dnstap]),
[
+1 -1
View File
@@ -98,7 +98,7 @@ message Policy {
// rule: the rule matched by the message.
//
// In a RPZ context, this is the owner name of the rule in
// the Response Policy Zone in wire format.
// the Reponse Policy Zone in wire format.
optional bytes rule = 2;
// action: the policy action taken in response to the
+1 -3
View File
@@ -1509,11 +1509,9 @@ void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg)
}
#endif
if((bits&UB_EV_READ) || dtio->ssl_brief_write) {
#ifdef HAVE_SSL
if((bits&UB_EV_READ || dtio->ssl_brief_write)) {
if(dtio->ssl_brief_write)
(void)dtio_disable_brief_write(dtio);
#endif
if(dtio->ready_frame_sent && !dtio->accept_frame_received) {
if(dtio_read_accept_frame(dtio) <= 0)
return;
+22 -104
View File
@@ -200,25 +200,18 @@ static void tap_data_list_try_to_free_tail(struct tap_data_list* list)
}
/** delete the tap structure */
static void tap_data_free(struct tap_data* data, int free_tail)
static void tap_data_free(struct tap_data* data)
{
if(!data)
return;
if(data->ev) {
ub_event_del(data->ev);
ub_event_free(data->ev);
}
ub_event_del(data->ev);
ub_event_free(data->ev);
#ifdef HAVE_SSL
SSL_free(data->ssl);
#endif
sock_close(data->fd);
close(data->fd);
free(data->id);
free(data->frame);
if(data->data_list) {
data->data_list->d = NULL;
if(free_tail)
tap_data_list_try_to_free_tail(data->data_list);
}
data->data_list->d = NULL;
tap_data_list_try_to_free_tail(data->data_list);
free(data);
}
@@ -244,7 +237,7 @@ static void tap_data_list_delete(struct tap_data_list* list)
while(e) {
next = e->next;
if(e->d) {
tap_data_free(e->d, 0);
tap_data_free(e->d);
e->d = NULL;
}
free(e);
@@ -267,7 +260,7 @@ static void tap_socket_close(struct tap_socket* s)
{
if(!s) return;
if(s->fd == -1) return;
sock_close(s->fd);
close(s->fd);
s->fd = -1;
}
@@ -346,8 +339,7 @@ static struct tap_socket* tap_socket_new_tlsaccept(char* ip,
s->fd = -1;
s->ev_cb = ev_cb;
s->data = data;
s->sslctx = listen_sslctx_create(server_key, server_cert, verifypem,
NULL, NULL, 0, 0, 0);
s->sslctx = listen_sslctx_create(server_key, server_cert, verifypem);
if(!s->sslctx) {
log_err("could not create ssl context");
free(s->ip);
@@ -830,6 +822,7 @@ static int reply_with_accept(struct tap_data* data)
{
#ifdef USE_DNSTAP
/* len includes the escape and framelength */
int r;
size_t len = 0;
void* acceptframe = fstrm_create_control_frame_accept(
DNSTAP_CONTENT_TYPE, &len);
@@ -840,8 +833,6 @@ static int reply_with_accept(struct tap_data* data)
fd_set_block(data->fd);
if(data->ssl) {
#ifdef HAVE_SSL
int r;
if((r=SSL_write(data->ssl, acceptframe, len)) <= 0) {
int r2;
if((r2=SSL_get_error(data->ssl, r)) == SSL_ERROR_ZERO_RETURN)
@@ -852,7 +843,6 @@ static int reply_with_accept(struct tap_data* data)
free(acceptframe);
return 0;
}
#endif
} else {
if(send(data->fd, acceptframe, len, 0) == -1) {
log_err("send failed: %s", sock_strerror(errno));
@@ -888,7 +878,6 @@ static int reply_with_finish(struct tap_data* data)
fd_set_block(data->fd);
if(data->ssl) {
#ifdef HAVE_SSL
int r;
if((r=SSL_write(data->ssl, finishframe, len)) <= 0) {
int r2;
@@ -900,7 +889,6 @@ static int reply_with_finish(struct tap_data* data)
free(finishframe);
return 0;
}
#endif
} else {
if(send(data->fd, finishframe, len, 0) == -1) {
log_err("send failed: %s", sock_strerror(errno));
@@ -1000,7 +988,7 @@ static int tap_handshake(struct tap_data* data)
return 0;
} else if(r == 0) {
/* closed */
tap_data_free(data, 1);
tap_data_free(data);
return 0;
} else if(want == SSL_ERROR_SYSCALL) {
/* SYSCALL and errno==0 means closed uncleanly */
@@ -1018,7 +1006,7 @@ static int tap_handshake(struct tap_data* data)
if(!silent)
log_err("SSL_handshake syscall: %s",
strerror(errno));
tap_data_free(data, 1);
tap_data_free(data);
return 0;
} else {
unsigned long err = ERR_get_error();
@@ -1028,7 +1016,7 @@ static int tap_handshake(struct tap_data* data)
verbose(VERB_OPS, "ssl handshake failed "
"from %s", data->id);
}
tap_data_free(data, 1);
tap_data_free(data);
return 0;
}
}
@@ -1036,7 +1024,7 @@ static int tap_handshake(struct tap_data* data)
data->ssl_handshake_done = 1;
if(!tap_check_peer(data)) {
/* closed */
tap_data_free(data, 1);
tap_data_free(data);
return 0;
}
return 1;
@@ -1062,7 +1050,7 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
if(verbosity>=4) log_info("s recv %d", (int)ret);
if(ret == 0) {
/* closed or error */
tap_data_free(data, 1);
tap_data_free(data);
return;
} else if(ret == -1) {
/* continue later */
@@ -1084,7 +1072,7 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
data->frame = calloc(1, data->len);
if(!data->frame) {
log_err("out of memory");
tap_data_free(data, 1);
tap_data_free(data);
return;
}
}
@@ -1097,7 +1085,7 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
if(verbosity>=4) log_info("f recv %d", (int)r);
if(r == 0) {
/* closed or error */
tap_data_free(data, 1);
tap_data_free(data);
return;
} else if(r == -1) {
/* continue later */
@@ -1122,13 +1110,13 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
data->is_bidirectional = 1;
if(verbosity) log_info("bidirectional stream");
if(!reply_with_accept(data)) {
tap_data_free(data, 1);
tap_data_free(data);
return;
}
} else if(data->len >= 4 && sldns_read_uint32(data->frame) ==
FSTRM_CONTROL_FRAME_STOP && data->is_bidirectional) {
if(!reply_with_finish(data)) {
tap_data_free(data, 1);
tap_data_free(data);
return;
}
}
@@ -1152,9 +1140,7 @@ void dtio_mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg)
char* id = NULL;
struct sockaddr_storage addr;
socklen_t addrlen = (socklen_t)sizeof(addr);
int s;
memset(&addr, 0, sizeof(addr));
s = accept(fd, (struct sockaddr*)&addr, &addrlen);
int s = accept(fd, (struct sockaddr*)&addr, &addrlen);
if(s == -1) {
#ifndef USE_WINSOCK
/* EINTR is signal interrupt. others are closed connection. */
@@ -1410,41 +1396,6 @@ static int internal_unittest()
/* clean up */
tap_data_list_delete(socket->data_list);
free(socket);
/* Start again. Add two elements */
socket = calloc(1, sizeof(*socket));
log_assert(socket);
for(i=0; i<2; i++) {
datas[i] = calloc(1, sizeof(struct tap_data));
log_assert(datas[i]);
log_assert(tap_data_list_insert(&socket->data_list, datas[i]));
}
/* sanity base check */
list = socket->data_list;
for(i=0; list; i++) list = list->next;
log_assert(i==2);
/* Free the last data, tail cannot be erased */
list = socket->data_list;
while(list->next) list = list->next;
free(list->d);
list->d = NULL;
tap_data_list_try_to_free_tail(list);
list = socket->data_list;
for(i=0; list; i++) list = list->next;
log_assert(i==2);
/* clean up */
tap_data_list_delete(socket->data_list);
free(socket);
if(log_get_lock()) {
lock_basic_destroy((lock_basic_type*)log_get_lock());
}
checklock_stop();
#ifdef USE_WINSOCK
WSACleanup();
#endif
return 0;
}
@@ -1546,8 +1497,8 @@ int main(int argc, char** argv)
usage(argv);
}
}
/* argc -= optind; not using further arguments */
/* argv += optind; not using further arguments */
argc -= optind;
argv += optind;
if(usessl) {
#ifdef HAVE_SSL
@@ -1576,9 +1527,6 @@ int main(int argc, char** argv)
config_delstrlist(tcp_list.first);
config_delstrlist(tls_list.first);
if(log_get_lock()) {
lock_basic_destroy((lock_basic_type*)log_get_lock());
}
checklock_stop();
#ifdef USE_WINSOCK
WSACleanup();
@@ -1786,33 +1734,3 @@ void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
int fast_reload_client_callback(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(repinfo))
{
log_assert(0);
return 0;
}
#ifdef HAVE_NGTCP2
void doq_client_event_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
#ifdef HAVE_NGTCP2
void doq_client_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
+22 -765
View File
@@ -1,746 +1,3 @@
11 September 2025: Wouter
- version set to 1.24.0 for release.
- tag for 1.24.0rc1.
9 September 2025: Wouter
- Fix #1332: CNAME chains are sometimes not followed when RPZs add a
local CNAME rewrite.
8 September 2025: Yorgos
- Update documentation for using "SET ... EX" in Redis.
- Document max buffer sizes for Redis commands.
- Update man pages.
3 September 2025: Wouter
- For #1328: make depend.
2 September 2025: Wouter
- Fix #1235: Outdated Python2 code in
unbound/pythonmod/examples/log.py.
- Fix #1324: Memory leak in 'msgparse.c' in
'parse_edns_options_from_query(...)'.
- Fix indentation in tcp-mss option parsing.
1 September 2025: Wouter
- Fix for #1324: Fix to free edns options scratch in ratelimit case.
29 August 2025: Yorgos
- Limit the number of consecutive reads on an HTTP/2 session.
Thanks to Gal Bar Nahum for exposing the possibility of infinite
reads on the session.
28 August 2025: Wouter
- Fix setup_listen_sslctx warning for nettle compile.
27 August 2025: Wouter
- Fix unbound-control dump_cache for double unlock of lruhash table.
26 August 2025: Wouter
- Fix ports workflow to install expat for macos.
22 August 2025: Wouter
- For #1318: Fix compile warnings for DoH compile on windows.
- Fix sha1 enable environment variable in test code on windows.
- Fix #1319: [FR] zone status for Unbound auth-zones.
- Fix that the zone acquired timestamp is set after the
zonefile is read.
21 August 2025: Wouter
- Fix to check for extraneous command arguments for unbound-control,
when the command takes no arguments but there are arguments present.
- Fix #1317: Unbound starts too early. Add
Wants=network-online.target under [Unit] in unbound.service.
- Fix for #1317: Fix contrib/unbound.service comment path for
systemd network configuration.
15 August 2025: Wouter
- unbound-control cache_lookup +t allows tld and root names. And
subnet cache contents are printed.
- Fix cache_lookup subnet printout to wipe zero part of the prefix.
- Fix cache_lookup subnet print to not print messages without rrsets
and perform in-depth check on node in the addrtree.
14 August 2025: Wouter
- Fix to increase responsiveness of dump_cache.
- Fix to decouple file descriptor activity and cache lookups in
dump_cache.
13 August 2025: Wouter
- unbound-control cache_lookup <domains> prints the cached rrsets
and messages for those.
- Fix to remove debug from cache_lookup.
- Fix to unlock cache_lookup message for malformed records.
12 August 2025: Wouter
- Fix that unbound-control dump_cache releases the cache locks
every so often, so that the server stays responsive.
7 August 2025: Wouter
- Fix dname_str for printout of long names. Thanks to Jan Komissar
for the fix.
- Fix that edns-subnet failure to create a subquery errors as
servfail, and not formerror.
- Fix to whitespace in dname_str.
6 August 2025: Wouter
- Fix edns subnet, so that the subquery without subnet is stored in
global cache if the querier used 0.0.0.0/0 and the name and address
do not receive subnet treatment. If the name and address are
configured for subnet, it is stored in the subnet cache.
5 August 2025: Wouter
- Fix #1309: incorrectly reclaimed tcp handler can cause data
corruption and segfault.
- Fix to use assertions for consistency checks in #1309 reclaimed
tcp handlers.
1 August 2025: Wouter
- Fix testbound test program to accurately output packets from hex.
28 July 2025: Wouter
- Fix redis cachedb module gettimeofday init failure.
24 July 2025: Wouter
- Redis checks for server down and throttles reconnects.
17 July 2025: Wouter
- Fix to not set rlimits in the unit tests.
- Fix #1303: [FR] Disable TLSv1.2.
- iana portlist updated.
16 July 2025: Wouter
- Fix for RebirthDay Attack CVE-2025-5994, reported by Xiang Li
from AOSP Lab Nankai University.
- Tag for 1.23.1 with the release of 1.23.0 and the CVE fix, the
repository continues with the previous fixes, with 1.23.2.
- Add unit tests for non-ecs aggregation.
12 July 2025: Yorgos
- Merge #1289 from Roland van Rijswijk-Deij: Add extra statistic to
track the number of signature validation operations.
Adds 'num.valops' to extended statistics.
- For #1289: test num.valops in existing stat_values.tdir.
- For #1289: add num.valops in the unbound-control man page.
11 July 2025: Wouter
- Fix detection of SSL_CTX_set_tmp_ecdh function.
- For #1301: configure cant find SSL_is_quic in OpenSSL 3.5.1.
8 July 2025: Wouter
- Fix to improve dnstap discovery on Fedora.
3 July 2025: Wouter
- Fix #1300: Is 'sock-queue-timeout' a linux only feature.
- For #1300: implement sock-queue-timeout for FreeBSD as well.
- Fix layout of comm_point_udp_ancil_callback.
2 July 2025: Wouter
- Merge #1299: Fix typos.
- Generate ltmain.sh and configure again.
25 June 2025: Yorgos
- Fix #1247: forward-first: ssl handshake failed on root nameservers.
- For #1247, turn off fetch-policy for delegation when looking into
parent side name servers that may not update the addresses and hit
NXNS limits.
- For #1247, replay test (added tcp_transport to
outnet_serviced_query).
20 June 2025: Yorgos
- Fix #1293: EDE 6 is attached to insecure cached answers when client
sends the CD bit.
19 June 2025: Wouter
- Fix #1296: DNS over QUIC depends on a very outdated version of
ngtcp2. Fixed so it works with ngtcp2 1.13.0 and OpenSSL 3.5.0.
- Merge #1297: edns-subnet: fix NULL_AFTER_DEREF on subnetmod.
- Fix rrset cache create allocation failure case.
17 June 2025: Yorgos
- Fix for consistent use of local zone CNAME alias for configured auth
zones. Now it also applies to downstream configured auth zones.
16 June 2025: Wouter
- Fix to check control-interface addresses in unbound-checkconf.
- Fix #1295: Windows 32-bit binaries download seems to be missing dll
dependency.
12 June 2025: Wouter
- Fix header return value description for skip_pkt_rrs and
parse_edns_from_query_pkt.
11 June 2025: Wouter
- Fix bitwise operators in conditional expressions with parentheses.
- Fix conditional expressions with parentheses for bitwise and.
5 June 2025: Wouter
- Fix unbound-anchor certificate file read for line ends and end of
file.
- Fix comment for the dname_remove_label_limit_len function.
- iana portlist updated.
3 June 2025: Yorgos
- Small manpage corrections for the 'disable-dnssec-lame-check' option.
21 May 2025: Wouter
- Fix #1288: [FR] Improve fuzzing of unbound by adapting the netbound
program.
20 May 2025: Yorgos
- Merge #1285: RST man pages. It introduces restructuredText man pages
to sync the online and source code man page documentation.
The templated man pages (*.in) are still part of the repo but
generated with docutils from their .rst counterpart.
Documentation on how to generate those (mainly for core developers)
is in README.man.
- Add more checks about respip in unbound-checkconf.
Also fixes #310: unbound-checkconf not reporting RPZ configuration
error.
19 May 2025: Wouter
- Fix for cname chain length with qtype ANY and qname minimisation.
Thanks to Jim Greenwood from Nominet for the report.
15 May 2025: Wouter
- Fix config of slab values when there is no config file.
13 May 2025: Yorgos
- Fix #1284: NULL pointer deref in az_find_nsec_cover() (latent bug)
by adding a log_assert() to safeguard future development.
- Fix #1282: log-destaddr fail on long ipv6 addresses.
13 May 2025: Wouter
- Change default for so-sndbuf to 1m, to mitigate a cross-layer
issue where the UDP socket send buffers are exhausted waiting
for ARP/NDP resolution. Thanks to Reflyable for the report.
- Adjusted so-sndbuf default to 4m.
12 May 2025: Yorgos
- Merge #1280: Fix auth nsec3 code. Fixes NSEC3 code to not break on
broken auth zones that include unsigned out of zone (above apex)
data. Could lead to hang while trying to prove a wildcard answer.
12 May 2025: Wouter
- Fix #1283: Unsafe usage of atoi() while parsing the configuration
file.
9 May 2025: Wouter
- Fix #1281: forward-zone "name: ." conflicts with auth-zone "name: ."
in 1.23.0, but worked in 1.22.0.
5 May 2025: Yorgos
- Sync unbound and unbound-checkconf log output for unknown modules.
29 April 2025: Wouter
- Fix for parallel build of dnstap protoc-c output.
- Fix dnstap to use protoc.
29 April 2025: Yorgos
- Merge #1276: Auto-configure '-slabs' values.
28 April 2025: Yorgos
- Merge #1275: Use macros for the fr_check_changed* functions.
25 April 2025: Wouter
- Fix #1272: assertion failure testcode/unitverify.c:202.
16 April 2025: Wouter
- Increase default to `num-queries-per-thread: 2048`, when unbound is
compiled with libevent. It makes saturation of the task queue more
resource intensive and less practical. Thanks to Shiming Liu,
Network and Information Security Lab, Tsinghua University for the
report.
11 April 2025: Wouter
- Tag for 1.23.0rc2. This became the release of 1.23.0 on 24 April
2025. The code repository continues with 1.23.1 in development.
11 April 2025: Yorgos
- Merge #1265: Fix WSAPoll.
10 April 2025: Wouter
- Fix for print of connection type in log-replies for dot and doh.
9 April 2025: Wouter
- Fix to detect if atomic_store links in configure.
- Fix #1264: unbound 1.22.0 leaks memory when doing DoH.
8 April 2025: Wouter
- Tag for 1.23.0rc1.
- Fix fast_reload to print chroot with config file name.
7 April 2025: Yorgos
- Merge #902: DNS Error Reporting (RFC 9567). Introduces new
configuration option 'dns-error-reporting' and new statistics for
'num.dns_error_reports'.
4 April 2025: Wouter
- Fix mesh_copy_client_info to omit null contents from copy.
- Fix comment name in the rpz nsdname test.
- Fix nettle compile for warnings and ticket keys.
- Fix redis_replica test for unused option defaults and log printout.
- Fix test to speed up common.sh script kill_pid.
- Fix to update common.sh for speed of kill_pid.
4 April 2025: Yorgos
- Merge #1019: Redis read-only replica support.
Introduces new 'redis-replica-*' options for the Redis cache backend.
3 April 2025: Wouter
- Fix #1263: Exempt loopback addresses from wait-limit.
- Fix wait-limit-netblock and wait-limit-cookie-netblock config parse
to allow two arguments.
- Fix ub_event and include dnstap and win_svc headers.
- Fix test for stat_values for wait limit defaults for localhost.
- Fix parameter unused warning in net_help.c.
2 April 2025: Yorgos
- Merge #1262 from markyang92, fix build with
'gcc-15 -Wbuiltin-declaration-mismatch' error in compat/malloc.c.
- For #1262, ifdef is no longer needed.
2 April 2025: Wouter
- Fix unbound-control test so it counts the new flush_negative output,
also answers the _ta probe from testns and prints command output
and skip a thread specific test when no threads are available.
- Fix that ub_event has the facility to deal with callbacks for
fast reload, doq, windows-stop and dnstap.
- Fix fast reload test to check if pid exists before acting on it.
1 April 2025: Wouter
- Fix escape more characters when printing an RR type with an unquoted
string.
- Enable the auth_tls.tdir and auth_tls_failcert.tdir tests.
31 March 2025: Wouter
- iana portlist update.
- Merge #1042: Fast Reload. The unbound-control fast_reload is added.
It reads changed config in a thread, then only briefly pauses the
service threads, that keep running. DNS service is only interrupted
briefly, less than a second.
- Skip the unit tests for auth_tls.tdir and auth_tls_failcert.tdir.
27 March 2025: Wouter
- Fix unit test dname log printout typecast.
- Fix for ci test, expat is installed on the osx image.
26 March 2025: Yorgos
- Fix #1255: Multiple pinnings to vulnerable copies of libexpat.
- For #1255, for ios use an older expat version that does not require
C++11 language features.
- For #1255, for ios disable building tests that require C++11.
- For #1255, for ios try the latest expat version again.
24 March 2025: Wouter
- Fix #1254: `send failed: Socket is not connected` and
`remote address is 0.0.0.0 port 53`.
21 March 2025: Wouter
- Fix #1253: Cache entries fail to be removed from Redis cachedb
backend with unbound-control flush* +c.
- Fix for #1253: Fix for redis cachedb backend to expect an integer
reply for the EXPIRE command.
20 March 2025: Wouter
- Fix print of RR type NSAP-PTR, it is an unquoted string.
18 March 2025: Wouter
- Fix #1251: WSAPoll first argument cannot be NULL.
- Fix for windows compile create ssl contexts.
17 March 2025: Wouter
- Fix representation of types GPOS and RESINFO, add rdf type for
unquoted str.
16 March 2025: Yorgos
- Fix 'unbound-control flush_negative' when reporting removed data;
reported by David 'eqvinox' Lamparter.
28 February 2025: Wouter
- Merge #1238: Prefer SOURCE_DATE_EPOCH over actual time.
Add --help output description for the SOURCE_DATE_EPOCH variable.
25 February 2025: Wouter
- Merge #1243: Do not shadow tm on line 236.
24 February 2025: Yorgos
- Fix hash calculation for cachedb to ignore case. Previously, cached
records there were only relevant for same case queries (if not
already in Unbound's internal cache).
19 February 2025: Yorgos
- Fix static analysis report about unhandled EOF on error conditions
when reading anchor key files.
- Merge #1241: Fix infra-keep-probing for low infra-cache-max-rtt
values.
17 February 2025: Yorgos
- Consider reconfigurations when calculating the still_useful_timeout
for servers in the infrastructure cache.
30 January 2025: Wouter
- Fix #986: Resolving sas.com with dnssec-validation fails though
signed delegations seem to be (mostly) correct.
29 January 2025: Yorgos
- Make the default value of module-config "validator iterator"
regardless of compilation options. --enable-subnet would implicitly
change the value to enable the subnetcache module by default in the
past.
24 January 2025: Yorgos
- Merge #1220 from Petr Menšík, Add unbound members group access to
control key.
21 January 2025: Yorgos
- Use the same interface listening port discovery code for all needed
protocols.
- Port to string only when needed before getaddrinfo().
- Do not open unencrypted channels next to encrypted ones on the same
port.
- Merge #1224 from Theo Buehler: Do not use DSA API unless USE_DSA is
set.
21 January 2025: Wouter
- Fix compile of interface check code when dnscrypt or quic is
disabled.
- Fix encoding of RR type ATMA.
- Fix to check length in ATMA string to wire.
- Merge #1229: check before use daemon->shm_info.
20 January 2025: Yorgos
- Merge #1222: Unique DoT and DoH SSL contexts to allow for different
ALPN.
- Create the quic SSL listening context only when needed.
15 January 2025: Yorgos
- Merge #1221: Consider auth zones when checking for forwarders.
14 January 2025: Yorgos
- Add resolver.arpa and service.arpa to the default locally served
zones.
13 January 2025: Yorgos
- Fix #1213: Misleading error message on default access control causing
refuse.
10 January 2025: Yorgos
- Merge #1214: Use TCP_NODELAY on TLS sockets to speed up the TLS
handshake.
31 December 2024: Yorgos
- Merge #1174: Serve expired cache update fixes. Fixes a regression bug
with serve-expired that appeared in 1.22.0 and would not allow the
iterator to update the cache with not-yet-validated entries resulting
in increased outgoing traffic.
20 December 2024: Yorgos
- For #1207: [FR] Support for RESINFO RRType 261 (RFC9606), add
LDNS_RR_TYPE_RESINFO similar to LDNS_RR_TYPE_TXT.
13 December 2024: Yorgos
- Merge #1204: ci: set persist-credentials: false for actions/checkout
per zizmor suggestion.
3 December 2024: Yorgos
- Merge #1189: Fix the dname_str method to cause conversion errors
when the domain name length is 255.
- Merge #1197: dname_str() fixes.
- For #1175, the default value of serve-expired-ttl is set to 86400
(1 day) as suggested by RFC8767.
- Merge #1198: Fix log-servfail with serve expired and no useful cache
contents.
- Safeguard alias loop while looking in the cache for expired answers.
- Merge #1187: Create the SSL_CTX for QUIC before chroot and privilege
drop.
- Fix typo in log_servfail.tdir test.
22 November 2024: Yorgos
- Fix #1175: serve-expired does not adhere to secure-by-default
principle. The default value of serve-expired-client-timeout
is set to 1800 as suggested by RFC8767.
- For #1175, update serve-expired tests.
20 November 2024: Yorgos
- Fix comparison to help static analyzer.
19 November 2024: Yorgos
- Merge #1169 from Sergey Kacheev, fix: lock-free counters for
auth_zone up/down queries.
15 November 2024: Wouter
- Fix #1183: the data being used is released in method
nsec3_hash_test_entry.
- Fix for #1183: release nsec3 hashes per test file.
8 November 2024: Yorgos
- More descriptive text for 'harden-algo-downgrade'.
- Complete fix for max-global-quota to 200.
6 November 2024: Yorgos
- Increase the default of max-global-quota to 200 from 128 after
operational feedback. Still keeping the possible amplification
factor (CAMP related issues) in the hundreds.
5 November 2024: Wouter
- Fix for the serve expired DNSSEC information fix, it would not allow
current delegation information be updated in cache. The fix allows
current delegation and validation recursion information to be
updated, but as a consequence no longer has certain expired
information around for later dnssec valid expired responses.
- Fix to log redis timeout error string on failure.
5 November 2024: Yorgos
- Fix SETEX check during Redis (re)initialization.
4 November 2024: Wouter
- Fix redis that during a reload it does not fail if the redis
server does not connect or does not respond. It still logs the
errors and if the server is up checks expiration features.
- Merge #1167: Makefile.in: fix occasional parallel build failures
around bison rule.
1 November 2024: Yorgos
- Merge #1159: Stats for discard-timeout and wait-limit.
- Add test case for #1159.
- Some clean up for stat_values.test.
- Merge #1170 from Melroy van den Berg, Fix chroot manpage
description.
- Merge #1157 from Liang Zhu, Fix heap corruption when calling
ub_ctx_delete in Windows.
25 October 2024: Yorgos
- Fix #1163: Typos in unbound.conf documentation.
17 October 2024: Wouter
- Tag for 1.22.0 release. This did not contain the 1154 fix
from 16 oct. The code repository continues with
version 1.22.1 in development.
16 October 2024: Yorgos
- Fix for dnsoverquic and dnstap to use the correct dnstap
environment.
16 October 2024: Wouter
- Fix for dnstap with dnscrypt and dnstap without dnsoverquic.
- Fix #1154: Tag Incorrectly Applying for Other Interfaces
Using the Same IP. This fix is not for 1.22.0.
14 October 2024: Wouter
- Fix to display warning if quic-port is set but dnsoverquic is not
enabled when compiled.
- Fix dnsoverquic to extend the number of streams when one is closed.
11 October 2024: Wouter
- Fix to disable detection of quic configured ports when quic is
not compiled in.
- Fix harden-unverified-glue for AAAA cache_fill_missing lookups.
- Fix contrib/aaaa-filter-iterator.patch for change in call
signature for cache_fill_missing.
10 October 2024: Wouter
- Fix cookie_file test sporadic fails for time change during
the test.
- Fix add reallocarray to alloc stats unit test, and disable
override of strdup in unbound-host, and the result of config
get option is freed properly.
- Tag for 1.22.0rc1.
9 October 2024: Wouter
- Merge #871: DNS over QUIC. This adds `quic-port: 853` and
`quic-size: 8m` that enable dnsoverquic, and the counters
`num.query.quic` and `mem.quic` in the statistics output.
The feature needs to be enabled by compiling with libngtcp2,
with `--with-libngtcp2=path` and libngtcp2 needs openssl+quic,
pass that with `--with-ssl=path` to compile unbound as well.
- Fix to limit NSEC TTL for messages from cachedb. Fix to limit the
prefetch ttl for messages after a CNAME with short TTL.
- Fix for dnstap compile of doqclient with doq disabled.
8 October 2024: Wouter
- Fix #1149: unbound-control-setup hangs sometimes depending on
the openssl version.
- Fix #1128: Cannot override tcp-upstream and tls-upstream with
forward-tcp-upstream and forward-tls-upstream.
3 October 2024: Yorgos
- Fix CVE-2024-8508, unbounded name compression could lead to denial
of service.
- This fix was part of 1.21.1, a security point release on 1.21.0.
The code repository continues with this fix and the version number
1.22.0.
30 September 2024: Wouter
- Fix negative cache NSEC3 parameter compares for zero length NSEC3
salt.
- Fix unbound dnstap socket test program analyzer warnings about
unused variable assignments and variable initialization.
25 September 2024: Wouter
- Fix #1144: [FR] log timestamps in ISO8601 format with timezone.
This adds the option `log-time-iso: yes` that logs in ISO8601
format.
24 September 2024: Yorgos
- Attempt to further fix doh_downstream_buffer_size.tdir flakiness.
- More clear text for prefetch and minimal-responses in the
unbound.conf man page.
- Merge #1143: Fix cache update when serve expired is used. Expired
records are favored over resolution and validation failures when
serve-expired is used.
23 September 2024: Wouter
- Fix dns64 with prefetch that the prefetch is stored in cache.
23 September 2024: Yorgos
- Fix doxygen warnings by commenting out CLANG_ASSISTED_PARSING,
CLANG_ADD_INC_PATHS, CLANG_OPTIONS and CLANG_DATABASE_PATH; they were
already disabled.
17 September 2024: Wouter
- Add redis-command-timeout: 20 and redis-connect-timeout: 200,
that can set the timeout separately for commands and the
connection set up to the redis server. If they are not
specified, the redis-timeout value is used.
16 September 2024: Wouter
- Merge #1140: Fix spelling mistake in comments.
11 September 2024: Yorgos
- Fix and add comments in testdata/val_negcache_ttl.rpl.
10 September 2024: Wouter
- Fix to limit NSEC and NSEC3 TTL when aggressive nsec is
enabled (RFC9077).
- Add unit test for ttl limit for aggressive nsec.
6 September 2024: Yorgos
- Fix alloc-size and calloc-transposed-args compiler warnings.
- Fix comment to not trigger doxygen unknown command.
5 September 2024: Wouter
- Fix config file read for dnstap-sample-rate.
2 September 2024: Wouter
- Merge #1135: Add new IANA trust anchor.
30 August 2024: Wouter
- Merge #1132: b.root renumbering.
- Fix for #1132, adjusted unit test for change in the test file.
- Fix for #1132, comment about adjusted copy of reference check.
29 August 2024: Wouter
- Unit test for auth zone transfer TLS, and TLS failure.
- Fix to print port number in logs for auth zone transfer activities.
28 August 2024: Wouter
- Fix that when rpz is applied the message does not get picked up by
the validator. That stops validation failures for the message.
- Fix that stub-zone and forward-zone clauses do not exhaust memory
for long content.
27 August 2024: Wouter
- Fix #1130: Loads of logs: "validation failure: key for validation
<domain>. is marked as invalid because of a previous" for
non-DNSSEC signed zone.
23 August 2024: Wouter
- Merge patch to fix for glue that is outside of zone, with
`harden-unverified-glue`, from Karthik Umashankar (Microsoft).
Enabling this option protects the Unbound resolver against bad
glue, that is unverified out of zone glue, by resolving them.
It uses the records as last resort if there is no other working
glue.
- Fix #1127: error: "memory exhausted" when defining more than 9994
local-zones.
- Fix documentation for cache_fill_missing function.
21 August 2024: Wouter
- Add cross platform freebsd, openbsd and netbsd to github ci.
- Fix for char signedness warnings on NetBSD.
20 August 2024: Wouter
- Add iter-scrub-ns, iter-scrub-cname and max-global-quota
configuration options.
19 August 2024: Wouter
- Fix #1126: unbound-control-setup hangs while testing for openssl
presence starting from version 1.21.0.
9 August 2024: Wouter
- Fix spelling for the cache-min-negative-ttl entry in the
example.conf.
- Tag for release 1.21.0, the repository continues with 1.21.1
in development.
8 August 2024: Wouter
- Fix CAMP issues with global quota. Thanks to Huayi Duan, Marco
Bearzi, Jodok Vieli, and Cagin Tanir from NetSec group, ETH Zurich.
- Fix CacheFlush issues with limit on NS RRs. Thanks to Yehuda Afek,
Anat Bremler-Barr, Shoham Danino and Yuval Shavitt (Tel-Aviv
University and Reichman University).
- Set version number to 1.21.0 for release. This has tag 1.21.0rc1.
- Fix that for windows the module startup is called and sets up
the module-config.
2 August 2024: Wouter
- Fix that alloc stats has strdup checks, it stops debuggers from
complaining about mismatch at free time.
- Fix testbound for alloc stats strdup in util/alloc.c.
- Merge #1090: Cookie secret file. Adds
`cookie-secret-file: "unbound_cookiesecrets.txt"` option to store
cookie secrets for EDNS COOKIE secret rollover. The remote control
add_cookie_secret, activate_cookie_secret and drop_cookie_secret
commands can be used for rollover, the command print_cookie_secrets
shows the values in use.
- Fix that alloc stats for forwards and hints are printed, and when
alloc stats is enabled, the unit test for unbound control waits for
reloads to complete.
1 August 2024: Wouter
- Fix dnstap test program, cleans up to have clean memory on exit,
for tap_data_free, does not delete NULL items. Also it does not try
to free the tail, specifically in the free of the list since that
picked up the next item in the list for its loop causing invalid
free. Added internal unit test to unbound-dnstap-socket for that.
- Fix that the worker mem report with alloc stats does not attempt
to print memory use of forwards and hints if they have been
deleted already.
31 July 2024: Wouter
- Fix for #1114: Fix that cache fill for forward-host names is
performed, so that with nonzero target-fetch-policy it fetches
forwarder addresses and uses them from cache. Also updated that
delegation point cache fill routines use CDflag for AAAA message
lookups, so that its negative lookup stops a recursion since the
cache uses the bit for disambiguation for dns64 but the recursion
uses CDflag for the AAAA target lookups, so the check correctly
stops a useless recursion by its cache lookup.
30 July 2024: Wouter
- Fix to document parameters of auth_zone_verify_zonemd_with_key.
25 July 2024: Wouter
- Add root key 38696 from 2024 for DNSSEC validation. It is added
to the default root keys in unbound-anchor. The content can be
inspected with `unbound-anchor -l`.
23 July 2024: Yorgos
- Fix #1106: ratelimit-below-domain logs the wrong FROM address.
- Cleanup ede.tdir test.
- For #935 and #1104, clarify RPZ order and semantics.
23 July 2024: Wouter
- Merge #1110: Make fallthrough explicit for libworker.c.
- For #1110: Test for fallthrough attribute in configure and add
fallthrough attribute annotations.
- Fix compile when the compiler does not support the noreturn
attribute.
- Fix to have empty definition when not supported for weak attribute.
- Fix uninitialized variable warning in create_tcp_accept_sock.
- Fix link of dnstap without openssl.
- Fix link of unbound-dnstap-socket without openssl.
19 July 2024: Wouter
- Add dnstap-sample-rate that logs only 1/N messages, for high volume
server environments. Thanks Dan Luther.
@@ -908,7 +165,7 @@
now checks both single and multi process/thread operation.
16 May 2024: Yorgos
- Merge #1070: Fix rtt assignment for low values of
- Merge #1070: Fix rtt assignement for low values of
infra-cache-max-rtt.
16 May 2024: Wouter
@@ -1316,7 +573,7 @@
13 October 2023: George
- Better fix for infinite loop when reading multiple lines of input on
a broken remote control socket, by treating a zero byte line the
same as transmission end. Addresses #947 and #948.
same as transmission end. Addesses #947 and #948.
12 October 2023: Wouter
- Merge #944: Disable EDNS DO.
@@ -1339,7 +596,7 @@
10 October 2023: George
- Fix infinite loop when reading multiple lines of input on a broken
remote control socket. Addresses #947 and #948.
remote control socket. Addesses #947 and #948.
9 October 2023: Wouter
- Fix edns subnet so that queries with a source prefix of zero cause
@@ -1772,7 +1029,7 @@
- Ignore expired error responses.
11 November 2022: Wouter
- Fix #779: [doc] Missing documentation in ub_resolve_event() for
- Fix #779: [doc] Missing documention in ub_resolve_event() for
callback parameter was_ratelimited.
9 November 2022: George
@@ -2736,7 +1993,7 @@
not hang. removed trailing slashes from configure paths. Moved iOS
tests to allow-failure.
- travis, analyzer disabled on test without debug, that does not
run anyway. Turn off failing tests except one. Update iOS test
run anway. Turn off failing tests except one. Update iOS test
to xcode image 12.2.
22 March 2021: George
@@ -2825,7 +2082,7 @@
- Fix build on Python 3.10.
10 February 2021: Wouter
- Merge PR #420 from dyunwei: DOH not responding with
- Merge PR #420 from dyunwei: DOH not responsing with
"http2_query_read_done failure" logged.
9 February 2021: Wouter
@@ -3225,7 +2482,7 @@
6 August 2020: Wouter
- Merge PR #284 and Fix #246: Remove DLV entirely from Unbound.
The DLV has been decommissioned and in unbound 1.5.4, in 2015, there
The DLV has been decommisioned and in unbound 1.5.4, in 2015, there
was advise to stop using it. The current code base does not contain
DLV code any more. The use of dlv options displays a warning.
@@ -3774,7 +3031,7 @@
3 December 2019: Wouter
- Merge pull request #124 from rmetrich: Changed log lock
from 'quick' to 'basic' because this is an I/O lock.
- Fix text around serial arithmetic used for RRSIG times to refer
- Fix text around serial arithmatic used for RRSIG times to refer
to correct RFC number.
- Fix Assert Causing DoS in synth_cname(),
reported by X41 D-Sec.
@@ -4037,7 +3294,7 @@
- For #52 #53, second context does not close logfile override.
- Fix #52 #53, fix for example fail program.
- Fix to return after failed auth zone http chunk write.
- Fix to remove unused test for task_probe existence.
- Fix to remove unused test for task_probe existance.
- Fix to timeval_add for remaining second in microseconds.
- Check repinfo in worker_handle_request, if null, drop it.
@@ -5294,7 +4551,7 @@
1 February 2018: Wouter
- fix unaligned structure making a false positive in checklock
uninitialised memory.
unitialised memory.
29 January 2018: Ralph
- Use NSEC with longest ce to prove wildcard absence.
@@ -5897,8 +5154,8 @@
- Remove (now unused) event2 include from dnscrypt code.
24 March 2017: George
- Fix to prevent non-referral query from being cached as referral when
the no_cache_store flag was set.
- Fix to prevent non-referal query from being cached as referal when the
no_cache_store flag was set.
23 March 2017: Wouter
- Fix #1239: configure fails to find python distutils if python
@@ -5961,7 +5218,7 @@
7 March 2017: Wouter
- Fix #1230: swig version 2.0.0 is required for pythonmod, with
1.3.40 it crashes when running repeatedly unbound-control reload.
1.3.40 it crashes when running repeatly unbound-control reload.
- Response actions based on IP address from Jinmei Tatuya (Infoblox).
6 March 2017: Wouter
@@ -5977,7 +5234,7 @@
known vulns.
27 February 2017: Wouter
- Fix #1227: Fix that Unbound control allows weak ciphersuites.
- Fix #1227: Fix that Unbound control allows weak ciphersuits.
- Fix #1226: provide official 32bit binary for windows.
24 February 2017: Wouter
@@ -6966,7 +6223,7 @@
- Fix #674: Do not free pointers given by getenv.
29 May 2015: Wouter
- Fix that unparsable error responses are ratelimited.
- Fix that unparseable error responses are ratelimited.
- SOA negative TTL is capped at minimumttl in its rdata section.
- cache-max-negative-ttl config option, default 3600.
@@ -6984,7 +6241,7 @@
10 May 2015: Wouter
- Change syntax of particular validator error to be easier for
machine parse, swap rrset and ip address info so it looks like:
machine parse, swap rrset and ip adres info so it looks like:
validation failure <www.example.nl. TXT IN>: signature crypto
failed from 2001:DB8:7:bba4::53 for <*.example.nl. NSEC IN>
@@ -8564,7 +7821,7 @@
- fix that --enable-static-exe does not complain about it unknown.
30 June 2011: Wouter
- tag release 1.4.11, trunk is 1.4.12 development.
- tag relase 1.4.11, trunk is 1.4.12 development.
- iana portlist updated.
- fix bug#395: id bits of other query may leak out under conditions
- fix replyaddr count wrong after jostled queries, which leads to
@@ -9894,7 +9151,7 @@
8 June 2009: Wouter
- Removed RFC5011 REVOKE flag support. Partial 5011 support may cause
inadvertent behaviour.
inadvertant behaviour.
- 1.3.0 tarball for release created.
- 1.3.1 development in svn trunk.
- iana portlist updated.
@@ -10243,7 +9500,7 @@
- initgroups(3) is called to drop secondary group permissions, if
applicable.
- configure option --with-ldns-builtin forces the use of the
included ldns package with the unbound source. The -I include
inluded ldns package with the unbound source. The -I include
is put before the others, so it avoids bad include files from
an older ldns install.
- daemon(3) posix call is used when available.
@@ -10548,7 +9805,7 @@
please ranlib, stop file without symbols warning.
- harden referral path now also validates the root after priming.
It looks up the root NS authoritatively as well as the root servers
and attempts to validate the entries.
and attemps to validate the entries.
16 October 2008: Wouter
- Fixup negative TTL values appearing (reported by Attila Nagy).
@@ -11327,7 +10584,7 @@
- please doxygen, put doxygen comment in one place.
- asynclook -b blocking mode and test.
- refactor asynclook, nicer code.
- fixup race problems from openssl in rand init from library, with
- fixup race problems from opensll in rand init from library, with
a mutex around the rand init.
- fix pass async_id=NULL to _async resolve().
- rewrote _wait() routine, so that it is threadsafe.
@@ -12300,7 +11557,7 @@
11 June 2007: Wouter
- replies on TCP queries have the address field set in replyinfo,
for serviced queries, because the initiator does not know that
a TCP fallback has occurred.
a TCP fallback has occured.
- omit DNSSEC types from nonDO replies, except if qtype is ANY or
if qtype directly queries for the type (and then only show that
'unknown type' in the answer section).
-16
View File
@@ -1,16 +0,0 @@
After Unbound 1.23.0, the source of the man pages is in reStructuredText format.
This helps with the online documentation at https://unbound.docs.nlnetlabs.nl
and makes it easier to maintain and contribute to the documentation.
The templated man pages (*.in) are still part of the code repository as to not
alter current procedures that could be in place by users/packagers.
The templated man pages (*.in) are generated by Sphinx (used for the online
documentation).
The online documentation has its own repository at
https://github.com/NLnetLabs/unbound-manual.
In the README.md there (branch test-auto for now), there are further simple
instructions on how to generate the templated man pages there and update them
in this repository.
+16 -76
View File
@@ -116,8 +116,8 @@ server:
# so-rcvbuf: 0
# buffer size for UDP port 53 outgoing (SO_SNDBUF socket option).
# 0 is system default. Set larger to handle spikes on very busy servers.
# so-sndbuf: 4m
# 0 is system default. Use 4m to handle spikes on very busy servers.
# so-sndbuf: 0
# use SO_REUSEPORT to distribute queries over threads.
# at extreme load it could be better to turn it off to distribute even.
@@ -163,7 +163,7 @@ server:
# msg-cache-slabs: 4
# the number of queries that a thread gets to service.
# num-queries-per-thread: 2048
# num-queries-per-thread: 1024
# if very busy, 50% queries run to completion, 50% get timeout in msec
# jostle-timeout: 200
@@ -187,15 +187,6 @@ server:
# query upon encountering a CNAME record.
# max-query-restarts: 11
# Limit on number of NS records in NS RRset for incoming packets.
# iter-scrub-ns: 20
# Limit on number of CNAME, DNAME records for incoming packets.
# iter-scrub-cname: 11
# Limit on upstream queries for an incoming query and its recursion.
# max-global-quota: 200
# msec for waiting for an unknown server to reply. Increase if you
# are behind a slow satellite link, to eg. 1128.
# unknown-server-time-limit: 376
@@ -215,12 +206,6 @@ server:
# Apart from the default, the wait limit with cookie can be adjusted.
# wait-limit-cookie-netblock: 192.0.2.0/24 50000
# Defaults for loopback, it has no wait limit.
# wait-limit-netblock: 127.0.0.0/8 -1
# wait-limit-netblock: ::1/128 -1
# wait-limit-cookie-netblock: 127.0.0.0/8 -1
# wait-limit-cookie-netblock: ::1/128 -1
# the amount of memory to use for the RRset cache.
# plain value in bytes or you can append k, m or G. default is "4Mb".
# rrset-cache-size: 4m
@@ -243,7 +228,7 @@ server:
# the time to live (TTL) value lower bound, in seconds. Default 0.
# For negative responses in the cache. If disabled, default,
# cache-min-ttl applies if configured.
# cache-min-tll applies if configured.
# cache-min-negative-ttl: 0
# the time to live (TTL) value for cached roundtrip times, lameness and
@@ -279,7 +264,7 @@ server:
# do-ip6: yes
# If running unbound on an IPv6-only host, domains that only have
# IPv4 servers would become unresolvable. If NAT64 is available in
# IPv4 servers would become unresolveable. If NAT64 is available in
# the network, unbound can use NAT64 to reach these servers with
# the following option. This is NOT needed for enabling DNS64 on a
# system that has IPv4 connectivity.
@@ -467,10 +452,6 @@ server:
# print UTC timestamp in ascii to logfile, default is epoch in seconds.
# log-time-ascii: no
# log timestamp in ISO8601 format if also log-time-ascii is enabled.
# (y-m-dTh:m:s.msec[+-]tzhours:tzminutes)
# log-time-iso: no
# print one line with time, IP, name, type, class for every query.
# log-queries: no
@@ -543,9 +524,6 @@ server:
# Harden against out of zone rrsets, to avoid spoofing attempts.
# harden-glue: yes
# Harden against unverified (outside-zone, including sibling zone) glue rrsets
# harden-unverified-glue: no
# Harden against receiving dnssec-stripped data. If you turn it
# off, failing to validate dnskey data for a trustanchor will
# trigger insecure mode for that zone (like without a trustanchor).
@@ -562,9 +540,8 @@ server:
# harden-referral-path: no
# Harden against algorithm downgrade when multiple algorithms are
# advertised in the DS record. If no, allows any algorithm
# to validate the zone which is the standard behavior for validators.
# Check the manpage for detailed information.
# advertised in the DS record. If no, allows the weakest algorithm
# to validate the zone.
# harden-algo-downgrade: no
# Harden against unknown records in the authority section and the
@@ -737,13 +714,12 @@ server:
# disable-edns-do: no
# Serve expired responses from cache, with serve-expired-reply-ttl in
# the response. By default it first tries to refresh an expired answer.
# Can be configured with serve-expired-client-timeout.
# the response, and then attempt to fetch the data afresh.
# serve-expired: no
#
# Limit serving of expired responses to configured seconds after
# expiration. 0 disables the limit.
# serve-expired-ttl: 86400
# serve-expired-ttl: 0
#
# Set the TTL of expired records to the serve-expired-ttl value after a
# failed attempt to retrieve the record from upstream. This makes sure
@@ -756,9 +732,10 @@ server:
#
# Time in milliseconds before replying to the client with expired data.
# This essentially enables the serve-stale behavior as specified in
# RFC 8767 that first tries to resolve before immediately responding
# with expired data. 0 disables this behavior.
# serve-expired-client-timeout: 1800
# RFC 8767 that first tries to resolve before
# immediately responding with expired data. 0 disables this behavior.
# A recommended value is 1800.
# serve-expired-client-timeout: 0
# Return the original TTL as received from the upstream name server rather
# than the decrementing TTL as stored in the cache. Enabling this feature
@@ -817,8 +794,6 @@ server:
# local-zone: "127.in-addr.arpa." nodefault
# local-zone: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." nodefault
# local-zone: "home.arpa." nodefault
# local-zone: "resolver.arpa." nodefault
# local-zone: "service.arpa." nodefault
# local-zone: "onion." nodefault
# local-zone: "test." nodefault
# local-zone: "invalid." nodefault
@@ -929,7 +904,6 @@ server:
# tls-service-pem: "path/to/publiccertfile.pem"
# tls-port: 853
# https-port: 443
# quic-port: 853
# cipher setting for TLSv1.2
# tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256"
@@ -994,9 +968,6 @@ server:
# Disable TLS for DNS-over-HTTP downstream service.
# http-notls-downstream: no
# Maximum number of bytes used for QUIC buffers.
# quic-size: 8m
# The interfaces that use these listed port numbers will support and
# expect PROXYv2. For UDP and TCP/TLS interfaces.
# proxy-protocol-port: portno for each of the port numbers.
@@ -1073,11 +1044,6 @@ server:
# example value "000102030405060708090a0b0c0d0e0f".
# cookie-secret: <128 bit random hex string>
# File with cookie secrets, the 'cookie-secret:' option is ignored
# and the file can be managed to have staging and active secrets
# with remote control commands. Disabled with "". Default is "".
# cookie-secret-file: "/usr/local/etc/unbound_cookiesecrets.txt"
# Enable to attach Extended DNS Error codes (RFC8914) to responses.
# ede: no
@@ -1086,11 +1052,6 @@ server:
# Note that the ede option above needs to be enabled for this to work.
# ede-serve-expired: no
# Enable DNS Error Reporting (RFC9567).
# qname-minimisation is advised to be turned on as well to increase
# privacy on the outgoing reports.
# dns-error-reporting: no
# Specific options for ipsecmod. Unbound needs to be configured with
# --enable-ipsecmod for these to take effect.
#
@@ -1318,35 +1279,15 @@ remote-control:
# # redis server's TCP port
# redis-server-port: 6379
# # if the server uses a unix socket, set its path, or "" when not used.
# redis-server-path: "/var/lib/redis/redis-server.sock"
# # redis-server-path: "/var/lib/redis/redis-server.sock"
# # if the server uses an AUTH password, specify here, or "" when not used.
# redis-server-password: ""
# # redis-server-password: ""
# # timeout (in ms) for communication with the redis server
# redis-timeout: 100
# # timeout (in ms) for commands, if 0, uses redis-timeout.
# redis-command-timeout: 0
# # timeout (in ms) for connection set up, if 0, uses redis-timeout.
# redis-connect-timeout: 0
# # set timeout on redis records based on DNS response TTL
# redis-expire-records: no
# # redis logical database to use, 0 is the default database.
# redis-logical-db: 0
# # redis replica server's IP address or host name
# redis-replica-server-host: 127.0.0.1
# # redis replica server's TCP port
# redis-replica-server-port: 6379
# # if the replica server uses a unix socket, set its path, or "" when not used.
# redis-replica-server-path: "/var/lib/redis/redis-server.sock"
# # if the replica server uses an AUTH password, specify here, or "" when not used.
# redis-replica-server-password: ""
# # timeout (in ms) for communication with the redis replica server
# redis-replica-timeout: 100
# # timeout (in ms) for redis replica commands, if 0, uses redis-replica-timeout.
# redis-replica-command-timeout: 0
# # timeout (in ms) for redis replica connection set up, if 0, uses redis-replica-timeout.
# redis-replica-connect-timeout: 0
# # redis logical database to use for the replica server, 0 is the default database.
# redis-replica-logical-db: 0
# IPSet
# Add specify domain into set via ipset.
@@ -1398,8 +1339,7 @@ remote-control:
# dnstap-log-forwarder-response-messages: no
# Response Policy Zones
# RPZ policies. Applied in order of configuration. Any match from an earlier
# RPZ zone will terminate the RPZ lookup. QNAME, Response IP
# RPZ policies. Applied in order of configuration. QNAME, Response IP
# Address, nsdname, nsip and clientip triggers are supported. Supported
# actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp-only
# and drop. Policies can be loaded from a file, or using zone
+343 -330
View File
@@ -1,306 +1,335 @@
.\" Man page generated from reStructuredText.
.
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "LIBUNBOUND" "3" "@date@" "@version@" "Unbound"
.SH NAME
libunbound \- Unbound DNS validating resolver @version@ functions.
.SH SYNOPSIS
.sp
\fB#include <unbound.h>\fP
.sp
struct ub_ctx * \fBub_ctx_create\fP(void);
.sp
void \fBub_ctx_delete\fP(struct ub_ctx* ctx);
.sp
int \fBub_ctx_set_option\fP(struct ub_ctx* ctx, char* opt, char* val);
.sp
int \fBub_ctx_get_option\fP(struct ub_ctx* ctx, char* opt, char** val);
.sp
int \fBub_ctx_config\fP(struct ub_ctx* ctx, char* fname);
.sp
int \fBub_ctx_set_fwd\fP(struct ub_ctx* ctx, char* addr);
.INDENT 0.0
.TP
int \fBub_ctx_set_stub\fP(struct ub_ctx* ctx, char* zone, char* addr,
int isprime);
.UNINDENT
.sp
int \fBub_ctx_set_tls\fP(struct ub_ctx* ctx, int tls);
.sp
int \fBub_ctx_resolvconf\fP(struct ub_ctx* ctx, char* fname);
.sp
int \fBub_ctx_hosts\fP(struct ub_ctx* ctx, char* fname);
.sp
int \fBub_ctx_add_ta\fP(struct ub_ctx* ctx, char* ta);
.sp
int \fBub_ctx_add_ta_autr\fP(struct ub_ctx* ctx, char* fname);
.sp
int \fBub_ctx_add_ta_file\fP(struct ub_ctx* ctx, char* fname);
.sp
int \fBub_ctx_trustedkeys\fP(struct ub_ctx* ctx, char* fname);
.sp
int \fBub_ctx_debugout\fP(struct ub_ctx* ctx, FILE* out);
.sp
int \fBub_ctx_debuglevel\fP(struct ub_ctx* ctx, int d);
.sp
int \fBub_ctx_async\fP(struct ub_ctx* ctx, int dothread);
.sp
int \fBub_poll\fP(struct ub_ctx* ctx);
.sp
int \fBub_wait\fP(struct ub_ctx* ctx);
.sp
int \fBub_fd\fP(struct ub_ctx* ctx);
.sp
int \fBub_process\fP(struct ub_ctx* ctx);
.INDENT 0.0
.TP
int \fBub_resolve\fP(struct ub_ctx* ctx, char* name,
int rrtype, int rrclass, struct ub_result** result);
.TP
int \fBub_resolve_async\fP(struct ub_ctx* ctx, char* name,
int rrtype, int rrclass, void* mydata,
ub_callback_type* callback, int* async_id);
.UNINDENT
.sp
int \fBub_cancel\fP(struct ub_ctx* ctx, int async_id);
.sp
void \fBub_resolve_free\fP(struct ub_result* result);
.sp
const char * \fBub_strerror\fP(int err);
.sp
int \fBub_ctx_print_local_zones\fP(struct ub_ctx* ctx);
.sp
int \fBub_ctx_zone_add\fP(struct ub_ctx* ctx, char* zone_name, char* zone_type);
.sp
int \fBub_ctx_zone_remove\fP(struct ub_ctx* ctx, char* zone_name);
.sp
int \fBub_ctx_data_add\fP(struct ub_ctx* ctx, char* data);
.sp
int \fBub_ctx_data_remove\fP(struct ub_ctx* ctx, char* data);
.SH DESCRIPTION
.sp
Unbound is an implementation of a DNS resolver, that does caching and DNSSEC
validation.
This is the library API, for using the \fB\-lunbound\fP library.
The server daemon is described in \fI\%unbound(8)\fP\&.
The library works independent from a running unbound server, and can be used to
convert hostnames to ip addresses, and back, and obtain other information from
the DNS.
The library performs public\-key validation of results with DNSSEC.
.sp
The library uses a variable of type \fIstruct ub_ctx\fP to keep context between
calls.
The user must maintain it, creating it with \fBub_ctx_create\fP and deleting it
with \fBub_ctx_delete\fP\&.
It can be created and deleted at any time.
Creating it anew removes any previous configuration (such as trusted keys) and
clears any cached results.
.sp
The functions are thread\-safe, and a context can be used in a threaded (as well
as in a non\-threaded) environment.
Also resolution (and validation) can be performed blocking and non\-blocking
(also called asynchronous).
The async method returns from the call immediately, so that processing can go
on, while the results become available later.
.sp
.TH "libunbound" "3" "@date@" "NLnet Labs" "unbound @version@"
.\"
.\" libunbound.3 -- unbound library functions manual
.\"
.\" Copyright (c) 2007, NLnet Labs. All rights reserved.
.\"
.\" See LICENSE for the license.
.\"
.\"
.SH "NAME"
.B libunbound,
.B unbound.h,
.B ub_ctx,
.B ub_result,
.B ub_callback_type,
.B ub_ctx_create,
.B ub_ctx_delete,
.B ub_ctx_set_option,
.B ub_ctx_get_option,
.B ub_ctx_config,
.B ub_ctx_set_fwd,
.B ub_ctx_set_stub,
.B ub_ctx_set_tls,
.B ub_ctx_resolvconf,
.B ub_ctx_hosts,
.B ub_ctx_add_ta,
.B ub_ctx_add_ta_autr,
.B ub_ctx_add_ta_file,
.B ub_ctx_trustedkeys,
.B ub_ctx_debugout,
.B ub_ctx_debuglevel,
.B ub_ctx_async,
.B ub_poll,
.B ub_wait,
.B ub_fd,
.B ub_process,
.B ub_resolve,
.B ub_resolve_async,
.B ub_cancel,
.B ub_resolve_free,
.B ub_strerror,
.B ub_ctx_print_local_zones,
.B ub_ctx_zone_add,
.B ub_ctx_zone_remove,
.B ub_ctx_data_add,
.B ub_ctx_data_remove
\- Unbound DNS validating resolver @version@ functions.
.SH "SYNOPSIS"
.B #include <unbound.h>
.LP
\fIstruct ub_ctx *\fR
\fBub_ctx_create\fR(\fIvoid\fR);
.LP
\fIvoid\fR
\fBub_ctx_delete\fR(\fIstruct ub_ctx*\fR ctx);
.LP
\fIint\fR
\fBub_ctx_set_option\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR opt, \fIchar*\fR val);
.LP
\fIint\fR
\fBub_ctx_get_option\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR opt, \fIchar**\fR val);
.LP
\fIint\fR
\fBub_ctx_config\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
\fBub_ctx_set_fwd\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR addr);
.LP
\fIint\fR
\fBub_ctx_set_stub\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR zone,
\fIchar*\fR addr,
.br
\fIint\fR isprime);
.LP
\fIint\fR
\fBub_ctx_set_tls\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR tls);
.LP
\fIint\fR
\fBub_ctx_resolvconf\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
\fBub_ctx_hosts\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
\fBub_ctx_add_ta\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR ta);
.LP
\fIint\fR
\fBub_ctx_add_ta_autr\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
\fBub_ctx_add_ta_file\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
\fBub_ctx_trustedkeys\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
.LP
\fIint\fR
\fBub_ctx_debugout\fR(\fIstruct ub_ctx*\fR ctx, \fIFILE*\fR out);
.LP
\fIint\fR
\fBub_ctx_debuglevel\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR d);
.LP
\fIint\fR
\fBub_ctx_async\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR dothread);
.LP
\fIint\fR
\fBub_poll\fR(\fIstruct ub_ctx*\fR ctx);
.LP
\fIint\fR
\fBub_wait\fR(\fIstruct ub_ctx*\fR ctx);
.LP
\fIint\fR
\fBub_fd\fR(\fIstruct ub_ctx*\fR ctx);
.LP
\fIint\fR
\fBub_process\fR(\fIstruct ub_ctx*\fR ctx);
.LP
\fIint\fR
\fBub_resolve\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR name,
.br
\fIint\fR rrtype, \fIint\fR rrclass, \fIstruct ub_result**\fR result);
.LP
\fIint\fR
\fBub_resolve_async\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR name,
.br
\fIint\fR rrtype, \fIint\fR rrclass, \fIvoid*\fR mydata,
.br
\fIub_callback_type\fR callback, \fIint*\fR async_id);
.LP
\fIint\fR
\fBub_cancel\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR async_id);
.LP
\fIvoid\fR
\fBub_resolve_free\fR(\fIstruct ub_result*\fR result);
.LP
\fIconst char *\fR
\fBub_strerror\fR(\fIint\fR err);
.LP
\fIint\fR
\fBub_ctx_print_local_zones\fR(\fIstruct ub_ctx*\fR ctx);
.LP
\fIint\fR
\fBub_ctx_zone_add\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR zone_name, \fIchar*\fR zone_type);
.LP
\fIint\fR
\fBub_ctx_zone_remove\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR zone_name);
.LP
\fIint\fR
\fBub_ctx_data_add\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR data);
.LP
\fIint\fR
\fBub_ctx_data_remove\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR data);
.SH "DESCRIPTION"
.B Unbound
is an implementation of a DNS resolver, that does caching and
DNSSEC validation. This is the library API, for using the \-lunbound library.
The server daemon is described in \fIunbound\fR(8).
The library works independent from a running unbound server, and
can be used to convert hostnames to ip addresses, and back,
and obtain other information from the DNS. The library performs public\-key
validation of results with DNSSEC.
.P
The library uses a variable of type \fIstruct ub_ctx\fR to keep context
between calls. The user must maintain it, creating it with
.B ub_ctx_create
and deleting it with
.B ub_ctx_delete\fR.
It can be created and deleted at any time. Creating it anew removes any
previous configuration (such as trusted keys) and clears any cached results.
.P
The functions are thread\-safe, and a context can be used in a threaded (as
well as in a non\-threaded) environment. Also resolution (and validation)
can be performed blocking and non\-blocking (also called asynchronous).
The async method returns from the call immediately, so that processing
can go on, while the results become available later.
.P
The functions are discussed in turn below.
.SH FUNCTIONS
.INDENT 0.0
.TP
.SH "FUNCTIONS"
.TP
.B ub_ctx_create
Create a new context, initialised with defaults.
The information from \fB/etc/resolv.conf\fP and \fB/etc/hosts\fP is
not utilised by default.
Use \fBub_ctx_resolvconf\fP and \fBub_ctx_hosts\fP to read them.
Before you call this, use the openssl functions
\fBCRYPTO_set_id_callback\fP and \fBCRYPTO_set_locking_callback\fP to set
up asynchronous operation if you use lib openssl (the application calls
these functions once for initialisation).
Openssl 1.0.0 or later uses the \fBCRYPTO_THREADID_set_callback\fP
function.
The information from /etc/resolv.conf and /etc/hosts is not utilised
by default. Use
.B ub_ctx_resolvconf
and
.B ub_ctx_hosts
to read them.
Before you call this, use the openssl functions CRYPTO_set_id_callback and
CRYPTO_set_locking_callback to set up asynchronous operation if you use
lib openssl (the application calls these functions once for initialisation).
Openssl 1.0.0 or later uses the CRYPTO_THREADID_set_callback function.
.TP
.B ub_ctx_delete
Delete validation context and free associated resources.
Outstanding async queries are killed and callbacks are not called for
them.
Outstanding async queries are killed and callbacks are not called for them.
.TP
.B ub_ctx_set_option
A power\-user interface that lets you specify one of the options from
the config file format, see \fI\%unbound.conf(5)\fP\&.
Not all options are relevant.
For some specific options, such as adding trust anchors, special
routines exist.
Pass the option name with the trailing \fB\(aq:\(aq\fP\&.
A power\-user interface that lets you specify one of the options from the
config file format, see \fIunbound.conf\fR(5). Not all options are
relevant. For some specific options, such as adding trust anchors, special
routines exist. Pass the option name with the trailing ':'.
.TP
.B ub_ctx_get_option
A power\-user interface that gets an option value.
Some options cannot be gotten, and others return a newline separated
list.
Pass the option name without trailing \fB\(aq:\(aq\fP\&.
The returned value must be free(2)d by the caller.
A power\-user interface that gets an option value. Some options cannot be
gotten, and others return a newline separated list. Pass the option name
without trailing ':'. The returned value must be free(2)d by the caller.
.TP
.B ub_ctx_config
A power\-user interface that lets you specify an unbound config file,
see \fI\%unbound.conf(5)\fP, which is read for
configuration.
Not all options are relevant.
For some specific options, such as adding trust anchors, special
routines exist.
This function is thread\-safe only if a single instance of \fBub_ctx\fP*
exists in the application.
If several instances exist the application has to ensure that
\fBub_ctx_config\fP is not called in parallel by the different instances.
A power\-user interface that lets you specify an unbound config file, see
\fIunbound.conf\fR(5), which is read for configuration. Not all options are
relevant. For some specific options, such as adding trust anchors, special
routines exist. This function is thread\-safe only if a single instance of
ub_ctx* exists in the application. If several instances exist the
application has to ensure that ub_ctx_config is not called in parallel by
the different instances.
.TP
.B ub_ctx_set_fwd
Set machine to forward DNS queries to, the caching resolver to use.
IP4 or IP6 address.
Forwards all DNS requests to that machine, which is expected to run a
recursive resolver.
If the proxy is not DNSSEC capable, validation may fail.
Can be called several times, in that case the addresses are used as
backup servers.
At this time it is only possible to set configuration before the first
resolve is done.
Set machine to forward DNS queries to, the caching resolver to use.
IP4 or IP6 address. Forwards all DNS requests to that machine, which
is expected to run a recursive resolver. If the proxy is not
DNSSEC capable, validation may fail. Can be called several times, in
that case the addresses are used as backup servers.
At this time it is only possible to set configuration before the
first resolve is done.
.TP
.B ub_ctx_set_stub
Set a stub zone, authoritative dns servers to use for a particular
zone.
IP4 or IP6 address.
If the address is NULL the stub entry is removed.
Set isprime true if you configure root hints with it.
Otherwise similar to the stub zone item from unbound\(aqs config file.
Can be called several times, for different zones, or to add multiple
addresses for a particular zone.
At this time it is only possible to set configuration before the first
resolve is done.
Set a stub zone, authoritative dns servers to use for a particular zone.
IP4 or IP6 address. If the address is NULL the stub entry is removed.
Set isprime true if you configure root hints with it. Otherwise similar to
the stub zone item from unbound's config file. Can be called several times,
for different zones, or to add multiple addresses for a particular zone.
At this time it is only possible to set configuration before the
first resolve is done.
.TP
.B ub_ctx_set_tls
Enable DNS over TLS (DoT) for machines set with \fBub_ctx_set_fwd\fP\&.
At this time it is only possible to set configuration before the first
resolve is done.
Enable DNS over TLS (DoT) for machines set with
.B ub_ctx_set_fwd.
At this time it is only possible to set configuration before the
first resolve is done.
.TP
.B ub_ctx_resolvconf
By default the root servers are queried and full resolver mode is used,
but you can use this call to read the list of nameservers to use from
the filename given.
Usually \fB\(dq/etc/resolv.conf\(dq\fP\&.
Uses those nameservers as caching proxies.
By default the root servers are queried and full resolver mode is used, but
you can use this call to read the list of nameservers to use from the
filename given.
Usually "/etc/resolv.conf". Uses those nameservers as caching proxies.
If they do not support DNSSEC, validation may fail.
Only nameservers are picked up, the searchdomain, ndots and other
settings from \fIresolv.conf(5)\fP are ignored.
If fname NULL is passed, \fB\(dq/etc/resolv.conf\(dq\fP is used (if on
Windows, the system\-wide configured nameserver is picked instead).
At this time it is only possible to set configuration before the first
resolve is done.
settings from \fIresolv.conf\fR(5) are ignored.
If fname NULL is passed, "/etc/resolv.conf" is used (if on Windows,
the system\-wide configured nameserver is picked instead).
At this time it is only possible to set configuration before the
first resolve is done.
.TP
.B ub_ctx_hosts
Read list of hosts from the filename given.
Usually \fB\(dq/etc/hosts\(dq\fP\&.
When queried for, these addresses are not marked DNSSEC secure.
If fname NULL is passed, \fB\(dq/etc/hosts\(dq\fP is used (if on Windows,
\fBetc/hosts\fP from WINDIR is picked instead).
At this time it is only possible to set configuration before the first
resolve is done.
Usually "/etc/hosts". When queried for, these addresses are not marked
DNSSEC secure. If fname NULL is passed, "/etc/hosts" is used
(if on Windows, etc/hosts from WINDIR is picked instead).
At this time it is only possible to set configuration before the
first resolve is done.
.TP
.B ub_ctx_add_ta
.B
ub_ctx_add_ta
Add a trust anchor to the given context.
At this time it is only possible to add trusted keys before the first
resolve is done.
At this time it is only possible to add trusted keys before the
first resolve is done.
The format is a string, similar to the zone\-file format,
\fB[domainname]\fP \fB[type]\fP \fB[rdata contents]\fP\&.
Both DS and DNSKEY records are accepted.
[domainname] [type] [rdata contents]. Both DS and DNSKEY records are accepted.
.TP
.B ub_ctx_add_ta_autr
Add filename with automatically tracked trust anchor to the given
context.
Pass name of a file with the managed trust anchor.
You can create this file with
\fI\%unbound\-anchor(8)\fP for the root anchor.
You can also create it with an initial file with one line with a DNSKEY
or DS record.
Add filename with automatically tracked trust anchor to the given context.
Pass name of a file with the managed trust anchor. You can create this
file with \fIunbound\-anchor\fR(8) for the root anchor. You can also
create it with an initial file with one line with a DNSKEY or DS record.
If the file is writable, it is updated when the trust anchor changes.
At this time it is only possible to add trusted keys before the first
resolve is done.
At this time it is only possible to add trusted keys before the
first resolve is done.
.TP
.B ub_ctx_add_ta_file
Add trust anchors to the given context.
Pass name of a file with DS and DNSKEY records in zone file format.
At this time it is only possible to add trusted keys before the first
resolve is done.
At this time it is only possible to add trusted keys before the
first resolve is done.
.TP
.B ub_ctx_trustedkeys
Add trust anchors to the given context.
Pass the name of a bind\-style config file with \fBtrusted\-keys{}\fP\&.
At this time it is only possible to add trusted keys before the first
resolve is done.
Pass the name of a bind\-style config file with trusted\-keys{}.
At this time it is only possible to add trusted keys before the
first resolve is done.
.TP
.B ub_ctx_debugout
Set debug and error log output to the given stream.
Pass NULL to disable output.
Default is stderr.
File\-names or using syslog can be enabled using config options, this
routine is for using your own stream.
Set debug and error log output to the given stream. Pass NULL to disable
output. Default is stderr. File\-names or using syslog can be enabled
using config options, this routine is for using your own stream.
.TP
.B ub_ctx_debuglevel
Set debug verbosity for the context.
Output is directed to stderr.
Set debug verbosity for the context. Output is directed to stderr.
Higher debug level gives more output.
.TP
.B ub_ctx_async
Set a context behaviour for asynchronous action.
if set to true, enables threading and a call to \fBub_resolve_async\fP
if set to true, enables threading and a call to
.B ub_resolve_async
creates a thread to handle work in the background.
If false, a process is forked to handle work in the background.
Changes to this setting after \fBub_resolve_async\fP calls have been made
have no effect (delete and re\-create the context to change).
Changes to this setting after
.B ub_resolve_async
calls have been made have no effect (delete and re\-create the context
to change).
.TP
.B ub_poll
Poll a context to see if it has any new results.
Do not poll in a loop, instead extract the \fBfd\fP below to poll for
readiness, and then check, or wait using the wait routine.
Do not poll in a loop, instead extract the fd below to poll for readiness,
and then check, or wait using the wait routine.
Returns 0 if nothing to read, or nonzero if a result is available.
If nonzero, call \fBub_process\fP to do callbacks.
If nonzero, call
.B ub_process
to do callbacks.
.TP
.B ub_wait
Wait for a context to finish with results.
Calls \fBub_process\fP after the wait for you.
After the wait, there are no more outstanding asynchronous queries.
Wait for a context to finish with results. Calls
.B ub_process
after the wait for you. After the wait, there are no more outstanding
asynchronous queries.
.TP
.B ub_fd
Get file descriptor.
Wait for it to become readable, at this point answers are returned from
the asynchronous validating resolver.
Then call the \fBub_process\fP to continue processing.
Get file descriptor. Wait for it to become readable, at this point
answers are returned from the asynchronous validating resolver.
Then call the \fBub_process\fR to continue processing.
.TP
.B ub_process
Call this routine to continue processing results from the validating
resolver (when the \fBfd\fP becomes readable).
resolver (when the fd becomes readable).
Will perform necessary callbacks.
.TP
.B ub_resolve
@@ -311,111 +340,95 @@ The result structure is newly allocated with the resulting data.
.TP
.B ub_resolve_async
Perform asynchronous resolution and validation of the target name.
Arguments mean the same as for \fBub_resolve\fP except no data is
returned immediately, instead a callback is called later.
The callback receives a copy of the mydata pointer, that you can use to
pass information to the callback.
The callback type is a function pointer to a function declared as:
.INDENT 7.0
.INDENT 3.5
.sp
.nf
.ft C
void my_callback_function(void* my_arg, int err,
struct ub_result* result);
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
The \fBasync_id\fP is returned so you can (at your option) decide to
track it and cancel the request if needed.
If you pass a NULL pointer the \fBasync_id\fP is not returned.
Arguments mean the same as for \fBub_resolve\fR except no
data is returned immediately, instead a callback is called later.
The callback receives a copy of the mydata pointer, that you can use to pass
information to the callback. The callback type is a function pointer to
a function declared as
.IP
void my_callback_function(void* my_arg, int err,
.br
struct ub_result* result);
.IP
The async_id is returned so you can (at your option) decide to track it
and cancel the request if needed. If you pass a NULL pointer the async_id
is not returned.
.TP
.B ub_cancel
Cancel an async query in progress.
This may return an error if the query does not exist, or the query is
already being delivered, in that case you may still get a callback for
the query.
Cancel an async query in progress. This may return an error if the query
does not exist, or the query is already being delivered, in that case you
may still get a callback for the query.
.TP
.B ub_resolve_free
Free struct \fBub_result\fP contents after use.
Free struct ub_result contents after use.
.TP
.B ub_strerror
Convert error value from one of the unbound library functions to a
human readable string.
Convert error value from one of the unbound library functions
to a human readable string.
.TP
.B ub_ctx_print_local_zones
Debug printout the local authority information to debug output.
.TP
.B ub_ctx_zone_add
Add new zone to local authority info, like local\-zone
\fI\%unbound.conf(5)\fP statement.
Add new zone to local authority info, like local\-zone \fIunbound.conf\fR(5)
statement.
.TP
.B ub_ctx_zone_remove
Delete zone from local authority info.
.TP
.B ub_ctx_data_add
Add resource record data to local authority info, like local\-data
\fI\%unbound.conf(5)\fP statement.
\fIunbound.conf\fR(5) statement.
.TP
.B ub_ctx_data_remove
Delete local authority data from the name given.
.UNINDENT
.SH RESULT DATA STRUCTURE
.sp
The result of the DNS resolution and validation is returned as \fIstruct
ub_result\fP\&.
The result structure contains the following entries:
.INDENT 0.0
.INDENT 3.5
.sp
.SH "RESULT DATA STRUCTURE"
The result of the DNS resolution and validation is returned as
\fIstruct ub_result\fR. The result structure contains the following entries.
.P
.nf
.ft C
struct ub_result {
char* qname; /* text string, original question */
int qtype; /* type code asked for */
int qclass; /* class code asked for */
char** data; /* array of rdata items, NULL terminated*/
int* len; /* array with lengths of rdata items */
char* canonname; /* canonical name of result */
int rcode; /* additional error code in case of no data */
void* answer_packet; /* full network format answer packet */
int answer_len; /* length of packet in octets */
int havedata; /* true if there is data */
int nxdomain; /* true if nodata because name does not exist */
int secure; /* true if result is secure */
int bogus; /* true if a security failure happened */
char* why_bogus; /* string with error if bogus */
int was_ratelimited; /* true if the query was ratelimited (SERVFAIL) by unbound */
int ttl; /* number of seconds the result is valid */
};
.ft P
struct ub_result {
char* qname; /* text string, original question */
int qtype; /* type code asked for */
int qclass; /* class code asked for */
char** data; /* array of rdata items, NULL terminated*/
int* len; /* array with lengths of rdata items */
char* canonname; /* canonical name of result */
int rcode; /* additional error code in case of no data */
void* answer_packet; /* full network format answer packet */
int answer_len; /* length of packet in octets */
int havedata; /* true if there is data */
int nxdomain; /* true if nodata because name does not exist */
int secure; /* true if result is secure */
int bogus; /* true if a security failure happened */
char* why_bogus; /* string with error if bogus */
int was_ratelimited; /* true if the query was ratelimited (SERVFAIL) by unbound */
int ttl; /* number of seconds the result is valid */
};
.fi
.UNINDENT
.UNINDENT
.sp
If both secure and bogus are false, security was not enabled for the domain of
the query.
Else, they are not both true, one of them is true.
.SH RETURN VALUES
.sp
Many routines return an error code.
The value 0 (zero) denotes no error happened.
Other values can be passed to \fBub_strerror\fP to obtain a readable error
string.
\fBub_strerror\fP returns a zero terminated string.
\fBub_ctx_create\fP returns NULL on an error (a malloc failure).
\fBub_poll\fP returns true if some information may be available, false otherwise.
\fBub_fd\fP returns a file descriptor or \-1 on error.
\fBub_ctx_config\fP and \fBub_ctx_resolvconf\fP attempt to leave errno informative
on a function return with file read failure.
.SH SEE ALSO
.sp
\fI\%unbound.conf(5)\fP, \fI\%unbound(8)\fP\&.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
.\" Generated by docutils manpage writer.
.
.P
If both secure and bogus are false, security was not enabled for the
domain of the query. Else, they are not both true, one of them is true.
.SH "RETURN VALUES"
Many routines return an error code. The value 0 (zero) denotes no error
happened. Other values can be passed to
.B ub_strerror
to obtain a readable error string.
.B ub_strerror
returns a zero terminated string.
.B ub_ctx_create
returns NULL on an error (a malloc failure).
.B ub_poll
returns true if some information may be available, false otherwise.
.B ub_fd
returns a file descriptor or \-1 on error.
.B ub_ctx_config
and
.B ub_ctx_resolvconf
attempt to leave errno informative on a function return with file read failure.
.SH "SEE ALSO"
\fIunbound.conf\fR(5),
\fIunbound\fR(8).
.SH "AUTHORS"
.B Unbound
developers are mentioned in the CREDITS file in the distribution.
-491
View File
@@ -1,491 +0,0 @@
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
libunbound(3)
=============
Synopsis
--------
.. only:: html
.. code-block:: c
#include <unbound.h>
struct ub_ctx * ub_ctx_create(void);
void ub_ctx_delete(struct ub_ctx* ctx);
int ub_ctx_set_option(struct ub_ctx* ctx, char* opt, char* val);
int ub_ctx_get_option(struct ub_ctx* ctx, char* opt, char** val);
int ub_ctx_config(struct ub_ctx* ctx, char* fname);
int ub_ctx_set_fwd(struct ub_ctx* ctx, char* addr);
int ub_ctx_set_stub(struct ub_ctx* ctx, char* zone, char* addr,
int isprime);
int ub_ctx_set_tls(struct ub_ctx* ctx, int tls);
int ub_ctx_resolvconf(struct ub_ctx* ctx, char* fname);
int ub_ctx_hosts(struct ub_ctx* ctx, char* fname);
int ub_ctx_add_ta(struct ub_ctx* ctx, char* ta);
int ub_ctx_add_ta_autr(struct ub_ctx* ctx, char* fname);
int ub_ctx_add_ta_file(struct ub_ctx* ctx, char* fname);
int ub_ctx_trustedkeys(struct ub_ctx* ctx, char* fname);
int ub_ctx_debugout(struct ub_ctx* ctx, FILE* out);
int ub_ctx_debuglevel(struct ub_ctx* ctx, int d);
int ub_ctx_async(struct ub_ctx* ctx, int dothread);
int ub_poll(struct ub_ctx* ctx);
int ub_wait(struct ub_ctx* ctx);
int ub_fd(struct ub_ctx* ctx);
int ub_process(struct ub_ctx* ctx);
int ub_resolve(struct ub_ctx* ctx, char* name, int rrtype,
int rrclass, struct ub_result** result);
int ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype,
int rrclass, void* mydata, ub_callback_type callback,
int* async_id);
int ub_cancel(struct ub_ctx* ctx, int async_id);
void ub_resolve_free(struct ub_result* result);
const char * ub_strerror(int err);
int ub_ctx_print_local_zones(struct ub_ctx* ctx);
int ub_ctx_zone_add(struct ub_ctx* ctx, char* zone_name, char* zone_type);
int ub_ctx_zone_remove(struct ub_ctx* ctx, char* zone_name);
int ub_ctx_data_add(struct ub_ctx* ctx, char* data);
int ub_ctx_data_remove(struct ub_ctx* ctx, char* data);
.. only:: man
**#include <unbound.h>**
struct ub_ctx \* **ub_ctx_create**\ (void);
void **ub_ctx_delete**\ (struct ub_ctx\* ctx);
int **ub_ctx_set_option**\ (struct ub_ctx\* ctx, char\* opt, char\* val);
int **ub_ctx_get_option**\ (struct ub_ctx\* ctx, char\* opt, char\*\* val);
int **ub_ctx_config**\ (struct ub_ctx\* ctx, char* fname);
int **ub_ctx_set_fwd**\ (struct ub_ctx\* ctx, char\* addr);
int **ub_ctx_set_stub**\ (struct ub_ctx\* ctx, char\* zone, char\* addr,
int isprime);
int **ub_ctx_set_tls**\ (struct ub_ctx\* ctx, int tls);
int **ub_ctx_resolvconf**\ (struct ub_ctx\* ctx, char\* fname);
int **ub_ctx_hosts**\ (struct ub_ctx\* ctx, char\* fname);
int **ub_ctx_add_ta**\ (struct ub_ctx\* ctx, char\* ta);
int **ub_ctx_add_ta_autr**\ (struct ub_ctx\* ctx, char\* fname);
int **ub_ctx_add_ta_file**\ (struct ub_ctx\* ctx, char\* fname);
int **ub_ctx_trustedkeys**\ (struct ub_ctx\* ctx, char\* fname);
int **ub_ctx_debugout**\ (struct ub_ctx\* ctx, FILE\* out);
int **ub_ctx_debuglevel**\ (struct ub_ctx\* ctx, int d);
int **ub_ctx_async**\ (struct ub_ctx\* ctx, int dothread);
int **ub_poll**\ (struct ub_ctx\* ctx);
int **ub_wait**\ (struct ub_ctx\* ctx);
int **ub_fd**\ (struct ub_ctx\* ctx);
int **ub_process**\ (struct ub_ctx\* ctx);
int **ub_resolve**\ (struct ub_ctx\* ctx, char\* name,
int rrtype, int rrclass, struct ub_result\*\* result);
int **ub_resolve_async**\ (struct ub_ctx\* ctx, char\* name,
int rrtype, int rrclass, void\* mydata,
ub_callback_type\* callback, int\* async_id);
int **ub_cancel**\ (struct ub_ctx\* ctx, int async_id);
void **ub_resolve_free**\ (struct ub_result\* result);
const char \* **ub_strerror**\ (int err);
int **ub_ctx_print_local_zones**\ (struct ub_ctx\* ctx);
int **ub_ctx_zone_add**\ (struct ub_ctx\* ctx, char\* zone_name, char\* zone_type);
int **ub_ctx_zone_remove**\ (struct ub_ctx\* ctx, char\* zone_name);
int **ub_ctx_data_add**\ (struct ub_ctx\* ctx, char\* data);
int **ub_ctx_data_remove**\ (struct ub_ctx\* ctx, char\* data);
Description
-----------
Unbound is an implementation of a DNS resolver, that does caching and DNSSEC
validation.
This is the library API, for using the ``-lunbound`` library.
The server daemon is described in :doc:`unbound(8)</manpages/unbound>`.
The library works independent from a running unbound server, and can be used to
convert hostnames to ip addresses, and back, and obtain other information from
the DNS.
The library performs public-key validation of results with DNSSEC.
The library uses a variable of type *struct ub_ctx* to keep context between
calls.
The user must maintain it, creating it with **ub_ctx_create** and deleting it
with **ub_ctx_delete**.
It can be created and deleted at any time.
Creating it anew removes any previous configuration (such as trusted keys) and
clears any cached results.
The functions are thread-safe, and a context can be used in a threaded (as well
as in a non-threaded) environment.
Also resolution (and validation) can be performed blocking and non-blocking
(also called asynchronous).
The async method returns from the call immediately, so that processing can go
on, while the results become available later.
The functions are discussed in turn below.
Functions
---------
.. glossary::
ub_ctx_create
Create a new context, initialised with defaults.
The information from :file:`/etc/resolv.conf` and :file:`/etc/hosts` is
not utilised by default.
Use **ub_ctx_resolvconf** and **ub_ctx_hosts** to read them.
Before you call this, use the openssl functions
**CRYPTO_set_id_callback** and **CRYPTO_set_locking_callback** to set
up asynchronous operation if you use lib openssl (the application calls
these functions once for initialisation).
Openssl 1.0.0 or later uses the **CRYPTO_THREADID_set_callback**
function.
ub_ctx_delete
Delete validation context and free associated resources.
Outstanding async queries are killed and callbacks are not called for
them.
ub_ctx_set_option
A power-user interface that lets you specify one of the options from
the config file format, see :doc:`unbound.conf(5)</manpages/unbound.conf>`.
Not all options are relevant.
For some specific options, such as adding trust anchors, special
routines exist.
Pass the option name with the trailing ``':'``.
ub_ctx_get_option
A power-user interface that gets an option value.
Some options cannot be gotten, and others return a newline separated
list.
Pass the option name without trailing ``':'``.
The returned value must be free(2)d by the caller.
ub_ctx_config
A power-user interface that lets you specify an unbound config file,
see :doc:`unbound.conf(5)</manpages/unbound.conf>`, which is read for
configuration.
Not all options are relevant.
For some specific options, such as adding trust anchors, special
routines exist.
This function is thread-safe only if a single instance of **ub_ctx**\*
exists in the application.
If several instances exist the application has to ensure that
**ub_ctx_config** is not called in parallel by the different instances.
ub_ctx_set_fwd
Set machine to forward DNS queries to, the caching resolver to use.
IP4 or IP6 address.
Forwards all DNS requests to that machine, which is expected to run a
recursive resolver.
If the proxy is not DNSSEC capable, validation may fail.
Can be called several times, in that case the addresses are used as
backup servers.
At this time it is only possible to set configuration before the first
resolve is done.
ub_ctx_set_stub
Set a stub zone, authoritative dns servers to use for a particular
zone.
IP4 or IP6 address.
If the address is NULL the stub entry is removed.
Set isprime true if you configure root hints with it.
Otherwise similar to the stub zone item from unbound's config file.
Can be called several times, for different zones, or to add multiple
addresses for a particular zone.
At this time it is only possible to set configuration before the first
resolve is done.
ub_ctx_set_tls
Enable DNS over TLS (DoT) for machines set with **ub_ctx_set_fwd**.
At this time it is only possible to set configuration before the first
resolve is done.
ub_ctx_resolvconf
By default the root servers are queried and full resolver mode is used,
but you can use this call to read the list of nameservers to use from
the filename given.
Usually :file:`"/etc/resolv.conf"`.
Uses those nameservers as caching proxies.
If they do not support DNSSEC, validation may fail.
Only nameservers are picked up, the searchdomain, ndots and other
settings from *resolv.conf(5)* are ignored.
If fname NULL is passed, :file:`"/etc/resolv.conf"` is used (if on
Windows, the system-wide configured nameserver is picked instead).
At this time it is only possible to set configuration before the first
resolve is done.
ub_ctx_hosts
Read list of hosts from the filename given.
Usually :file:`"/etc/hosts"`.
When queried for, these addresses are not marked DNSSEC secure.
If fname NULL is passed, :file:`"/etc/hosts"` is used (if on Windows,
:file:`etc/hosts` from WINDIR is picked instead).
At this time it is only possible to set configuration before the first
resolve is done.
ub_ctx_add_ta
Add a trust anchor to the given context.
At this time it is only possible to add trusted keys before the first
resolve is done.
The format is a string, similar to the zone-file format,
**[domainname]** **[type]** **[rdata contents]**.
Both DS and DNSKEY records are accepted.
ub_ctx_add_ta_autr
Add filename with automatically tracked trust anchor to the given
context.
Pass name of a file with the managed trust anchor.
You can create this file with
:doc:`unbound-anchor(8)</manpages/unbound-anchor>` for the root anchor.
You can also create it with an initial file with one line with a DNSKEY
or DS record.
If the file is writable, it is updated when the trust anchor changes.
At this time it is only possible to add trusted keys before the first
resolve is done.
ub_ctx_add_ta_file
Add trust anchors to the given context.
Pass name of a file with DS and DNSKEY records in zone file format.
At this time it is only possible to add trusted keys before the first
resolve is done.
ub_ctx_trustedkeys
Add trust anchors to the given context.
Pass the name of a bind-style config file with ``trusted-keys{}``.
At this time it is only possible to add trusted keys before the first
resolve is done.
ub_ctx_debugout
Set debug and error log output to the given stream.
Pass NULL to disable output.
Default is stderr.
File-names or using syslog can be enabled using config options, this
routine is for using your own stream.
ub_ctx_debuglevel
Set debug verbosity for the context.
Output is directed to stderr.
Higher debug level gives more output.
ub_ctx_async
Set a context behaviour for asynchronous action.
if set to true, enables threading and a call to **ub_resolve_async**
creates a thread to handle work in the background.
If false, a process is forked to handle work in the background.
Changes to this setting after **ub_resolve_async** calls have been made
have no effect (delete and re-create the context to change).
ub_poll
Poll a context to see if it has any new results.
Do not poll in a loop, instead extract the **fd** below to poll for
readiness, and then check, or wait using the wait routine.
Returns 0 if nothing to read, or nonzero if a result is available.
If nonzero, call **ub_process** to do callbacks.
ub_wait
Wait for a context to finish with results.
Calls **ub_process** after the wait for you.
After the wait, there are no more outstanding asynchronous queries.
ub_fd
Get file descriptor.
Wait for it to become readable, at this point answers are returned from
the asynchronous validating resolver.
Then call the **ub_process** to continue processing.
ub_process
Call this routine to continue processing results from the validating
resolver (when the **fd** becomes readable).
Will perform necessary callbacks.
ub_resolve
Perform resolution and validation of the target name.
The name is a domain name in a zero terminated text string.
The rrtype and rrclass are DNS type and class codes.
The result structure is newly allocated with the resulting data.
ub_resolve_async
Perform asynchronous resolution and validation of the target name.
Arguments mean the same as for **ub_resolve** except no data is
returned immediately, instead a callback is called later.
The callback receives a copy of the mydata pointer, that you can use to
pass information to the callback.
The callback type is a function pointer to a function declared as:
.. code-block:: c
void my_callback_function(void* my_arg, int err,
struct ub_result* result);
The **async_id** is returned so you can (at your option) decide to
track it and cancel the request if needed.
If you pass a NULL pointer the **async_id** is not returned.
ub_cancel
Cancel an async query in progress.
This may return an error if the query does not exist, or the query is
already being delivered, in that case you may still get a callback for
the query.
ub_resolve_free
Free struct **ub_result** contents after use.
ub_strerror
Convert error value from one of the unbound library functions to a
human readable string.
ub_ctx_print_local_zones
Debug printout the local authority information to debug output.
ub_ctx_zone_add
Add new zone to local authority info, like local-zone
:doc:`unbound.conf(5)</manpages/unbound.conf>` statement.
ub_ctx_zone_remove
Delete zone from local authority info.
ub_ctx_data_add
Add resource record data to local authority info, like local-data
:doc:`unbound.conf(5)</manpages/unbound.conf>` statement.
ub_ctx_data_remove
Delete local authority data from the name given.
Result Data structure
---------------------
The result of the DNS resolution and validation is returned as *struct
ub_result*.
The result structure contains the following entries:
.. code-block:: c
struct ub_result {
char* qname; /* text string, original question */
int qtype; /* type code asked for */
int qclass; /* class code asked for */
char** data; /* array of rdata items, NULL terminated*/
int* len; /* array with lengths of rdata items */
char* canonname; /* canonical name of result */
int rcode; /* additional error code in case of no data */
void* answer_packet; /* full network format answer packet */
int answer_len; /* length of packet in octets */
int havedata; /* true if there is data */
int nxdomain; /* true if nodata because name does not exist */
int secure; /* true if result is secure */
int bogus; /* true if a security failure happened */
char* why_bogus; /* string with error if bogus */
int was_ratelimited; /* true if the query was ratelimited (SERVFAIL) by unbound */
int ttl; /* number of seconds the result is valid */
};
If both secure and bogus are false, security was not enabled for the domain of
the query.
Else, they are not both true, one of them is true.
Return Values
-------------
Many routines return an error code.
The value 0 (zero) denotes no error happened.
Other values can be passed to **ub_strerror** to obtain a readable error
string.
**ub_strerror** returns a zero terminated string.
**ub_ctx_create** returns NULL on an error (a malloc failure).
**ub_poll** returns true if some information may be available, false otherwise.
**ub_fd** returns a file descriptor or -1 on error.
**ub_ctx_config** and **ub_ctx_resolvconf** attempt to leave errno informative
on a function return with file read failure.
See Also
--------
:doc:`unbound.conf(5)</manpages/unbound.conf>`, :doc:`unbound(8)</manpages/unbound>`.
+134 -245
View File
@@ -1,300 +1,189 @@
.\" Man page generated from reStructuredText.
.
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "UNBOUND-ANCHOR" "8" "@date@" "@version@" "Unbound"
.SH NAME
unbound-anchor \- Unbound @version@ anchor utility.
.SH SYNOPSIS
.sp
\fBunbound\-anchor\fP [\fBopts\fP]
.SH DESCRIPTION
.sp
\fBunbound\-anchor\fP performs setup or update of the root trust anchor for DNSSEC
validation.
The program fetches the trust anchor with the method from \fI\%RFC 7958\fP when
regular \fI\%RFC 5011\fP update fails to bring it up to date.
.TH "unbound-anchor" "8" "@date@" "NLnet Labs" "unbound @version@"
.\"
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
.\"
.\" Copyright (c) 2008, NLnet Labs. All rights reserved.
.\"
.\" See LICENSE for the license.
.\"
.\"
.SH "NAME"
.B unbound\-anchor
\- Unbound anchor utility.
.SH "SYNOPSIS"
.B unbound\-anchor
.RB [ opts ]
.SH "DESCRIPTION"
.B Unbound\-anchor
performs setup or update of the root trust anchor for DNSSEC validation.
The program fetches the trust anchor with the method from RFC7958 when
regular RFC5011 update fails to bring it up to date.
It can be run (as root) from the commandline, or run as part of startup
scripts.
Before you start the \fI\%unbound(8)\fP DNS server.
.sp
scripts. Before you start the \fIunbound\fR(8) DNS server.
.P
Suggested usage:
.INDENT 0.0
.INDENT 3.5
.sp
.P
.nf
.ft C
# in the init scripts.
# provide or update the root anchor (if necessary)
unbound\-anchor \-a \(dq@UNBOUND_ROOTKEY_FILE@\(dq
# Please note usage of this root anchor is at your own risk
# and under the terms of our LICENSE (see source).
#
# start validating resolver
# the unbound.conf contains:
# auto\-trust\-anchor\-file: \(dq@UNBOUND_ROOTKEY_FILE@\(dq
unbound \-c unbound.conf
.ft P
# in the init scripts.
# provide or update the root anchor (if necessary)
unbound-anchor \-a "@UNBOUND_ROOTKEY_FILE@"
# Please note usage of this root anchor is at your own risk
# and under the terms of our LICENSE (see source).
#
# start validating resolver
# the unbound.conf contains:
# auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@"
unbound \-c unbound.conf
.fi
.UNINDENT
.UNINDENT
.sp
This tool provides builtin default contents for the root anchor and root update
certificate files.
.sp
.P
This tool provides builtin default contents for the root anchor and root
update certificate files.
.P
It tests if the root anchor file works, and if not, and an update is possible,
attempts to update the root anchor using the root update certificate.
It performs a https fetch of
\fI\%root\-anchors.xml\fP
and checks the results (\fI\%RFC 7958\fP); if all checks are successful, it updates
the root anchor file.
Otherwise the root anchor file is unchanged.
It performs \fI\%RFC 5011\fP tracking if the DNSSEC information available via the
DNS makes that possible.
.sp
It does not perform an update if the certificate is expired, if the network is
down or other errors occur.
.sp
It performs a https fetch of root-anchors.xml and checks the results (RFC7958),
if all checks are successful, it updates the root anchor file. Otherwise
the root anchor file is unchanged. It performs RFC5011 tracking if the
DNSSEC information available via the DNS makes that possible.
.P
It does not perform an update if the certificate is expired, if the network
is down or other errors occur.
.P
The available options are:
.INDENT 0.0
.TP
.B \-a <file>
.B \-a \fIfile
The root anchor key file, that is read in and written out.
Default is \fB@UNBOUND_ROOTKEY_FILE@\fP\&.
If the file does not exist, or is empty, a builtin root key is written
to it.
.UNINDENT
.INDENT 0.0
Default is @UNBOUND_ROOTKEY_FILE@.
If the file does not exist, or is empty, a builtin root key is written to it.
.TP
.B \-c <file>
.B \-c \fIfile
The root update certificate file, that is read in.
Default is \fB@UNBOUND_ROOTCERT_FILE@\fP\&.
Default is @UNBOUND_ROOTCERT_FILE@.
If the file does not exist, or is empty, a builtin certificate is used.
.UNINDENT
.INDENT 0.0
.TP
.B \-l
List the builtin root key and builtin root update certificate on stdout.
.UNINDENT
.INDENT 0.0
.TP
.B \-u <name>
The server name, it connects to \fBhttps://name\fP\&.
Specify without \fBhttps://\fP prefix.
The default is \fB\(dqdata.iana.org\(dq\fP\&.
It connects to the port specified with \fI\%\-P\fP\&.
.B \-u \fIname
The server name, it connects to https://name. Specify without https:// prefix.
The default is "data.iana.org". It connects to the port specified with \-P.
You can pass an IPv4 address or IPv6 address (no brackets) if you want.
.UNINDENT
.INDENT 0.0
.TP
.B \-S
Do not use SNI for the HTTPS connection.
Default is to use SNI.
.UNINDENT
.INDENT 0.0
Do not use SNI for the HTTPS connection. Default is to use SNI.
.TP
.B \-b <address>
The source address to bind to for domain resolution and contacting the
server on https.
May be either an IPv4 address or IPv6 address (no brackets).
.UNINDENT
.INDENT 0.0
.B \-b \fIaddress
The source address to bind to for domain resolution and contacting the server
on https. May be either an IPv4 address or IPv6 address (no brackets).
.TP
.B \-x <path>
The pathname to the root\-anchors.xml file on the server.
(forms URL with \fI\%\-u\fP).
The default is \fB/root\-anchors/root\-anchors.xml\fP\&.
.UNINDENT
.INDENT 0.0
.B \-x \fIpath
The pathname to the root\-anchors.xml file on the server. (forms URL with \-u).
The default is /root\-anchors/root\-anchors.xml.
.TP
.B \-s <path>
The pathname to the root\-anchors.p7s file on the server.
(forms URL with \fI\%\-u\fP).
The default is \fB/root\-anchors/root\-anchors.p7s\fP\&.
This file has to be a PKCS7 signature over the xml file, using the pem
file (\fI\%\-c\fP) as trust anchor.
.UNINDENT
.INDENT 0.0
.B \-s \fIpath
The pathname to the root\-anchors.p7s file on the server. (forms URL with \-u).
The default is /root\-anchors/root\-anchors.p7s. This file has to be a PKCS7
signature over the xml file, using the pem file (\-c) as trust anchor.
.TP
.B \-n <name>
The emailAddress for the Subject of the signer\(aqs certificate from the
p7s signature file.
Only signatures from this name are allowed.
The default is \fBdnssec@iana.org\fP\&.
If you pass \fB\(dq\(dq\fP then the emailAddress is not checked.
.UNINDENT
.INDENT 0.0
.B \-n \fIname
The emailAddress for the Subject of the signer's certificate from the p7s
signature file. Only signatures from this name are allowed. default is
dnssec@iana.org. If you pass "" then the emailAddress is not checked.
.TP
.B \-4
Use IPv4 for domain resolution and contacting the server on
https.
Default is to use IPv4 and IPv6 where appropriate.
.UNINDENT
.INDENT 0.0
Use IPv4 for domain resolution and contacting the server on https. Default is
to use IPv4 and IPv6 where appropriate.
.TP
.B \-6
Use IPv6 for domain resolution and contacting the server on https.
Default is to use IPv4 and IPv6 where appropriate.
.UNINDENT
.INDENT 0.0
Use IPv6 for domain resolution and contacting the server on https. Default is
to use IPv4 and IPv6 where appropriate.
.TP
.B \-f <resolv.conf>
Use the given resolv.conf file.
Not enabled by default, but you could try to pass
\fB/etc/resolv.conf\fP on some systems.
It contains the IP addresses of the recursive nameservers to use.
However, since this tool could be used to bootstrap that very recursive
nameserver, it would not be useful (since that server is not up yet,
since we are bootstrapping it).
It could be useful in a situation where you know an upstream cache is
deployed (and running) and in captive portal situations.
.UNINDENT
.INDENT 0.0
.B \-f \fIresolv.conf
Use the given resolv.conf file. Not enabled by default, but you could try to
pass /etc/resolv.conf on some systems. It contains the IP addresses of the
recursive nameservers to use. However, since this tool could be used to
bootstrap that very recursive nameserver, it would not be useful (since
that server is not up yet, since we are bootstrapping it). It could be
useful in a situation where you know an upstream cache is deployed (and
running) and in captive portal situations.
.TP
.B \-r <root.hints>
Use the given root.hints file (same syntax as the BIND and Unbound root
hints file) to bootstrap domain resolution.
By default a list of builtin root hints is used.
unbound\-anchor goes to the network itself for these roots, to resolve
the server (\fI\%\-u\fP option) and to check the root DNSKEY records.
.B \-r \fIroot.hints
Use the given root.hints file (same syntax as the BIND and Unbound root hints
file) to bootstrap domain resolution. By default a list of builtin root
hints is used. Unbound\-anchor goes to the network itself for these roots,
to resolve the server (\-u option) and to check the root DNSKEY records.
It does so, because the tool when used for bootstrapping the recursive
resolver, cannot use that recursive resolver itself because it is
bootstrapping that server.
.UNINDENT
.INDENT 0.0
resolver, cannot use that recursive resolver itself because it is bootstrapping
that server.
.TP
.B \-R
Allow fallback from \fI\%\-f\fP \fB<resolv.conf>\fP file to direct root
servers query.
It allows you to prefer local resolvers, but fallback automatically to
direct root query if they do not respond or do not support DNSSEC.
.UNINDENT
.INDENT 0.0
Allow fallback from \-f resolv.conf file to direct root servers query.
It allows you to prefer local resolvers, but fallback automatically
to direct root query if they do not respond or do not support DNSSEC.
.TP
.B \-v
More verbose.
Once prints informational messages, multiple times may enable large
debug amounts (such as full certificates or byte\-dumps of downloaded
files).
By default it prints almost nothing.
It also prints nothing on errors by default; in that case the original
root anchor file is simply left undisturbed, so that a recursive server
can start right after it.
.UNINDENT
.INDENT 0.0
More verbose. Once prints informational messages, multiple times may enable
large debug amounts (such as full certificates or byte\-dumps of downloaded
files). By default it prints almost nothing. It also prints nothing on
errors by default; in that case the original root anchor file is simply
left undisturbed, so that a recursive server can start right after it.
.TP
.B \-C <unbound.conf>
Debug option to read \fB<unbound.conf>\fP into the resolver process
used.
.UNINDENT
.INDENT 0.0
.B \-C \fIunbound.conf
Debug option to read unbound.conf into the resolver process used.
.TP
.B \-P <port>
Set the port number to use for the https connection.
The default is 443.
.UNINDENT
.INDENT 0.0
.B \-P \fIport
Set the port number to use for the https connection. The default is 443.
.TP
.B \-F
Debug option to force update of the root anchor through downloading the
xml file and verifying it with the certificate.
By default it first tries to update by contacting the DNS, which uses
much less bandwidth, is much faster (200 msec not 2 sec), and is nicer
to the deployed infrastructure.
With this option, it still attempts to do so (and may verbosely tell
you), but then ignores the result and goes on to use the xml fallback
method.
.UNINDENT
.INDENT 0.0
Debug option to force update of the root anchor through downloading the xml
file and verifying it with the certificate. By default it first tries to
update by contacting the DNS, which uses much less bandwidth, is much
faster (200 msec not 2 sec), and is nicer to the deployed infrastructure.
With this option, it still attempts to do so (and may verbosely tell you),
but then ignores the result and goes on to use the xml fallback method.
.TP
.B \-h
Show the version and commandline option help.
.UNINDENT
.SH EXIT CODE
.sp
.SH "EXIT CODE"
This tool exits with value 1 if the root anchor was updated using the
certificate or if the builtin root\-anchor was used.
It exits with code 0 if no update was necessary, if the update was possible
with \fI\%RFC 5011\fP tracking, or if an error occurred.
.sp
certificate or if the builtin root-anchor was used. It exits with code
0 if no update was necessary, if the update was possible with RFC5011
tracking, or if an error occurred.
.P
You can check the exit value in this manner:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
unbound\-anchor \-a \(dqroot.key\(dq || logger \(dqPlease check root.key\(dq
.ft P
unbound-anchor \-a "root.key" || logger "Please check root.key"
.fi
.UNINDENT
.UNINDENT
.sp
Or something more suitable for your operational environment.
.SH TRUST
.sp
The root keys and update certificate included in this tool are provided for
convenience and under the terms of our license (see the LICENSE file in the
source distribution or \fI\%https://github.com/NLnetLabs/unbound/blob/master/LICENSE\fP
and might be stale or not suitable to your purpose.
.sp
By running \fI\%unbound\-anchor \-l\fP the keys and certificate that are
.SH "TRUST"
The root keys and update certificate included in this tool
are provided for convenience and under the terms of our
license (see the LICENSE file in the source distribution or
https://github.com/NLnetLabs/unbound/blob/master/LICENSE) and might be stale or
not suitable to your purpose.
.P
By running "unbound\-anchor \-l" the keys and certificate that are
configured in the code are printed for your convenience.
.sp
The built\-in configuration can be overridden by providing a root\-cert file and
a rootkey file.
.SH FILES
.INDENT 0.0
.P
The build\-in configuration can be overridden by providing a root\-cert
file and a rootkey file.
.SH "FILES"
.TP
.B @UNBOUND_ROOTKEY_FILE@
The root anchor file, updated with 5011 tracking, and read and written
to.
.I @UNBOUND_ROOTKEY_FILE@
The root anchor file, updated with 5011 tracking, and read and written to.
The file is created if it does not exist.
.TP
.B @UNBOUND_ROOTCERT_FILE@
The trusted self\-signed certificate that is used to verify the
downloaded DNSSEC root trust anchor.
You can update it by fetching it from
\fI\%https://data.iana.org/root\-anchors/icannbundle.pem\fP (and validate it).
.I @UNBOUND_ROOTCERT_FILE@
The trusted self\-signed certificate that is used to verify the downloaded
DNSSEC root trust anchor. You can update it by fetching it from
https://data.iana.org/root\-anchors/icannbundle.pem (and validate it).
If the file does not exist or is empty, a builtin version is used.
.TP
.B \fI\%https://data.iana.org/root\-anchors/root\-anchors.xml\fP
.I https://data.iana.org/root\-anchors/root\-anchors.xml
Source for the root key information.
.TP
.B \fI\%https://data.iana.org/root\-anchors/root\-anchors.p7s\fP
.I https://data.iana.org/root\-anchors/root\-anchors.p7s
Signature on the root key information.
.UNINDENT
.SH SEE ALSO
.sp
\fI\%unbound.conf(5)\fP,
\fI\%unbound(8)\fP\&.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
.\" Generated by docutils manpage writer.
.
.SH "SEE ALSO"
\fIunbound.conf\fR(5),
\fIunbound\fR(8).
-281
View File
@@ -1,281 +0,0 @@
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
.. program:: unbound-anchor
unbound-anchor(8)
=================
Synopsis
--------
**unbound-anchor** [``opts``]
Description
-----------
``unbound-anchor`` performs setup or update of the root trust anchor for DNSSEC
validation.
The program fetches the trust anchor with the method from :rfc:`7958` when
regular :rfc:`5011` update fails to bring it up to date.
It can be run (as root) from the commandline, or run as part of startup
scripts.
Before you start the :doc:`unbound(8)</manpages/unbound>` DNS server.
Suggested usage:
.. code-block:: text
# in the init scripts.
# provide or update the root anchor (if necessary)
unbound-anchor -a "@UNBOUND_ROOTKEY_FILE@"
# Please note usage of this root anchor is at your own risk
# and under the terms of our LICENSE (see source).
#
# start validating resolver
# the unbound.conf contains:
# auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@"
unbound -c unbound.conf
This tool provides builtin default contents for the root anchor and root update
certificate files.
It tests if the root anchor file works, and if not, and an update is possible,
attempts to update the root anchor using the root update certificate.
It performs a https fetch of
`root-anchors.xml <http://data.iana.org/root-anchors/root-anchors.xml>`__
and checks the results (:rfc:`7958`); if all checks are successful, it updates
the root anchor file.
Otherwise the root anchor file is unchanged.
It performs :rfc:`5011` tracking if the DNSSEC information available via the
DNS makes that possible.
It does not perform an update if the certificate is expired, if the network is
down or other errors occur.
The available options are:
.. option:: -a <file>
The root anchor key file, that is read in and written out.
Default is :file:`@UNBOUND_ROOTKEY_FILE@`.
If the file does not exist, or is empty, a builtin root key is written
to it.
.. option:: -c <file>
The root update certificate file, that is read in.
Default is :file:`@UNBOUND_ROOTCERT_FILE@`.
If the file does not exist, or is empty, a builtin certificate is used.
.. option:: -l
List the builtin root key and builtin root update certificate on stdout.
.. option:: -u <name>
The server name, it connects to ``https://name``.
Specify without ``https://`` prefix.
The default is ``"data.iana.org"``.
It connects to the port specified with :option:`-P`.
You can pass an IPv4 address or IPv6 address (no brackets) if you want.
.. option:: -S
Do not use SNI for the HTTPS connection.
Default is to use SNI.
.. option:: -b <address>
The source address to bind to for domain resolution and contacting the
server on https.
May be either an IPv4 address or IPv6 address (no brackets).
.. option:: -x <path>
The pathname to the root-anchors.xml file on the server.
(forms URL with :option:`-u`).
The default is :file:`/root-anchors/root-anchors.xml`.
.. option:: -s <path>
The pathname to the root-anchors.p7s file on the server.
(forms URL with :option:`-u`).
The default is :file:`/root-anchors/root-anchors.p7s`.
This file has to be a PKCS7 signature over the xml file, using the pem
file (:option:`-c`) as trust anchor.
.. option:: -n <name>
The emailAddress for the Subject of the signer's certificate from the
p7s signature file.
Only signatures from this name are allowed.
The default is ``dnssec@iana.org``.
If you pass ``""`` then the emailAddress is not checked.
.. option:: -4
Use IPv4 for domain resolution and contacting the server on
https.
Default is to use IPv4 and IPv6 where appropriate.
.. option:: -6
Use IPv6 for domain resolution and contacting the server on https.
Default is to use IPv4 and IPv6 where appropriate.
.. option:: -f <resolv.conf>
Use the given resolv.conf file.
Not enabled by default, but you could try to pass
:file:`/etc/resolv.conf` on some systems.
It contains the IP addresses of the recursive nameservers to use.
However, since this tool could be used to bootstrap that very recursive
nameserver, it would not be useful (since that server is not up yet,
since we are bootstrapping it).
It could be useful in a situation where you know an upstream cache is
deployed (and running) and in captive portal situations.
.. option:: -r <root.hints>
Use the given root.hints file (same syntax as the BIND and Unbound root
hints file) to bootstrap domain resolution.
By default a list of builtin root hints is used.
unbound-anchor goes to the network itself for these roots, to resolve
the server (:option:`-u` option) and to check the root DNSKEY records.
It does so, because the tool when used for bootstrapping the recursive
resolver, cannot use that recursive resolver itself because it is
bootstrapping that server.
.. option:: -R
Allow fallback from :option:`-f` ``<resolv.conf>`` file to direct root
servers query.
It allows you to prefer local resolvers, but fallback automatically to
direct root query if they do not respond or do not support DNSSEC.
.. option:: -v
More verbose.
Once prints informational messages, multiple times may enable large
debug amounts (such as full certificates or byte-dumps of downloaded
files).
By default it prints almost nothing.
It also prints nothing on errors by default; in that case the original
root anchor file is simply left undisturbed, so that a recursive server
can start right after it.
.. option:: -C <unbound.conf>
Debug option to read :file:`<unbound.conf>` into the resolver process
used.
.. option:: -P <port>
Set the port number to use for the https connection.
The default is 443.
.. option:: -F
Debug option to force update of the root anchor through downloading the
xml file and verifying it with the certificate.
By default it first tries to update by contacting the DNS, which uses
much less bandwidth, is much faster (200 msec not 2 sec), and is nicer
to the deployed infrastructure.
With this option, it still attempts to do so (and may verbosely tell
you), but then ignores the result and goes on to use the xml fallback
method.
.. option:: -h
Show the version and commandline option help.
Exit Code
---------
This tool exits with value 1 if the root anchor was updated using the
certificate or if the builtin root-anchor was used.
It exits with code 0 if no update was necessary, if the update was possible
with :rfc:`5011` tracking, or if an error occurred.
You can check the exit value in this manner:
.. code-block:: text
unbound-anchor -a "root.key" || logger "Please check root.key"
Or something more suitable for your operational environment.
Trust
-----
The root keys and update certificate included in this tool are provided for
convenience and under the terms of our license (see the LICENSE file in the
source distribution or https://github.com/NLnetLabs/unbound/blob/master/LICENSE
and might be stale or not suitable to your purpose.
By running :option:`unbound-anchor -l` the keys and certificate that are
configured in the code are printed for your convenience.
The built-in configuration can be overridden by providing a root-cert file and
a rootkey file.
Files
-----
@UNBOUND_ROOTKEY_FILE@
The root anchor file, updated with 5011 tracking, and read and written
to.
The file is created if it does not exist.
@UNBOUND_ROOTCERT_FILE@
The trusted self-signed certificate that is used to verify the
downloaded DNSSEC root trust anchor.
You can update it by fetching it from
https://data.iana.org/root-anchors/icannbundle.pem (and validate it).
If the file does not exist or is empty, a builtin version is used.
https://data.iana.org/root-anchors/root-anchors.xml
Source for the root key information.
https://data.iana.org/root-anchors/root-anchors.p7s
Signature on the root key information.
See Also
--------
:doc:`unbound.conf(5)</manpages/unbound.conf>`,
:doc:`unbound(8)</manpages/unbound>`.
+42 -79
View File
@@ -1,93 +1,56 @@
.\" Man page generated from reStructuredText.
.
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "UNBOUND-CHECKCONF" "8" "@date@" "@version@" "Unbound"
.SH NAME
unbound-checkconf \- Check Unbound @version@ configuration file for errors.
.SH SYNOPSIS
.sp
\fBunbound\-checkconf\fP [\fB\-hf\fP] [\fB\-o option\fP] [cfgfile]
.SH DESCRIPTION
.sp
\fBunbound\-checkconf\fP checks the configuration file for the
\fI\%unbound(8)\fP DNS resolver for syntax and other errors.
.TH "unbound-checkconf" "8" "@date@" "NLnet Labs" "unbound @version@"
.\"
.\" unbound-checkconf.8 -- unbound configuration checker manual
.\"
.\" Copyright (c) 2007, NLnet Labs. All rights reserved.
.\"
.\" See LICENSE for the license.
.\"
.\"
.SH "NAME"
unbound\-checkconf
\- Check Unbound configuration file for errors.
.SH "SYNOPSIS"
.B unbound\-checkconf
.RB [ \-h ]
.RB [ \-f ]
.RB [ \-q ]
.RB [ \-o
.IR option ]
.RI [ cfgfile ]
.SH "DESCRIPTION"
.B Unbound\-checkconf
checks the configuration file for the
\fIunbound\fR(8)
DNS resolver for syntax and other errors.
The config file syntax is described in
\fI\%unbound.conf(5)\fP\&.
.sp
\fIunbound.conf\fR(5).
.P
The available options are:
.INDENT 0.0
.TP
.B \-h
Show the version and commandline option help.
.UNINDENT
.INDENT 0.0
.TP
.B \-f
Print full pathname, with chroot applied to it.
Use with the \fI\%\-o\fP option.
.UNINDENT
.INDENT 0.0
Print full pathname, with chroot applied to it. Use with the \-o option.
.TP
.B \-o\fI option
If given, after checking the config file the value of this option is
printed to stdout. For "" (disabled) options an empty line is printed.
.TP
.B \-q
Make the operation quiet, suppress output on success.
.UNINDENT
.INDENT 0.0
.TP
.B \-o <option>
If given, after checking the config file the value of this option is
printed to stdout.
For \fB\(dq\(dq\fP (disabled) options an empty line is printed.
.UNINDENT
.INDENT 0.0
.TP
.B cfgfile
The config file to read with settings for Unbound.
It is checked.
.I cfgfile
The config file to read with settings for Unbound. It is checked.
If omitted, the config file at the default location is checked.
.UNINDENT
.SH EXIT CODE
.sp
The \fBunbound\-checkconf\fP program exits with status code 1 on error, 0 for a
correct config file.
.SH FILES
.INDENT 0.0
.SH "EXIT CODE"
The unbound\-checkconf program exits with status code 1 on error,
0 for a correct config file.
.SH "FILES"
.TP
.B @ub_conf_file@
.I @ub_conf_file@
Unbound configuration file.
.UNINDENT
.SH SEE ALSO
.sp
\fI\%unbound.conf(5)\fP,
\fI\%unbound(8)\fP\&.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
.\" Generated by docutils manpage writer.
.
.SH "SEE ALSO"
\fIunbound.conf\fR(5),
\fIunbound\fR(8).
-98
View File
@@ -1,98 +0,0 @@
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
.. program:: unbound-checkconf
unbound-checkconf(8)
====================
Synopsis
--------
**unbound-checkconf** [``-hf``] [``-o option``] [cfgfile]
Description
-----------
``unbound-checkconf`` checks the configuration file for the
:doc:`unbound(8)</manpages/unbound>` DNS resolver for syntax and other errors.
The config file syntax is described in
:doc:`unbound.conf(5)</manpages/unbound.conf>`.
The available options are:
.. option:: -h
Show the version and commandline option help.
.. option:: -f
Print full pathname, with chroot applied to it.
Use with the :option:`-o` option.
.. option:: -q
Make the operation quiet, suppress output on success.
.. option:: -o <option>
If given, after checking the config file the value of this option is
printed to stdout.
For ``""`` (disabled) options an empty line is printed.
.. option:: cfgfile
The config file to read with settings for Unbound.
It is checked.
If omitted, the config file at the default location is checked.
Exit Code
---------
The ``unbound-checkconf`` program exits with status code 1 on error, 0 for a
correct config file.
Files
-----
@ub_conf_file@
Unbound configuration file.
See Also
--------
:doc:`unbound.conf(5)</manpages/unbound.conf>`,
:doc:`unbound(8)</manpages/unbound>`.
+472 -1247
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+85 -157
View File
@@ -1,190 +1,118 @@
.\" Man page generated from reStructuredText.
.
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "UNBOUND-HOST" "1" "@date@" "@version@" "Unbound"
.SH NAME
unbound-host \- Unbound @version@ DNS lookup utility.
.SH SYNOPSIS
.sp
\fBunbound\-host\fP [\fB\-C configfile\fP] [\fB\-vdhr46D\fP] [\fB\-c class\fP]
[\fB\-t type\fP] [\fB\-y key\fP] [\fB\-f keyfile\fP] [\fB\-F namedkeyfile\fP] hostname
.SH DESCRIPTION
.sp
\fBunbound\-host\fP uses the Unbound validating resolver to query for the hostname
and display results.
With the \fI\%\-v\fP option it displays validation status: secure, insecure,
bogus (security failure).
.sp
By default it reads no configuration file whatsoever.
It attempts to reach the internet root servers.
With \fI\%\-C\fP an unbound config file and with \fI\%\-r\fP \fBresolv.conf\fP
can be read.
.sp
.TH "unbound\-host" "1" "@date@" "NLnet Labs" "unbound @version@"
.\"
.\" unbound-host.1 -- unbound DNS lookup utility
.\"
.\" Copyright (c) 2007, NLnet Labs. All rights reserved.
.\"
.\" See LICENSE for the license.
.\"
.\"
.SH "NAME"
.B unbound\-host
\- unbound DNS lookup utility
.SH "SYNOPSIS"
.B unbound\-host
.RB [ \-C
.IR configfile ]
.RB [ \-vdhr46D ]
.RB [ \-c
.IR class ]
.RB [ \-t
.IR type ]
.RB [ \-y
.IR key ]
.RB [ \-f
.IR keyfile ]
.RB [ \-F
.IR namedkeyfile ]
.I hostname
.SH "DESCRIPTION"
.B Unbound\-host
uses the Unbound validating resolver to query for the hostname and display
results. With the \fB\-v\fR option it displays validation
status: secure, insecure, bogus (security failure).
.P
By default it reads no configuration file whatsoever. It attempts to reach
the internet root servers. With \fB\-C\fR an Unbound config file and with
\fB\-r\fR resolv.conf can be read.
.P
The available options are:
.INDENT 0.0
.TP
.B hostname
.I hostname
This name is resolved (looked up in the DNS).
If a IPv4 or IPv6 address is given, a reverse lookup is performed.
.UNINDENT
.INDENT 0.0
.TP
.B \-h
Show the version and commandline option help.
.UNINDENT
.INDENT 0.0
.TP
.B \-v
Enable verbose output and it shows validation results, on every line.
Secure means that the NXDOMAIN (no such domain name), nodata (no such
data) or positive data response validated correctly with one of the
keys.
Secure means that the NXDOMAIN (no such domain name), nodata (no such data)
or positive data response validated correctly with one of the keys.
Insecure means that that domain name has no security set up for it.
Bogus (security failure) means that the response failed one or more
checks, it is likely wrong, outdated, tampered with, or broken.
.UNINDENT
.INDENT 0.0
Bogus (security failure) means that the response failed one or more checks,
it is likely wrong, outdated, tampered with, or broken.
.TP
.B \-d
Enable debug output to stderr.
One \fI\%\-d\fP shows what the resolver and validator are doing and may
tell you what is going on.
More times, \fI\%\-d\fP \fI\%\-d\fP, gives a lot of output, with every
packet sent and received.
.UNINDENT
.INDENT 0.0
Enable debug output to stderr. One \-d shows what the resolver and validator
are doing and may tell you what is going on. More times, \-d \-d, gives a
lot of output, with every packet sent and received.
.TP
.B \-c <class>
Specify the class to lookup for, the default is IN the internet
class.
.UNINDENT
.INDENT 0.0
.B \-c \fIclass
Specify the class to lookup for, the default is IN the internet class.
.TP
.B \-t <type>
Specify the type of data to lookup.
The default looks for IPv4, IPv6 and mail handler data, or domain name
pointers for reverse queries.
.UNINDENT
.INDENT 0.0
.B \-t \fItype
Specify the type of data to lookup. The default looks for IPv4, IPv6 and
mail handler data, or domain name pointers for reverse queries.
.TP
.B \-y <key>
Specify a public key to use as trust anchor.
This is the base for a chain of trust that is built up from the trust
anchor to the response, in order to validate the response message.
Can be given as a DS or DNSKEY record.
For example:
.INDENT 7.0
.INDENT 3.5
.sp
.nf
.ft C
\-y \(dqexample.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD\(dq
.ft P
.fi
.UNINDENT
.UNINDENT
.UNINDENT
.INDENT 0.0
.B \-y \fIkey
Specify a public key to use as trust anchor. This is the base for a chain
of trust that is built up from the trust anchor to the response, in order
to validate the response message. Can be given as a DS or DNSKEY record.
For example \-y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD".
.TP
.B \-D
Enables DNSSEC validation.
Reads the root anchor from the default configured root anchor at the
default location, \fB@UNBOUND_ROOTKEY_FILE@\fP\&.
.UNINDENT
.INDENT 0.0
Enables DNSSEC validation. Reads the root anchor from the default configured
root anchor at the default location, \fI@UNBOUND_ROOTKEY_FILE@\fR.
.TP
.B \-f <keyfile>
Reads keys from a file.
Every line has a DS or DNSKEY record, in the format as for \fI\%\-y\fP\&.
The zone file format, the same as \fBdig\fP and \fBdrill\fP produce.
.UNINDENT
.INDENT 0.0
.B \-f \fIkeyfile
Reads keys from a file. Every line has a DS or DNSKEY record, in the format
as for \-y. The zone file format, the same as dig and drill produce.
.TP
.B \-F <namedkeyfile>
Reads keys from a BIND\-style \fBnamed.conf\fP file.
Only the \fBtrusted\-key {};\fP entries are read.
.UNINDENT
.INDENT 0.0
.B \-F \fInamedkeyfile
Reads keys from a BIND\-style named.conf file. Only the trusted\-key {}; entries
are read.
.TP
.B \-C <configfile>
Uses the specified unbound.conf to prime \fI\%libunbound(3)\fP\&.
.B \-C \fIconfigfile
Uses the specified unbound.conf to prime
.IR libunbound (3).
Pass it as first argument if you want to override some options from the
config file with further arguments on the commandline.
.UNINDENT
.INDENT 0.0
.TP
.B \-r
Read \fB/etc/resolv.conf\fP, and use the forward DNS servers from
there (those could have been set by DHCP).
More info in \fIresolv.conf(5)\fP\&.
Read /etc/resolv.conf, and use the forward DNS servers from there (those could
have been set by DHCP). More info in
.IR resolv.conf (5).
Breaks validation if those servers do not support DNSSEC.
.UNINDENT
.INDENT 0.0
.TP
.B \-4
Use solely the IPv4 network for sending packets.
.UNINDENT
.INDENT 0.0
.TP
.B \-6
Use solely the IPv6 network for sending packets.
.UNINDENT
.SH EXAMPLES
.sp
Some examples of use.
The keys shown below are fakes, thus a security failure is encountered.
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
.SH "EXAMPLES"
Some examples of use. The keys shown below are fakes, thus a security failure
is encountered.
.P
$ unbound\-host www.example.com
$ unbound\-host \-v \-y \(dqexample.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD\(dq www.example.com
$ unbound\-host \-v \-y \(dqexample.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD\(dq 192.0.2.153
.ft P
.fi
.UNINDENT
.UNINDENT
.SH EXIT CODE
.sp
The \fBunbound\-host\fP program exits with status code 1 on error, 0 on no error.
The data may not be available on exit code 0, exit code 1 means the lookup
encountered a fatal error.
.SH SEE ALSO
.sp
\fI\%unbound.conf(5)\fP,
\fI\%unbound(8)\fP\&.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
.\" Generated by docutils manpage writer.
.
.P
$ unbound\-host \-v \-y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD" www.example.com
.P
$ unbound\-host \-v \-y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD" 192.0.2.153
.SH "EXIT CODE"
The unbound\-host program exits with status code 1 on error,
0 on no error. The data may not be available on exit code 0, exit code 1
means the lookup encountered a fatal error.
.SH "SEE ALSO"
\fIunbound.conf\fR(5),
\fIunbound\fR(8).
-176
View File
@@ -1,176 +0,0 @@
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
.. program:: unbound-host
unbound-host(1)
===============
Synopsis
--------
**unbound-host** [``-C configfile``] [``-vdhr46D``] [``-c class``]
[``-t type``] [``-y key``] [``-f keyfile``] [``-F namedkeyfile``] hostname
Description
-----------
``unbound-host`` uses the Unbound validating resolver to query for the hostname
and display results.
With the :option:`-v` option it displays validation status: secure, insecure,
bogus (security failure).
By default it reads no configuration file whatsoever.
It attempts to reach the internet root servers.
With :option:`-C` an unbound config file and with :option:`-r` ``resolv.conf``
can be read.
The available options are:
.. option:: hostname
This name is resolved (looked up in the DNS).
If a IPv4 or IPv6 address is given, a reverse lookup is performed.
.. option:: -h
Show the version and commandline option help.
.. option:: -v
Enable verbose output and it shows validation results, on every line.
Secure means that the NXDOMAIN (no such domain name), nodata (no such
data) or positive data response validated correctly with one of the
keys.
Insecure means that that domain name has no security set up for it.
Bogus (security failure) means that the response failed one or more
checks, it is likely wrong, outdated, tampered with, or broken.
.. option:: -d
Enable debug output to stderr.
One :option:`-d` shows what the resolver and validator are doing and may
tell you what is going on.
More times, :option:`-d` :option:`-d`, gives a lot of output, with every
packet sent and received.
.. option:: -c <class>
Specify the class to lookup for, the default is IN the internet
class.
.. option:: -t <type>
Specify the type of data to lookup.
The default looks for IPv4, IPv6 and mail handler data, or domain name
pointers for reverse queries.
.. option:: -y <key>
Specify a public key to use as trust anchor.
This is the base for a chain of trust that is built up from the trust
anchor to the response, in order to validate the response message.
Can be given as a DS or DNSKEY record.
For example:
.. code-block:: text
-y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD"
.. option:: -D
Enables DNSSEC validation.
Reads the root anchor from the default configured root anchor at the
default location, :file:`@UNBOUND_ROOTKEY_FILE@`.
.. option:: -f <keyfile>
Reads keys from a file.
Every line has a DS or DNSKEY record, in the format as for :option:`-y`.
The zone file format, the same as ``dig`` and ``drill`` produce.
.. option:: -F <namedkeyfile>
Reads keys from a BIND-style :file:`named.conf` file.
Only the ``trusted-key {};`` entries are read.
.. option:: -C <configfile>
Uses the specified unbound.conf to prime :doc:`libunbound(3)</manpages/libunbound>`.
Pass it as first argument if you want to override some options from the
config file with further arguments on the commandline.
.. option:: -r
Read :file:`/etc/resolv.conf`, and use the forward DNS servers from
there (those could have been set by DHCP).
More info in *resolv.conf(5)*.
Breaks validation if those servers do not support DNSSEC.
.. option:: -4
Use solely the IPv4 network for sending packets.
.. option:: -6
Use solely the IPv6 network for sending packets.
Examples
--------
Some examples of use.
The keys shown below are fakes, thus a security failure is encountered.
.. code-block:: text
$ unbound-host www.example.com
$ unbound-host -v -y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD" www.example.com
$ unbound-host -v -y "example.com DS 31560 5 1 1CFED84787E6E19CCF9372C1187325972FE546CD" 192.0.2.153
Exit Code
---------
The ``unbound-host`` program exits with status code 1 on error, 0 on no error.
The data may not be available on exit code 0, exit code 1 means the lookup
encountered a fatal error.
See Also
--------
:doc:`unbound.conf(5)</manpages/unbound.conf>`,
:doc:`unbound(8)</manpages/unbound>`.
+67 -102
View File
@@ -1,123 +1,88 @@
.\" Man page generated from reStructuredText.
.
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "UNBOUND" "8" "@date@" "@version@" "Unbound"
.SH NAME
unbound \- Unbound DNS validating resolver @version@.
.SH SYNOPSIS
.sp
\fBunbound\fP [\fB\-hdpv\fP] [\fB\-c <cfgfile>\fP]
.SH DESCRIPTION
.sp
\fBunbound\fP is a caching DNS resolver.
.sp
It uses a built in list of authoritative nameservers for the root zone (\fB\&.\fP),
.TH "unbound" "8" "@date@" "NLnet Labs" "unbound @version@"
.\"
.\" unbound.8 -- unbound manual
.\"
.\" Copyright (c) 2007, NLnet Labs. All rights reserved.
.\"
.\" See LICENSE for the license.
.\"
.\"
.SH "NAME"
.B unbound
\- Unbound DNS validating resolver @version@.
.SH "SYNOPSIS"
.B unbound
.RB [ \-h ]
.RB [ \-d ]
.RB [ \-p ]
.RB [ \-v ]
.RB [ \-c
.IR cfgfile ]
.SH "DESCRIPTION"
.B Unbound
is a caching DNS resolver.
.P
It uses a built in list of authoritative nameservers for the root zone (.),
the so called root hints.
On receiving a DNS query it will ask the root nameservers for an answer and
will in almost all cases receive a delegation to a top level domain (TLD)
authoritative nameserver.
On receiving a DNS query it will ask the root nameservers for
an answer and will in almost all cases receive a delegation to a top level
domain (TLD) authoritative nameserver.
It will then ask that nameserver for an answer.
It will recursively continue until an answer is found or no answer is available
(NXDOMAIN).
For performance and efficiency reasons that answer is cached for a certain time
(the answer\(aqs time\-to\-live or TTL).
It will recursively continue until an answer is found or no answer is
available (NXDOMAIN).
For performance and efficiency reasons that answer is cached for a
certain time (the answer's time\-to\-live or TTL).
A second query for the same name will then be answered from the cache.
Unbound can also do DNSSEC validation.
.P
To use a locally running
.B Unbound
for resolving put
.sp
To use a locally running Unbound for resolving put:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
.RS 6n
nameserver 127.0.0.1
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
into \fIresolv.conf(5)\fP\&.
.sp
If authoritative DNS is needed as well using \fI\%nsd(8)\fP,
careful setup is required because authoritative nameservers and resolvers are
using the same port number (53).
.RE
.sp
into
.IR resolv.conf (5).
.P
If authoritative DNS is needed as well using
.IR nsd (8),
careful setup is required because authoritative nameservers and
resolvers are using the same port number (53).
.P
The available options are:
.INDENT 0.0
.TP
.B \-h
Show the version number and commandline option help, and exit.
.UNINDENT
.INDENT 0.0
.TP
.B \-c <cfgfile>
Set the config file with settings for unbound to read instead of reading the
file at the default location, \fB@ub_conf_file@\fP\&.
The syntax is described in \fI\%unbound.conf(5)\fP\&.
.UNINDENT
.INDENT 0.0
.B \-c\fI cfgfile
Set the config file with settings for Unbound to read instead of reading the
file at the default location, @ub_conf_file@. The syntax is
described in \fIunbound.conf\fR(5).
.TP
.B \-d
Debug flag: do not fork into the background, but stay attached to the
console.
This flag will also delay writing to the log file until the thread\-spawn
time, so that most config and setup errors appear on stderr.
If given twice or more, logging does not switch to the log file or to
syslog, but the log messages are printed to stderr all the time.
.UNINDENT
.INDENT 0.0
Debug flag: do not fork into the background, but stay attached to
the console. This flag will also delay writing to the log file until
the thread\-spawn time, so that most config and setup errors appear on
stderr. If given twice or more, logging does not switch to the log file
or to syslog, but the log messages are printed to stderr all the time.
.TP
.B \-p
Don\(aqt use a pidfile.
This argument should only be used by supervision systems which can ensure
that only one instance of Unbound will run concurrently.
.UNINDENT
.INDENT 0.0
Don't use a pidfile. This argument should only be used by supervision
systems which can ensure that only one instance of Unbound will run
concurrently.
.TP
.B \-v
Increase verbosity.
If given multiple times, more information is logged.
This is in addition to the verbosity (if any) from the config file.
.UNINDENT
.INDENT 0.0
Increase verbosity. If given multiple times, more information is logged.
This is added to the verbosity (if any) from the config file.
.TP
.B \-V
Show the version number and build options, and exit.
.UNINDENT
.SH SEE ALSO
.sp
\fI\%unbound.conf(5)\fP,
\fI\%unbound\-checkconf(8)\fP,
\fI\%nsd(8)\fP\&.
.SH AUTHOR
Unbound developers are mentioned in the CREDITS file in the distribution.
.SH COPYRIGHT
1999-2025, NLnet Labs
.\" Generated by docutils manpage writer.
.
.SH "SEE ALSO"
\fIunbound.conf\fR(5),
\fIunbound\-checkconf\fR(8),
\fInsd\fR(8).
.SH "AUTHORS"
.B Unbound
developers are mentioned in the CREDITS file in the distribution.
+2428 -5089
View File
File diff suppressed because it is too large Load Diff
-4997
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -1226,7 +1226,7 @@ VERBATIM_HEADERS = NO
# generated with the -Duse_libclang=ON option for CMake.
# The default value is: NO.
#CLANG_ASSISTED_PARSING = NO
CLANG_ASSISTED_PARSING = NO
# If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS
# tag is set to YES then doxygen will add the directory of each input to the
@@ -1234,7 +1234,7 @@ VERBATIM_HEADERS = NO
# The default value is: YES.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
#CLANG_ADD_INC_PATHS = YES
CLANG_ADD_INC_PATHS = YES
# If clang assisted parsing is enabled you can provide the compiler with command
# line options that you would normally use when invoking the compiler. Note that
@@ -1242,7 +1242,7 @@ VERBATIM_HEADERS = NO
# specified with INPUT and INCLUDE_PATH.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
#CLANG_OPTIONS =
CLANG_OPTIONS =
# If clang assisted parsing is enabled you can provide the clang parser with the
# path to the directory containing a file called compile_commands.json. This
@@ -1255,7 +1255,7 @@ VERBATIM_HEADERS = NO
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse_libclang=ON option for CMake.
#CLANG_DATABASE_PATH =
CLANG_DATABASE_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
-119
View File
@@ -1,119 +0,0 @@
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
..
WHEN EDITING MAKE SURE EACH SENTENCE STARTS ON A NEW LINE
..
IT HELPS RENDERERS TO DO THE RIGHT THING WRT SPACE
..
IT HELPS PEOPLE DIFFING THE CHANGES
.. program:: unbound
unbound(8)
==========
Synopsis
--------
**unbound** [``-hdpv``] [``-c <cfgfile>``]
Description
-----------
``unbound`` is a caching DNS resolver.
It uses a built in list of authoritative nameservers for the root zone (``.``),
the so called root hints.
On receiving a DNS query it will ask the root nameservers for an answer and
will in almost all cases receive a delegation to a top level domain (TLD)
authoritative nameserver.
It will then ask that nameserver for an answer.
It will recursively continue until an answer is found or no answer is available
(NXDOMAIN).
For performance and efficiency reasons that answer is cached for a certain time
(the answer's time-to-live or TTL).
A second query for the same name will then be answered from the cache.
Unbound can also do DNSSEC validation.
To use a locally running Unbound for resolving put:
.. code-block:: text
nameserver 127.0.0.1
into *resolv.conf(5)*.
If authoritative DNS is needed as well using :external+nsd:doc:`manpages/nsd`,
careful setup is required because authoritative nameservers and resolvers are
using the same port number (53).
The available options are:
.. option:: -h
Show the version number and commandline option help, and exit.
.. option:: -c <cfgfile>
Set the config file with settings for unbound to read instead of reading the
file at the default location, :file:`@ub_conf_file@`.
The syntax is described in :doc:`unbound.conf(5)</manpages/unbound.conf>`.
.. option:: -d
Debug flag: do not fork into the background, but stay attached to the
console.
This flag will also delay writing to the log file until the thread-spawn
time, so that most config and setup errors appear on stderr.
If given twice or more, logging does not switch to the log file or to
syslog, but the log messages are printed to stderr all the time.
.. option:: -p
Don't use a pidfile.
This argument should only be used by supervision systems which can ensure
that only one instance of Unbound will run concurrently.
.. option:: -v
Increase verbosity.
If given multiple times, more information is logged.
This is in addition to the verbosity (if any) from the config file.
.. option:: -V
Show the version number and build options, and exit.
See Also
--------
:doc:`unbound.conf(5)</manpages/unbound.conf>`,
:doc:`unbound-checkconf(8)</manpages/unbound-checkconf>`,
:external+nsd:doc:`manpages/nsd`.
+1 -1
View File
@@ -116,7 +116,7 @@ struct addredge {
addrlen_t len;
/** child node this edge is connected to */
struct addrnode *node;
/** Parent node this edge is connected to */
/** Parent node this ege is connected to */
struct addrnode *parent_node;
/** Index of this edge in parent_node */
int parent_index;
+15 -168
View File
@@ -51,7 +51,6 @@
#include "services/cache/dns.h"
#include "util/module.h"
#include "util/regional.h"
#include "util/fptr_wlist.h"
#include "util/storage/slabhash.h"
#include "util/config_file.h"
#include "util/data/msgreply.h"
@@ -154,25 +153,9 @@ int ecs_whitelist_check(struct query_info* qinfo,
return 1;
sn_env = (struct subnet_env*)qstate->env->modinfo[id];
if(sq->is_subquery_nonsubnet) {
if(sq->is_subquery_scopezero) {
/* Check if the result can be stored in the global cache,
* this is okay if the address and name are not configured
* as subnet address and subnet zone. */
if(!ecs_is_whitelisted(sn_env->whitelist,
addr, addrlen, qinfo->qname, qinfo->qname_len,
qinfo->qclass)) {
verbose(VERB_ALGO, "subnet store subquery global, name and addr have no subnet treatment.");
qstate->no_cache_store = 0;
}
}
return 1;
}
/* Cache by default, might be disabled after parsing EDNS option
* received from nameserver. */
if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0)
&& sq->ecs_client_in.subnet_validdata) {
if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0)) {
qstate->no_cache_store = 0;
}
@@ -249,13 +232,13 @@ subnetmod_init(struct module_env *env, int id)
HASH_DEFAULT_STARTARRAY, env->cfg->msg_cache_size,
msg_cache_sizefunc, query_info_compare, query_entry_delete,
subnet_data_delete, NULL);
slabhash_setmarkdel(sn_env->subnet_msg_cache, &subnet_markdel);
if(!sn_env->subnet_msg_cache) {
log_err("subnetcache: could not create cache");
free(sn_env);
env->modinfo[id] = NULL;
return 0;
}
slabhash_setmarkdel(sn_env->subnet_msg_cache, &subnet_markdel);
/* whitelist for edns subnet capable servers */
sn_env->whitelist = ecs_whitelist_create();
if(!sn_env->whitelist ||
@@ -539,83 +522,6 @@ common_prefix(uint8_t *a, uint8_t *b, uint8_t net)
return !memcmp(a, b, n) && ((net % 8) == 0 || a[n] == b[n]);
}
/**
* Create sub request that looks up the query.
* @param qstate: query state
* @param id: module id.
* @param sq: subnet qstate
* @return false on failure.
*/
static int
generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate* sq)
{
struct module_qstate* subq = NULL;
uint16_t qflags = 0; /* OPCODE QUERY, no flags */
int prime = 0;
int valrec = 0;
struct query_info qinf;
qinf.qname = qstate->qinfo.qname;
qinf.qname_len = qstate->qinfo.qname_len;
qinf.qtype = qstate->qinfo.qtype;
qinf.qclass = qstate->qinfo.qclass;
qinf.local_alias = NULL;
qflags |= BIT_RD;
if((qstate->query_flags & BIT_CD)!=0) {
qflags |= BIT_CD;
valrec = 1;
}
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec,
&subq)) {
return 0;
}
if(subq) {
/* It is possible to access the subquery module state. */
struct subnet_qstate* subsq;
if(!subnet_new_qstate(subq, id)) {
verbose(VERB_ALGO, "Could not allocate new subnet qstate");
return 0;
}
subsq = (struct subnet_qstate*)subq->minfo[id];
subsq->is_subquery_nonsubnet = 1;
/* When the client asks 0.0.0.0/0 and the name is not treated
* as subnet, it is to be stored in the global cache.
* Store that the client asked for that, if so. */
if(sq->ecs_client_in.subnet_source_mask == 0 &&
edns_opt_list_find(qstate->edns_opts_front_in,
qstate->env->cfg->client_subnet_opcode)) {
subq->no_cache_store = 1;
subsq->is_subquery_scopezero = 1;
}
}
return 1;
}
/**
* Perform the query without subnet
* @param qstate: query state
* @param id: module id.
* @param sq: subnet qstate
* @return module state
*/
static enum module_ext_state
generate_lookup_without_subnet(struct module_qstate *qstate, int id,
struct subnet_qstate* sq)
{
verbose(VERB_ALGO, "subnetcache: make subquery to look up without subnet");
if(!generate_sub_request(qstate, id, sq)) {
verbose(VERB_ALGO, "Could not generate sub query");
qstate->return_rcode = LDNS_RCODE_SERVFAIL;
qstate->return_msg = NULL;
return module_finished;
}
sq->wait_subquery = 1;
return module_wait_subquery;
}
static enum module_ext_state
eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
{
@@ -651,7 +557,14 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
* is still useful to put it in the edns subnet cache for
* when a client explicitly asks for subnet specific answer. */
verbose(VERB_QUERY, "subnetcache: Authority indicates no support");
return generate_lookup_without_subnet(qstate, id, sq);
if(!sq->started_no_cache_store) {
lock_rw_wrlock(&sne->biglock);
update_cache(qstate, id);
lock_rw_unlock(&sne->biglock);
}
if (sq->subnet_downstream)
cp_edns_bad_response(c_out, c_in);
return module_finished;
}
/* Purposefully there was no sent subnet, and there is consequently
@@ -676,14 +589,14 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
!common_prefix(s_out->subnet_addr, s_in->subnet_addr,
s_out->subnet_source_mask))
{
/* we can not accept, perform query without option */
/* we can not accept, restart query without option */
verbose(VERB_QUERY, "subnetcache: forged data");
s_out->subnet_validdata = 0;
(void)edns_opt_list_remove(&qstate->edns_opts_back_out,
qstate->env->cfg->client_subnet_opcode);
sq->subnet_sent = 0;
sq->subnet_sent_no_subnet = 0;
return generate_lookup_without_subnet(qstate, id, sq);
return module_restart_next;
}
lock_rw_wrlock(&sne->biglock);
@@ -882,9 +795,6 @@ ecs_edns_back_parsed(struct module_qstate* qstate, int id,
} else if(sq->subnet_sent_no_subnet) {
/* The answer can be stored as scope 0, not in global cache. */
qstate->no_cache_store = 1;
} else if(sq->subnet_sent) {
/* Need another query to be able to store in global cache. */
qstate->no_cache_store = 1;
}
return 1;
@@ -902,32 +812,6 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
strmodulevent(event));
log_query_info(VERB_QUERY, "subnetcache operate: query", &qstate->qinfo);
if(sq && sq->wait_subquery_done) {
/* The subquery lookup returned. */
if(sq->ecs_client_in.subnet_source_mask == 0 &&
edns_opt_list_find(qstate->edns_opts_front_in,
qstate->env->cfg->client_subnet_opcode)) {
if(!sq->started_no_cache_store &&
qstate->return_msg) {
lock_rw_wrlock(&sne->biglock);
update_cache(qstate, id);
lock_rw_unlock(&sne->biglock);
}
if (sq->subnet_downstream)
cp_edns_bad_response(&sq->ecs_client_out,
&sq->ecs_client_in);
/* It is a scope zero lookup, append edns subnet
* option to the querier. */
subnet_ecs_opt_list_append(&sq->ecs_client_out,
&qstate->edns_opts_front_out, qstate,
qstate->region);
}
sq->wait_subquery_done = 0;
qstate->ext_state[id] = module_finished;
qstate->no_cache_store = sq->started_no_cache_store;
qstate->no_cache_lookup = sq->started_no_cache_lookup;
return;
}
if((event == module_event_new || event == module_event_pass) &&
sq == NULL) {
struct edns_option* ecs_opt;
@@ -938,8 +822,6 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
}
sq = (struct subnet_qstate*)qstate->minfo[id];
if(sq->wait_subquery)
return; /* Wait for that subquery to return */
if((ecs_opt = edns_opt_list_find(
qstate->edns_opts_front_in,
@@ -969,14 +851,6 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
/* No clients are interested in result or we could not
* parse it, we don't do client subnet */
sq->ecs_server_out.subnet_validdata = 0;
if(edns_opt_list_find(qstate->edns_opts_front_in,
qstate->env->cfg->client_subnet_opcode)) {
/* aggregated this deaggregated state */
qstate->ext_state[id] =
generate_lookup_without_subnet(
qstate, id, sq);
return;
}
verbose(VERB_ALGO, "subnetcache: pass to next module");
qstate->ext_state[id] = module_wait_module;
return;
@@ -1017,14 +891,6 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
}
lock_rw_unlock(&sne->biglock);
}
if(sq->ecs_client_in.subnet_source_mask == 0 &&
edns_opt_list_find(qstate->edns_opts_front_in,
qstate->env->cfg->client_subnet_opcode)) {
/* client asked for resolution without edns subnet */
qstate->ext_state[id] = generate_lookup_without_subnet(
qstate, id, sq);
return;
}
sq->ecs_server_out.subnet_addr_fam =
sq->ecs_client_in.subnet_addr_fam;
@@ -1061,8 +927,6 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
qstate->ext_state[id] = module_wait_module;
return;
}
if(sq && sq->wait_subquery)
return; /* Wait for that subquery to return */
/* Query handed back by next module, we have a 'final' answer */
if(sq && event == module_event_moddone) {
qstate->ext_state[id] = eval_response(qstate, id, sq);
@@ -1111,27 +975,10 @@ subnetmod_clear(struct module_qstate *ATTR_UNUSED(qstate),
}
void
subnetmod_inform_super(struct module_qstate *qstate, int id,
struct module_qstate *super)
subnetmod_inform_super(struct module_qstate *ATTR_UNUSED(qstate),
int ATTR_UNUSED(id), struct module_qstate *ATTR_UNUSED(super))
{
struct subnet_qstate* super_sq =
(struct subnet_qstate*)super->minfo[id];
log_query_info(VERB_ALGO, "subnetcache inform_super: query",
&super->qinfo);
super_sq->wait_subquery = 0;
super_sq->wait_subquery_done = 1;
if(qstate->return_rcode != LDNS_RCODE_NOERROR ||
!qstate->return_msg) {
super->return_msg = NULL;
super->return_rcode = LDNS_RCODE_SERVFAIL;
return;
}
super->return_rcode = LDNS_RCODE_NOERROR;
super->return_msg = dns_copy_msg(qstate->return_msg, super->region);
if(!super->return_msg) {
log_err("subnetcache: copy response, out of memory");
super->return_rcode = LDNS_RCODE_SERVFAIL;
}
/* Not used */
}
size_t
-8
View File
@@ -102,14 +102,6 @@ struct subnet_qstate {
int started_no_cache_store;
/** has the subnet module been started with no_cache_lookup? */
int started_no_cache_lookup;
/** Wait for subquery that has been started for nonsubnet lookup. */
int wait_subquery;
/** The subquery waited for is done. */
int wait_subquery_done;
/** The subnet state is a subquery state for nonsubnet lookup. */
int is_subquery_nonsubnet;
/** This is a subquery, and it is made due to a scope zero request. */
int is_subquery_scopezero;
};
void subnet_data_delete(void* d, void* ATTR_UNUSED(arg));
+1 -2
View File
@@ -456,8 +456,7 @@ ipsecmod_handle_query(struct module_qstate* qstate,
/* Store A/AAAA in cache. */
if(!dns_cache_store(qstate->env, &qstate->qinfo,
qstate->return_msg->rep, 0, qstate->prefetch_leeway,
0, qstate->region, qstate->query_flags, qstate->qstarttime,
qstate->is_valrec)) {
0, qstate->region, qstate->query_flags, qstate->qstarttime)) {
log_err("ipsecmod: out of memory caching record");
}
qstate->ext_state[id] = module_finished;
+1 -1
View File
@@ -278,7 +278,7 @@ delegpt_count_addr(struct delegpt* dp, size_t* numaddr, size_t* numres,
void delegpt_log(enum verbosity_value v, struct delegpt* dp)
{
char buf[LDNS_MAX_DOMAINLEN];
char buf[LDNS_MAX_DOMAINLEN+1];
struct delegpt_ns* ns;
struct delegpt_addr* a;
size_t missing=0, numns=0, numaddr=0, numres=0, numavail=0;
-10
View File
@@ -79,16 +79,6 @@ struct delegpt {
* Also true if the delegationpoint was created from a delegation
* message and thus contains the parent-side-info already. */
uint8_t has_parent_side_NS;
/** if true, the delegation point has reached last resort processing
* and the parent side information has been possibly added to the
* delegation point.
* For now this signals that further target lookups will ignore
* the configured target-fetch-policy and only resolve on
* demand to try and avoid triggering limits at this stage (.i.e, it
* is very likely that the A/AAAA queries for the newly added name
* servers will not yield new IP addresses and trigger NXNS
* countermeasures. */
uint8_t fallback_to_parent_side_NS;
/** for assertions on type of delegpt */
uint8_t dp_type_mlc;
/** use SSL for upstream query */
+12 -72
View File
@@ -129,7 +129,7 @@ forwards_insert_data(struct iter_forwards* fwd, uint16_t c, uint8_t* nm,
node->namelabs = nmlabs;
node->dp = dp;
if(!rbtree_insert(fwd->tree, &node->node)) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[257];
dname_str(nm, buf);
log_err("duplicate forward zone %s ignored.", buf);
delegpt_free_mlc(dp);
@@ -139,17 +139,6 @@ forwards_insert_data(struct iter_forwards* fwd, uint16_t c, uint8_t* nm,
return 1;
}
static struct iter_forward_zone*
fwd_zone_find(struct iter_forwards* fwd, uint16_t c, uint8_t* nm)
{
struct iter_forward_zone key;
key.node.key = &key;
key.dclass = c;
key.name = nm;
key.namelabs = dname_count_size_labels(nm, &key.namelen);
return (struct iter_forward_zone*)rbtree_search(fwd->tree, &key);
}
/** insert new info into forward structure given dp */
static int
forwards_insert(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp)
@@ -332,40 +321,6 @@ make_stub_holes(struct iter_forwards* fwd, struct config_file* cfg)
log_err("cannot parse stub name '%s'", s->name);
return 0;
}
if(fwd_zone_find(fwd, LDNS_RR_CLASS_IN, dname) != NULL) {
/* Already a forward zone there. */
free(dname);
continue;
}
if(!fwd_add_stub_hole(fwd, LDNS_RR_CLASS_IN, dname)) {
free(dname);
log_err("out of memory");
return 0;
}
free(dname);
}
return 1;
}
/** make NULL entries for auths */
static int
make_auth_holes(struct iter_forwards* fwd, struct config_file* cfg)
{
struct config_auth* a;
uint8_t* dname;
size_t dname_len;
for(a = cfg->auths; a; a = a->next) {
if(!a->name) continue;
dname = sldns_str2wire_dname(a->name, &dname_len);
if(!dname) {
log_err("cannot parse auth name '%s'", a->name);
return 0;
}
if(fwd_zone_find(fwd, LDNS_RR_CLASS_IN, dname) != NULL) {
/* Already a forward zone there. */
free(dname);
continue;
}
if(!fwd_add_stub_hole(fwd, LDNS_RR_CLASS_IN, dname)) {
free(dname);
log_err("out of memory");
@@ -398,16 +353,6 @@ forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg)
lock_rw_unlock(&fwd->lock);
return 0;
}
/* TODO: Now we punch holes for auth zones as well so that in
* iterator:forward_request() we see the configured
* delegation point, but code flow/naming is hard to follow.
* Consider having a single tree with configured
* delegation points for all categories
* (stubs, forwards, auths). */
if(!make_auth_holes(fwd, cfg)) {
lock_rw_unlock(&fwd->lock);
return 0;
}
fwd_init_parents(fwd);
lock_rw_unlock(&fwd->lock);
return 1;
@@ -558,6 +503,17 @@ forwards_get_mem(struct iter_forwards* fwd)
return s;
}
static struct iter_forward_zone*
fwd_zone_find(struct iter_forwards* fwd, uint16_t c, uint8_t* nm)
{
struct iter_forward_zone key;
key.node.key = &key;
key.dclass = c;
key.name = nm;
key.namelabs = dname_count_size_labels(nm, &key.namelen);
return (struct iter_forward_zone*)rbtree_search(fwd->tree, &key);
}
int
forwards_add_zone(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp,
int nolock)
@@ -634,19 +590,3 @@ forwards_delete_stub_hole(struct iter_forwards* fwd, uint16_t c,
fwd_init_parents(fwd);
if(!nolock) { lock_rw_unlock(&fwd->lock); }
}
void
forwards_swap_tree(struct iter_forwards* fwd, struct iter_forwards* data)
{
rbtree_type* oldtree = fwd->tree;
if(oldtree) {
lock_unprotect(&fwd->lock, oldtree);
}
if(data->tree) {
lock_unprotect(&data->lock, data->tree);
}
fwd->tree = data->tree;
data->tree = oldtree;
lock_protect(&fwd->lock, fwd->tree, sizeof(*fwd->tree));
lock_protect(&data->lock, data->tree, sizeof(*data->tree));
}
-9
View File
@@ -234,13 +234,4 @@ int forwards_add_stub_hole(struct iter_forwards* fwd, uint16_t c,
void forwards_delete_stub_hole(struct iter_forwards* fwd, uint16_t c,
uint8_t* nm, int nolock);
/**
* Swap internal tree with preallocated entries. Caller should manage
* the locks.
* @param fwd: the forward data structure.
* @param data: the data structure used to take elements from. This contains
* the old elements on return.
*/
void forwards_swap_tree(struct iter_forwards* fwd, struct iter_forwards* data);
#endif /* ITERATOR_ITER_FWD_H */
+1 -12
View File
@@ -181,7 +181,7 @@ hints_insert(struct iter_hints* hints, uint16_t c, struct delegpt* dp,
node->noprime = (uint8_t)noprime;
if(!name_tree_insert(&hints->tree, &node->node, dp->name, dp->namelen,
dp->namelabs, c)) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[257];
dname_str(dp->name, buf);
log_err("second hints for zone %s ignored.", buf);
delegpt_free_mlc(dp);
@@ -611,14 +611,3 @@ hints_delete_stub(struct iter_hints* hints, uint16_t c, uint8_t* nm,
name_tree_init_parents(&hints->tree);
if(!nolock) { lock_rw_unlock(&hints->lock); }
}
void
hints_swap_tree(struct iter_hints* hints, struct iter_hints* data)
{
rbnode_type* oldroot = hints->tree.root;
size_t oldcount = hints->tree.count;
hints->tree.root = data->tree.root;
hints->tree.count = data->tree.count;
data->tree.root = oldroot;
data->tree.count = oldcount;
}
-9
View File
@@ -198,13 +198,4 @@ int hints_add_stub(struct iter_hints* hints, uint16_t c, struct delegpt* dp,
void hints_delete_stub(struct iter_hints* hints, uint16_t c,
uint8_t* nm, int nolock);
/**
* Swap internal tree with preallocated entries. Caller should manage
* the locks.
* @param hints: the hints data structure.
* @param data: the data structure used to take elements from. This contains
* the old elements on return.
*/
void hints_swap_tree(struct iter_hints* hints, struct iter_hints* data);
#endif /* ITERATOR_ITER_HINTS_H */
-113
View File
@@ -367,47 +367,6 @@ type_allowed_in_additional_section(uint16_t tp)
return 0;
}
/** Shorten RRset */
static void
shorten_rrset(sldns_buffer* pkt, struct rrset_parse* rrset, int count)
{
/* The too large NS RRset is shortened. This is so that too large
* content does not overwhelm the cache. It may make the rrset
* bogus if it was signed, and then the domain is not resolved any
* more, that is okay, the NS RRset was too large. During a referral
* it can be shortened and then the first part of the list could
* be used to resolve. The scrub continues to disallow glue for the
* removed nameserver RRs and removes that too. Because the glue
* is not marked as okay, since the RRs have been removed here. */
int i;
struct rr_parse* rr = rrset->rr_first, *prev = NULL;
if(!rr)
return;
for(i=0; i<count; i++) {
prev = rr;
rr = rr->next;
if(!rr)
return; /* The RRset is already short. */
}
if(verbosity >= VERB_QUERY
&& rrset->dname_len <= LDNS_MAX_DOMAINLEN) {
uint8_t buf[LDNS_MAX_DOMAINLEN+1];
dname_pkt_copy(pkt, buf, rrset->dname);
log_nametypeclass(VERB_QUERY, "normalize: shorten RRset:", buf,
rrset->type, ntohs(rrset->rrset_class));
}
/* remove further rrs */
rrset->rr_last = prev;
rrset->rr_count = count;
while(rr) {
rrset->size -= rr->size;
rr = rr->next;
}
if(rrset->rr_last)
rrset->rr_last->next = NULL;
else rrset->rr_first = NULL;
}
/**
* This routine normalizes a response. This includes removing "irrelevant"
* records from the answer and additional sections and (re)synthesizing
@@ -428,7 +387,6 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
uint8_t* sname = qinfo->qname;
size_t snamelen = qinfo->qname_len;
struct rrset_parse* rrset, *prev, *nsset=NULL;
int cname_length = 0; /* number of CNAMEs, or DNAMEs */
if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN)
@@ -443,16 +401,6 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
prev = NULL;
rrset = msg->rrset_first;
while(rrset && rrset->section == LDNS_SECTION_ANSWER) {
if(cname_length > env->cfg->iter_scrub_cname) {
/* Too many CNAMEs, or DNAMEs, from the authority
* server, scrub down the length to something
* shorter. This deletes everything after the limit
* is reached. The iterator is going to look up
* the content one by one anyway. */
remove_rrset("normalize: removing because too many cnames:",
pkt, msg, prev, &rrset);
continue;
}
if(rrset->type == LDNS_RR_TYPE_DNAME &&
pkt_strict_sub(pkt, sname, rrset->dname)) {
/* check if next rrset is correct CNAME. else,
@@ -472,7 +420,6 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
"too long");
return 0;
}
cname_length++;
if(nx && nx->type == LDNS_RR_TYPE_CNAME &&
dname_pkt_compare(pkt, sname, nx->dname) == 0) {
/* check next cname */
@@ -513,7 +460,6 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
if(rrset->type == LDNS_RR_TYPE_CNAME) {
struct rrset_parse* nx = rrset->rrset_all_next;
uint8_t* oldsname = sname;
cname_length++;
/* see if the next one is a DNAME, if so, swap them */
if(nx && nx->section == LDNS_SECTION_ANSWER &&
nx->type == LDNS_RR_TYPE_DNAME &&
@@ -561,10 +507,6 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
LDNS_SECTION_ANSWER &&
dname_pkt_compare(pkt, oldsname,
rrset->dname) == 0) {
if(rrset->type == LDNS_RR_TYPE_NS &&
rrset->rr_count > env->cfg->iter_scrub_ns) {
shorten_rrset(pkt, rrset, env->cfg->iter_scrub_ns);
}
prev = rrset;
rrset = rrset->rrset_all_next;
}
@@ -580,11 +522,6 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
continue;
}
if(rrset->type == LDNS_RR_TYPE_NS &&
rrset->rr_count > env->cfg->iter_scrub_ns) {
shorten_rrset(pkt, rrset, env->cfg->iter_scrub_ns);
}
/* Mark the additional names from relevant rrset as OK. */
/* only for RRsets that match the query name, other ones
* will be removed by sanitize, so no additional for them */
@@ -641,25 +578,6 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset);
continue;
}
if(rrset->rr_count > env->cfg->iter_scrub_ns) {
/* If this is not a referral, and the NS RRset
* is signed, then remove it entirely, so
* that when it becomes bogus it does not
* make the message that is otherwise fine
* into a bogus message. */
if(!(msg->an_rrsets == 0 &&
FLAGS_GET_RCODE(msg->flags) ==
LDNS_RCODE_NOERROR &&
!soa_in_auth(msg) &&
!(msg->flags & BIT_AA)) &&
rrset->rrsig_count != 0) {
remove_rrset("normalize: removing too large NS "
"RRset:", pkt, msg, prev, &rrset);
continue;
} else {
shorten_rrset(pkt, rrset, env->cfg->iter_scrub_ns);
}
}
}
/* if this is type DS and we query for type DS we just got
* a referral answer for our type DS query, fix packet */
@@ -871,7 +789,6 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
{
int del_addi = 0; /* if additional-holding rrsets are deleted, we
do not trust the normalized additional-A-AAAA any more */
uint8_t* ns_rrset_dname = NULL;
int added_rrlen_ede = 0;
struct rrset_parse* rrset, *prev;
prev = NULL;
@@ -977,16 +894,6 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
continue;
}
}
if(rrset->type == LDNS_RR_TYPE_NS &&
(rrset->section == LDNS_SECTION_AUTHORITY ||
rrset->section == LDNS_SECTION_ANSWER)) {
/* If the type is NS, and we're in the
* answer or authority section, then
* store the dname so we can check
* against the glue records
* further down */
ns_rrset_dname = rrset->dname;
}
if(del_addi && rrset->section == LDNS_SECTION_ADDITIONAL) {
remove_rrset("sanitize: removing potential "
"poison reference RRset:", pkt, msg, prev, &rrset);
@@ -999,26 +906,6 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
"RRset:", pkt, msg, prev, &rrset);
continue;
}
if(env->cfg->harden_unverified_glue && ns_rrset_dname &&
rrset->section == LDNS_SECTION_ADDITIONAL &&
(rrset->type == LDNS_RR_TYPE_A || rrset->type == LDNS_RR_TYPE_AAAA) &&
!pkt_strict_sub(pkt, rrset->dname, ns_rrset_dname)) {
/* We're in the additional section, looking
* at an A/AAAA rrset, have a previous
* delegation point and we notice that
* the glue records are NOT for strict
* subdomains of the delegation. So set a
* flag, recompute the hash for the rrset
* and write the A/AAAA record to cache.
* It'll be retrieved if we can't separately
* resolve the glue */
rrset->flags = PACKED_RRSET_UNVERIFIED_GLUE;
rrset->hash = pkt_hash_rrset(pkt, rrset->dname, rrset->type, rrset->rrset_class, rrset->flags);
store_rrset(pkt, msg, env, rrset);
remove_rrset("sanitize: storing potential "
"unverified glue reference RRset:", pkt, msg, prev, &rrset);
continue;
}
prev = rrset;
rrset = rrset->rrset_all_next;
}
+49 -146
View File
@@ -77,73 +77,41 @@
static const char DEFAULT_NAT64_PREFIX[] = "64:ff9b::/96";
/** fillup fetch policy array */
static int
fetch_fill(int* target_fetch_policy, int max_dependency_depth, const char* str)
static void
fetch_fill(struct iter_env* ie, const char* str)
{
char* s = (char*)str, *e;
int i;
for(i=0; i<max_dependency_depth+1; i++) {
target_fetch_policy[i] = strtol(s, &e, 10);
if(s == e) {
log_err("cannot parse fetch policy number %s", s);
return 0;
}
for(i=0; i<ie->max_dependency_depth+1; i++) {
ie->target_fetch_policy[i] = strtol(s, &e, 10);
if(s == e)
fatal_exit("cannot parse fetch policy number %s", s);
s = e;
}
return 1;
}
/** Read config string that represents the target fetch policy */
int
read_fetch_policy(int** target_fetch_policy, int* max_dependency_depth,
const char* str)
static int
read_fetch_policy(struct iter_env* ie, const char* str)
{
int count = cfg_count_numbers(str);
if(count < 1) {
log_err("Cannot parse target fetch policy: \"%s\"", str);
return 0;
}
*max_dependency_depth = count - 1;
*target_fetch_policy = (int*)calloc(
(size_t)(*max_dependency_depth)+1, sizeof(int));
if(!*target_fetch_policy) {
ie->max_dependency_depth = count - 1;
ie->target_fetch_policy = (int*)calloc(
(size_t)ie->max_dependency_depth+1, sizeof(int));
if(!ie->target_fetch_policy) {
log_err("alloc fetch policy: out of memory");
return 0;
}
if(!fetch_fill(*target_fetch_policy, *max_dependency_depth, str))
return 0;
fetch_fill(ie, str);
return 1;
}
struct rbtree_type*
caps_white_create(void)
{
struct rbtree_type* caps_white = rbtree_create(name_tree_compare);
if(!caps_white)
log_err("out of memory");
return caps_white;
}
/** delete caps_whitelist element */
static void
caps_free(struct rbnode_type* n, void* ATTR_UNUSED(d))
{
if(n) {
free(((struct name_tree_node*)n)->name);
free(n);
}
}
void
caps_white_delete(struct rbtree_type* caps_white)
{
if(!caps_white)
return;
traverse_postorder(caps_white, caps_free, NULL);
free(caps_white);
}
int
/** apply config caps whitelist items to name tree */
static int
caps_white_apply_cfg(rbtree_type* ntree, struct config_file* cfg)
{
struct config_strlist* p;
@@ -176,42 +144,13 @@ caps_white_apply_cfg(rbtree_type* ntree, struct config_file* cfg)
return 1;
}
int
nat64_apply_cfg(struct iter_nat64* nat64, struct config_file* cfg)
{
const char *nat64_prefix;
nat64_prefix = cfg->nat64_prefix;
if(!nat64_prefix)
nat64_prefix = cfg->dns64_prefix;
if(!nat64_prefix)
nat64_prefix = DEFAULT_NAT64_PREFIX;
if(!netblockstrtoaddr(nat64_prefix, 0, &nat64->nat64_prefix_addr,
&nat64->nat64_prefix_addrlen, &nat64->nat64_prefix_net)) {
log_err("cannot parse nat64-prefix netblock: %s", nat64_prefix);
return 0;
}
if(!addr_is_ip6(&nat64->nat64_prefix_addr,
nat64->nat64_prefix_addrlen)) {
log_err("nat64-prefix is not IPv6: %s", cfg->nat64_prefix);
return 0;
}
if(!prefixnet_is_nat64(nat64->nat64_prefix_net)) {
log_err("nat64-prefix length it not 32, 40, 48, 56, 64 or 96: %s",
nat64_prefix);
return 0;
}
nat64->use_nat64 = cfg->do_nat64;
return 1;
}
int
iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
{
const char *nat64_prefix;
int i;
/* target fetch policy */
if(!read_fetch_policy(&iter_env->target_fetch_policy,
&iter_env->max_dependency_depth, cfg->target_fetch_policy))
if(!read_fetch_policy(iter_env, cfg->target_fetch_policy))
return 0;
for(i=0; i<iter_env->max_dependency_depth+1; i++)
verbose(VERB_QUERY, "target fetch policy for level %d is %d",
@@ -231,7 +170,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
}
if(cfg->caps_whitelist) {
if(!iter_env->caps_white)
iter_env->caps_white = caps_white_create();
iter_env->caps_white = rbtree_create(name_tree_compare);
if(!iter_env->caps_white || !caps_white_apply_cfg(
iter_env->caps_white, cfg)) {
log_err("Could not set capsforid whitelist");
@@ -240,13 +179,31 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
}
if(!nat64_apply_cfg(&iter_env->nat64, cfg)) {
log_err("Could not setup nat64");
nat64_prefix = cfg->nat64_prefix;
if(!nat64_prefix)
nat64_prefix = cfg->dns64_prefix;
if(!nat64_prefix)
nat64_prefix = DEFAULT_NAT64_PREFIX;
if(!netblockstrtoaddr(nat64_prefix, 0, &iter_env->nat64_prefix_addr,
&iter_env->nat64_prefix_addrlen,
&iter_env->nat64_prefix_net)) {
log_err("cannot parse nat64-prefix netblock: %s", nat64_prefix);
return 0;
}
if(!addr_is_ip6(&iter_env->nat64_prefix_addr,
iter_env->nat64_prefix_addrlen)) {
log_err("nat64-prefix is not IPv6: %s", cfg->nat64_prefix);
return 0;
}
if(!prefixnet_is_nat64(iter_env->nat64_prefix_net)) {
log_err("nat64-prefix length it not 32, 40, 48, 56, 64 or 96: %s",
nat64_prefix);
return 0;
}
iter_env->supports_ipv6 = cfg->do_ip6;
iter_env->supports_ipv4 = cfg->do_ip4;
iter_env->use_nat64 = cfg->do_nat64;
iter_env->outbound_msg_retry = cfg->outbound_msg_retry;
iter_env->max_sent_count = cfg->max_sent_count;
iter_env->max_query_restarts = cfg->max_query_restarts;
@@ -313,7 +270,7 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr, a->addrlen)) {
return -1; /* there is no ip6 available */
}
if(!iter_env->supports_ipv4 && !iter_env->nat64.use_nat64 &&
if(!iter_env->supports_ipv4 && !iter_env->use_nat64 &&
!addr_is_ip6(&a->addr, a->addrlen)) {
return -1; /* there is no ip4 available */
}
@@ -736,11 +693,10 @@ dns_copy_msg(struct dns_msg* from, struct regional* region)
void
iter_dns_store(struct module_env* env, struct query_info* msgqinf,
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
struct regional* region, uint16_t flags, time_t qstarttime,
int is_valrec)
struct regional* region, uint16_t flags, time_t qstarttime)
{
if(!dns_cache_store(env, msgqinf, msgrep, is_referral, leeway,
pside, region, flags, qstarttime, is_valrec))
pside, region, flags, qstarttime))
log_err("out of memory: cannot store data in cache");
}
@@ -1532,15 +1488,14 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
/* check stub */
if (stub != NULL && stub->dp != NULL) {
enum verbosity_value level = VERB_ALGO;
int stub_no_cache = stub->dp->no_cache;
lock_rw_unlock(&qstate->env->fwds->lock);
if(verbosity >= level && stub_no_cache) {
char qname[LDNS_MAX_DOMAINLEN];
char dpname[LDNS_MAX_DOMAINLEN];
if(stub_no_cache) {
char qname[255+1];
char dpname[255+1];
dname_str(qinf->qname, qname);
dname_str(stub->dp->name, dpname);
verbose(level, "stub for %s %s has no_cache", qname, dpname);
verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname);
}
if(retdpname) {
if(stub->dp->namelen > dpname_storage_len) {
@@ -1561,15 +1516,14 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
/* Check for forward. */
if (dp) {
enum verbosity_value level = VERB_ALGO;
int dp_no_cache = dp->no_cache;
lock_rw_unlock(&qstate->env->hints->lock);
if(verbosity >= level && dp_no_cache) {
char qname[LDNS_MAX_DOMAINLEN];
char dpname[LDNS_MAX_DOMAINLEN];
if(dp_no_cache) {
char qname[255+1];
char dpname[255+1];
dname_str(qinf->qname, qname);
dname_str(dp->name, dpname);
verbose(level, "forward for %s %s has no_cache", qname, dpname);
verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname);
}
if(retdpname) {
if(dp->namelen > dpname_storage_len) {
@@ -1610,54 +1564,3 @@ void iterator_set_ip46_support(struct module_stack* mods,
if(outnet->num_ip6 == 0)
ie->supports_ipv6 = 0;
}
void
limit_nsec_ttl(struct dns_msg* msg)
{
/* Limit NSEC and NSEC3 TTL in response, RFC9077 */
size_t i;
int found = 0;
time_t soa_ttl = 0;
/* Limit the NSEC and NSEC3 TTL values to the SOA TTL and SOA minimum
* TTL. That has already been applied to the SOA record ttl. */
for(i=0; i<msg->rep->rrset_count; i++) {
struct ub_packed_rrset_key* s = msg->rep->rrsets[i];
if(ntohs(s->rk.type) == LDNS_RR_TYPE_SOA) {
struct packed_rrset_data* soadata = (struct packed_rrset_data*)s->entry.data;
found = 1;
soa_ttl = soadata->ttl;
break;
}
}
if(!found)
return;
for(i=0; i<msg->rep->rrset_count; i++) {
struct ub_packed_rrset_key* s = msg->rep->rrsets[i];
if(ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC ||
ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC3) {
struct packed_rrset_data* data = (struct packed_rrset_data*)s->entry.data;
/* Limit the negative TTL. */
if(data->ttl > soa_ttl) {
if(verbosity >= VERB_ALGO) {
char buf[256];
snprintf(buf, sizeof(buf),
"limiting TTL %d of %s record to the SOA TTL of %d for",
(int)data->ttl, ((ntohs(s->rk.type) == LDNS_RR_TYPE_NSEC)?"NSEC":"NSEC3"), (int)soa_ttl);
log_nametypeclass(VERB_ALGO, buf,
s->rk.dname, ntohs(s->rk.type),
ntohs(s->rk.rrset_class));
}
data->ttl = soa_ttl;
}
}
}
}
void
iter_make_minimal(struct reply_info* rep)
{
size_t rem = rep->ns_numrrsets + rep->ar_numrrsets;
rep->ns_numrrsets = 0;
rep->ar_numrrsets = 0;
rep->rrset_count -= rem;
}
+1 -55
View File
@@ -61,7 +61,6 @@ struct sock_list;
struct ub_packed_rrset_key;
struct module_stack;
struct outside_network;
struct iter_nat64;
/* max number of lookups in the cache for target nameserver names.
* This stops, for large delegations, N*N lookups in the cache. */
@@ -143,7 +142,6 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
* @param region: to copy modified (cache is better) rrs back to.
* @param flags: with BIT_CD for dns64 AAAA translated queries.
* @param qstarttime: time of query start.
* @param is_valrec: if the query is validation recursion and does not get
* return void, because we are not interested in alloc errors,
* the iterator and validator can operate on the results in their
* scratch space (the qstate.region) and are not dependent on the cache.
@@ -152,8 +150,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
*/
void iter_dns_store(struct module_env* env, struct query_info* qinf,
struct reply_info* rep, int is_referral, time_t leeway, int pside,
struct regional* region, uint16_t flags, time_t qstarttime,
int is_valrec);
struct regional* region, uint16_t flags, time_t qstarttime);
/**
* Select randomly with n/m probability.
@@ -431,55 +428,4 @@ int iter_stub_fwd_no_cache(struct module_qstate *qstate,
void iterator_set_ip46_support(struct module_stack* mods,
struct module_env* env, struct outside_network* outnet);
/**
* Read config string that represents the target fetch policy.
* @param target_fetch_policy: alloced on return.
* @param max_dependency_depth: set on return.
* @param str: the config string
* @return false on failure.
*/
int read_fetch_policy(int** target_fetch_policy, int* max_dependency_depth,
const char* str);
/**
* Create caps exempt data structure.
* @return NULL on failure.
*/
struct rbtree_type* caps_white_create(void);
/**
* Delete caps exempt data structure.
* @param caps_white: caps exempt tree.
*/
void caps_white_delete(struct rbtree_type* caps_white);
/**
* Apply config caps whitelist items to name tree
* @param ntree: caps exempt tree.
* @param cfg: config with options.
*/
int caps_white_apply_cfg(struct rbtree_type* ntree, struct config_file* cfg);
/**
* Apply config for nat64
* @param nat64: the nat64 state.
* @param cfg: config with options.
* @return false on failure.
*/
int nat64_apply_cfg(struct iter_nat64* nat64, struct config_file* cfg);
/**
* Limit NSEC and NSEC3 TTL in response, RFC9077
* @param msg: dns message, the SOA record ttl is used to restrict ttls
* of NSEC and NSEC3 RRsets. If no SOA record, nothing happens.
*/
void limit_nsec_ttl(struct dns_msg* msg);
/**
* Make the response minimal. Removed authority and additional section,
* that works when there is an answer in the answer section.
* @param rep: reply to modify.
*/
void iter_make_minimal(struct reply_info* rep);
#endif /* ITERATOR_ITER_UTILS_H */
+60 -128
View File
@@ -70,16 +70,12 @@
#include "sldns/parseutil.h"
#include "sldns/sbuffer.h"
/* number of packets */
int MAX_GLOBAL_QUOTA = 200;
/* in msec */
int UNKNOWN_SERVER_NICENESS = 376;
/* in msec */
int USEFUL_SERVER_TOP_TIMEOUT = 120000;
/* Equals USEFUL_SERVER_TOP_TIMEOUT*4 */
int BLACKLIST_PENALTY = (120000*4);
/** Timeout when only a single probe query per IP is allowed. */
int PROBE_MAXRTO = PROBE_MAXRTO_DEFAULT; /* in msec */
static void target_count_increase_nx(struct iter_qstate* iq, int num);
@@ -107,6 +103,16 @@ iter_init(struct module_env* env, int id)
return 1;
}
/** delete caps_whitelist element */
static void
caps_free(struct rbnode_type* n, void* ATTR_UNUSED(d))
{
if(n) {
free(((struct name_tree_node*)n)->name);
free(n);
}
}
void
iter_deinit(struct module_env* env, int id)
{
@@ -118,7 +124,10 @@ iter_deinit(struct module_env* env, int id)
free(iter_env->target_fetch_policy);
priv_delete(iter_env->priv);
donotq_delete(iter_env->donotq);
caps_white_delete(iter_env->caps_white);
if(iter_env->caps_white) {
traverse_postorder(iter_env->caps_white, caps_free, NULL);
free(iter_env->caps_white);
}
free(iter_env);
env->modinfo[id] = NULL;
}
@@ -243,11 +252,11 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
} else {
/* see if the failure did get (parent-lame) info */
if(!cache_fill_missing(super->env, super_iq->qchase.qclass,
super->region, super_iq->dp, 0))
super->region, super_iq->dp))
log_err("out of memory adding missing");
}
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
if((dpns->got4 == 2 || (!ie->supports_ipv4 && !ie->nat64.use_nat64)) &&
if((dpns->got4 == 2 || (!ie->supports_ipv4 && !ie->use_nat64)) &&
(dpns->got6 == 2 || !ie->supports_ipv6)) {
dpns->resolved = 1; /* mark as failed */
target_count_increase_nx(super_iq, 1);
@@ -311,21 +320,16 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
qstate->qinfo.qname, qstate->qinfo.qname_len,
qstate->qinfo.qtype, qstate->qinfo.qclass,
qstate->query_flags, 0,
qstate->env->cfg->serve_expired)) != NULL) {
qstate->env->cfg->serve_expired_ttl_reset)) != NULL) {
struct reply_info* rep = (struct reply_info*)msg->entry.data;
if(qstate->env->cfg->serve_expired && rep) {
if(qstate->env->cfg->serve_expired_ttl_reset &&
*qstate->env->now + qstate->env->cfg->serve_expired_ttl
> rep->serve_expired_ttl) {
verbose(VERB_ALGO, "reset serve-expired-ttl for "
"response in cache");
rep->serve_expired_ttl = *qstate->env->now +
qstate->env->cfg->serve_expired_ttl;
}
verbose(VERB_ALGO, "set serve-expired-norec-ttl for "
if(qstate->env->cfg->serve_expired &&
qstate->env->cfg->serve_expired_ttl_reset && rep &&
*qstate->env->now + qstate->env->cfg->serve_expired_ttl
> rep->serve_expired_ttl) {
verbose(VERB_ALGO, "reset serve-expired-ttl for "
"response in cache");
rep->serve_expired_norec_ttl = NORR_TTL +
*qstate->env->now;
rep->serve_expired_ttl = *qstate->env->now +
qstate->env->cfg->serve_expired_ttl;
}
if(rep && (FLAGS_GET_RCODE(rep->flags) ==
LDNS_RCODE_NOERROR ||
@@ -357,7 +361,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
err.security = sec_status_indeterminate;
verbose(VERB_ALGO, "store error response in message cache");
iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL,
qstate->query_flags, qstate->qstarttime, qstate->is_valrec);
qstate->query_flags, qstate->qstarttime);
return error_response(qstate, id, rcode);
}
@@ -403,11 +407,8 @@ iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
num_an = 0;
for(p = iq->an_prepend_list; p; p = p->next) {
sets[num_an++] = p->rrset;
if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl) {
if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl)
msg->rep->ttl = ub_packed_rrset_ttl(p->rrset);
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
}
}
memcpy(sets+num_an, msg->rep->rrsets, msg->rep->an_numrrsets *
sizeof(struct ub_packed_rrset_key*));
@@ -420,11 +421,8 @@ iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
msg->rep->ns_numrrsets, p->rrset))
continue;
sets[msg->rep->an_numrrsets + num_an + num_ns++] = p->rrset;
if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl) {
if(ub_packed_rrset_ttl(p->rrset) < msg->rep->ttl)
msg->rep->ttl = ub_packed_rrset_ttl(p->rrset);
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
}
}
memcpy(sets + num_an + msg->rep->an_numrrsets + num_ns,
msg->rep->rrsets + msg->rep->an_numrrsets,
@@ -762,14 +760,6 @@ target_count_increase_nx(struct iter_qstate* iq, int num)
iq->target_count[TARGET_COUNT_NX] += num;
}
static void
target_count_increase_global_quota(struct iter_qstate* iq, int num)
{
target_count_create(iq);
if(iq->target_count)
iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] += num;
}
/**
* Generate a subrequest.
* Generate a local request event. Local events are tied to this module, and
@@ -1081,7 +1071,7 @@ auth_zone_delegpt(struct module_qstate* qstate, struct iter_qstate* iq,
/* cache is blacklisted and fallback, and we
* already have an auth_zone dp */
if(verbosity>=VERB_ALGO) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[255+1];
dname_str(z->name, buf);
verbose(VERB_ALGO, "auth_zone %s "
"fallback because cache blacklisted",
@@ -1098,7 +1088,7 @@ auth_zone_delegpt(struct module_qstate* qstate, struct iter_qstate* iq,
* validation failure, and the zone allows
* fallback to the internet, query there. */
if(verbosity>=VERB_ALGO) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[255+1];
dname_str(z->name, buf);
verbose(VERB_ALGO, "auth_zone %s "
"fallback because cache blacklisted",
@@ -1570,11 +1560,6 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
errinf(qstate, "malloc failure for forward zone");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp, 0)) {
errinf(qstate, "malloc failure, copy extra info into delegation point");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
if((qstate->query_flags&BIT_RD)==0) {
/* If the server accepts RD=0 queries and forwards
* with RD=1, then if the server is listed as an NS
@@ -1712,7 +1697,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
*/
if(iter_dp_is_useless(&qstate->qinfo, qstate->query_flags,
iq->dp, ie->supports_ipv4, ie->supports_ipv6,
ie->nat64.use_nat64)) {
ie->use_nat64)) {
int have_dp = 0;
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass, &have_dp, &iq->dp, qstate->region)) {
if(have_dp) {
@@ -2022,7 +2007,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
return 1;
if(iq->depth > 0 && iq->target_count &&
iq->target_count[TARGET_COUNT_QUERIES] > MAX_TARGET_COUNT) {
char s[LDNS_MAX_DOMAINLEN];
char s[LDNS_MAX_DOMAINLEN+1];
dname_str(qstate->qinfo.qname, s);
verbose(VERB_QUERY, "request %s has exceeded the maximum "
"number of glue fetches %d", s,
@@ -2030,7 +2015,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
return 2;
}
if(iq->dp_target_count > MAX_DP_TARGET_COUNT) {
char s[LDNS_MAX_DOMAINLEN];
char s[LDNS_MAX_DOMAINLEN+1];
dname_str(qstate->qinfo.qname, s);
verbose(VERB_QUERY, "request %s has exceeded the maximum "
"number of glue fetches %d to a single delegation point",
@@ -2076,7 +2061,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
if(mesh_jostle_exceeded(qstate->env->mesh)) {
/* If no ip4 query is possible, that makes
* this ns resolved. */
if(!((ie->supports_ipv4 || ie->nat64.use_nat64) &&
if(!((ie->supports_ipv4 || ie->use_nat64) &&
((ns->lame && !ns->done_pside4) ||
(!ns->lame && !ns->got4)))) {
ns->resolved = 1;
@@ -2085,7 +2070,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
}
}
/* Send the A request. */
if((ie->supports_ipv4 || ie->nat64.use_nat64) &&
if((ie->supports_ipv4 || ie->use_nat64) &&
((ns->lame && !ns->done_pside4) ||
(!ns->lame && !ns->got4))) {
if(!generate_target_query(qstate, iq, id,
@@ -2152,16 +2137,6 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
verbose(VERB_QUERY, "configured stub or forward servers failed -- returning SERVFAIL");
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
iq->dp->fallback_to_parent_side_NS = 1;
if(qstate->env->cfg->harden_unverified_glue) {
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp, PACKED_RRSET_UNVERIFIED_GLUE))
log_err("out of memory in cache_fill_missing");
if(iq->dp->usable_list) {
verbose(VERB_ALGO, "try unverified glue from cache");
return next_state(iq, QUERYTARGETS_STATE);
}
}
if(!iq->dp->has_parent_side_NS && dname_is_root(iq->dp->name)) {
struct delegpt* dp;
int nolock = 0;
@@ -2181,10 +2156,6 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
a->lame, a->tls_auth_name, -1, NULL);
}
lock_rw_unlock(&qstate->env->hints->lock);
/* copy over some configuration since we update the
* delegation point in place */
iq->dp->tcp_upstream = dp->tcp_upstream;
iq->dp->ssl_upstream = dp->ssl_upstream;
}
iq->dp->has_parent_side_NS = 1;
} else if(!iq->dp->has_parent_side_NS) {
@@ -2208,7 +2179,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
}
/* see if that makes new names available */
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp, 0))
qstate->region, iq->dp))
log_err("out of memory in cache_fill_missing");
if(iq->dp->usable_list) {
verbose(VERB_ALGO, "try parent-side-name, w. glue from cache");
@@ -2246,7 +2217,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
}
if(iq->depth > 0 && iq->target_count &&
iq->target_count[TARGET_COUNT_QUERIES] > MAX_TARGET_COUNT) {
char s[LDNS_MAX_DOMAINLEN];
char s[LDNS_MAX_DOMAINLEN+1];
dname_str(qstate->qinfo.qname, s);
verbose(VERB_QUERY, "request %s has exceeded the maximum "
"number of glue fetches %d", s,
@@ -2262,14 +2233,14 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
/* if this nameserver is at a delegation point, but that
* delegation point is a stub and we cannot go higher, skip*/
if( ((ie->supports_ipv6 && !ns->done_pside6) ||
((ie->supports_ipv4 || ie->nat64.use_nat64) && !ns->done_pside4)) &&
((ie->supports_ipv4 || ie->use_nat64) && !ns->done_pside4)) &&
!can_have_last_resort(qstate->env, ns->name, ns->namelen,
iq->qchase.qclass, NULL, NULL, NULL)) {
log_nametypeclass(VERB_ALGO, "cannot pside lookup ns "
"because it is also a stub/forward,",
ns->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);
if(ie->supports_ipv6) ns->done_pside6 = 1;
if(ie->supports_ipv4 || ie->nat64.use_nat64) ns->done_pside4 = 1;
if(ie->supports_ipv4 || ie->use_nat64) ns->done_pside4 = 1;
continue;
}
/* query for parent-side A and AAAA for nameservers */
@@ -2294,7 +2265,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
}
}
if((ie->supports_ipv4 || ie->nat64.use_nat64) && !ns->done_pside4) {
if((ie->supports_ipv4 || ie->use_nat64) && !ns->done_pside4) {
/* Send the A request. */
if(!generate_parentside_target_query(qstate, iq, id,
ns->name, ns->namelen,
@@ -2563,7 +2534,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
}
if(!ie->supports_ipv6)
delegpt_no_ipv6(iq->dp);
if(!ie->supports_ipv4 && !ie->nat64.use_nat64)
if(!ie->supports_ipv4 && !ie->use_nat64)
delegpt_no_ipv4(iq->dp);
delegpt_log(VERB_ALGO, iq->dp);
@@ -2735,7 +2706,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
if((iq->chase_flags&BIT_RD) && !(iq->response->rep->flags&BIT_AA)) {
verbose(VERB_ALGO, "forwarder, ignoring referral from auth zone");
} else {
qstate->env->mesh->num_query_authzone_up++;
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;
@@ -2773,8 +2746,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
}
/* if the mesh query list is full, then do not waste cpu and sockets to
* fetch promiscuous targets. They can be looked up when needed. */
if(!iq->dp->fallback_to_parent_side_NS && can_do_promisc
&& !mesh_jostle_exceeded(qstate->env->mesh)) {
if(can_do_promisc && !mesh_jostle_exceeded(qstate->env->mesh)) {
tf_policy = ie->target_fetch_policy[iq->depth];
}
@@ -3036,17 +3008,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
}
}
target_count_increase_global_quota(iq, 1);
if(iq->target_count && iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]
> MAX_GLOBAL_QUOTA) {
char s[LDNS_MAX_DOMAINLEN];
dname_str(qstate->qinfo.qname, s);
verbose(VERB_QUERY, "request %s has exceeded the maximum "
"global quota on number of upstream queries %d", s,
iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]);
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
}
/* Do not check ratelimit for forwarding queries or if we already got a
* pass. */
sq_check_ratelimit = (!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok);
@@ -3063,9 +3024,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
real_addr = target->addr;
real_addrlen = target->addrlen;
if(ie->nat64.use_nat64 && target->addr.ss_family == AF_INET) {
addr_to_nat64(&target->addr, &ie->nat64.nat64_prefix_addr,
ie->nat64.nat64_prefix_addrlen, ie->nat64.nat64_prefix_net,
if(ie->use_nat64 && target->addr.ss_family == AF_INET) {
addr_to_nat64(&target->addr, &ie->nat64_prefix_addr,
ie->nat64_prefix_addrlen, ie->nat64_prefix_net,
&real_addr, &real_addrlen);
log_name_addr(VERB_QUERY, "applied NAT64:",
iq->dp->name, &real_addr, real_addrlen);
@@ -3253,19 +3214,13 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
}
}
if(type == RESPONSE_TYPE_CNAME &&
(iq->qchase.qtype == LDNS_RR_TYPE_CNAME ||
iq->qchase.qtype == LDNS_RR_TYPE_ANY) &&
iq->qchase.qtype == LDNS_RR_TYPE_CNAME &&
iq->minimisation_state == MINIMISE_STATE &&
query_dname_compare(iq->qchase.qname, iq->qinfo_out.qname) == 0) {
/* The minimised query for full QTYPE and hidden QTYPE can be
* classified as CNAME response type, even when the original
* QTYPE=CNAME. This should be treated as answer response type.
*/
/* For QTYPE=ANY, it is also considered the response, that
* is what the classifier would say, if it saw qtype ANY,
* and this same response was returned for that. The response
* can already be treated as such an answer, without having
* to send another query with a new qtype. */
type = RESPONSE_TYPE_ANSWER;
}
@@ -3295,16 +3250,6 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->num_target_queries = 0;
return processDSNSFind(qstate, iq, id);
}
if(iq->qchase.qtype == LDNS_RR_TYPE_DNSKEY && SERVE_EXPIRED
&& qstate->is_valrec &&
reply_find_answer_rrset(&iq->qchase, iq->response->rep) != NULL) {
/* clean out the authority section, if any, so it
* does not overwrite dnssec valid data in the
* validation recursion lookup. */
verbose(VERB_ALGO, "make DNSKEY minimal for serve "
"expired");
iter_make_minimal(iq->response->rep);
}
if(!qstate->no_cache_store)
iter_dns_store(qstate->env, &iq->response->qinfo,
iq->response->rep,
@@ -3312,7 +3257,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS,
qstate->region, qstate->query_flags,
qstate->qstarttime, qstate->is_valrec);
qstate->qstarttime);
/* close down outstanding requests to be discarded */
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
@@ -3406,7 +3351,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* no prefetch-leeway, since its not the answer */
iter_dns_store(qstate->env, &iq->response->qinfo,
iq->response->rep, 1, 0, 0, NULL, 0,
qstate->qstarttime, qstate->is_valrec);
qstate->qstarttime);
if(iq->store_parent_NS)
iter_store_parentside_NS(qstate->env,
iq->response->rep);
@@ -3455,7 +3400,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
old_dp->name, old_dp->namelen);
}
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
qstate->region, iq->dp, 0)) {
qstate->region, iq->dp)) {
errinf(qstate, "malloc failure, copy extra info into delegation point");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
@@ -3522,15 +3467,6 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->num_target_queries = 0;
return processDSNSFind(qstate, iq, id);
}
if(iq->minimisation_state == MINIMISE_STATE &&
query_dname_compare(iq->qchase.qname,
iq->qinfo_out.qname) != 0) {
verbose(VERB_ALGO, "continue query minimisation, "
"downwards, after CNAME response for "
"intermediate label");
/* continue query minimisation, downwards */
return next_state(iq, QUERYTARGETS_STATE);
}
/* Process the CNAME response. */
if(!handle_cname_response(qstate, iq, iq->response,
&sname, &snamelen)) {
@@ -3545,8 +3481,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iter_dns_store(qstate->env, &iq->response->qinfo,
iq->response->rep, 1, qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS, NULL,
qstate->query_flags, qstate->qstarttime,
qstate->is_valrec);
qstate->query_flags, qstate->qstarttime);
/* set the current request's qname to the new value. */
iq->qchase.qname = sname;
iq->qchase.qname_len = snamelen;
@@ -3593,7 +3528,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->auth_zone_response = 0;
iq->sent_count = 0;
iq->dp_target_count = 0;
iq->query_restart_count++;
if(iq->minimisation_state != MINIMISE_STATE)
/* Only count as query restart when it is not an extra
* query as result of qname minimisation. */
iq->query_restart_count++;
if(qstate->env->cfg->qname_minimisation)
iq->minimisation_state = INIT_MINIMISE_STATE;
@@ -3887,7 +3825,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
} else {
verbose(VERB_ALGO, "iterator TargetResponse failed");
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
if((dpns->got4 == 2 || (!ie->supports_ipv4 && !ie->nat64.use_nat64)) &&
if((dpns->got4 == 2 || (!ie->supports_ipv4 && !ie->use_nat64)) &&
(dpns->got6 == 2 || !ie->supports_ipv6)) {
dpns->resolved = 1; /* fail the target */
/* do not count cached answers */
@@ -4031,8 +3969,6 @@ processClassResponse(struct module_qstate* qstate, int id,
to->rep->prefetch_ttl = from->rep->prefetch_ttl;
if(from->rep->serve_expired_ttl < to->rep->serve_expired_ttl)
to->rep->serve_expired_ttl = from->rep->serve_expired_ttl;
if(from->rep->serve_expired_norec_ttl < to->rep->serve_expired_norec_ttl)
to->rep->serve_expired_norec_ttl = from->rep->serve_expired_norec_ttl;
}
/* are we done? */
foriq->num_current_queries --;
@@ -4165,12 +4101,12 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
/* store message with the finished prepended items,
* but only if we did recursion. The nonrecursion referral
* from cache does not need to be stored in the msg cache. */
if(!qstate->no_cache_store && (qstate->query_flags&BIT_RD)) {
if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
iter_dns_store(qstate->env, &qstate->qinfo,
iq->response->rep, 0, qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS,
qstate->region, qstate->query_flags,
qstate->qstarttime, qstate->is_valrec);
qstate->qstarttime);
}
}
qstate->return_rcode = LDNS_RCODE_NOERROR;
@@ -4350,7 +4286,6 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
}
/* Copy the edns options we may got from the back end */
qstate->edns_opts_back_in = NULL;
if(edns.opt_list_in) {
qstate->edns_opts_back_in = edns_opt_copy_region(edns.opt_list_in,
qstate->region);
@@ -4396,10 +4331,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
if(verbosity >= VERB_ALGO)
log_dns_msg("incoming scrubbed packet:", &iq->response->qinfo,
iq->response->rep);
if(qstate->env->cfg->aggressive_nsec) {
limit_nsec_ttl(iq->response);
}
if(event == module_event_capsfail || iq->caps_fallback) {
if(qstate->env->cfg->qname_minimisation &&
iq->minimisation_state != DONOT_MINIMISE_STATE) {
+10 -22
View File
@@ -46,6 +46,8 @@
#include "util/data/msgreply.h"
#include "util/module.h"
struct delegpt;
struct iter_hints;
struct iter_forwards;
struct iter_donotq;
struct iter_prep_list;
struct iter_priv;
@@ -53,9 +55,6 @@ struct rbtree_type;
/** max number of targets spawned for a query and its subqueries */
#define MAX_TARGET_COUNT 64
/** max number of upstream queries for a query and its subqueries, it is
* never reset. */
extern int MAX_GLOBAL_QUOTA;
/** max number of target lookups per qstate, per delegation point */
#define MAX_DP_TARGET_COUNT 16
/** max number of nxdomains allowed for target lookups for a query and
@@ -106,9 +105,15 @@ extern int BLACKLIST_PENALTY;
#define EMPTY_NODATA_RETRY_COUNT 2
/**
* Iterator global state for nat64.
* Global state for the iterator.
*/
struct iter_nat64 {
struct iter_env {
/** A flag to indicate whether or not we have an IPv6 route */
int supports_ipv6;
/** A flag to indicate whether or not we have an IPv4 route */
int supports_ipv4;
/** A flag to locally apply NAT64 to make IPv4 addrs into IPv6 */
int use_nat64;
@@ -120,20 +125,6 @@ struct iter_nat64 {
/** CIDR mask length of NAT64 prefix */
int nat64_prefix_net;
};
/**
* Global state for the iterator.
*/
struct iter_env {
/** A flag to indicate whether or not we have an IPv6 route */
int supports_ipv6;
/** A flag to indicate whether or not we have an IPv4 route */
int supports_ipv4;
/** State for nat64 */
struct iter_nat64 nat64;
/** A set of inetaddrs that should never be queried. */
struct iter_donotq* donotq;
@@ -257,9 +248,6 @@ enum target_count_variables {
TARGET_COUNT_QUERIES,
/** Number of nxdomain responses encountered. */
TARGET_COUNT_NX,
/** Global quota on number of queries to upstream servers per
* client request, that is never reset. */
TARGET_COUNT_GLOBAL_QUOTA,
/** This should stay last here, it is used for the allocation */
TARGET_COUNT_MAX,
+1 -1
View File
@@ -395,7 +395,7 @@ context_serialize_cancel(struct ctx_query* q, uint32_t* len)
/* format of cancel:
* o uint32 cmd
* o uint32 async-id */
uint8_t* p = (uint8_t*)reallocarray(NULL, 2, sizeof(uint32_t));
uint8_t* p = (uint8_t*)reallocarray(NULL, sizeof(uint32_t), 2);
if(!p) return NULL;
*len = 2*sizeof(uint32_t);
sldns_write_uint32(p, UB_LIBCMD_CANCEL);
+7 -41
View File
@@ -292,7 +292,6 @@ libworker_do_cmd(struct libworker* w, uint8_t* msg, uint32_t len)
log_err("unknown command for bg worker %d",
(int)context_serial_getcmd(msg, len));
/* and fall through to quit */
ATTR_FALLTHROUGH
/* fallthrough */
case UB_LIBCMD_QUIT:
free(msg);
@@ -423,7 +422,7 @@ int libworker_bg(struct ub_ctx* ctx)
static int
fill_canon(struct ub_result* res, uint8_t* s)
{
char buf[LDNS_MAX_DOMAINLEN];
char buf[255+2];
dname_str(s, buf);
res->canonname = strdup(buf);
return res->canonname != 0;
@@ -630,9 +629,8 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
free(qinfo.qname);
return UB_NOERROR;
}
if(ctx->env->auth_zones && auth_zones_downstream_answer(
ctx->env->auth_zones, w->env, &qinfo, &edns, NULL,
w->back->udp_buff, w->env->scratch)) {
if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
regional_free_all(w->env->scratch);
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
w->back->udp_buff, sec_status_insecure, NULL, 0);
@@ -710,9 +708,8 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
w->back->udp_buff, sec_status_insecure, NULL, 0);
return UB_NOERROR;
}
if(ctx->env->auth_zones && auth_zones_downstream_answer(
ctx->env->auth_zones, w->env, &qinfo, &edns, NULL,
w->back->udp_buff, w->env->scratch)) {
if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
regional_free_all(w->env->scratch);
free(qinfo.qname);
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
@@ -849,9 +846,8 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
free(qinfo.qname);
return;
}
if(w->ctx->env->auth_zones && auth_zones_downstream_answer(
w->ctx->env->auth_zones, w->env, &qinfo, &edns, NULL,
w->back->udp_buff, w->env->scratch)) {
if(w->ctx->env->auth_zones && auth_zones_answer(w->ctx->env->auth_zones,
w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) {
regional_free_all(w->env->scratch);
q->msg_security = sec_status_insecure;
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0);
@@ -1061,33 +1057,3 @@ void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
log_assert(0);
}
#endif
void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
int fast_reload_client_callback(struct comm_point* ATTR_UNUSED(c),
void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
struct comm_reply* ATTR_UNUSED(repinfo))
{
log_assert(0);
return 0;
}
#ifdef HAVE_NGTCP2
void doq_client_event_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
#ifdef HAVE_NGTCP2
void doq_client_timer_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
@@ -30,7 +30,6 @@ def dnssecParse(domain, rrType=RR_TYPE_A):
resolver = ub_ctx()
resolver.add_ta(". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5")
resolver.add_ta(". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D")
resolver.add_ta(". IN DS 38696 8 2 683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16")
dnssecParse("nic.cz")
dnssecParse("nonexistent-domain-blablabla.cz")
-12
View File
@@ -772,8 +772,6 @@ struct ub_server_stats {
long long ans_bogus;
/** rrsets marked bogus by validator */
long long rrset_bogus;
/** number of signature validation operations performed by validator */
long long val_ops;
/** number of queries that have been ratelimited by domain recursion. */
long long queries_ratelimited;
/** unwanted traffic received on server-facing ports */
@@ -847,16 +845,6 @@ struct ub_server_stats {
long long qtls_resume;
/** RPZ action stats */
long long rpz_action[UB_STATS_RPZ_ACTION_NUM];
/** number of bytes in QUIC buffers */
long long mem_quic;
/** number of queries over (DNS over) QUIC */
long long qquic;
/** number of queries removed due to discard-timeout */
long long num_queries_discard_timeout;
/** number of queries removed due to wait-limit */
long long num_queries_wait_limit;
/** number of dns error reports generated */
long long num_dns_error_reports;
};
/**
+1 -7
View File
@@ -59,7 +59,7 @@ Generate a distribution tar file for unbound.
-wxp expat.xx.tar.gz Also build expat from tarball for windows dist.
-wdir directory Build openssl and expat in a persistent directory for
windows dist. If builds are already in that directory
they are used right away. Useful when debugging windows
they are used right away. Useful when debuggin windows
builds.
-w32 32bit windows compile.
-w ... Build windows binary dist. last args passed to configure.
@@ -539,12 +539,6 @@ if [ "$DOWIN" = "yes" ]; then
if test -f "$sspdll"; then
cp "$sspdll" libunbound/.
fi
if test "$W64" = "no"; then
# This could be solved with -static -static-libgcc -static-libstdc++.
# The dependency on c++ is probably due to libexpat. But the copy
# of the dll should work too. It may be needed for the libunbound.dll.
cp /usr/i686-w64-mingw32/sys-root/mingw/bin/libgcc_s_dw2-1.dll libunbound/.
fi
# zipfile
zip -r ../$file LICENSE README.txt unbound.exe unbound-anchor.exe unbound-host.exe unbound-control.exe unbound-checkconf.exe unbound-service-install.exe unbound-service-remove.exe unbound-control-setup.cmd example.conf service.conf root.key unbound-website.url create_unbound_ad_servers.cmd warmup.cmd unbound_cache.cmd Changelog libunbound
info "Testing $file"
-4
View File
@@ -176,10 +176,6 @@ config_file
Harden against spoofed glue (out of zone data).
.. attribute:: harden_unverified_glue
Harden against unverified glue.
.. attribute:: harden_dnssec_stripped
Harden against receiving no DNSSEC data for trust anchor.
+15 -17
View File
@@ -38,14 +38,12 @@ import os
def dataHex(data, prefix=""):
"""Converts binary string data to display representation form"""
res = ""
for i in range(0, int((len(data)+15)/16)):
for i in range(0, (len(data)+15)/16):
res += "%s0x%02X | " % (prefix, i*16)
d = map(lambda x:x, data[i*16:i*16+17])
count=0
d = map(lambda x:ord(x), data[i*16:i*16+17])
for ch in d:
res += "%02X " % ch
count+=1
for i in range(0,17-count):
for i in range(0,17-len(d)):
res += " "
res += "| "
for ch in d:
@@ -62,31 +60,31 @@ def logDnsMsg(qstate):
r = qstate.return_msg.rep
q = qstate.return_msg.qinfo
print("-"*100)
print "-"*100
print("Query: %s, type: %s (%d), class: %s (%d) " % (
qstate.qinfo.qname_str, qstate.qinfo.qtype_str, qstate.qinfo.qtype,
qstate.qinfo.qclass_str, qstate.qinfo.qclass))
print("-"*100)
print("Return reply :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (r.flags, r.qdcount, r.security, r.ttl))
print(" qinfo :: qname: %s %s, qtype: %s, qclass: %s" % (str(q.qname_list), q.qname_str, q.qtype_str, q.qclass_str))
print "-"*100
print "Return reply :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (r.flags, r.qdcount, r.security, r.ttl)
print " qinfo :: qname: %s %s, qtype: %s, qclass: %s" % (str(q.qname_list), q.qname_str, q.qtype_str, q.qclass_str)
if (r):
print("Reply:")
print "Reply:"
for i in range(0, r.rrset_count):
rr = r.rrsets[i]
rk = rr.rk
print(i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags,)
print("type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class))
print i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags,
print "type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class)
d = rr.entry.data
for j in range(0,d.count+d.rrsig_count):
print(" ",j,":","TTL=",d.rr_ttl[j],)
if (j >= d.count): print("rrsig",)
print()
print(dataHex(d.rr_data[j]," "))
print " ",j,":","TTL=",d.rr_ttl[j],
if (j >= d.count): print "rrsig",
print
print dataHex(d.rr_data[j]," ")
print("-"*100)
print "-"*100
def init(id, cfg):
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, mod_env['script']))
+1 -2
View File
@@ -204,7 +204,7 @@ struct query_info {
%inline %{
PyObject* dnameAsStr(PyObject* dname) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[LDNS_MAX_DOMAINLEN+1];
buf[0] = '\0';
dname_str((uint8_t*)PyBytes_AsString(dname), buf);
return PyString_FromString(buf);
@@ -1009,7 +1009,6 @@ struct config_file {
int harden_short_bufsize;
int harden_large_queries;
int harden_glue;
int harden_unverified_glue;
int harden_dnssec_stripped;
int harden_referral_path;
int use_caps_bits_for_id;
+1 -1
View File
@@ -73,7 +73,7 @@ int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo,
return dns_cache_store(qstate->env, qinfo, msgrep, is_referral,
qstate->prefetch_leeway, 0, NULL, qstate->query_flags,
qstate->qstarttime, qstate->is_valrec);
qstate->qstarttime);
}
/* Invalidate the message associated with query_info stored in message cache */
+10 -64
View File
@@ -105,7 +105,6 @@ respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage*
socklen_t addrlen, int net, int create, const char* ipstr)
{
struct resp_addr* node;
log_assert(set);
node = (struct resp_addr*)addr_tree_find(&set->ip_tree, addr, addrlen, net);
if(!node && create) {
node = regional_alloc_zero(set->region, sizeof(*node));
@@ -129,7 +128,6 @@ void
respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node)
{
struct resp_addr* prev;
log_assert(set);
prev = (struct resp_addr*)rbtree_previous((struct rbnode_type*)node);
lock_rw_destroy(&node->lock);
(void)rbtree_delete(&set->ip_tree, node);
@@ -148,7 +146,6 @@ respip_find_or_create(struct respip_set* set, const char* ipstr, int create)
struct sockaddr_storage addr;
int net;
socklen_t addrlen;
log_assert(set);
if(!netblockstrtoaddr(ipstr, 0, &addr, &addrlen, &net)) {
log_err("cannot parse netblock: '%s'", ipstr);
@@ -163,7 +160,6 @@ respip_tag_cfg(struct respip_set* set, const char* ipstr,
const uint8_t* taglist, size_t taglen)
{
struct resp_addr* node;
log_assert(set);
if(!(node=respip_find_or_create(set, ipstr, 1)))
return 0;
@@ -187,7 +183,6 @@ respip_action_cfg(struct respip_set* set, const char* ipstr,
{
struct resp_addr* node;
enum respip_action action;
log_assert(set);
if(!(node=respip_find_or_create(set, ipstr, 1)))
return 0;
@@ -330,7 +325,6 @@ static int
respip_data_cfg(struct respip_set* set, const char* ipstr, const char* rrstr)
{
struct resp_addr* node;
log_assert(set);
node=respip_find_or_create(set, ipstr, 0);
if(!node || node->action == respip_none) {
@@ -350,7 +344,6 @@ respip_set_apply_cfg(struct respip_set* set, char* const* tagname, int num_tags,
struct config_strbytelist* p;
struct config_str2list* pa;
struct config_str2list* pd;
log_assert(set);
set->tagname = tagname;
set->num_tags = num_tags;
@@ -616,7 +609,6 @@ respip_addr_lookup(const struct reply_info *rep, struct respip_set* rs,
struct resp_addr* ra;
struct sockaddr_storage ss;
socklen_t addrlen;
log_assert(rs);
lock_rw_rdlock(&rs->lock);
for(i=0; i<rep->an_numrrsets; i++) {
@@ -875,8 +867,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
const struct respip_client_info* cinfo, const struct reply_info* rep,
struct reply_info** new_repp, struct respip_action_info* actinfo,
struct ub_packed_rrset_key** alias_rrset, int search_only,
struct regional* region, struct auth_zones* az, int* rpz_passthru,
struct views* views, struct respip_set* ipset)
struct regional* region, struct auth_zones* az, int* rpz_passthru)
{
const uint8_t* ctaglist;
size_t ctaglen;
@@ -885,6 +876,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
struct config_strlist** tag_datas;
size_t tag_datas_size;
struct view* view = NULL;
struct respip_set* ipset = NULL;
size_t rrset_id = 0, rr_id = 0;
enum respip_action action = respip_none;
int tag = -1;
@@ -907,20 +899,8 @@ respip_rewrite_reply(const struct query_info* qinfo,
tag_actions_size = cinfo->tag_actions_size;
tag_datas = cinfo->tag_datas;
tag_datas_size = cinfo->tag_datas_size;
if(cinfo->view) {
view = cinfo->view;
lock_rw_rdlock(&view->lock);
} else if(cinfo->view_name) {
view = views_find_view(views, cinfo->view_name, 0);
if(!view) {
/* If the view no longer exists, the rewrite can not
* be processed further. */
verbose(VERB_ALGO, "respip: failed because view %s no "
"longer exists", cinfo->view_name);
return 0;
}
/* The view is rdlocked by views_find_view. */
}
view = cinfo->view;
ipset = cinfo->respip_set;
log_assert(ipset);
@@ -935,6 +915,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
* Note also that we assume 'view' is valid in this function, which
* should be safe (see unbound bug #1191) */
if(view) {
lock_rw_rdlock(&view->lock);
if(view->respip_set) {
if((raddr = respip_addr_lookup(rep,
view->respip_set, &rrset_id, &rr_id))) {
@@ -980,7 +961,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
struct sockaddr_storage ss;
socklen_t ss_len = 0;
char nm[256], ip[256];
char qn[LDNS_MAX_DOMAINLEN];
char qn[255+1];
if(!rdata2sockaddr(rep->rrsets[rrset_id]->entry.data, ntohs(rep->rrsets[rrset_id]->rk.type), rr_id, &ss, &ss_len))
snprintf(ip, sizeof(ip), "invalidRRdata");
else
@@ -1120,8 +1101,7 @@ respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
qstate->client_info, qstate->return_msg->rep,
&new_rep, &actinfo, &alias_rrset, 0,
qstate->region, qstate->env->auth_zones,
&qstate->rpz_passthru, qstate->env->views,
qstate->env->respip_set)) {
&qstate->rpz_passthru)) {
goto servfail;
}
if(actinfo.action != respip_none) {
@@ -1169,8 +1149,7 @@ respip_merge_cname(struct reply_info* base_rep,
const struct query_info* qinfo, const struct reply_info* tgt_rep,
const struct respip_client_info* cinfo, int must_validate,
struct reply_info** new_repp, struct regional* region,
struct auth_zones* az, struct views* views,
struct respip_set* respip_set)
struct auth_zones* az)
{
struct reply_info* new_rep;
struct reply_info* tmp_rep = NULL; /* just a placeholder */
@@ -1197,7 +1176,7 @@ respip_merge_cname(struct reply_info* base_rep,
/* see if the target reply would be subject to a response-ip action. */
if(!respip_rewrite_reply(qinfo, cinfo, tgt_rep, &tmp_rep, &actinfo,
&alias_rrset, 1, region, az, NULL, views, respip_set))
&alias_rrset, 1, region, az, NULL))
return 0;
if(actinfo.action != respip_none) {
log_info("CNAME target of redirect response-ip action would "
@@ -1250,8 +1229,7 @@ respip_inform_super(struct module_qstate* qstate, int id,
if(!respip_merge_cname(super->return_msg->rep, &qstate->qinfo,
qstate->return_msg->rep, super->client_info,
super->env->need_to_validate, &new_rep, super->region,
qstate->env->auth_zones, qstate->env->views,
qstate->env->respip_set))
qstate->env->auth_zones))
goto fail;
super->return_msg->rep = new_rep;
return;
@@ -1348,35 +1326,3 @@ respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
(actionstr) ? actionstr : "inform", srcip, port);
log_nametypeclass(NO_VERBOSE, txt, qname, qtype, qclass);
}
size_t respip_set_get_mem(struct respip_set* set)
{
size_t m;
if(!set) return 0;
m = sizeof(*set);
lock_rw_rdlock(&set->lock);
m += regional_get_mem(set->region);
lock_rw_unlock(&set->lock);
return m;
}
void
respip_set_swap_tree(struct respip_set* respip_set,
struct respip_set* data)
{
rbnode_type* oldroot = respip_set->ip_tree.root;
size_t oldcount = respip_set->ip_tree.count;
struct regional* oldregion = respip_set->region;
char* const* oldtagname = respip_set->tagname;
int oldnum_tags = respip_set->num_tags;
respip_set->ip_tree.root = data->ip_tree.root;
respip_set->ip_tree.count = data->ip_tree.count;
respip_set->region = data->region;
respip_set->tagname = data->tagname;
respip_set->num_tags = data->num_tags;
data->ip_tree.root = oldroot;
data->ip_tree.count = oldcount;
data->region = oldregion;
data->tagname = oldtagname;
data->num_tags = oldnum_tags;
}
+6 -29
View File
@@ -23,8 +23,7 @@
struct respip_set {
struct regional* region;
struct rbtree_type ip_tree;
lock_rw_type lock; /* lock on the respip tree. It is ordered
after views and before hints, stubs and local zones. */
lock_rw_type lock; /* lock on the respip tree */
char* const* tagname; /* shallow copy of tag names, for logging */
int num_tags; /* number of tagname entries */
};
@@ -60,6 +59,7 @@ struct respip_addr_info;
* This is essentially a subset of acl_addr (except for respip_set) but
* defined as a separate structure to avoid dependency on the daemon-specific
* structure.
* respip_set is supposed to refer to the response-ip set for the global view.
*/
struct respip_client_info {
uint8_t* taglist;
@@ -68,12 +68,8 @@ struct respip_client_info {
size_t tag_actions_size;
struct config_strlist** tag_datas;
size_t tag_datas_size;
/** The view for the action, during cache callback that is by
* pointer. */
struct view* view;
/** If from module query state, the view pointer is NULL, but the
* name is stored in reference to the view. */
char* view_name;
struct respip_set* respip_set;
};
/**
@@ -153,16 +149,13 @@ int respip_views_apply_cfg(struct views* vs, struct config_file* cfg,
* on error.
* @param region: allocator to build *new_repp.
* @param az: auth zones containing RPZ information.
* @param views: views tree to lookup view used.
* @param respip_set: the respip set for the global view.
* @return 1 on success, 0 on error.
*/
int respip_merge_cname(struct reply_info* base_rep,
const struct query_info* qinfo, const struct reply_info* tgt_rep,
const struct respip_client_info* cinfo, int must_validate,
struct reply_info** new_repp, struct regional* region,
struct auth_zones* az, struct views* views,
struct respip_set* respip_set);
struct auth_zones* az);
/**
* See if any IP-based action should apply to any IP address of AAAA/A answer
@@ -185,8 +178,6 @@ int respip_merge_cname(struct reply_info* base_rep,
* @param region: allocator to build *new_repp.
* @param rpz_passthru: keeps track of query state can have passthru that
* stops further rpz processing. Or NULL for cached answer processing.
* @param views: views tree to lookup view used.
* @param ipset: the respip set for the global view.
* @return 1 on success, 0 on error.
*/
int respip_rewrite_reply(const struct query_info* qinfo,
@@ -195,7 +186,7 @@ int respip_rewrite_reply(const struct query_info* qinfo,
struct respip_action_info* actinfo,
struct ub_packed_rrset_key** alias_rrset,
int search_only, struct regional* region, struct auth_zones* az,
int* rpz_passthru, struct views* views, struct respip_set* ipset);
int* rpz_passthru);
/**
* Get the response-ip function block.
@@ -276,7 +267,7 @@ void respip_inform_print(struct respip_action_info* respip_actinfo,
* @param addrlen: length of addr.
* @param net: netblock to lookup.
* @param create: create node if it does not exist when 1.
* @param ipstr: human readable ip string, for logging.
* @param ipstr: human redable ip string, for logging.
* @return newly created of found node, not holding lock.
*/
struct resp_addr*
@@ -311,18 +302,4 @@ respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node);
struct ub_packed_rrset_key*
respip_copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region);
/** Get memory usage of respip set tree. The routine locks and unlocks the
* set for reading. */
size_t respip_set_get_mem(struct respip_set* set);
/**
* Swap internal tree with preallocated entries. Caller should manage
* the locks.
* @param respip_set: response ip tree
* @param data: preallocated information.
*/
void respip_set_swap_tree(struct respip_set* respip_set,
struct respip_set* data);
#endif /* RESPIP_RESPIP_H */
+100 -303
View File
@@ -1578,7 +1578,7 @@ auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg)
cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
zfilename += strlen(cfg->chrootdir);
if(verbosity >= VERB_ALGO) {
char nm[LDNS_MAX_DOMAINLEN];
char nm[255+1];
dname_str(z->name, nm);
verbose(VERB_ALGO, "read zonefile %s for %s", zfilename, nm);
}
@@ -1942,7 +1942,7 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z,
unsupported_reason = *reason;
/* continue to check for valid ZONEMD */
if(verbosity >= VERB_ALGO) {
char zstr[LDNS_MAX_DOMAINLEN];
char zstr[255+1];
dname_str(z->name, zstr);
verbose(VERB_ALGO, "auth-zone %s ZONEMD %d %d is unsupported: %s", zstr, (int)scheme, (int)hashalgo, *reason);
}
@@ -1950,7 +1950,7 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z,
continue;
}
if(verbosity >= VERB_ALGO) {
char zstr[LDNS_MAX_DOMAINLEN];
char zstr[255+1];
dname_str(z->name, zstr);
if(!*reason)
verbose(VERB_ALGO, "auth-zone %s ZONEMD hash is correct", zstr);
@@ -1973,7 +1973,7 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z,
if(!*reason)
*reason = "no ZONEMD records found";
if(verbosity >= VERB_ALGO) {
char zstr[LDNS_MAX_DOMAINLEN];
char zstr[255+1];
dname_str(z->name, zstr);
verbose(VERB_ALGO, "auth-zone %s ZONEMD failed: %s", zstr, *reason);
}
@@ -2317,6 +2317,9 @@ auth_free_masters(struct auth_master* list)
}
}
/** delete auth xfer structure
* @param xfr: delete this xfer and its tasks.
*/
void
auth_xfer_delete(struct auth_xfer* xfr)
{
@@ -2413,12 +2416,14 @@ az_find_wildcard(struct auth_zone* z, struct query_info* qinfo,
if(!dname_subdomain_c(nm, z->name))
return NULL; /* out of zone */
while((node=az_find_wildcard_domain(z, nm, nmlen))==NULL) {
/* see if we can go up to find the wildcard */
if(nmlen == z->namelen)
return NULL; /* top of zone reached */
if(ce && nmlen == ce->namelen)
return NULL; /* ce reached */
if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen))
return NULL; /* can't go up */
if(dname_is_root(nm))
return NULL; /* cannot go up */
dname_remove_label(&nm, &nmlen);
}
return node;
}
@@ -2440,8 +2445,9 @@ az_find_candidate_ce(struct auth_zone* z, struct query_info* qinfo,
n = az_find_name(z, nm, nmlen);
/* delete labels and go up on name */
while(!n) {
if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen))
return NULL; /* can't go up */
if(dname_is_root(nm))
return NULL; /* cannot go up */
dname_remove_label(&nm, &nmlen);
n = az_find_name(z, nm, nmlen);
}
return n;
@@ -2453,7 +2459,8 @@ az_domain_go_up(struct auth_zone* z, struct auth_data* n)
{
uint8_t* nm = n->name;
size_t nmlen = n->namelen;
while(dname_remove_label_limit_len(&nm, &nmlen, z->namelen)) {
while(!dname_is_root(nm)) {
dname_remove_label(&nm, &nmlen);
if((n=az_find_name(z, nm, nmlen)) != NULL)
return n;
}
@@ -2767,23 +2774,26 @@ az_change_dnames(struct dns_msg* msg, uint8_t* oldname, uint8_t* newname,
}
}
/** find NSEC record covering the query, with the given node in the zone */
/** find NSEC record covering the query */
static struct auth_rrset*
az_find_nsec_cover(struct auth_zone* z, struct auth_data** node)
{
uint8_t* nm;
size_t nmlen;
uint8_t* nm = (*node)->name;
size_t nmlen = (*node)->namelen;
struct auth_rrset* rrset;
log_assert(*node); /* we already have a node when calling this */
nm = (*node)->name;
nmlen = (*node)->namelen;
/* find the NSEC for the smallest-or-equal node */
/* But there could be glue, and then it has no NSEC.
/* if node == NULL, we did not find a smaller name. But the zone
* name is the smallest name and should have an NSEC. So there is
* no NSEC to return (for a properly signed zone) */
/* for empty nonterminals, the auth-data node should not exist,
* and thus we don't need to go rbtree_previous here to find
* a domain with an NSEC record */
/* but there could be glue, and if this is node, then it has no NSEC.
* Go up to find nonglue (previous) NSEC-holding nodes */
while((rrset=az_domain_rrset(*node, LDNS_RR_TYPE_NSEC)) == NULL) {
if(dname_is_root(nm)) return NULL;
if(nmlen == z->namelen) return NULL;
if(!dname_remove_label_limit_len(&nm, &nmlen, z->namelen))
return NULL; /* can't go up */
dname_remove_label(&nm, &nmlen);
/* adjust *node for the nsec rrset to find in */
*node = az_find_name(z, nm, nmlen);
}
@@ -3011,9 +3021,12 @@ az_nsec3_find_ce(struct auth_zone* z, uint8_t** cenm, size_t* cenmlen,
struct auth_data* node;
while((node = az_nsec3_find_exact(z, *cenm, *cenmlen,
algo, iter, salt, saltlen)) == NULL) {
if(!dname_remove_label_limit_len(cenm, cenmlen, z->namelen))
return NULL; /* can't go up */
if(*cenmlen == z->namelen) {
/* next step up would take us out of the zone. fail */
return NULL;
}
*no_exact_ce = 1;
dname_remove_label(cenm, cenmlen);
}
return node;
}
@@ -3330,8 +3343,7 @@ az_generate_wildcard_answer(struct auth_zone* z, struct query_info* qinfo,
} else if(ce) {
uint8_t* wildup = wildcard->name;
size_t wilduplen= wildcard->namelen;
if(!dname_remove_label_limit_len(&wildup, &wilduplen, z->namelen))
return 0; /* can't go up */
dname_remove_label(&wildup, &wilduplen);
if(!az_add_nsec3_proof(z, region, msg, wildup,
wilduplen, msg->qinfo.qname,
msg->qinfo.qname_len, 0, insert_ce, 1, 0))
@@ -3390,7 +3402,7 @@ az_generate_answer_with_node(struct auth_zone* z, struct query_info* qinfo,
}
/** Generate answer without an existing-node that we can use.
* So it'll be a referral, DNAME, notype, wildcard or nxdomain */
* So it'll be a referral, DNAME or nxdomain */
static int
az_generate_answer_nonexistnode(struct auth_zone* z, struct query_info* qinfo,
struct regional* region, struct dns_msg* msg, struct auth_data* ce,
@@ -3556,17 +3568,14 @@ auth_error_encode(struct query_info* qinfo, struct module_env* env,
sldns_buffer_read_u16_at(buf, 2), edns);
}
int auth_zones_downstream_answer(struct auth_zones* az, struct module_env* env,
int auth_zones_answer(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns,
struct comm_reply* repinfo, struct sldns_buffer* buf,
struct regional* temp)
struct comm_reply* repinfo, struct sldns_buffer* buf, struct regional* temp)
{
struct dns_msg* msg = NULL;
struct auth_zone* z;
int r;
int fallback = 0;
/* Copy the qinfo in case of cname aliasing from local-zone */
struct query_info zqinfo = *qinfo;
lock_rw_rdlock(&az->lock);
if(!az->have_downstream) {
@@ -3574,7 +3583,6 @@ int auth_zones_downstream_answer(struct auth_zones* az, struct module_env* env,
lock_rw_unlock(&az->lock);
return 0;
}
if(qinfo->qtype == LDNS_RR_TYPE_DS) {
uint8_t* delname = qinfo->qname;
size_t delnamelen = qinfo->qname_len;
@@ -3582,14 +3590,8 @@ int auth_zones_downstream_answer(struct auth_zones* az, struct module_env* env,
z = auth_zones_find_zone(az, delname, delnamelen,
qinfo->qclass);
} else {
if(zqinfo.local_alias && !local_alias_shallow_copy_qname(
zqinfo.local_alias, &zqinfo.qname,
&zqinfo.qname_len)) {
lock_rw_unlock(&az->lock);
return 0;
}
z = auth_zones_find_zone(az, zqinfo.qname, zqinfo.qname_len,
zqinfo.qclass);
z = auth_zones_find_zone(az, qinfo->qname, qinfo->qname_len,
qinfo->qclass);
}
if(!z) {
/* no zone above it */
@@ -3608,20 +3610,24 @@ int auth_zones_downstream_answer(struct auth_zones* az, struct module_env* env,
return 0;
}
lock_rw_unlock(&z->lock);
env->mesh->num_query_authzone_down++;
lock_rw_wrlock(&az->lock);
az->num_query_down++;
lock_rw_unlock(&az->lock);
auth_error_encode(qinfo, env, edns, repinfo, buf, temp,
LDNS_RCODE_SERVFAIL);
return 1;
}
/* answer it from zone z */
r = auth_zone_generate_answer(z, &zqinfo, temp, &msg, &fallback);
r = auth_zone_generate_answer(z, qinfo, temp, &msg, &fallback);
lock_rw_unlock(&z->lock);
if(!r && fallback) {
/* fallback to regular answering (recursive) */
return 0;
}
env->mesh->num_query_authzone_down++;
lock_rw_wrlock(&az->lock);
az->num_query_down++;
lock_rw_unlock(&az->lock);
/* encode answer */
if(!r)
@@ -3678,29 +3684,6 @@ auth_zone_parse_notify_serial(sldns_buffer* pkt, uint32_t *serial)
return 1;
}
/** print addr to str, and if not 53, append "@port_number", for logs. */
static void addr_port_to_str(struct sockaddr_storage* addr, socklen_t addrlen,
char* buf, size_t len)
{
uint16_t port = 0;
if(addr_is_ip6(addr, addrlen)) {
struct sockaddr_in6* sa = (struct sockaddr_in6*)addr;
port = ntohs((uint16_t)sa->sin6_port);
} else {
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
port = ntohs((uint16_t)sa->sin_port);
}
if(port == UNBOUND_DNS_PORT) {
/* If it is port 53, print it plainly. */
addr_to_str(addr, addrlen, buf, len);
} else {
char a[256];
a[0]=0;
addr_to_str(addr, addrlen, a, sizeof(a));
snprintf(buf, len, "%s@%d", a, (int)port);
}
}
/** see if addr appears in the list */
static int
addr_in_list(struct auth_addr* list, struct sockaddr_storage* addr,
@@ -4797,8 +4780,8 @@ log_rrlist_position(const char* label, struct auth_chunk* rr_chunk,
{
sldns_buffer pkt;
size_t dlen;
uint8_t buf[LDNS_MAX_DOMAINLEN];
char str[LDNS_MAX_DOMAINLEN];
uint8_t buf[256];
char str[256];
char typestr[32];
sldns_buffer_init_frm_data(&pkt, rr_chunk->data, rr_chunk->len);
sldns_buffer_set_position(&pkt, (size_t)(rr_dname -
@@ -5024,7 +5007,6 @@ apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
xfr->have_zone = 0;
xfr->serial = 0;
xfr->soa_zone_acquired = 0;
/* insert all RRs in to the zone */
/* insert the SOA only once, skip the last one */
@@ -5126,7 +5108,6 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
xfr->have_zone = 0;
xfr->serial = 0;
xfr->soa_zone_acquired = 0;
chunk = xfr->task_transfer->chunks_first;
chunk_pos = 0;
@@ -5227,7 +5208,7 @@ xfr_write_after_update(struct auth_xfer* xfr, struct module_env* env)
cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
zfilename += strlen(cfg->chrootdir);
if(verbosity >= VERB_ALGO) {
char nm[LDNS_MAX_DOMAINLEN];
char nm[255+1];
dname_str(z->name, nm);
verbose(VERB_ALGO, "write zonefile %s for %s", zfilename, nm);
}
@@ -5337,8 +5318,6 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
" (or malformed RR)", xfr->task_transfer->master->host);
return 0;
}
z->soa_zone_acquired = *env->now;
xfr->soa_zone_acquired = *env->now;
/* release xfr lock while verifying zonemd because it may have
* to spawn lookups in the state machines */
@@ -5346,7 +5325,7 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
/* holding z lock */
auth_zone_verify_zonemd(z, env, &env->mesh->mods, NULL, 0, 0);
if(z->zone_expired) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[256];
/* ZONEMD must have failed */
/* reacquire locks, so we hold xfr lock on exit of routine,
* and both xfr and z again after releasing xfr for potential
@@ -5378,7 +5357,7 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
lock_rw_unlock(&z->lock);
if(verbosity >= VERB_QUERY && xfr->have_zone) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[256];
dname_str(xfr->name, zname);
verbose(VERB_QUERY, "auth zone %s updated to serial %u", zname,
(unsigned)xfr->serial);
@@ -5440,7 +5419,7 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env)
qinfo.local_alias = NULL;
if(verbosity >= VERB_ALGO) {
char buf1[512];
char buf2[LDNS_MAX_DOMAINLEN];
char buf2[LDNS_MAX_DOMAINLEN+1];
dname_str(xfr->name, buf2);
snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup"
" for task_transfer", buf2);
@@ -5496,7 +5475,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
/* the ones that are not in addr format are supposed
* to be looked up. The lookup has failed however,
* so skip them */
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
log_err("%s: failed lookup, cannot transfer from master %s",
zname, master->host);
@@ -5535,18 +5514,18 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
&addr, addrlen, -1, master->ssl, master->host,
master->file, env->cfg);
if(!xfr->task_transfer->cp) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
addr_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "cannot create http cp "
"connection for %s to %s", zname, as);
return 0;
}
comm_timer_set(xfr->task_transfer->timer, &t);
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
addr_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "auth zone %s transfer next HTTP fetch from %s started", zname, as);
}
/* Create or refresh the list of allow_notify addrs */
@@ -5567,18 +5546,18 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
env->scratch_buffer, -1,
auth_name != NULL, auth_name);
if(!xfr->task_transfer->cp) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
addr_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "cannot create tcp cp connection for "
"xfr %s to %s", zname, as);
return 0;
}
comm_timer_set(xfr->task_transfer->timer, &t);
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
addr_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "auth zone %s transfer next %s fetch from %s started", zname,
(xfr->task_transfer->on_ixfr?"IXFR":"AXFR"), as);
}
@@ -5600,7 +5579,7 @@ xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env)
* and that calls the callback just like a full
* lookup and lookup failures also call callback */
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s transfer next target lookup", zname);
}
@@ -5623,7 +5602,7 @@ xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env)
xfr_transfer_nextmaster(xfr);
}
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s transfer failed, wait", zname);
}
@@ -5681,7 +5660,7 @@ xfr_master_add_addrs(struct auth_master* m, struct ub_packed_rrset_key* rrset,
}
if(verbosity >= VERB_ALGO) {
char s[64];
addr_port_to_str(&a->addr, a->addrlen, s, sizeof(s));
addr_to_str(&a->addr, a->addrlen, s, sizeof(s));
verbose(VERB_ALGO, "auth host %s lookup %s",
m->host, s);
}
@@ -5726,14 +5705,14 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
lookup_target, answer, wanted_qtype);
} else {
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has nodata", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A"));
}
}
} else {
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has no answer", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A"));
}
@@ -5741,7 +5720,7 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
regional_free_all(temp);
} else {
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup failed", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A"));
}
@@ -6383,7 +6362,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
/* the ones that are not in addr format are supposed
* to be looked up. The lookup has failed however,
* so skip them */
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
log_err("%s: failed lookup, cannot probe to master %s",
zname, master->host);
@@ -6425,9 +6404,9 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
xfr->task_probe->cp = outnet_comm_point_for_udp(env->outnet,
auth_xfer_probe_udp_callback, xfr, &addr, addrlen);
if(!xfr->task_probe->cp) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
addr_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "cannot create udp cp for "
"probe %s to %s", zname, as);
return 0;
@@ -6445,17 +6424,17 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
/* send udp packet */
if(!comm_point_send_udp_msg(xfr->task_probe->cp, env->scratch_buffer,
(struct sockaddr*)&addr, addrlen, 0)) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
addr_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "failed to send soa probe for %s to %s",
zname, as);
return 0;
}
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN], as[256];
char zname[255+1], as[256];
dname_str(xfr->name, zname);
addr_port_to_str(&addr, addrlen, as, sizeof(as));
addr_to_str(&addr, addrlen, as, sizeof(as));
verbose(VERB_ALGO, "auth zone %s soa probe sent to %s", zname,
as);
}
@@ -6484,7 +6463,7 @@ auth_xfer_probe_timer_callback(void* arg)
}
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s soa probe timeout", zname);
}
@@ -6532,7 +6511,7 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
&serial)) {
/* successful lookup */
if(verbosity >= VERB_ALGO) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[256];
dname_str(xfr->name, buf);
verbose(VERB_ALGO, "auth zone %s: soa probe "
"serial is %u", buf, (unsigned)serial);
@@ -6571,14 +6550,14 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
}
} else {
if(verbosity >= VERB_ALGO) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[256];
dname_str(xfr->name, buf);
verbose(VERB_ALGO, "auth zone %s: bad reply to soa probe", buf);
}
}
} else {
if(verbosity >= VERB_ALGO) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[256];
dname_str(xfr->name, buf);
verbose(VERB_ALGO, "auth zone %s: soa probe failed", buf);
}
@@ -6635,7 +6614,7 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
qinfo.local_alias = NULL;
if(verbosity >= VERB_ALGO) {
char buf1[512];
char buf2[LDNS_MAX_DOMAINLEN];
char buf2[LDNS_MAX_DOMAINLEN+1];
dname_str(xfr->name, buf2);
snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup"
" for task_probe", buf2);
@@ -6681,7 +6660,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
* and that calls the callback just like a full
* lookup and lookup failures also call callback */
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s probe next target lookup", zname);
}
@@ -6694,7 +6673,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
* allow_notify addrs */
probe_copy_masters_for_allow_notify(xfr);
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s probe: notify addrs updated", zname);
}
@@ -6702,7 +6681,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
/* only wanted lookups for copy, stop probe and start wait */
xfr->task_probe->only_lookup = 0;
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s probe: finished only_lookup", zname);
}
@@ -6728,7 +6707,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
if(xfr->task_probe->have_new_lease) {
/* if zone not updated, start the wait timer again */
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth_zone %s unchanged, new lease, wait", zname);
}
@@ -6739,7 +6718,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
xfr_set_timeout(xfr, env, 0, 0);
} else {
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s soa probe failed, wait to retry", zname);
}
@@ -6789,14 +6768,14 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
lookup_target, answer, wanted_qtype);
} else {
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has nodata", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A"));
}
}
} else {
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has no address", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A"));
}
@@ -6804,7 +6783,7 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
regional_free_all(temp);
} else {
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup failed", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A"));
}
@@ -6978,7 +6957,7 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
if(!xfr->task_nextprobe->timer) {
/* failed to malloc memory. likely zone transfer
* also fails for that. skip the timeout */
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
log_err("cannot allocate timer, no refresh for %s",
zname);
@@ -6999,7 +6978,7 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
xfr->task_probe->only_lookup = 1;
}
if(verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(xfr->name, zname);
verbose(VERB_ALGO, "auth zone %s timeout in %d seconds",
zname, (int)tv.tv_sec);
@@ -7008,43 +6987,22 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
comm_timer_set(xfr->task_nextprobe->timer, &tv);
}
void auth_zone_pickup_initial_zone(struct auth_zone* z, struct module_env* env)
{
/* Set the time, because we now have timestamp in env,
* (not earlier during startup and apply_cfg), and this
* notes the start time when the data was acquired. */
z->soa_zone_acquired = *env->now;
}
void auth_xfer_pickup_initial_zone(struct auth_xfer* x, struct module_env* env)
{
/* set lease_time, because we now have timestamp in env,
* (not earlier during startup and apply_cfg), and this
* notes the start time when the data was acquired */
if(x->have_zone) {
x->lease_time = *env->now;
x->soa_zone_acquired = *env->now;
}
if(x->task_nextprobe && x->task_nextprobe->worker == NULL) {
xfr_set_timeout(x, env, 0, 1);
}
}
/** initial pick up of worker timeouts, ties events to worker event loop */
void
auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env)
{
struct auth_xfer* x;
struct auth_zone* z;
lock_rw_wrlock(&az->lock);
RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
lock_rw_wrlock(&z->lock);
auth_zone_pickup_initial_zone(z, env);
lock_rw_unlock(&z->lock);
}
RBTREE_FOR(x, struct auth_xfer*, &az->xtree) {
lock_basic_lock(&x->lock);
auth_xfer_pickup_initial_zone(x, env);
/* set lease_time, because we now have timestamp in env,
* (not earlier during startup and apply_cfg), and this
* 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, 1);
}
lock_basic_unlock(&x->lock);
}
lock_rw_unlock(&az->lock);
@@ -7126,7 +7084,6 @@ auth_xfer_new(struct auth_zone* z)
lock_protect(&xfr->lock, &xfr->notify_serial, sizeof(xfr->notify_serial));
lock_protect(&xfr->lock, &xfr->zone_expired, sizeof(xfr->zone_expired));
lock_protect(&xfr->lock, &xfr->have_zone, sizeof(xfr->have_zone));
lock_protect(&xfr->lock, &xfr->soa_zone_acquired, sizeof(xfr->soa_zone_acquired));
lock_protect(&xfr->lock, &xfr->serial, sizeof(xfr->serial));
lock_protect(&xfr->lock, &xfr->retry, sizeof(xfr->retry));
lock_protect(&xfr->lock, &xfr->refresh, sizeof(xfr->refresh));
@@ -7808,7 +7765,7 @@ static void auth_zone_log(uint8_t* name, enum verbosity_value level,
va_list args;
va_start(args, format);
if(verbosity >= level) {
char str[LDNS_MAX_DOMAINLEN];
char str[255+1];
char msg[MAXSYSLOGMSGLEN];
dname_str(name, str);
vsnprintf(msg, sizeof(msg), format, args);
@@ -8010,7 +7967,7 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
static void auth_zone_zonemd_fail(struct auth_zone* z, struct module_env* env,
char* reason, char* why_bogus, char** result)
{
char zstr[LDNS_MAX_DOMAINLEN];
char zstr[255+1];
/* if fail: log reason, and depending on config also take action
* and drop the zone, eg. it is gone from memory, set zone_expired */
dname_str(z->name, zstr);
@@ -8155,8 +8112,6 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
* @param why_bogus: if the routine fails, returns the failure reason.
* @param keystorage: where to store the ub_packed_rrset_key that is created
* on success. A pointer to it is returned on success.
* @param reasonbuf: buffer to use for fail reason string print.
* @param reasonlen: length of reasonbuf.
* @return the dnskey RRset, reference to zone data and keystorage, or
* NULL on failure.
*/
@@ -8456,7 +8411,7 @@ zonemd_lookup_dnskey(struct auth_zone* z, struct module_env* env)
qinfo.local_alias = NULL;
if(verbosity >= VERB_ALGO) {
char buf1[512];
char buf2[LDNS_MAX_DOMAINLEN];
char buf2[LDNS_MAX_DOMAINLEN+1];
dname_str(z->name, buf2);
snprintf(buf1, sizeof(buf1), "auth zone %s: lookup %s "
"for zonemd verification", buf2,
@@ -8604,161 +8559,3 @@ void auth_zones_pickup_zonemd_verify(struct auth_zones* az,
}
lock_rw_unlock(&az->lock);
}
/** Get memory usage of auth rrset */
static size_t
auth_rrset_get_mem(struct auth_rrset* rrset)
{
size_t m = sizeof(*rrset) + packed_rrset_sizeof(rrset->data);
return m;
}
/** Get memory usage of auth data */
static size_t
auth_data_get_mem(struct auth_data* node)
{
size_t m = sizeof(*node) + node->namelen;
struct auth_rrset* rrset;
for(rrset = node->rrsets; rrset; rrset = rrset->next) {
m += auth_rrset_get_mem(rrset);
}
return m;
}
/** Get memory usage of auth zone */
static size_t
auth_zone_get_mem(struct auth_zone* z)
{
size_t m = sizeof(*z) + z->namelen;
struct auth_data* node;
if(z->zonefile)
m += strlen(z->zonefile)+1;
RBTREE_FOR(node, struct auth_data*, &z->data) {
m += auth_data_get_mem(node);
}
if(z->rpz)
m += rpz_get_mem(z->rpz);
return m;
}
/** Get memory usage of list of auth addr */
static size_t
auth_addrs_get_mem(struct auth_addr* list)
{
size_t m = 0;
struct auth_addr* a;
for(a = list; a; a = a->next) {
m += sizeof(*a);
}
return m;
}
/** Get memory usage of list of primaries for auth xfer */
static size_t
auth_primaries_get_mem(struct auth_master* list)
{
size_t m = 0;
struct auth_master* n;
for(n = list; n; n = n->next) {
m += sizeof(*n);
m += auth_addrs_get_mem(n->list);
if(n->host)
m += strlen(n->host)+1;
if(n->file)
m += strlen(n->file)+1;
}
return m;
}
/** Get memory usage or list of auth chunks */
static size_t
auth_chunks_get_mem(struct auth_chunk* list)
{
size_t m = 0;
struct auth_chunk* chunk;
for(chunk = list; chunk; chunk = chunk->next) {
m += sizeof(*chunk) + chunk->len;
}
return m;
}
/** Get memory usage of auth xfer */
static size_t
auth_xfer_get_mem(struct auth_xfer* xfr)
{
size_t m = sizeof(*xfr) + xfr->namelen;
/* auth_nextprobe */
m += comm_timer_get_mem(xfr->task_nextprobe->timer);
/* auth_probe */
m += auth_primaries_get_mem(xfr->task_probe->masters);
m += comm_point_get_mem(xfr->task_probe->cp);
m += comm_timer_get_mem(xfr->task_probe->timer);
/* auth_transfer */
m += auth_chunks_get_mem(xfr->task_transfer->chunks_first);
m += auth_primaries_get_mem(xfr->task_transfer->masters);
m += comm_point_get_mem(xfr->task_transfer->cp);
m += comm_timer_get_mem(xfr->task_transfer->timer);
/* allow_notify_list */
m += auth_primaries_get_mem(xfr->allow_notify_list);
return m;
}
/** Get memory usage of auth zones ztree */
static size_t
az_ztree_get_mem(struct auth_zones* az)
{
size_t m = 0;
struct auth_zone* z;
RBTREE_FOR(z, struct auth_zone*, &az->ztree) {
lock_rw_rdlock(&z->lock);
m += auth_zone_get_mem(z);
lock_rw_unlock(&z->lock);
}
return m;
}
/** Get memory usage of auth zones xtree */
static size_t
az_xtree_get_mem(struct auth_zones* az)
{
size_t m = 0;
struct auth_xfer* xfr;
RBTREE_FOR(xfr, struct auth_xfer*, &az->xtree) {
lock_basic_lock(&xfr->lock);
m += auth_xfer_get_mem(xfr);
lock_basic_unlock(&xfr->lock);
}
return m;
}
size_t auth_zones_get_mem(struct auth_zones* zones)
{
size_t m;
if(!zones) return 0;
m = sizeof(*zones);
lock_rw_rdlock(&zones->rpz_lock);
lock_rw_rdlock(&zones->lock);
m += az_ztree_get_mem(zones);
m += az_xtree_get_mem(zones);
lock_rw_unlock(&zones->lock);
lock_rw_unlock(&zones->rpz_lock);
return m;
}
void xfr_disown_tasks(struct auth_xfer* xfr, struct worker* worker)
{
if(xfr->task_nextprobe->worker == worker) {
xfr_nextprobe_disown(xfr);
}
if(xfr->task_probe->worker == worker) {
xfr_probe_disown(xfr);
}
if(xfr->task_transfer->worker == worker) {
xfr_transfer_disown(xfr);
}
}
+8 -49
View File
@@ -70,8 +70,7 @@ struct auth_chunk;
* Authoritative zones, shared.
*/
struct auth_zones {
/** lock on the authzone trees. It is locked after views, respip,
* local_zones and before fwds and stubs. */
/** lock on the authzone trees */
lock_rw_type lock;
/** rbtree of struct auth_zone */
rbtree_type ztree;
@@ -79,6 +78,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;
/** first auth zone containing rpz item in linked list */
struct auth_zone* rpz_first;
/** rw lock for rpz linked list, needed when iterating or editing linked
@@ -118,8 +121,6 @@ struct auth_zone {
char* zonefile;
/** fallback to the internet on failure or ttl-expiry of auth zone */
int fallback_enabled;
/** the time when zone was transferred from upstream */
time_t soa_zone_acquired;
/** the zone has expired (enabled by the xfer worker), fallback
* happens if that option is enabled. */
int zone_expired;
@@ -210,9 +211,7 @@ struct auth_xfer {
* one of the tasks.
* Once it has the task assigned to it, the worker can access the
* other elements of the task structure without a lock, because that
* is necessary for the eventloop and callbacks from that.
* The auth_zone->lock is locked before this lock.
*/
* is necessary for the eventloop and callbacks from that. */
lock_basic_type lock;
/** zone name, in uncompressed wireformat */
@@ -263,8 +262,6 @@ struct auth_xfer {
int zone_expired;
/** do we have a zone (if 0, no zone data at all) */
int have_zone;
/** the time when zone was transferred from upstream */
time_t soa_zone_acquired;
/** current serial (from SOA), if we have no zone, 0 */
uint32_t serial;
@@ -554,10 +551,9 @@ int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo,
* @param temp: temporary storage region.
* @return false if not answered
*/
int auth_zones_downstream_answer(struct auth_zones* az, struct module_env* env,
int auth_zones_answer(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns,
struct comm_reply* repinfo, struct sldns_buffer* buf,
struct regional* temp);
struct comm_reply* repinfo, struct sldns_buffer* buf, struct regional* temp);
/**
* Find the auth zone that is above the given qname.
@@ -791,41 +787,4 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode,
void auth_zones_pickup_zonemd_verify(struct auth_zones* az,
struct module_env* env);
/** Get memory usage for auth zones. The routine locks and unlocks
* for reading. */
size_t auth_zones_get_mem(struct auth_zones* zones);
/**
* Initial pick up of the auth zone nextprobe timeout and that turns
* into further zone transfer work, if any. Also sets the lease time.
* @param x: xfer structure, locked by caller.
* @param env: environment of the worker that picks up the task.
*/
void auth_xfer_pickup_initial_zone(struct auth_xfer* x,
struct module_env* env);
/**
* Initial pick up of the auth zone, it sets the acquired time.
* @param z: the zone, write locked by caller.
* @param env: environment of the worker, with current time.
*/
void auth_zone_pickup_initial_zone(struct auth_zone* z,
struct module_env* env);
/**
* Delete auth xfer structure
* @param xfr: delete this xfer and its tasks.
*/
void auth_xfer_delete(struct auth_xfer* xfr);
/**
* Disown tasks from the xfr that belong to this worker.
* Only tasks for the worker in question, the comm point and timer
* delete functions need to run in the thread of that worker to be
* able to delete the callback from the event base.
* @param xfr: xfr structure
* @param worker: the worker for which to stop tasks.
*/
void xfr_disown_tasks(struct auth_xfer* xfr, struct worker* worker);
#endif /* SERVICES_AUTHZONE_H */
+22 -93
View File
@@ -88,7 +88,7 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
/* update ref if it was in the cache */
switch(rrset_cache_update(env->rrset_cache, &rep->ref[i],
env->alloc, ((ntohs(rep->ref[i].key->rk.type)==
LDNS_RR_TYPE_NS && !pside)?qstarttime:now) + leeway)) {
LDNS_RR_TYPE_NS && !pside)?qstarttime:now + leeway))) {
case 0: /* ref unchanged, item inserted */
break;
case 2: /* ref updated, cache is superior */
@@ -110,7 +110,6 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
/* no break: also copy key item */
/* the line below is matched by gcc regex and silences
* the fallthrough warning */
ATTR_FALLTHROUGH
/* fallthrough */
case 1: /* ref updated, item inserted */
rep->rrsets[i] = rep->ref[i].key;
@@ -162,7 +161,7 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
size_t i;
/* store RRsets */
for(i=0; i<rep->rrset_count; i++) {
for(i=0; i<rep->rrset_count; i++) {
rep->ref[i].key = rep->rrsets[i];
rep->ref[i].id = rep->rrsets[i]->id;
}
@@ -197,7 +196,6 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
reply_info_sortref(rep);
if(!(e = query_info_entrysetup(qinfo, rep, hash))) {
log_err("store_msg: malloc failed");
reply_info_delete(rep, NULL);
return;
}
slabhash_insert(env->msg_cache, hash, &e->entry, rep, env->alloc);
@@ -347,13 +345,6 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
* not use dns64 translation */
neg = msg_cache_lookup(env, ns->name, ns->namelen,
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
/* Because recursion for lookup uses BIT_CD, check
* for that so it stops the recursion lookup, if a
* negative answer is cached. Because the cache uses
* the CD flag for type AAAA. */
if(!neg)
neg = msg_cache_lookup(env, ns->name, ns->namelen,
LDNS_RR_TYPE_AAAA, qclass, BIT_CD, now, 0);
if(neg) {
delegpt_add_neg_msg(dp, neg);
lock_rw_unlock(&neg->entry.lock);
@@ -366,7 +357,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
/** find and add A and AAAA records for missing nameservers in delegpt */
int
cache_fill_missing(struct module_env* env, uint16_t qclass,
struct regional* region, struct delegpt* dp, uint32_t flags)
struct regional* region, struct delegpt* dp)
{
struct delegpt_ns* ns;
struct msgreply_entry* neg;
@@ -377,7 +368,7 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
continue;
ns->cache_lookup_count++;
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
ns->namelen, LDNS_RR_TYPE_A, qclass, flags, now, 0);
ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0);
if(akey) {
if(!delegpt_add_rrset_A(dp, region, akey, ns->lame,
NULL)) {
@@ -398,7 +389,7 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
}
}
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
ns->namelen, LDNS_RR_TYPE_AAAA, qclass, flags, now, 0);
ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
if(akey) {
if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame,
NULL)) {
@@ -413,13 +404,6 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
* not use dns64 translation */
neg = msg_cache_lookup(env, ns->name, ns->namelen,
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
/* Because recursion for lookup uses BIT_CD, check
* for that so it stops the recursion lookup, if a
* negative answer is cached. Because the cache uses
* the CD flag for type AAAA. */
if(!neg)
neg = msg_cache_lookup(env, ns->name, ns->namelen,
LDNS_RR_TYPE_AAAA, qclass, BIT_CD, now, 0);
if(neg) {
delegpt_add_neg_msg(dp, neg);
lock_rw_unlock(&neg->entry.lock);
@@ -608,8 +592,22 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
time_t now_control = now;
if(now > r->ttl) {
/* Check if we are allowed to serve expired */
if(!allow_expired || !reply_info_can_answer_expired(r, now))
if(allow_expired) {
if(env->cfg->serve_expired_ttl &&
r->serve_expired_ttl < now) {
return NULL;
}
/* Ignore expired failure answers */
if(FLAGS_GET_RCODE(r->flags) !=
LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(r->flags) !=
LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(r->flags) !=
LDNS_RCODE_YXDOMAIN)
return 0;
} else {
return NULL;
}
/* Change the current time so we can pass the below TTL checks when
* serving expired data. */
now_control = r->ttl - env->cfg->serve_expired_reply_ttl;
@@ -628,7 +626,6 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
else
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
msg->rep->serve_expired_norec_ttl = 0;
msg->rep->security = r->security;
msg->rep->an_numrrsets = r->an_numrrsets;
msg->rep->ns_numrrsets = r->ns_numrrsets;
@@ -712,7 +709,6 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
msg->rep->ttl = d->ttl - now;
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
msg->rep->serve_expired_norec_ttl = 0;
msg->rep->security = sec_status_unchecked;
msg->rep->an_numrrsets = 1;
msg->rep->ns_numrrsets = 0;
@@ -752,7 +748,6 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
msg->rep->ttl = d->ttl - now;
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
msg->rep->serve_expired_norec_ttl = 0;
msg->rep->security = sec_status_unchecked;
msg->rep->an_numrrsets = 1;
msg->rep->ns_numrrsets = 0;
@@ -1056,76 +1051,10 @@ dns_cache_lookup(struct module_env* env,
int
dns_cache_store(struct module_env* env, struct query_info* msgqinf,
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
struct regional* region, uint32_t flags, time_t qstarttime,
int is_valrec)
struct reply_info* msgrep, int is_referral, time_t leeway, int pside,
struct regional* region, uint32_t flags, time_t qstarttime)
{
struct reply_info* rep = NULL;
if(SERVE_EXPIRED) {
/* We are serving expired records. Before caching, check if a
* useful expired record exists. */
struct msgreply_entry* e = msg_cache_lookup(env,
msgqinf->qname, msgqinf->qname_len, msgqinf->qtype,
msgqinf->qclass, flags, 0, 1);
if(e) {
struct reply_info* cached = e->entry.data;
if(cached->ttl < *env->now
&& reply_info_could_use_expired(cached, *env->now)
/* If we are validating make sure only
* validating modules can update such messages.
* In that case don't cache it and let a
* subsequent module handle the caching. For
* example, the iterator should not replace an
* expired secure answer with a fresh unchecked
* one and let the validator manage caching. */
&& cached->security != sec_status_bogus
&& (env->need_to_validate &&
msgrep->security == sec_status_unchecked)
/* Exceptions to that rule are:
* o recursions that don't need validation but
* need to update the cache for coherence
* (delegation information while iterating,
* DNSKEY and DS lookups from validator)
* o explicit RRSIG queries that are not
* validated. */
&& !is_valrec
&& msgqinf->qtype != LDNS_RR_TYPE_RRSIG) {
if((int)FLAGS_GET_RCODE(msgrep->flags) !=
LDNS_RCODE_NOERROR &&
(int)FLAGS_GET_RCODE(msgrep->flags) !=
LDNS_RCODE_NXDOMAIN) {
/* The current response has an
* erroneous rcode. Adjust norec time
* so that additional lookups are not
* performed for some time. */
verbose(VERB_ALGO, "set "
"serve-expired-norec-ttl for "
"response in cache");
cached->serve_expired_norec_ttl =
NORR_TTL + *env->now;
if(env->cfg->serve_expired_ttl_reset &&
cached->serve_expired_ttl
< *env->now +
env->cfg->serve_expired_ttl) {
/* Reset serve-expired-ttl for
* valid response in cache. */
verbose(VERB_ALGO, "reset "
"serve-expired-ttl "
"for response in cache");
cached->serve_expired_ttl =
*env->now +
env->cfg->serve_expired_ttl;
}
}
verbose(VERB_ALGO, "a validated expired entry "
"could be overwritten, skip caching "
"the new message at this stage");
lock_rw_unlock(&e->entry.lock);
return 1;
}
lock_rw_unlock(&e->entry.lock);
}
}
/* alloc, malloc properly (not in region, like msg is) */
rep = reply_info_copy(msgrep, env->alloc, NULL);
if(!rep)
+2 -6
View File
@@ -90,14 +90,11 @@ struct dns_msg {
* (See DNSCACHE_STORE_xxx flags).
* @param qstarttime: time when the query was started, and thus when the
* delegations were looked up.
* @param is_valrec: if the query is validation recursion and does not get
* dnssec validation itself.
* @return 0 on alloc error (out of memory).
*/
int dns_cache_store(struct module_env* env, struct query_info* qinf,
struct reply_info* rep, int is_referral, time_t leeway, int pside,
struct regional* region, uint32_t flags, time_t qstarttime,
int is_valrec);
struct regional* region, uint32_t flags, time_t qstarttime);
/**
* Store message in the cache. Stores in message cache and rrset cache.
@@ -205,11 +202,10 @@ struct dns_msg* dns_cache_lookup(struct module_env* env,
* @param qclass: which class to look in.
* @param region: where to store new dp info.
* @param dp: delegation point to fill missing entries.
* @param flags: rrset flags, or 0.
* @return false on alloc failure.
*/
int cache_fill_missing(struct module_env* env, uint16_t qclass,
struct regional* region, struct delegpt* dp, uint32_t flags);
struct regional* region, struct delegpt* dp);
/**
* Utility, create new, unpacked data structure for cache response.
+65 -105
View File
@@ -52,6 +52,24 @@
#include "util/config_file.h"
#include "iterator/iterator.h"
/** Timeout when only a single probe query per IP is allowed. */
#define PROBE_MAXRTO 12000 /* in msec */
/** number of timeouts for a type when the domain can be blocked ;
* even if another type has completely rtt maxed it, the different type
* can do this number of packets (until those all timeout too) */
#define TIMEOUT_COUNT_MAX 3
/** Minus 1000 because that is outside of the RTTBAND, so
* blacklisted servers stay blacklisted if this is chosen.
* If USEFUL_SERVER_TOP_TIMEOUT is below 1000 (configured via RTT_MAX_TIMEOUT,
* infra-cache-max-rtt) change it to just above the RTT_BAND. */
#define STILL_USEFUL_TIMEOUT ( \
USEFUL_SERVER_TOP_TIMEOUT < 1000 || \
USEFUL_SERVER_TOP_TIMEOUT - 1000 <= RTT_BAND \
?RTT_BAND + 1 \
:USEFUL_SERVER_TOP_TIMEOUT - 1000)
/** ratelimit value for delegation point */
int infra_dp_ratelimit = 0;
@@ -64,20 +82,6 @@ int infra_ip_ratelimit = 0;
* For clients with a valid DNS Cookie. */
int infra_ip_ratelimit_cookie = 0;
/** Minus 1000 because that is outside of the RTTBAND, so
* blacklisted servers stay blacklisted if this is chosen.
* If USEFUL_SERVER_TOP_TIMEOUT is below 1000 (configured via RTT_MAX_TIMEOUT,
* infra-cache-max-rtt) change it to just above the RTT_BAND. */
int
still_useful_timeout()
{
return
USEFUL_SERVER_TOP_TIMEOUT < 1000 ||
USEFUL_SERVER_TOP_TIMEOUT - 1000 <= RTT_BAND
?RTT_BAND + 1
:USEFUL_SERVER_TOP_TIMEOUT - 1000;
}
size_t
infra_sizefunc(void* k, void* ATTR_UNUSED(d))
{
@@ -161,7 +165,7 @@ rate_deldatafunc(void* d, void* ATTR_UNUSED(arg))
/** find or create element in domainlimit tree */
static struct domain_limit_data* domain_limit_findcreate(
struct rbtree_type* domain_limits, char* name)
struct infra_cache* infra, char* name)
{
uint8_t* nm;
int labs;
@@ -177,8 +181,8 @@ static struct domain_limit_data* domain_limit_findcreate(
labs = dname_count_labels(nm);
/* can we find it? */
d = (struct domain_limit_data*)name_tree_find(domain_limits, nm,
nmlen, labs, LDNS_RR_CLASS_IN);
d = (struct domain_limit_data*)name_tree_find(&infra->domain_limits,
nm, nmlen, labs, LDNS_RR_CLASS_IN);
if(d) {
free(nm);
return d;
@@ -197,8 +201,8 @@ static struct domain_limit_data* domain_limit_findcreate(
d->node.dclass = LDNS_RR_CLASS_IN;
d->lim = -1;
d->below = -1;
if(!name_tree_insert(domain_limits, &d->node, nm, nmlen, labs,
LDNS_RR_CLASS_IN)) {
if(!name_tree_insert(&infra->domain_limits, &d->node, nm, nmlen,
labs, LDNS_RR_CLASS_IN)) {
log_err("duplicate element in domainlimit tree");
free(nm);
free(d);
@@ -208,19 +212,19 @@ static struct domain_limit_data* domain_limit_findcreate(
}
/** insert rate limit configuration into lookup tree */
static int infra_ratelimit_cfg_insert(struct rbtree_type* domain_limits,
static int infra_ratelimit_cfg_insert(struct infra_cache* infra,
struct config_file* cfg)
{
struct config_str2list* p;
struct domain_limit_data* d;
for(p = cfg->ratelimit_for_domain; p; p = p->next) {
d = domain_limit_findcreate(domain_limits, p->str);
d = domain_limit_findcreate(infra, p->str);
if(!d)
return 0;
d->lim = atoi(p->str2);
}
for(p = cfg->ratelimit_below_domain; p; p = p->next) {
d = domain_limit_findcreate(domain_limits, p->str);
d = domain_limit_findcreate(infra, p->str);
if(!d)
return 0;
d->below = atoi(p->str2);
@@ -228,21 +232,24 @@ static int infra_ratelimit_cfg_insert(struct rbtree_type* domain_limits,
return 1;
}
int
setup_domain_limits(struct rbtree_type* domain_limits, struct config_file* cfg)
/** setup domain limits tree (0 on failure) */
static int
setup_domain_limits(struct infra_cache* infra, struct config_file* cfg)
{
name_tree_init(domain_limits);
if(!infra_ratelimit_cfg_insert(domain_limits, cfg)) {
name_tree_init(&infra->domain_limits);
if(!infra_ratelimit_cfg_insert(infra, cfg)) {
return 0;
}
name_tree_init_parents(domain_limits);
name_tree_init_parents(&infra->domain_limits);
return 1;
}
/** find or create element in wait limit netblock tree */
static struct wait_limit_netblock_info*
wait_limit_netblock_findcreate(struct rbtree_type* tree, char* str)
wait_limit_netblock_findcreate(struct infra_cache* infra, char* str,
int cookie)
{
rbtree_type* tree;
struct sockaddr_storage addr;
int net;
socklen_t addrlen;
@@ -254,6 +261,10 @@ wait_limit_netblock_findcreate(struct rbtree_type* tree, char* str)
}
/* can we find it? */
if(cookie)
tree = &infra->wait_limits_cookie_netblock;
else
tree = &infra->wait_limits_netblock;
d = (struct wait_limit_netblock_info*)addr_tree_find(tree, &addr,
addrlen, net);
if(d)
@@ -275,21 +286,19 @@ wait_limit_netblock_findcreate(struct rbtree_type* tree, char* str)
/** insert wait limit information into lookup tree */
static int
infra_wait_limit_netblock_insert(rbtree_type* wait_limits_netblock,
rbtree_type* wait_limits_cookie_netblock, struct config_file* cfg)
infra_wait_limit_netblock_insert(struct infra_cache* infra,
struct config_file* cfg)
{
struct config_str2list* p;
struct wait_limit_netblock_info* d;
for(p = cfg->wait_limit_netblock; p; p = p->next) {
d = wait_limit_netblock_findcreate(wait_limits_netblock,
p->str);
d = wait_limit_netblock_findcreate(infra, p->str, 0);
if(!d)
return 0;
d->limit = atoi(p->str2);
}
for(p = cfg->wait_limit_cookie_netblock; p; p = p->next) {
d = wait_limit_netblock_findcreate(wait_limits_cookie_netblock,
p->str);
d = wait_limit_netblock_findcreate(infra, p->str, 1);
if(!d)
return 0;
d->limit = atoi(p->str2);
@@ -297,48 +306,16 @@ infra_wait_limit_netblock_insert(rbtree_type* wait_limits_netblock,
return 1;
}
/** Add a default wait limit netblock */
/** setup wait limits tree (0 on failure) */
static int
wait_limit_netblock_default(struct rbtree_type* tree, char* str, int limit)
setup_wait_limits(struct infra_cache* infra, struct config_file* cfg)
{
struct wait_limit_netblock_info* d;
d = wait_limit_netblock_findcreate(tree, str);
if(!d)
addr_tree_init(&infra->wait_limits_netblock);
addr_tree_init(&infra->wait_limits_cookie_netblock);
if(!infra_wait_limit_netblock_insert(infra, cfg))
return 0;
d->limit = limit;
return 1;
}
int
setup_wait_limits(rbtree_type* wait_limits_netblock,
rbtree_type* wait_limits_cookie_netblock, struct config_file* cfg)
{
addr_tree_init(wait_limits_netblock);
addr_tree_init(wait_limits_cookie_netblock);
/* Insert defaults */
/* The loopback address is separated from the rest of the network. */
/* wait-limit-netblock: 127.0.0.0/8 -1 */
if(!wait_limit_netblock_default(wait_limits_netblock, "127.0.0.0/8",
-1))
return 0;
/* wait-limit-netblock: ::1/128 -1 */
if(!wait_limit_netblock_default(wait_limits_netblock, "::1/128", -1))
return 0;
/* wait-limit-cookie-netblock: 127.0.0.0/8 -1 */
if(!wait_limit_netblock_default(wait_limits_cookie_netblock,
"127.0.0.0/8", -1))
return 0;
/* wait-limit-cookie-netblock: ::1/128 -1 */
if(!wait_limit_netblock_default(wait_limits_cookie_netblock,
"::1/128", -1))
return 0;
if(!infra_wait_limit_netblock_insert(wait_limits_netblock,
wait_limits_cookie_netblock, cfg))
return 0;
addr_tree_init_parents(wait_limits_netblock);
addr_tree_init_parents(wait_limits_cookie_netblock);
addr_tree_init_parents(&infra->wait_limits_netblock);
addr_tree_init_parents(&infra->wait_limits_cookie_netblock);
return 1;
}
@@ -371,12 +348,11 @@ infra_create(struct config_file* cfg)
return NULL;
}
/* insert config data into ratelimits */
if(!setup_domain_limits(&infra->domain_limits, cfg)) {
if(!setup_domain_limits(infra, cfg)) {
infra_delete(infra);
return NULL;
}
if(!setup_wait_limits(&infra->wait_limits_netblock,
&infra->wait_limits_cookie_netblock, cfg)) {
if(!setup_wait_limits(infra, cfg)) {
infra_delete(infra);
return NULL;
}
@@ -401,29 +377,12 @@ static void domain_limit_free(rbnode_type* n, void* ATTR_UNUSED(arg))
}
}
void
domain_limits_free(struct rbtree_type* domain_limits)
{
if(!domain_limits)
return;
traverse_postorder(domain_limits, domain_limit_free, NULL);
}
/** delete wait_limit_netblock_info entries */
static void wait_limit_netblock_del(rbnode_type* n, void* ATTR_UNUSED(arg))
{
free(n);
}
void
wait_limits_free(struct rbtree_type* wait_limits_tree)
{
if(!wait_limits_tree)
return;
traverse_postorder(wait_limits_tree, wait_limit_netblock_del,
NULL);
}
void
infra_delete(struct infra_cache* infra)
{
@@ -431,10 +390,12 @@ infra_delete(struct infra_cache* infra)
return;
slabhash_delete(infra->hosts);
slabhash_delete(infra->domain_rates);
domain_limits_free(&infra->domain_limits);
traverse_postorder(&infra->domain_limits, domain_limit_free, NULL);
slabhash_delete(infra->client_ip_rates);
wait_limits_free(&infra->wait_limits_netblock);
wait_limits_free(&infra->wait_limits_cookie_netblock);
traverse_postorder(&infra->wait_limits_netblock,
wait_limit_netblock_del, NULL);
traverse_postorder(&infra->wait_limits_cookie_netblock,
wait_limit_netblock_del, NULL);
free(infra);
}
@@ -465,7 +426,7 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
/* reapply domain limits */
traverse_postorder(&infra->domain_limits, domain_limit_free,
NULL);
if(!setup_domain_limits(&infra->domain_limits, cfg)) {
if(!setup_domain_limits(infra, cfg)) {
infra_delete(infra);
return NULL;
}
@@ -707,7 +668,7 @@ infra_update_tcp_works(struct infra_cache* infra,
if(data->rtt.rto >= RTT_MAX_TIMEOUT)
/* do not disqualify this server altogether, it is better
* than nothing */
data->rtt.rto = still_useful_timeout();
data->rtt.rto = STILL_USEFUL_TIMEOUT;
lock_rw_unlock(&e->lock);
}
@@ -847,7 +808,7 @@ infra_get_lame_rtt(struct infra_cache* infra,
&& infra->infra_keep_probing) {
/* single probe, keep probing */
if(*rtt >= USEFUL_SERVER_TOP_TIMEOUT)
*rtt = still_useful_timeout();
*rtt = STILL_USEFUL_TIMEOUT;
} else if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay
&& rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) {
/* single probe for this domain, and we are not probing */
@@ -855,15 +816,15 @@ infra_get_lame_rtt(struct infra_cache* infra,
if(qtype == LDNS_RR_TYPE_A) {
if(host->timeout_A >= TIMEOUT_COUNT_MAX)
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
else *rtt = still_useful_timeout();
else *rtt = STILL_USEFUL_TIMEOUT;
} else if(qtype == LDNS_RR_TYPE_AAAA) {
if(host->timeout_AAAA >= TIMEOUT_COUNT_MAX)
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
else *rtt = still_useful_timeout();
else *rtt = STILL_USEFUL_TIMEOUT;
} else {
if(host->timeout_other >= TIMEOUT_COUNT_MAX)
*rtt = USEFUL_SERVER_TOP_TIMEOUT;
else *rtt = still_useful_timeout();
else *rtt = STILL_USEFUL_TIMEOUT;
}
}
/* expired entry */
@@ -871,7 +832,7 @@ infra_get_lame_rtt(struct infra_cache* infra,
/* see if this can be a re-probe of an unresponsive server */
if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
lock_rw_unlock(&e->lock);
*rtt = still_useful_timeout();
*rtt = STILL_USEFUL_TIMEOUT;
*lame = 0;
*dnsseclame = 0;
*reclame = 0;
@@ -1120,8 +1081,7 @@ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
lock_rw_unlock(&entry->lock);
if(premax <= lim && max > lim) {
char buf[LDNS_MAX_DOMAINLEN], qnm[LDNS_MAX_DOMAINLEN];
char ts[12], cs[12], ip[128];
char buf[257], qnm[257], ts[12], cs[12], ip[128];
dname_str(name, buf);
dname_str(qinfo->qname, qnm);
sldns_wire2str_type_buf(qinfo->qtype, ts, sizeof(ts));
-31
View File
@@ -52,19 +52,6 @@
struct slabhash;
struct config_file;
/** number of timeouts for a type when the domain can be blocked ;
* even if another type has completely rtt maxed it, the different type
* can do this number of packets (until those all timeout too) */
#define TIMEOUT_COUNT_MAX 3
/** Timeout when only a single probe query per IP is allowed.
* Any RTO above this number is considered a probe.
* It is synchronized (caped) with USEFUL_SERVER_TOP_TIMEOUT so that probing
* keeps working even if that configurable number drops below the default
* 12000 ms of probing. */
extern int PROBE_MAXRTO;
/**
* Host information kept for every server, per zone.
*/
@@ -515,22 +502,4 @@ void infra_wait_limit_inc(struct infra_cache* infra, struct comm_reply* rep,
void infra_wait_limit_dec(struct infra_cache* infra, struct comm_reply* rep,
struct config_file* cfg);
/** setup wait limits tree (0 on failure) */
int setup_wait_limits(struct rbtree_type* wait_limits_netblock,
struct rbtree_type* wait_limits_cookie_netblock,
struct config_file* cfg);
/** Free the wait limits and wait cookie limits tree. */
void wait_limits_free(struct rbtree_type* wait_limits_tree);
/** setup domain limits tree (0 on failure) */
int setup_domain_limits(struct rbtree_type* domain_limits,
struct config_file* cfg);
/** Free the domain limits tree. */
void domain_limits_free(struct rbtree_type* domain_limits);
/** exported for unit test */
int still_useful_timeout();
#endif /* SERVICES_CACHE_INFRA_H */
+5 -7
View File
@@ -68,8 +68,6 @@ struct rrset_cache* rrset_cache_create(struct config_file* cfg,
struct rrset_cache *r = (struct rrset_cache*)slabhash_create(slabs,
startarray, maxmem, ub_rrset_sizefunc, ub_rrset_compare,
ub_rrset_key_delete, rrset_data_delete, alloc);
if(!r)
return NULL;
slabhash_setmarkdel(&r->table, &rrset_markdel);
return r;
}
@@ -130,8 +128,8 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
{
struct packed_rrset_data* newd = (struct packed_rrset_data*)nd;
struct packed_rrset_data* cached = (struct packed_rrset_data*)cd;
/* o if new data is expired, cached data is better */
if( newd->ttl < timenow && timenow <= cached->ttl)
/* o if new data is expired, current data is better */
if( newd->ttl < timenow && cached->ttl >= timenow)
return 0;
/* o store if rrset has been validated
* everything better than bogus data
@@ -142,9 +140,9 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
if( cached->security == sec_status_bogus &&
newd->security != sec_status_bogus && !equal)
return 1;
/* o if new RRset is more trustworthy - insert it */
/* o if current RRset is more trustworthy - insert it */
if( newd->trust > cached->trust ) {
/* if the cached rrset is bogus, and new is equal,
/* if the cached rrset is bogus, and this one equal,
* do not update the TTL - let it expire. */
if(equal && cached->ttl >= timenow &&
cached->security == sec_status_bogus)
@@ -157,7 +155,7 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
/* o same trust, but different in data - insert it */
if( newd->trust == cached->trust && !equal ) {
/* if this is type NS, do not 'stick' to owner that changes
* the NS RRset, but use the cached TTL for the new data, and
* the NS RRset, but use the old TTL for the new data, and
* update to fetch the latest data. ttl is not expired, because
* that check was before this one. */
if(ns) {
+90 -2610
View File
File diff suppressed because it is too large Load Diff
+5 -416
View File
@@ -43,19 +43,10 @@
#define LISTEN_DNSPORT_H
#include "util/netevent.h"
#include "util/rbtree.h"
#include "util/locks.h"
#include "daemon/acl_list.h"
#ifdef HAVE_NGHTTP2_NGHTTP2_H
#include <nghttp2/nghttp2.h>
#endif
#ifdef HAVE_NGTCP2
#include <ngtcp2/ngtcp2.h>
#include <ngtcp2/ngtcp2_crypto.h>
#ifdef USE_NGTCP2_CRYPTO_OSSL
struct ngtcp2_crypto_ossl_ctx;
#endif
#endif
struct listen_list;
struct config_file;
struct addrinfo;
@@ -109,9 +100,7 @@ enum listen_type {
/** udp ipv6 (v4mapped) for use with ancillary data + dnscrypt*/
listen_type_udpancil_dnscrypt,
/** HTTP(2) over TLS over TCP */
listen_type_http,
/** DNS over QUIC */
listen_type_doq
listen_type_http
};
/*
@@ -197,13 +186,8 @@ int resolve_interface_names(char** ifs, int num_ifs,
* @param http_endpoint: HTTP endpoint to service queries on
* @param http_notls: no TLS for http downstream
* @param tcp_conn_limit: TCP connection limit info.
* @param dot_sslctx: nonNULL if dot ssl context.
* @param doh_sslctx: nonNULL if doh ssl context.
* @param quic_sslctx: nonNULL if quic ssl context.
* @param sslctx: nonNULL if ssl context.
* @param dtenv: nonNULL if dnstap enabled.
* @param doq_table: the doq connection table, with shared information.
* @param rnd: random state.
* @param cfg: config file struct.
* @param cb: callback function when a request arrives. It is passed
* the packet and user argument. Return true to send a reply.
* @param cb_arg: user data argument for callback function.
@@ -214,11 +198,8 @@ listen_create(struct comm_base* base, struct listen_port* ports,
size_t bufsize, int tcp_accept_count, int tcp_idle_timeout,
int harden_large_queries, uint32_t http_max_streams,
char* http_endpoint, int http_notls, struct tcl_list* tcp_conn_limit,
void* dot_sslctx, void* doh_sslctx, void* quic_sslctx,
struct dt_env* dtenv,
struct doq_table* doq_table,
struct ub_randstate* rnd,struct config_file* cfg,
comm_point_callback_type* cb, void *cb_arg);
void* sslctx, struct dt_env* dtenv, comm_point_callback_type* cb,
void *cb_arg);
/**
* delete the listening structure
@@ -297,12 +278,11 @@ int create_udp_sock(int family, int socktype, struct sockaddr* addr,
* @param freebind: set IP_FREEBIND socket option.
* @param use_systemd: if true, fetch sockets from systemd.
* @param dscp: DSCP to use.
* @param additional: additional log information for the socket type.
* @return: the socket. -1 on error.
*/
int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
int* reuseport, int transparent, int mss, int nodelay, int freebind,
int use_systemd, int dscp, const char* additional);
int use_systemd, int dscp);
/**
* Create and bind local listening socket
@@ -472,387 +452,6 @@ int http2_submit_dns_response(struct http2_session* h2_session);
int http2_submit_dns_response(void* v);
#endif /* HAVE_NGHTTP2 */
#ifdef HAVE_NGTCP2
struct doq_conid;
struct doq_server_socket;
/**
* DoQ shared connection table. This is the connections for the host.
* And some config parameter values for connections. The host has to
* respond on that ip,port for those connections, so they are shared
* between threads.
*/
struct doq_table {
/** the lock on the tree and config elements. insert and deletion,
* also lookup in the tree needs to hold the lock. */
lock_rw_type lock;
/** rbtree of doq_conn, the connections to different destination
* addresses, and can be found by dcid. */
struct rbtree_type* conn_tree;
/** lock for the conid tree, needed for the conid tree and also
* the conid elements */
lock_rw_type conid_lock;
/** rbtree of doq_conid, connections can be found by their
* connection ids. Lookup by connection id, finds doq_conn. */
struct rbtree_type* conid_tree;
/** the server scid length */
int sv_scidlen;
/** the static secret for the server */
uint8_t* static_secret;
/** length of the static secret */
size_t static_secret_len;
/** the idle timeout in nanoseconds */
uint64_t idle_timeout;
/** the list of write interested connections, hold the doq_table.lock
* to change them */
struct doq_conn* write_list_first, *write_list_last;
/** rbtree of doq_timer. */
struct rbtree_type* timer_tree;
/** lock on the current_size counter. */
lock_basic_type size_lock;
/** current use, in bytes, of QUIC buffers.
* The doq_conn ngtcp2_conn structure, SSL structure and conid structs
* are not counted. */
size_t current_size;
};
/**
* create SSL context for QUIC
* @param key: private key file.
* @param pem: public key cert.
* @param verifypem: if nonNULL, verifylocation file.
* return SSL_CTX* or NULL on failure (logged).
*/
void* quic_sslctx_create(char* key, char* pem, char* verifypem);
/** create doq table */
struct doq_table* doq_table_create(struct config_file* cfg,
struct ub_randstate* rnd);
/** delete doq table */
void doq_table_delete(struct doq_table* table);
/**
* Timer information for doq timer.
*/
struct doq_timer {
/** The rbnode in the tree sorted by timeout value. Key this struct. */
struct rbnode_type node;
/** The timeout value. Absolute time value. */
struct timeval time;
/** If the timer is in the time tree, with the node. */
int timer_in_tree;
/** If there are more timers with the exact same timeout value,
* they form a set of timers. The rbnode timer has a link to the list
* with the other timers in the set. The rbnode timer is not a
* member of the list with the other timers. The other timers are not
* linked into the tree. */
struct doq_timer* setlist_first, *setlist_last;
/** If the timer is on the setlist. */
int timer_in_list;
/** If in the setlist, the next and prev element. */
struct doq_timer* setlist_next, *setlist_prev;
/** The connection that is timeouted. */
struct doq_conn* conn;
/** The worker that is waiting for the timeout event.
* Set for the rbnode tree linked element. If a worker is waiting
* for the event. If NULL, no worker is waiting for this timeout. */
struct doq_server_socket* worker_doq_socket;
};
/**
* Key information that makes a doq_conn node in the tree lookup.
*/
struct doq_conn_key {
/** the remote endpoint and local endpoint and ifindex */
struct doq_pkt_addr paddr;
/** the doq connection dcid */
uint8_t* dcid;
/** length of dcid */
size_t dcidlen;
};
/**
* DoQ connection, for DNS over QUIC. One connection to a remote endpoint
* with a number of streams in it. Every stream is like a tcp stream with
* a uint16_t length, query read, and a uint16_t length and answer written.
*/
struct doq_conn {
/** rbtree node, key is addresses and dcid */
struct rbnode_type node;
/** lock on the connection */
lock_basic_type lock;
/** the key information, with dcid and address endpoint */
struct doq_conn_key key;
/** the doq server socket for inside callbacks */
struct doq_server_socket* doq_socket;
/** the doq table this connection is part of */
struct doq_table* table;
/** if the connection is about to be deleted. */
uint8_t is_deleted;
/** the version, the client chosen version of QUIC */
uint32_t version;
/** the ngtcp2 connection, a server connection */
struct ngtcp2_conn* conn;
/** the connection ids that are associated with this doq_conn.
* There can be a number, that can change. They are linked here,
* so that upon removal, the list of actually associated conid
* elements can be removed as well. */
struct doq_conid* conid_list;
/** the ngtcp2 last error for the connection */
#ifdef HAVE_NGTCP2_CCERR_DEFAULT
struct ngtcp2_ccerr ccerr;
#else
struct ngtcp2_connection_close_error last_error;
#endif
/** the recent tls alert error code */
uint8_t tls_alert;
/** the ssl context, SSL* */
void* ssl;
#if defined(USE_NGTCP2_CRYPTO_OSSL) || defined(HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT)
/** the connection reference for ngtcp2_conn and userdata in ssl */
struct ngtcp2_crypto_conn_ref conn_ref;
#endif
#ifdef USE_NGTCP2_CRYPTO_OSSL
/** the per-connection state for ngtcp2_crypto_ossl */
struct ngtcp2_crypto_ossl_ctx* ossl_ctx;
#endif
/** closure packet, if any */
uint8_t* close_pkt;
/** length of closure packet. */
size_t close_pkt_len;
/** closure ecn */
uint32_t close_ecn;
/** the streams for this connection, of type doq_stream */
struct rbtree_type stream_tree;
/** the streams that want write, they have something to write.
* The list is ordered, the last have to wait for the first to
* get their data written. */
struct doq_stream* stream_write_first, *stream_write_last;
/** the conn has write interest if true, no write interest if false. */
uint8_t write_interest;
/** if the conn is on the connection write list */
uint8_t on_write_list;
/** the connection write list prev and next, if on the write list */
struct doq_conn* write_prev, *write_next;
/** The timer for the connection. If unused, it is not in the tree
* and not in the list. It is alloced here, so that it is prealloced.
* It has to be set after every read and write on the connection, so
* this improves performance, but also the allocation does not fail. */
struct doq_timer timer;
};
/**
* Connection ID and the doq_conn that is that connection. A connection
* has an original dcid, and then more connection ids associated.
*/
struct doq_conid {
/** rbtree node, key is the connection id. */
struct rbnode_type node;
/** the next and prev in the list of conids for the doq_conn */
struct doq_conid* next, *prev;
/** key to the doq_conn that is the connection */
struct doq_conn_key key;
/** the connection id, byte string */
uint8_t* cid;
/** the length of cid */
size_t cidlen;
};
/**
* DoQ stream, for DNS over QUIC.
*/
struct doq_stream {
/** the rbtree node for the stream, key is the stream_id */
rbnode_type node;
/** the stream id */
int64_t stream_id;
/** if the stream is closed */
uint8_t is_closed;
/** if the query is complete */
uint8_t is_query_complete;
/** the number of bytes read on the stream, up to querylen+2. */
size_t nread;
/** the length of the input query bytes */
size_t inlen;
/** the input bytes */
uint8_t* in;
/** does the stream have an answer to send */
uint8_t is_answer_available;
/** the answer bytes sent, up to outlen+2. */
size_t nwrite;
/** the length of the output answer bytes */
size_t outlen;
/** the output length in network wireformat */
uint16_t outlen_wire;
/** the output packet bytes */
uint8_t* out;
/** if the stream is on the write list */
uint8_t on_write_list;
/** the prev and next on the write list, if on the list */
struct doq_stream* write_prev, *write_next;
};
/** doq application error code that is sent when a stream is closed */
#define DOQ_APP_ERROR_CODE 1
/**
* Create the doq connection.
* @param c: the comm point for the listening doq socket.
* @param paddr: with remote and local address and ifindex for the
* connection destination. This is where packets are sent.
* @param dcid: the dcid, Destination Connection ID.
* @param dcidlen: length of dcid.
* @param version: client chosen version.
* @return new doq connection or NULL on allocation failure.
*/
struct doq_conn* doq_conn_create(struct comm_point* c,
struct doq_pkt_addr* paddr, const uint8_t* dcid, size_t dcidlen,
uint32_t version);
/**
* Delete the doq connection structure.
* @param conn: to delete.
* @param table: with memory size.
*/
void doq_conn_delete(struct doq_conn* conn, struct doq_table* table);
/** compare function of doq_conn */
int doq_conn_cmp(const void* key1, const void* key2);
/** compare function of doq_conid */
int doq_conid_cmp(const void* key1, const void* key2);
/** compare function of doq_timer */
int doq_timer_cmp(const void* key1, const void* key2);
/** compare function of doq_stream */
int doq_stream_cmp(const void* key1, const void* key2);
/** setup the doq connection callbacks, and settings. */
int doq_conn_setup(struct doq_conn* conn, uint8_t* scid, size_t scidlen,
uint8_t* ocid, size_t ocidlen, const uint8_t* token, size_t tokenlen);
/** fill a buffer with random data */
void doq_fill_rand(struct ub_randstate* rnd, uint8_t* buf, size_t len);
/** delete a doq_conid */
void doq_conid_delete(struct doq_conid* conid);
/** add a connection id to the doq_conn.
* caller must hold doq_table.conid_lock. */
int doq_conn_associate_conid(struct doq_conn* conn, uint8_t* data,
size_t datalen);
/** remove a connection id from the doq_conn.
* caller must hold doq_table.conid_lock. */
void doq_conn_dissociate_conid(struct doq_conn* conn, const uint8_t* data,
size_t datalen);
/** initial setup to link current connection ids to the doq_conn */
int doq_conn_setup_conids(struct doq_conn* conn);
/** remove the connection ids from the doq_conn.
* caller must hold doq_table.conid_lock. */
void doq_conn_clear_conids(struct doq_conn* conn);
/** find a conid in the doq_conn connection.
* caller must hold table.conid_lock. */
struct doq_conid* doq_conid_find(struct doq_table* doq_table,
const uint8_t* data, size_t datalen);
/** receive a packet for a connection */
int doq_conn_recv(struct comm_point* c, struct doq_pkt_addr* paddr,
struct doq_conn* conn, struct ngtcp2_pkt_info* pi, int* err_retry,
int* err_drop);
/** send packets for a connection */
int doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
int* err_drop);
/** send the close packet for the connection, perhaps again. */
int doq_conn_send_close(struct comm_point* c, struct doq_conn* conn);
/** delete doq stream */
void doq_stream_delete(struct doq_stream* stream);
/** doq read a connection key from repinfo. It is not malloced, but points
* into the repinfo for the dcid. */
void doq_conn_key_from_repinfo(struct doq_conn_key* key,
struct comm_reply* repinfo);
/** doq find a stream in the connection */
struct doq_stream* doq_stream_find(struct doq_conn* conn, int64_t stream_id);
/** doq shutdown the stream. */
int doq_stream_close(struct doq_conn* conn, struct doq_stream* stream,
int send_shutdown);
/** send reply for a connection */
int doq_stream_send_reply(struct doq_conn* conn, struct doq_stream* stream,
struct sldns_buffer* buf);
/** the connection has write interest, wants to write packets */
void doq_conn_write_enable(struct doq_conn* conn);
/** the connection has no write interest, does not want to write packets */
void doq_conn_write_disable(struct doq_conn* conn);
/** set the connection on or off the write list, depending on write interest */
void doq_conn_set_write_list(struct doq_table* table, struct doq_conn* conn);
/** doq remove the connection from the write list */
void doq_conn_write_list_remove(struct doq_table* table,
struct doq_conn* conn);
/** doq get the first conn from the write list, if any, popped from list.
* Locks the conn that is returned. */
struct doq_conn* doq_table_pop_first(struct doq_table* table);
/**
* doq check if the timer for the conn needs to be changed.
* @param conn: connection, caller must hold lock on it.
* @param tv: time value, absolute time, returned.
* @return true if timer needs to be set to tv, false if no change is needed
* to the timer. The timer is already set to the right time in that case.
*/
int doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv);
/** doq remove timer from tree */
void doq_timer_tree_remove(struct doq_table* table, struct doq_timer* timer);
/** doq remove timer from list */
void doq_timer_list_remove(struct doq_table* table, struct doq_timer* timer);
/** doq unset the timer if it was set. */
void doq_timer_unset(struct doq_table* table, struct doq_timer* timer);
/** doq set the timer and add it. */
void doq_timer_set(struct doq_table* table, struct doq_timer* timer,
struct doq_server_socket* worker_doq_socket, struct timeval* tv);
/** doq find a timeout in the timer tree */
struct doq_timer* doq_timer_find_time(struct doq_table* table,
struct timeval* tv);
/** doq handle timeout for a connection. Pass conn locked. Returns false for
* deletion. */
int doq_conn_handle_timeout(struct doq_conn* conn);
/** doq add size to the current quic buffer counter */
void doq_table_quic_size_add(struct doq_table* table, size_t add);
/** doq subtract size from the current quic buffer counter */
void doq_table_quic_size_subtract(struct doq_table* table, size_t subtract);
/** doq check if mem is available for quic. */
int doq_table_quic_size_available(struct doq_table* table,
struct config_file* cfg, size_t mem);
/** doq get the quic size value */
size_t doq_table_quic_size_get(struct doq_table* table);
#endif /* HAVE_NGTCP2 */
char* set_ip_dscp(int socket, int addrfamily, int ds);
/** for debug and profiling purposes only
@@ -860,14 +459,4 @@ char* set_ip_dscp(int socket, int addrfamily, int ds);
*/
void verbose_print_unbound_socket(struct unbound_socket* ub_sock);
/** event callback for testcode/doqclient */
void doq_client_event_cb(int fd, short event, void* arg);
/** timer event callback for testcode/doqclient */
void doq_client_timer_cb(int fd, short event, void* arg);
#ifdef HAVE_NGTCP2
/** get a timestamp in nanoseconds */
ngtcp2_tstamp doq_get_timestamp_nanosec(void);
#endif
#endif /* LISTEN_DNSPORT_H */
+4 -46
View File
@@ -223,7 +223,7 @@ lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len,
lock_rw_wrlock(&z->lock);
if(!rbtree_insert(&zones->ztree, &z->node)) {
struct local_zone* oldz;
char str[LDNS_MAX_DOMAINLEN];
char str[256];
dname_str(nm, str);
log_warn("duplicate local-zone %s", str);
lock_rw_unlock(&z->lock);
@@ -943,16 +943,6 @@ int local_zone_enter_defaults(struct local_zones* zones, struct config_file* cfg
log_err("out of memory adding default zone");
return 0;
}
/* resolver.arpa. zone (RFC 9462) */
if(!add_empty_default(zones, cfg, "resolver.arpa.")) {
log_err("out of memory adding default zone");
return 0;
}
/* service.arpa. zone (draft-ietf-dnssd-srp-25) */
if(!add_empty_default(zones, cfg, "service.arpa.")) {
log_err("out of memory adding default zone");
return 0;
}
/* onion. zone (RFC 7686) */
if(!add_empty_default(zones, cfg, "onion.")) {
log_err("out of memory adding default zone");
@@ -1775,7 +1765,7 @@ lz_inform_print(struct local_zone* z, struct query_info* qinfo,
struct sockaddr_storage* addr, socklen_t addrlen)
{
char ip[128], txt[512];
char zname[LDNS_MAX_DOMAINLEN];
char zname[LDNS_MAX_DOMAINLEN+1];
uint16_t port = ntohs(((struct sockaddr_in*)addr)->sin_port);
dname_str(z->name, zname);
addr_to_str(addr, addrlen, ip, sizeof(ip));
@@ -1885,7 +1875,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
return 0;
}
if(z && verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(z->name, zname);
verbose(VERB_ALGO, "using localzone %s %s from view %s",
zname, local_zone_type2str(lzt), view->name);
@@ -1907,7 +1897,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
z->override_tree, &tag, tagname, num_tags);
lock_rw_unlock(&zones->lock);
if(z && verbosity >= VERB_ALGO) {
char zname[LDNS_MAX_DOMAINLEN];
char zname[255+1];
dname_str(z->name, zname);
verbose(VERB_ALGO, "using localzone %s %s", zname,
local_zone_type2str(lzt));
@@ -2220,35 +2210,3 @@ void local_zones_del_data(struct local_zones* zones,
lock_rw_unlock(&z->lock);
}
/** Get memory usage for local_zone */
static size_t
local_zone_get_mem(struct local_zone* z)
{
size_t m = sizeof(*z);
lock_rw_rdlock(&z->lock);
m += z->namelen + z->taglen + regional_get_mem(z->region);
lock_rw_unlock(&z->lock);
return m;
}
size_t local_zones_get_mem(struct local_zones* zones)
{
struct local_zone* z;
size_t m;
if(!zones) return 0;
m = sizeof(*zones);
lock_rw_rdlock(&zones->lock);
RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
m += local_zone_get_mem(z);
}
lock_rw_unlock(&zones->lock);
return m;
}
void local_zones_swap_tree(struct local_zones* zones, struct local_zones* data)
{
rbtree_type oldtree = zones->ztree;
zones->ztree = data->ztree;
data->ztree = oldtree;
}
-14
View File
@@ -642,20 +642,6 @@ local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
struct local_data*
local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs);
/** Get memory usage for local_zones tree. The routine locks and unlocks
* the tree for reading. */
size_t local_zones_get_mem(struct local_zones* zones);
/**
* Swap internal tree with preallocated entries. Caller should manage
* the locks.
* @param zones: the local zones structure.
* @param data: the data structure used to take elements from. This contains
* the old elements on return.
*/
void local_zones_swap_tree(struct local_zones* zones,
struct local_zones* data);
/** Enter a new zone; returns with WRlock
* Made public for unit testing
* @param zones: the local zones tree
+25 -292
View File
@@ -77,20 +77,6 @@
#include <netdb.h>
#endif
/** Compare two views by name */
static int
view_name_compare(const char* v_a, const char* v_b)
{
if(v_a == NULL && v_b == NULL)
return 0;
/* The NULL name is smaller than if the name is set. */
if(v_a == NULL)
return -1;
if(v_b == NULL)
return 1;
return strcmp(v_a, v_b);
}
/**
* Compare two response-ip client info entries for the purpose of mesh state
* compare. It returns 0 if ci_a and ci_b are considered equal; otherwise
@@ -146,14 +132,12 @@ client_info_compare(const struct respip_client_info* ci_a,
}
if(ci_a->tag_datas != ci_b->tag_datas)
return ci_a->tag_datas < ci_b->tag_datas ? -1 : 1;
if(ci_a->view || ci_a->view_name || ci_b->view || ci_b->view_name) {
/* Compare the views by name. */
cmp = view_name_compare(
(ci_a->view?ci_a->view->name:ci_a->view_name),
(ci_b->view?ci_b->view->name:ci_b->view_name));
if(cmp != 0)
return cmp;
}
if(ci_a->view != ci_b->view)
return ci_a->view < ci_b->view ? -1 : 1;
/* For the unbound daemon these should be non-NULL and identical,
* but we check that just in case. */
if(ci_a->respip_set != ci_b->respip_set)
return ci_a->respip_set < ci_b->respip_set ? -1 : 1;
return 0;
}
@@ -230,9 +214,6 @@ mesh_create(struct module_stack* stack, struct module_env* env)
mesh->stats_dropped = 0;
mesh->ans_expired = 0;
mesh->ans_cachedb = 0;
mesh->num_queries_discard_timeout = 0;
mesh->num_queries_wait_limit = 0;
mesh->num_dns_error_reports = 0;
mesh->max_reply_states = env->cfg->num_queries_per_thread;
mesh->max_forever_states = (mesh->max_reply_states+1)/2;
#ifndef S_SPLINT_S
@@ -330,7 +311,7 @@ int mesh_make_new_space(struct mesh_area* mesh, sldns_buffer* qbuf)
struct dns_msg*
mesh_serve_expired_lookup(struct module_qstate* qstate,
struct query_info* lookup_qinfo, int* is_expired)
struct query_info* lookup_qinfo)
{
hashvalue_type h;
struct lruhash_entry* e;
@@ -340,7 +321,6 @@ mesh_serve_expired_lookup(struct module_qstate* qstate,
time_t timenow = *qstate->env->now;
int must_validate = (!(qstate->query_flags&BIT_CD)
|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
*is_expired = 0;
/* Lookup cache */
h = query_info_hash(lookup_qinfo, qstate->query_flags);
e = slabhash_lookup(qstate->env->msg_cache, h, lookup_qinfo, 0);
@@ -348,7 +328,6 @@ mesh_serve_expired_lookup(struct module_qstate* qstate,
key = (struct msgreply_entry*)e->key;
data = (struct reply_info*)e->data;
if(data->ttl < timenow) *is_expired = 1;
msg = tomsg(qstate->env, &key->key, data, qstate->region, timenow,
qstate->env->cfg->serve_expired, qstate->env->scratch);
if(!msg)
@@ -443,7 +422,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
verbose(VERB_ALGO, "Too many queries waiting from the IP. "
"dropping incoming query.");
comm_point_drop_reply(rep);
mesh->num_queries_wait_limit++;
mesh->stats_dropped++;
return;
}
if(!unique)
@@ -887,78 +866,6 @@ void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
mesh_run(mesh, e->qstate->mesh_info, event, e);
}
/** copy strlist to region */
static struct config_strlist*
cfg_region_strlist_copy(struct regional* region, struct config_strlist* list)
{
struct config_strlist* result = NULL, *last = NULL, *s = list;
while(s) {
struct config_strlist* n = regional_alloc_zero(region,
sizeof(*n));
if(!n)
return NULL;
n->str = regional_strdup(region, s->str);
if(!n->str)
return NULL;
if(last)
last->next = n;
else result = n;
last = n;
s = s->next;
}
return result;
}
/** Copy the client info to the query region. */
static struct respip_client_info*
mesh_copy_client_info(struct regional* region, struct respip_client_info* cinfo)
{
size_t i;
struct respip_client_info* client_info;
client_info = regional_alloc_init(region, cinfo, sizeof(*cinfo));
if(!client_info)
return NULL;
/* Copy the client_info so that if the configuration changes,
* then the data stays valid. */
if(cinfo->taglist) {
client_info->taglist = regional_alloc_init(region, cinfo->taglist,
cinfo->taglen);
if(!client_info->taglist)
return NULL;
}
if(cinfo->tag_actions) {
client_info->tag_actions = regional_alloc_init(region, cinfo->tag_actions,
cinfo->tag_actions_size);
if(!client_info->tag_actions)
return NULL;
}
if(cinfo->tag_datas) {
client_info->tag_datas = regional_alloc_zero(region,
sizeof(struct config_strlist*)*cinfo->tag_datas_size);
if(!client_info->tag_datas)
return NULL;
for(i=0; i<cinfo->tag_datas_size; i++) {
if(cinfo->tag_datas[i]) {
client_info->tag_datas[i] = cfg_region_strlist_copy(
region, cinfo->tag_datas[i]);
if(!client_info->tag_datas[i])
return NULL;
}
}
}
if(cinfo->view) {
/* Do not copy the view pointer but store a name instead.
* The name is looked up later when done, this means that
* the view tree can be changed, by reloads. */
client_info->view = NULL;
client_info->view_name = regional_strdup(region,
cinfo->view->name);
if(!client_info->view_name)
return NULL;
}
return client_info;
}
struct mesh_state*
mesh_state_create(struct module_env* env, struct query_info* qinfo,
struct respip_client_info* cinfo, uint16_t qflags, int prime,
@@ -999,7 +906,8 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
return NULL;
}
if(cinfo) {
mstate->s.client_info = mesh_copy_client_info(region, cinfo);
mstate->s.client_info = regional_alloc_init(region, cinfo,
sizeof(*cinfo));
if(!mstate->s.client_info) {
alloc_reg_release(env->alloc, region);
return NULL;
@@ -1579,121 +1487,10 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
&r->query_reply.client_addr,
r->query_reply.client_addrlen, duration, 0, r_buffer,
(m->s.env->cfg->log_destaddr?(void*)r->query_reply.c->socket->addr:NULL),
r->query_reply.c->type, r->query_reply.c->ssl);
r->query_reply.c->type);
}
}
/**
* Generate the DNS Error Report (RFC9567).
* If there is an EDE attached for this reply and there was a Report-Channel
* EDNS0 option from the upstream, fire up a report query.
* @param qstate: module qstate.
* @param rep: prepared reply to be sent.
*/
static void dns_error_reporting(struct module_qstate* qstate,
struct reply_info* rep)
{
struct query_info qinfo;
struct mesh_state* sub;
struct module_qstate* newq;
uint8_t buf[LDNS_MAX_DOMAINLEN];
size_t count = 0;
int written;
size_t expected_length;
struct edns_option* opt;
sldns_ede_code reason_bogus = LDNS_EDE_NONE;
sldns_rr_type qtype = qstate->qinfo.qtype;
uint8_t* qname = qstate->qinfo.qname;
size_t qname_len = qstate->qinfo.qname_len-1; /* skip the trailing \0 */
uint8_t* agent_domain;
size_t agent_domain_len;
/* We need a valid reporting agent;
* this is based on qstate->edns_opts_back_in that will probably have
* the latest reporting agent we found while iterating */
opt = edns_opt_list_find(qstate->edns_opts_back_in,
LDNS_EDNS_REPORT_CHANNEL);
if(!opt) return;
agent_domain_len = opt->opt_len;
agent_domain = opt->opt_data;
if(dname_valid(agent_domain, agent_domain_len) < 3) {
/* The agent domain needs to be a valid dname that is not the
* root; from RFC9567. */
return;
}
/* Get the EDE generated from the mesh state, these are mostly
* validator errors. If other errors are produced in the future (e.g.,
* RPZ) we would not want them to result in error reports. */
reason_bogus = errinf_to_reason_bogus(qstate);
if(rep && ((reason_bogus == LDNS_EDE_DNSSEC_BOGUS &&
rep->reason_bogus != LDNS_EDE_NONE) ||
reason_bogus == LDNS_EDE_NONE)) {
reason_bogus = rep->reason_bogus;
}
if(reason_bogus == LDNS_EDE_NONE ||
/* other, does not make sense without the text that comes
* with it */
reason_bogus == LDNS_EDE_OTHER) return;
/* Synthesize the error report query in the format:
* "_er.$qtype.$qname.$ede._er.$reporting-agent-domain" */
/* First check if the static length parts fit in the buffer.
* That is everything except for qtype and ede that need to be
* converted to decimal and checked further on. */
expected_length = 4/*_er*/+qname_len+4/*_er*/+agent_domain_len;
if(expected_length > LDNS_MAX_DOMAINLEN) goto skip;
memmove(buf+count, "\3_er", 4);
count += 4;
written = snprintf((char*)buf+count, LDNS_MAX_DOMAINLEN-count,
"X%d", qtype);
expected_length += written;
/* Skip on error, truncation or long expected length */
if(written < 0 || (size_t)written >= LDNS_MAX_DOMAINLEN-count ||
expected_length > LDNS_MAX_DOMAINLEN ) goto skip;
/* Put in the label length */
*(buf+count) = (char)(written - 1);
count += written;
memmove(buf+count, qname, qname_len);
count += qname_len;
written = snprintf((char*)buf+count, LDNS_MAX_DOMAINLEN-count,
"X%d", reason_bogus);
expected_length += written;
/* Skip on error, truncation or long expected length */
if(written < 0 || (size_t)written >= LDNS_MAX_DOMAINLEN-count ||
expected_length > LDNS_MAX_DOMAINLEN ) goto skip;
*(buf+count) = (char)(written - 1);
count += written;
memmove(buf+count, "\3_er", 4);
count += 4;
/* Copy the agent domain */
memmove(buf+count, agent_domain, agent_domain_len);
count += agent_domain_len;
qinfo.qname = buf;
qinfo.qname_len = count;
qinfo.qtype = LDNS_RR_TYPE_TXT;
qinfo.qclass = qstate->qinfo.qclass;
qinfo.local_alias = NULL;
log_query_info(VERB_ALGO, "DNS Error Reporting: generating report "
"query for", &qinfo);
if(mesh_add_sub(qstate, &qinfo, BIT_RD, 0, 0, &newq, &sub)) {
qstate->env->mesh->num_dns_error_reports++;
}
return;
skip:
verbose(VERB_ALGO, "DNS Error Reporting: report query qname too long; "
"skip");
return;
}
void mesh_query_done(struct mesh_state* mstate)
{
struct mesh_reply* r;
@@ -1711,10 +1508,8 @@ void mesh_query_done(struct mesh_state* mstate)
}
if(mstate->s.return_rcode == LDNS_RCODE_SERVFAIL ||
(rep && FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_SERVFAIL)) {
if(mstate->s.env->cfg->serve_expired) {
/* we are SERVFAILing; check for expired answer here */
mesh_respond_serve_expired(mstate);
}
/* we are SERVFAILing; check for expired answer here */
mesh_serve_expired_callback(mstate);
if((mstate->reply_list || mstate->cb_list)
&& mstate->s.env->cfg->log_servfail
&& !mstate->s.env->cfg->val_log_squelch) {
@@ -1722,10 +1517,6 @@ void mesh_query_done(struct mesh_state* mstate)
if(err) { log_err("%s", err); }
}
}
if(mstate->reply_list && mstate->s.env->cfg->dns_error_reporting)
dns_error_reporting(&mstate->s, rep);
for(r = mstate->reply_list; r; r = r->next) {
struct timeval old;
timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time);
@@ -1747,7 +1538,7 @@ void mesh_query_done(struct mesh_state* mstate)
http2_stream_remove_mesh_state(r->h2_stream);
comm_point_drop_reply(&r->query_reply);
mstate->reply_list = reply_list;
mstate->s.env->mesh->num_queries_discard_timeout++;
mstate->s.env->mesh->stats_dropped++;
continue;
}
@@ -1889,25 +1680,6 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
return result;
}
/** remove mesh state callback */
int mesh_state_del_cb(struct mesh_state* s, mesh_cb_func_type cb, void* cb_arg)
{
struct mesh_cb* r, *prev = NULL;
r = s->cb_list;
while(r) {
if(r->cb == cb && r->cb_arg == cb_arg) {
/* Delete this entry. */
/* It was allocated in the s.region, so no free. */
if(prev) prev->next = r->next;
else s->cb_list = r->next;
return 1;
}
prev = r;
r = r->next;
}
return 0;
}
int mesh_state_add_cb(struct mesh_state* s, struct edns_data* edns,
sldns_buffer* buf, mesh_cb_func_type cb, void* cb_arg,
uint16_t qid, uint16_t qflags)
@@ -2255,8 +2027,6 @@ mesh_stats_clear(struct mesh_area* mesh)
{
if(!mesh)
return;
mesh->num_query_authzone_up = 0;
mesh->num_query_authzone_down = 0;
mesh->replies_sent = 0;
mesh->replies_sum_wait.tv_sec = 0;
mesh->replies_sum_wait.tv_usec = 0;
@@ -2265,15 +2035,11 @@ mesh_stats_clear(struct mesh_area* mesh)
timehist_clear(mesh->histogram);
mesh->ans_secure = 0;
mesh->ans_bogus = 0;
mesh->val_ops = 0;
mesh->ans_expired = 0;
mesh->ans_cachedb = 0;
memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*UB_STATS_RCODE_NUM);
memset(&mesh->rpz_action[0], 0, sizeof(size_t)*UB_STATS_RPZ_ACTION_NUM);
mesh->ans_nodata = 0;
mesh->num_queries_discard_timeout = 0;
mesh->num_queries_wait_limit = 0;
mesh->num_dns_error_reports = 0;
}
size_t
@@ -2375,8 +2141,7 @@ apply_respip_action(struct module_qstate* qstate,
return 1;
if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, actinfo,
alias_rrset, 0, qstate->region, az, NULL, qstate->env->views,
qstate->env->respip_set))
alias_rrset, 0, qstate->region, az, NULL))
return 0;
/* xxx_deny actions mean dropping the reply, unless the original reply
@@ -2410,8 +2175,7 @@ mesh_serve_expired_callback(void* arg)
struct timeval tv = {0, 0};
int must_validate = (!(qstate->query_flags&BIT_CD)
|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
int i = 0, for_count;
int is_expired;
int i = 0;
if(!qstate->serve_expired_data) return;
verbose(VERB_ALGO, "Serve expired: Trying to reply with expired data");
comm_timer_delete(qstate->serve_expired_data->timer);
@@ -2423,21 +2187,15 @@ mesh_serve_expired_callback(void* arg)
"Serve expired: Not allowed to look into cache for stale");
return;
}
/* The following for is used instead of the `goto lookup_cache`
* like in the worker. This loop should get max 2 passes if we need to
* do any aliasing. */
for(for_count = 0; for_count < 2; for_count++) {
/* The following while is used instead of the `goto lookup_cache`
* like in the worker. */
while(1) {
fptr_ok(fptr_whitelist_serve_expired_lookup(
qstate->serve_expired_data->get_cached_answer));
msg = (*qstate->serve_expired_data->get_cached_answer)(qstate,
lookup_qinfo, &is_expired);
if(!msg || (FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NOERROR
&& FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NXDOMAIN
&& FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_YXDOMAIN)) {
/* We don't care for cached failure answers at this
* stage. */
lookup_qinfo);
if(!msg)
return;
}
/* Reset these in case we pass a second time from here. */
encode_rep = msg->rep;
memset(&actinfo, 0, sizeof(actinfo));
@@ -2451,8 +2209,7 @@ mesh_serve_expired_callback(void* arg)
} else if(partial_rep &&
!respip_merge_cname(partial_rep, &qstate->qinfo, msg->rep,
qstate->client_info, must_validate, &encode_rep, qstate->region,
qstate->env->auth_zones, qstate->env->views,
qstate->env->respip_set)) {
qstate->env->auth_zones)) {
return;
}
if(!encode_rep || alias_rrset) {
@@ -2510,7 +2267,7 @@ mesh_serve_expired_callback(void* arg)
http2_stream_remove_mesh_state(r->h2_stream);
comm_point_drop_reply(&r->query_reply);
mstate->reply_list = reply_list;
mstate->s.env->mesh->num_queries_discard_timeout++;
mstate->s.env->mesh->stats_dropped++;
continue;
}
@@ -2528,10 +2285,8 @@ mesh_serve_expired_callback(void* arg)
/* Add EDE Stale Answer (RCF8914). Ignore global ede as this is
* warning instead of an error */
if(r->edns.edns_present &&
qstate->env->cfg->ede_serve_expired &&
qstate->env->cfg->ede &&
is_expired) {
if (r->edns.edns_present && qstate->env->cfg->ede_serve_expired &&
qstate->env->cfg->ede) {
edns_opt_list_append_ede(&r->edns.opt_list_out,
mstate->s.region, LDNS_EDE_STALE_ANSWER, NULL);
}
@@ -2606,25 +2361,3 @@ int mesh_jostle_exceeded(struct mesh_area* mesh)
return 0;
return 1;
}
void mesh_remove_callback(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, mesh_cb_func_type cb, void* cb_arg)
{
struct mesh_state* s = NULL;
s = mesh_area_find(mesh, NULL, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
if(!s) return;
if(!mesh_state_del_cb(s, cb, cb_arg)) return;
/* It was in the list and removed. */
log_assert(mesh->num_reply_addrs > 0);
mesh->num_reply_addrs--;
if(!s->reply_list && !s->cb_list) {
/* was a reply state, not anymore */
log_assert(mesh->num_reply_states > 0);
mesh->num_reply_states--;
}
if(!s->reply_list && !s->cb_list &&
s->super_set.count == 0) {
mesh->num_detached_states++;
}
}
+1 -28
View File
@@ -90,11 +90,6 @@ struct mesh_area {
/** rbtree of all current queries (mesh_state.node)*/
rbtree_type all;
/** number of queries for unbound's auth_zones, upstream query */
size_t num_query_authzone_up;
/** number of queries for unbound's auth_zones, downstream answers */
size_t num_query_authzone_down;
/** count of the total number of mesh_reply entries */
size_t num_reply_addrs;
/** count of the number of mesh_states that have mesh_replies
@@ -131,20 +126,12 @@ struct mesh_area {
size_t ans_secure;
/** (extended stats) bogus replies */
size_t ans_bogus;
/** (extended stats) number of validation operations */
size_t val_ops;
/** (extended stats) rcodes in replies */
size_t ans_rcode[UB_STATS_RCODE_NUM];
/** (extended stats) rcode nodata in replies */
size_t ans_nodata;
/** (extended stats) type of applied RPZ action */
size_t rpz_action[UB_STATS_RPZ_ACTION_NUM];
/** stats, number of queries removed due to discard-timeout */
size_t num_queries_discard_timeout;
/** stats, number of queries removed due to wait-limit */
size_t num_queries_wait_limit;
/** stats, number of dns error reports generated */
size_t num_dns_error_reports;
/** backup of query if other operations recurse and need the
* network buffers */
@@ -686,12 +673,11 @@ void mesh_serve_expired_callback(void* arg);
* the same behavior as when replying from cache.
* @param qstate: the module qstate.
* @param lookup_qinfo: the query info to look for in the cache.
* @param is_expired: set if the cached answer is expired.
* @return dns_msg if a cached answer was found, otherwise NULL.
*/
struct dns_msg*
mesh_serve_expired_lookup(struct module_qstate* qstate,
struct query_info* lookup_qinfo, int* is_expired);
struct query_info* lookup_qinfo);
/**
* See if the mesh has space for more queries. You can allocate queries
@@ -710,17 +696,4 @@ int mesh_jostle_exceeded(struct mesh_area* mesh);
*/
void mesh_respond_serve_expired(struct mesh_state* mstate);
/**
* Remove callback from mesh. Removes the callback from the state.
* The state itself is left to run. Searches for the pointer values.
*
* @param mesh: the mesh.
* @param qinfo: query from client.
* @param qflags: flags from client query.
* @param cb: callback function.
* @param cb_arg: callback user arg.
*/
void mesh_remove_callback(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, mesh_cb_func_type cb, void* cb_arg);
#endif /* SERVICES_MESH_H */
+3 -3
View File
@@ -138,8 +138,8 @@ modstack_config(struct module_stack* stack, const char* module_conf)
if(strchr(s, ' ')) *(strchr(s, ' ')) = 0;
if(strchr(s, '\t')) *(strchr(s, '\t')) = 0;
log_err("Unknown value in module-config, module: '%s'."
" This module is not present (not compiled in);"
" see the list of linked modules with unbound -V", s);
" This module is not present (not compiled in),"
" See the list of linked modules with unbound -V", s);
return 0;
}
}
@@ -265,7 +265,7 @@ modstack_call_init(struct module_stack* stack, const char* module_conf,
int i, changed = 0;
env->need_to_validate = 0; /* set by module init below */
for(i=0; i<stack->num; i++) {
while(*module_conf && isspace((unsigned char)*module_conf))
while(*module_conf && isspace(*module_conf))
module_conf++;
if(strncmp(stack->mod[i]->name, module_conf,
strlen(stack->mod[i]->name))) {
+1 -1
View File
@@ -67,7 +67,7 @@ void modstack_init(struct module_stack* stack);
void modstack_free(struct module_stack* stack);
/**
* Initialises modules and assigns ids. Calls module_startup().
* Initialises modules and assignes ids. Calls module_startup().
* @param stack: Expected empty, filled according to module_conf
* @param module_conf: string what modules to initialize
* @param env: module environment which is inited by the modules.
+12 -32
View File
@@ -262,14 +262,12 @@ pick_outgoing_tcp(struct pending_tcp* pend, struct waiting_tcp* w, int s)
/** get TCP file descriptor for address, returns -1 on failure,
* tcp_mss is 0 or maxseg size to set for TCP packets. */
int
outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen,
int tcp_mss, int dscp, int nodelay)
outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss, int dscp)
{
int s;
int af;
char* err;
#if defined(SO_REUSEADDR) || defined(IP_BIND_ADDRESS_NO_PORT) \
|| defined(TCP_NODELAY)
#if defined(SO_REUSEADDR) || defined(IP_BIND_ADDRESS_NO_PORT)
int on = 1;
#endif
#ifdef INET6
@@ -322,18 +320,6 @@ outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen,
" setsockopt(.. IP_BIND_ADDRESS_NO_PORT ..) failed");
}
#endif /* IP_BIND_ADDRESS_NO_PORT */
if(nodelay) {
#if defined(IPPROTO_TCP) && defined(TCP_NODELAY)
if(setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void*)&on,
(socklen_t)sizeof(on)) < 0) {
verbose(VERB_ALGO, "outgoing tcp:"
" setsockopt(.. TCP_NODELAY ..) failed");
}
#else
verbose(VERB_ALGO, "outgoing tcp:"
" setsockopt(.. TCP_NODELAY ..) unsupported");
#endif /* defined(IPPROTO_TCP) && defined(TCP_NODELAY) */
}
return s;
}
@@ -663,8 +649,7 @@ outnet_tcp_take_into_use(struct waiting_tcp* w)
}
/* open socket */
s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss,
w->outnet->ip_dscp, w->ssl_upstream);
s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss, w->outnet->ip_dscp);
if(s == -1)
return 0;
@@ -1069,7 +1054,7 @@ reuse_move_writewait_away(struct outside_network* outnet,
if(verbosity >= VERB_CLIENT && pend->query->pkt_len > 12+2+2 &&
LDNS_QDCOUNT(pend->query->pkt) > 0 &&
dname_valid(pend->query->pkt+12, pend->query->pkt_len-12)) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[LDNS_MAX_DOMAINLEN+1];
dname_str(pend->query->pkt+12, buf);
verbose(VERB_CLIENT, "reuse_move_writewait_away current %s %d bytes were written",
buf, (int)pend->c->tcp_write_byte_count);
@@ -1094,7 +1079,7 @@ reuse_move_writewait_away(struct outside_network* outnet,
if(verbosity >= VERB_CLIENT && w->pkt_len > 12+2+2 &&
LDNS_QDCOUNT(w->pkt) > 0 &&
dname_valid(w->pkt+12, w->pkt_len-12)) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[LDNS_MAX_DOMAINLEN+1];
dname_str(w->pkt+12, buf);
verbose(VERB_CLIENT, "reuse_move_writewait_away item %s", buf);
}
@@ -2827,7 +2812,7 @@ serviced_perturb_qname(struct ub_randstate* rnd, uint8_t* qbuf, size_t len)
random = ub_random(rnd);
bits = 30;
}
if((random & 0x1)) {
if(random & 0x1) {
*d = (uint8_t)toupper((unsigned char)*d);
} else {
*d = (uint8_t)tolower((unsigned char)*d);
@@ -2840,7 +2825,7 @@ serviced_perturb_qname(struct ub_randstate* rnd, uint8_t* qbuf, size_t len)
lablen = *d++;
}
if(verbosity >= VERB_ALGO) {
char buf[LDNS_MAX_DOMAINLEN];
char buf[LDNS_MAX_DOMAINLEN+1];
dname_str(qbuf+10, buf);
verbose(VERB_ALGO, "qname perturbed to %s", buf);
}
@@ -2890,9 +2875,9 @@ serviced_encode(struct serviced_query* sq, sldns_buffer* buff, int with_edns)
edns.opt_list_inplace_cb_out = NULL;
edns.udp_size = serviced_query_udp_size(sq, sq->status);
edns.bits = 0;
if((sq->dnssec & EDNS_DO))
if(sq->dnssec & EDNS_DO)
edns.bits = EDNS_DO;
if((sq->dnssec & BIT_CD))
if(sq->dnssec & BIT_CD)
LDNS_CD_SET(sldns_buffer_begin(buff));
if (sq->ssl_upstream && sq->padding_block_size) {
padding_option.opt_code = LDNS_EDNS_PADDING;
@@ -3481,10 +3466,7 @@ outnet_serviced_query(struct outside_network* outnet,
timenow = *env->now;
if(!infra_ratelimit_inc(env->infra_cache, zone,
zonelen, timenow, env->cfg->ratelimit_backoff,
&qstate->qinfo,
qstate->mesh_info->reply_list
?&qstate->mesh_info->reply_list->query_reply
:NULL)) {
&qstate->qinfo, qstate->reply)) {
/* Can we pass through with slip factor? */
if(env->cfg->ratelimit_factor == 0 ||
ub_random_max(env->rnd,
@@ -3733,8 +3715,7 @@ outnet_comm_point_for_tcp(struct outside_network* outnet,
sldns_buffer* query, int timeout, int ssl, char* host)
{
struct comm_point* cp;
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss,
outnet->ip_dscp, ssl);
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss, outnet->ip_dscp);
if(fd == -1) {
return 0;
}
@@ -3809,8 +3790,7 @@ outnet_comm_point_for_http(struct outside_network* outnet,
{
/* cp calls cb with err=NETEVENT_DONE when transfer is done */
struct comm_point* cp;
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss,
outnet->ip_dscp, ssl);
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss, outnet->ip_dscp);
if(fd == -1) {
return 0;
}
+2 -4
View File
@@ -743,11 +743,9 @@ void reuse_write_wait_remove(struct reuse_tcp* reuse, struct waiting_tcp* w);
void reuse_write_wait_push_back(struct reuse_tcp* reuse, struct waiting_tcp* w);
/** get TCP file descriptor for address, returns -1 on failure,
* tcp_mss is 0 or maxseg size to set for TCP packets,
* nodelay (TCP_NODELAY) should be set for TLS connections to speed up the TLS
* handshake.*/
* tcp_mss is 0 or maxseg size to set for TCP packets. */
int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen,
int tcp_mss, int dscp, int nodelay);
int tcp_mss, int dscp);
/**
* Create udp commpoint suitable for sending packets to the destination.
+14 -92
View File
@@ -242,14 +242,10 @@ rpz_action_to_localzone_type(enum rpz_action a)
case RPZ_NODATA_ACTION: return local_zone_always_nodata;
case RPZ_DROP_ACTION: return local_zone_always_deny;
case RPZ_PASSTHRU_ACTION: return local_zone_always_transparent;
case RPZ_LOCAL_DATA_ACTION:
ATTR_FALLTHROUGH
/* fallthrough */
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect;
case RPZ_TCP_ONLY_ACTION: return local_zone_truncate;
case RPZ_INVALID_ACTION:
ATTR_FALLTHROUGH
/* fallthrough */
case RPZ_INVALID_ACTION: /* fallthrough */
default: return local_zone_invalid;
}
}
@@ -262,14 +258,10 @@ rpz_action_to_respip_action(enum rpz_action a)
case RPZ_NODATA_ACTION: return respip_always_nodata;
case RPZ_DROP_ACTION: return respip_always_deny;
case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
case RPZ_LOCAL_DATA_ACTION:
ATTR_FALLTHROUGH
/* fallthrough */
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect;
case RPZ_TCP_ONLY_ACTION: return respip_truncate;
case RPZ_INVALID_ACTION:
ATTR_FALLTHROUGH
/* fallthrough */
case RPZ_INVALID_ACTION: /* fallthrough */
default: return respip_invalid;
}
}
@@ -284,9 +276,7 @@ localzone_type_to_rpz_action(enum localzone_type lzt)
case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION;
case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION;
case local_zone_truncate: return RPZ_TCP_ONLY_ACTION;
case local_zone_invalid:
ATTR_FALLTHROUGH
/* fallthrough */
case local_zone_invalid: /* fallthrough */
default: return RPZ_INVALID_ACTION;
}
}
@@ -301,9 +291,7 @@ respip_action_to_rpz_action(enum respip_action a)
case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
case respip_truncate: return RPZ_TCP_ONLY_ACTION;
case respip_invalid:
ATTR_FALLTHROUGH
/* fallthrough */
case respip_invalid: /* fallthrough */
default: return RPZ_INVALID_ACTION;
}
}
@@ -666,7 +654,7 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
int newzone = 0;
if(a == RPZ_INVALID_ACTION) {
char str[LDNS_MAX_DOMAINLEN];
char str[255+1];
if(rrtype == LDNS_RR_TYPE_SOA || rrtype == LDNS_RR_TYPE_NS ||
rrtype == LDNS_RR_TYPE_DNAME ||
rrtype == LDNS_RR_TYPE_DNSKEY ||
@@ -739,7 +727,7 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
static void
rpz_log_dname(char const* msg, uint8_t* dname, size_t dname_len)
{
char buf[LDNS_MAX_DOMAINLEN];
char buf[LDNS_MAX_DOMAINLEN+1];
(void)dname_len;
dname_str(dname, buf);
verbose(VERB_ALGO, "rpz: %s: <%s>", msg, buf);
@@ -1062,7 +1050,7 @@ rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
if(a == RPZ_INVALID_ACTION ||
rpz_action_to_respip_action(a) == respip_invalid) {
char str[LDNS_MAX_DOMAINLEN];
char str[255+1];
dname_str(dname, str);
verbose(VERB_ALGO, "rpz: respip trigger, %s skipping unsupported action: %s",
str, rpz_action_to_string(a));
@@ -1633,7 +1621,7 @@ log_rpz_apply(char* trigger, uint8_t* dname, struct addr_tree_node* addrnode,
struct comm_reply* repinfo, struct module_qstate* ms, char* log_name)
{
char ip[128], txt[512], portstr[32];
char dnamestr[LDNS_MAX_DOMAINLEN];
char dnamestr[LDNS_MAX_DOMAINLEN+1];
uint16_t port = 0;
if(dname) {
dname_str(dname, dnamestr);
@@ -1969,7 +1957,6 @@ rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
0, /* ttl */
0, /* prettl */
0, /* expttl */
0, /* norecttl */
0, /* an */
0, /* ns */
0, /* ar */
@@ -2000,7 +1987,6 @@ rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms,
0, /* ttl */
0, /* prettl */
0, /* expttl */
0, /* norecttl */
0, /* an */
0, /* ns */
0, /* ar */
@@ -2033,7 +2019,6 @@ rpz_synthesize_localdata_from_rrset(struct rpz* ATTR_UNUSED(r), struct module_qs
0, /* ttl */
0, /* prettl */
0, /* expttl */
0, /* norecttl */
1, /* an */
0, /* ns */
0, /* ar */
@@ -2121,17 +2106,8 @@ rpz_synthesize_nsdname_localdata(struct rpz* r, struct module_qstate* ms,
rpz_log_dname("nsdname local data", key.name, key.namelen);
ld = (struct local_data*)rbtree_search(&z->data, &key.node);
if(ld == NULL && dname_is_wild(z->name)) {
key.name = z->name;
key.namelen = z->namelen;
key.namelabs = z->namelabs;
ld = (struct local_data*)rbtree_search(&z->data, &key.node);
/* rpz_synthesize_localdata_from_rrset is going to make
* the rrset source name equal to the query name. So no need
* to make the wildcard rrset here. */
}
if(ld == NULL) {
verbose(VERB_ALGO, "rpz: nsdname: qname not found");
verbose(VERB_ALGO, "rpz: nsdname: impossible: qname not found");
return NULL;
}
@@ -2157,15 +2133,6 @@ rpz_synthesize_qname_localdata_msg(struct rpz* r, struct module_qstate* ms,
key.namelen = qinfo->qname_len;
key.namelabs = dname_count_labels(qinfo->qname);
ld = (struct local_data*)rbtree_search(&z->data, &key.node);
if(ld == NULL && dname_is_wild(z->name)) {
key.name = z->name;
key.namelen = z->namelen;
key.namelabs = z->namelabs;
ld = (struct local_data*)rbtree_search(&z->data, &key.node);
/* rpz_synthesize_localdata_from_rrset is going to make
* the rrset source name equal to the query name. So no need
* to make the wildcard rrset here. */
}
if(ld == NULL) {
verbose(VERB_ALGO, "rpz: qname: name not found");
return NULL;
@@ -2197,7 +2164,6 @@ rpz_synthesize_cname_override_msg(struct rpz* r, struct module_qstate* ms,
0, /* ttl */
0, /* prettl */
0, /* expttl */
0, /* norecttl */
1, /* an */
0, /* ns */
0, /* ar */
@@ -2310,18 +2276,15 @@ rpz_apply_nsip_trigger(struct module_qstate* ms, struct query_info* qchase,
if(action == RPZ_LOCAL_DATA_ACTION && raddr->data == NULL) {
verbose(VERB_ALGO, "rpz: bug: nsip local data action but no local data");
ret = rpz_synthesize_nodata(r, ms, qchase, az);
ms->rpz_applied = 1;
goto done;
}
switch(action) {
case RPZ_NXDOMAIN_ACTION:
ret = rpz_synthesize_nxdomain(r, ms, qchase, az);
ms->rpz_applied = 1;
break;
case RPZ_NODATA_ACTION:
ret = rpz_synthesize_nodata(r, ms, qchase, az);
ms->rpz_applied = 1;
break;
case RPZ_TCP_ONLY_ACTION:
/* basically a passthru here but the tcp-only will be
@@ -2331,13 +2294,11 @@ rpz_apply_nsip_trigger(struct module_qstate* ms, struct query_info* qchase,
break;
case RPZ_DROP_ACTION:
ret = rpz_synthesize_nodata(r, ms, qchase, az);
ms->rpz_applied = 1;
ms->is_drop = 1;
break;
case RPZ_LOCAL_DATA_ACTION:
ret = rpz_synthesize_nsip_localdata(r, ms, qchase, raddr, az);
if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, qchase, az); }
ms->rpz_applied = 1;
break;
case RPZ_PASSTHRU_ACTION:
ret = NULL;
@@ -2345,7 +2306,6 @@ rpz_apply_nsip_trigger(struct module_qstate* ms, struct query_info* qchase,
break;
case RPZ_CNAME_OVERRIDE_ACTION:
ret = rpz_synthesize_cname_override_msg(r, ms, qchase);
ms->rpz_applied = 1;
break;
default:
verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'",
@@ -2380,11 +2340,9 @@ rpz_apply_nsdname_trigger(struct module_qstate* ms, struct query_info* qchase,
switch(action) {
case RPZ_NXDOMAIN_ACTION:
ret = rpz_synthesize_nxdomain(r, ms, qchase, az);
ms->rpz_applied = 1;
break;
case RPZ_NODATA_ACTION:
ret = rpz_synthesize_nodata(r, ms, qchase, az);
ms->rpz_applied = 1;
break;
case RPZ_TCP_ONLY_ACTION:
/* basically a passthru here but the tcp-only will be
@@ -2394,13 +2352,11 @@ rpz_apply_nsdname_trigger(struct module_qstate* ms, struct query_info* qchase,
break;
case RPZ_DROP_ACTION:
ret = rpz_synthesize_nodata(r, ms, qchase, az);
ms->rpz_applied = 1;
ms->is_drop = 1;
break;
case RPZ_LOCAL_DATA_ACTION:
ret = rpz_synthesize_nsdname_localdata(r, ms, qchase, z, match, az);
if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, qchase, az); }
ms->rpz_applied = 1;
break;
case RPZ_PASSTHRU_ACTION:
ret = NULL;
@@ -2408,7 +2364,6 @@ rpz_apply_nsdname_trigger(struct module_qstate* ms, struct query_info* qchase,
break;
case RPZ_CNAME_OVERRIDE_ACTION:
ret = rpz_synthesize_cname_override_msg(r, ms, qchase);
ms->rpz_applied = 1;
break;
default:
verbose(VERB_ALGO, "rpz: nsdname: bug: unhandled or invalid action: '%s'",
@@ -2445,8 +2400,7 @@ rpz_delegation_point_zone_lookup(struct delegpt* dp, struct local_zones* zones,
match->dname = nameserver->name;
match->dname_len = nameserver->namelen;
if(verbosity >= VERB_ALGO) {
char nm[LDNS_MAX_DOMAINLEN];
char zn[LDNS_MAX_DOMAINLEN];
char nm[255+1], zn[255+1];
dname_str(match->dname, nm);
dname_str(z->name, zn);
if(strcmp(nm, zn) != 0)
@@ -2600,7 +2554,7 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
}
if(verbosity >= VERB_ALGO) {
char nm[LDNS_MAX_DOMAINLEN], zn[LDNS_MAX_DOMAINLEN];
char nm[255+1], zn[255+1];
dname_str(is->qchase.qname, nm);
dname_str(z->name, zn);
if(strcmp(zn, nm) != 0)
@@ -2613,11 +2567,9 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
switch(localzone_type_to_rpz_action(lzt)) {
case RPZ_NXDOMAIN_ACTION:
ret = rpz_synthesize_nxdomain(r, ms, &is->qchase, a);
ms->rpz_applied = 1;
break;
case RPZ_NODATA_ACTION:
ret = rpz_synthesize_nodata(r, ms, &is->qchase, a);
ms->rpz_applied = 1;
break;
case RPZ_TCP_ONLY_ACTION:
/* basically a passthru here but the tcp-only will be
@@ -2627,13 +2579,11 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
break;
case RPZ_DROP_ACTION:
ret = rpz_synthesize_nodata(r, ms, &is->qchase, a);
ms->rpz_applied = 1;
ms->is_drop = 1;
break;
case RPZ_LOCAL_DATA_ACTION:
ret = rpz_synthesize_qname_localdata_msg(r, ms, &is->qchase, z, a);
if(ret == NULL) { ret = rpz_synthesize_nodata(r, ms, &is->qchase, a); }
ms->rpz_applied = 1;
break;
case RPZ_PASSTHRU_ACTION:
ret = NULL;
@@ -2777,7 +2727,7 @@ rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
}
if(verbosity >= VERB_ALGO) {
char nm[LDNS_MAX_DOMAINLEN], zn[LDNS_MAX_DOMAINLEN];
char nm[255+1], zn[255+1];
dname_str(qinfo->qname, nm);
dname_str(z->name, zn);
if(strcmp(zn, nm) != 0)
@@ -2810,31 +2760,3 @@ void rpz_disable(struct rpz* r)
return;
r->disabled = 1;
}
/** Get memory usage for clientip_synthesized_rrset. Ignores memory usage
* of locks. */
static size_t
rpz_clientip_synthesized_set_get_mem(struct clientip_synthesized_rrset* set)
{
size_t m = sizeof(*set);
lock_rw_rdlock(&set->lock);
m += regional_get_mem(set->region);
lock_rw_unlock(&set->lock);
return m;
}
size_t rpz_get_mem(struct rpz* r)
{
size_t m = sizeof(*r);
if(r->taglist)
m += r->taglistlen;
if(r->log_name)
m += strlen(r->log_name) + 1;
m += regional_get_mem(r->region);
m += local_zones_get_mem(r->local_zones);
m += local_zones_get_mem(r->nsdname_zones);
m += respip_set_get_mem(r->respip_set);
m += rpz_clientip_synthesized_set_get_mem(r->client_set);
m += rpz_clientip_synthesized_set_get_mem(r->ns_set);
return m;
}
-7
View File
@@ -269,11 +269,4 @@ void rpz_enable(struct rpz* r);
*/
void rpz_disable(struct rpz* r);
/**
* Get memory usage of rpz. Caller must manage locks.
* @param r: RPZ struct.
* @return memory usage.
*/
size_t rpz_get_mem(struct rpz* r);
#endif /* SERVICES_RPZ_H */
+5 -36
View File
@@ -43,7 +43,6 @@
#include "services/view.h"
#include "services/localzone.h"
#include "util/config_file.h"
#include "respip/respip.h"
int
view_cmp(const void* v1, const void* v2)
@@ -67,6 +66,11 @@ views_create(void)
return v;
}
/* \noop (ignore this comment for doxygen)
* This prototype is defined in in respip.h, but we want to avoid
* unnecessary dependencies */
void respip_set_delete(struct respip_set *set);
void
view_delete(struct view* v)
{
@@ -243,38 +247,3 @@ void views_print(struct views* v)
/* TODO implement print */
(void)v;
}
size_t views_get_mem(struct views* vs)
{
struct view* v;
size_t m;
if(!vs) return 0;
m = sizeof(struct views);
lock_rw_rdlock(&vs->lock);
RBTREE_FOR(v, struct view*, &vs->vtree) {
m += view_get_mem(v);
}
lock_rw_unlock(&vs->lock);
return m;
}
size_t view_get_mem(struct view* v)
{
size_t m = sizeof(*v);
lock_rw_rdlock(&v->lock);
m += getmem_str(v->name);
m += local_zones_get_mem(v->local_zones);
m += respip_set_get_mem(v->respip_set);
lock_rw_unlock(&v->lock);
return m;
}
void views_swap_tree(struct views* vs, struct views* data)
{
rbnode_type* oldroot = vs->vtree.root;
size_t oldcount = vs->vtree.count;
vs->vtree.root = data->vtree.root;
vs->vtree.count = data->vtree.count;
data->vtree.root = oldroot;
data->vtree.count = oldcount;
}
+1 -25
View File
@@ -54,8 +54,7 @@ struct respip_set;
* Views storage, shared.
*/
struct views {
/** lock on the view tree. When locking order, the views lock
* is before the forwards,hints,anchors,localzones lock. */
/** lock on the view tree */
lock_rw_type lock;
/** rbtree of struct view */
rbtree_type vtree;
@@ -136,27 +135,4 @@ void views_print(struct views* v);
*/
struct view* views_find_view(struct views* vs, const char* name, int write);
/**
* Calculate memory usage of views.
* @param vs: the views tree. The routine locks and unlocks the structure
* for reading.
* @return memory in bytes.
*/
size_t views_get_mem(struct views* vs);
/**
* Calculate memory usage of view.
* @param v: the view. The routine locks and unlocks the structure for reading.
* @return memory in bytes.
*/
size_t view_get_mem(struct view* v);
/**
* Swap internal tree with preallocated entries. Caller should manage
* the locks.
* @param vs: views tree
* @param data: preallocated information.
*/
void views_swap_tree(struct views* vs, struct views* data);
#endif /* SERVICES_VIEW_H */
+2 -4
View File
@@ -124,7 +124,7 @@ uint16_t sldns_calc_keytag_raw(uint8_t* key, size_t keysize)
size_t i;
uint32_t ac32 = 0;
for (i = 0; i < keysize; ++i) {
ac32 += ((i & 1)) ? key[i] : key[i] << 8;
ac32 += (i & 1) ? key[i] : key[i] << 8;
}
ac32 += (ac32 >> 16) & 0xFFFF;
return (uint16_t) (ac32 & 0xFFFF);
@@ -195,7 +195,6 @@ void sldns_key_EVP_unload_gost(void)
}
#endif /* USE_GOST */
#ifdef USE_DSA
/* Retrieve params as BIGNUM from raw buffer */
static int
sldns_key_dsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** p,
@@ -272,7 +271,7 @@ sldns_key_buf2dsa_raw(unsigned char* key, size_t len)
return NULL;
}
if (!DSA_set0_key(dsa, Y, NULL)) {
/* QPG attached, cleaned up by DSA_free() */
/* QPG attached, cleaned up by DSA_fre() */
DSA_free(dsa);
BN_free(Y);
return NULL;
@@ -371,7 +370,6 @@ EVP_PKEY *sldns_key_dsa2pkey_raw(unsigned char* key, size_t len)
return evp_key;
#endif
}
#endif /* USE_DSA */
/* Retrieve params as BIGNUM from raw buffer, n is modulus, e is exponent */
static int

Some files were not shown because too many files have changed in this diff Show More