mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
145
Commits
ideleg
...
release-1.22.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0076736fc4 | ||
|
|
f8e45ed696 | ||
|
|
2a28c7389c | ||
|
|
114edf2c38 | ||
|
|
e0c93e300b | ||
|
|
bd1813b126 | ||
|
|
1b7e14dc39 | ||
|
|
8b7782e8fc | ||
|
|
e0201435a4 | ||
|
|
66fb3ff670 | ||
|
|
36461ea73d | ||
|
|
5679c8b1df | ||
|
|
a4d8c0c43b | ||
|
|
3d89c26d32 | ||
|
|
dcf7afd722 | ||
|
|
e67171612b | ||
|
|
a1b25f0296 | ||
|
|
490585bf29 | ||
|
|
b7c61d7cc2 | ||
|
|
01883fb017 | ||
|
|
5bb3b9cc83 | ||
|
|
3a1b79f6a1 | ||
|
|
84eeb9b97c | ||
|
|
d88eeb4c32 | ||
|
|
2e398d51ba | ||
|
|
24ebca7df6 | ||
|
|
7f4a61e6fc | ||
|
|
db719d404f | ||
|
|
a35a0c49da | ||
|
|
5e9b6296b7 | ||
|
|
606e262fdd | ||
|
|
819764663b | ||
|
|
6bf2b2ac56 | ||
|
|
5767b0933f | ||
|
|
24e0f0ab7e | ||
|
|
d3fdbba877 | ||
|
|
c36ce2a390 | ||
|
|
7ecff4113c | ||
|
|
99824bc0e6 | ||
|
|
9f09c36401 | ||
|
|
a887284703 | ||
|
|
fb198b96f1 | ||
|
|
30bf996f39 | ||
|
|
52154e658a | ||
|
|
c06d3646a9 | ||
|
|
42d421a305 | ||
|
|
b5951ce1fa | ||
|
|
6b37309705 | ||
|
|
dc274fef9b | ||
|
|
db1167c8b3 | ||
|
|
1e0cf1e86b | ||
|
|
348df52e05 | ||
|
|
6b3266aaf8 | ||
|
|
4f52461e81 | ||
|
|
06d5031d22 | ||
|
|
12119e2d3e | ||
|
|
19d53d5663 | ||
|
|
04e6f9e03b | ||
|
|
3d350fa73d | ||
|
|
015b2b0daf | ||
|
|
5fa84d50bf | ||
|
|
79e4c57851 | ||
|
|
5abdd09095 | ||
|
|
158c1defe3 | ||
|
|
b4519012dc | ||
|
|
ed883238fd | ||
|
|
0f2f6025e7 | ||
|
|
3cbf554e3b | ||
|
|
ad21dbd1c2 | ||
|
|
50cf55bdac | ||
|
|
6106528a50 | ||
|
|
befa7d8cd8 | ||
|
|
92be76fb89 | ||
|
|
9a6b6765cc | ||
|
|
03b511b1a2 | ||
|
|
6af28bed08 | ||
|
|
f094f4ea3c | ||
|
|
c717debace | ||
|
|
7d4d21764a | ||
|
|
83e6977f06 | ||
|
|
671e11552c | ||
|
|
c4541e634b | ||
|
|
30da725e67 | ||
|
|
8de5ae3552 | ||
|
|
5bea29b01c | ||
|
|
89c9eafa44 | ||
|
|
3512eaec48 | ||
|
|
f9bd35dcfa | ||
|
|
3af4e44646 | ||
|
|
c3dd6a2dbd | ||
|
|
8fca3e7c5b | ||
|
|
8947c2c764 | ||
|
|
b1e3319a11 | ||
|
|
d52f501d90 | ||
|
|
7083d58c6b | ||
|
|
3adb9c8f92 | ||
|
|
51425b2388 | ||
|
|
d43760a8cd | ||
|
|
ea3e327006 | ||
|
|
be09350eca | ||
|
|
169acfc546 | ||
|
|
bed7cc2a90 | ||
|
|
02f4446833 | ||
|
|
c8a2289542 | ||
|
|
b53d90053e | ||
|
|
978b0696d3 | ||
|
|
ec5f86b4eb | ||
|
|
ec2f45c6fd | ||
|
|
6b319c97ee | ||
|
|
6eb3992c9e | ||
|
|
94a94fd8c8 | ||
|
|
36f9d1a2a9 | ||
|
|
d3a2264272 | ||
|
|
92b6c2a7b9 | ||
|
|
a335e601e4 | ||
|
|
a19009df1d | ||
|
|
96f8a94c19 | ||
|
|
2fe4e2ec3e | ||
|
|
e54928a628 | ||
|
|
538434186e | ||
|
|
65e7253d19 | ||
|
|
03ac902296 | ||
|
|
97ad1df343 | ||
|
|
2279cde8f7 | ||
|
|
ff653a7ef8 | ||
|
|
fd11cd9182 | ||
|
|
3953f827fb | ||
|
|
7fbc061846 | ||
|
|
70f73a33b3 | ||
|
|
b67fbb69e7 | ||
|
|
902c79608c | ||
|
|
08050dc939 | ||
|
|
9603924bb4 | ||
|
|
4c2da2b979 | ||
|
|
1974732d19 | ||
|
|
3cad5818a1 | ||
|
|
ad12109191 | ||
|
|
f611220eb8 | ||
|
|
ac609fcbfc | ||
|
|
486985fbdf | ||
|
|
caab100207 | ||
|
|
1d23e0c920 | ||
|
|
ad51795314 | ||
|
|
7d76e84953 | ||
|
|
c96e4ca121 |
@@ -161,6 +161,33 @@ 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
|
||||
@@ -331,6 +358,33 @@ 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
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
/config.status
|
||||
/dnstap/dnstap_config.h
|
||||
/dnscrypt/dnscrypt_config.h
|
||||
/util/configlexer.c
|
||||
/util/configparser.c
|
||||
/util/configparser.h
|
||||
/clubsyms.def
|
||||
/doc/example.conf
|
||||
/doc/libunbound.3
|
||||
@@ -33,6 +36,7 @@
|
||||
/asynclook
|
||||
/delayer
|
||||
/dohclient
|
||||
/doqclient
|
||||
/lock-verify
|
||||
/memstats
|
||||
/perf
|
||||
@@ -55,6 +59,7 @@
|
||||
/pythonmod/unboundmodule.py
|
||||
/testdata/result.*
|
||||
/testdata/.done-*
|
||||
/testdata/.skip-*
|
||||
/testdata/.perfstats.txt
|
||||
/doc/html
|
||||
/doc/xml
|
||||
|
||||
+17
-7
@@ -179,11 +179,11 @@ testcode/unitlruhash.c testcode/unitmain.c testcode/unitmsgparse.c \
|
||||
testcode/unitneg.c testcode/unitregional.c testcode/unitslabhash.c \
|
||||
testcode/unitverify.c testcode/readhex.c testcode/testpkts.c testcode/unitldns.c \
|
||||
testcode/unitecs.c testcode/unitauth.c testcode/unitzonemd.c \
|
||||
testcode/unittcpreuse.c
|
||||
testcode/unittcpreuse.c testcode/unitdoq.c
|
||||
UNITTEST_OBJ=unitanchor.lo unitdname.lo unitlruhash.lo unitmain.lo \
|
||||
unitmsgparse.lo unitneg.lo unitregional.lo unitslabhash.lo unitverify.lo \
|
||||
readhex.lo testpkts.lo unitldns.lo unitecs.lo unitauth.lo unitzonemd.lo \
|
||||
unittcpreuse.lo
|
||||
unittcpreuse.lo unitdoq.lo
|
||||
UNITTEST_OBJ_LINK=$(UNITTEST_OBJ) worker_cb.lo $(COMMON_OBJ) $(SLDNS_OBJ) \
|
||||
$(COMPAT_OBJ)
|
||||
DAEMON_SRC=daemon/acl_list.c daemon/cachedump.c daemon/daemon.c \
|
||||
@@ -242,6 +242,10 @@ DOHCLIENT_SRC=testcode/dohclient.c
|
||||
DOHCLIENT_OBJ=dohclient.lo
|
||||
DOHCLIENT_OBJ_LINK=$(DOHCLIENT_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
|
||||
$(SLDNS_OBJ)
|
||||
DOQCLIENT_SRC=testcode/doqclient.c
|
||||
DOQCLIENT_OBJ=doqclient.lo
|
||||
DOQCLIENT_OBJ_LINK=$(DOQCLIENT_OBJ) $(COMMON_OBJ) $(COMPAT_OBJ) \
|
||||
$(SLDNS_OBJ)
|
||||
PERF_SRC=testcode/perf.c
|
||||
PERF_OBJ=perf.lo
|
||||
PERF_OBJ_LINK=$(PERF_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) $(SLDNS_OBJ)
|
||||
@@ -288,7 +292,7 @@ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
|
||||
$(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC) $(DNSTAP_SOCKET_SRC)\
|
||||
$(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC) \
|
||||
$(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC) \
|
||||
$(DOHCLIENT_SRC) $(READZONE_SRC)
|
||||
$(DOHCLIENT_SRC) $(DOQCLIENT_SRC) $(READZONE_SRC)
|
||||
|
||||
ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
|
||||
$(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \
|
||||
@@ -297,7 +301,7 @@ ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
|
||||
$(CONTROL_OBJ) $(UBANCHOR_OBJ) $(PETAL_OBJ) $(DNSTAP_SOCKET_OBJ)\
|
||||
$(COMPAT_OBJ) $(PYUNBOUND_OBJ) \
|
||||
$(SVCINST_OBJ) $(SVCUNINST_OBJ) $(ANCHORUPD_OBJ) $(SLDNS_OBJ) \
|
||||
$(DOHCLIENT_OBJ) $(READZONE_OBJ)
|
||||
$(DOHCLIENT_OBJ) $(DOQCLIENT_OBJ) $(READZONE_OBJ)
|
||||
|
||||
COMPILE=$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@
|
||||
LINK=$(LIBTOOL) --tag=CC --mode=link $(CC) $(staticexe) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
||||
@@ -334,7 +338,7 @@ rsrc_unbound_checkconf.o: $(srcdir)/winrc/rsrc_unbound_checkconf.rc config.h
|
||||
TEST_BIN=asynclook$(EXEEXT) delayer$(EXEEXT) \
|
||||
lock-verify$(EXEEXT) memstats$(EXEEXT) perf$(EXEEXT) \
|
||||
petal$(EXEEXT) pktview$(EXEEXT) streamtcp$(EXEEXT) \
|
||||
$(DNSTAP_SOCKET_TESTBIN) dohclient$(EXEEXT) \
|
||||
$(DNSTAP_SOCKET_TESTBIN) dohclient$(EXEEXT) doqclient$(EXEEXT) \
|
||||
testbound$(EXEEXT) unittest$(EXEEXT) readzone$(EXEEXT)
|
||||
tests: all $(TEST_BIN)
|
||||
|
||||
@@ -416,6 +420,9 @@ streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK)
|
||||
dohclient$(EXEEXT): $(DOHCLIENT_OBJ_LINK)
|
||||
$(LINK) -o $@ $(DOHCLIENT_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
|
||||
doqclient$(EXEEXT): $(DOQCLIENT_OBJ_LINK)
|
||||
$(LINK) -o $@ $(DOQCLIENT_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
|
||||
perf$(EXEEXT): $(PERF_OBJ_LINK)
|
||||
$(LINK) -o $@ $(PERF_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
|
||||
@@ -439,7 +446,8 @@ unbound-control-setup: smallapp/unbound-control-setup.sh
|
||||
dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h dnstap/dnstap_config.h \
|
||||
dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h $(srcdir)/dnstap/dnstap.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/util/net_help.h
|
||||
$(srcdir)/util/netevent.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/locks.h
|
||||
|
||||
dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h: $(srcdir)/dnstap/dnstap.proto
|
||||
@-if test ! -d dnstap; then $(INSTALL) -d dnstap; fi
|
||||
@@ -702,6 +710,8 @@ depend:
|
||||
|
||||
# build rules
|
||||
ipset.lo ipset.o: $(srcdir)/ipset/ipset.c
|
||||
doqclient.lo doqclient.o: $(srcdir)/testcode/doqclient.c
|
||||
unitdoq.lo unitdoq.o: $(srcdir)/testcode/unitdoq.c
|
||||
|
||||
# Dependencies
|
||||
dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
|
||||
@@ -1297,7 +1307,7 @@ remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h
|
||||
$(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
|
||||
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h \
|
||||
$(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h \
|
||||
$(srcdir)/sldns/wire2str.h
|
||||
$(srcdir)/sldns/wire2str.h $(srcdir)/util/edns.h
|
||||
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
|
||||
|
||||
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
|
||||
if test -z "$PYTHON"; then
|
||||
AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
|
||||
AC_MSG_ERROR([Cannot find 'python$PYTHON_VERSION' in your system path. You can use the environment variable 'PYTHON_VERSION=version_number' for an explicit version.])
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
|
||||
|
||||
+4
-3
@@ -621,6 +621,9 @@ 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
|
||||
@@ -828,8 +831,6 @@ 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;
|
||||
@@ -983,7 +984,7 @@ cachedb_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block cachedb_block = {
|
||||
"cachedb",
|
||||
&cachedb_init, &cachedb_deinit, &cachedb_operate,
|
||||
NULL, NULL, &cachedb_init, &cachedb_deinit, &cachedb_operate,
|
||||
&cachedb_inform_super, &cachedb_clear, &cachedb_get_mem
|
||||
};
|
||||
|
||||
|
||||
+23
-6
@@ -58,7 +58,8 @@ struct redis_moddata {
|
||||
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 */
|
||||
struct timeval command_timeout; /* timeout for commands */
|
||||
struct timeval connect_timeout; /* timeout for connect */
|
||||
int logical_db; /* the redis logical database to use */
|
||||
};
|
||||
|
||||
@@ -88,10 +89,10 @@ redis_connect(const struct redis_moddata* moddata)
|
||||
|
||||
if(moddata->server_path && moddata->server_path[0]!=0) {
|
||||
ctx = redisConnectUnixWithTimeout(moddata->server_path,
|
||||
moddata->timeout);
|
||||
moddata->connect_timeout);
|
||||
} else {
|
||||
ctx = redisConnectWithTimeout(moddata->server_host,
|
||||
moddata->server_port, moddata->timeout);
|
||||
moddata->server_port, moddata->connect_timeout);
|
||||
}
|
||||
if(!ctx || ctx->err) {
|
||||
const char *errstr = "out of memory";
|
||||
@@ -100,7 +101,7 @@ redis_connect(const struct redis_moddata* moddata)
|
||||
log_err("failed to connect to redis server: %s", errstr);
|
||||
goto fail;
|
||||
}
|
||||
if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) {
|
||||
if(redisSetTimeout(ctx, moddata->command_timeout) != REDIS_OK) {
|
||||
log_err("failed to set redis timeout");
|
||||
goto fail;
|
||||
}
|
||||
@@ -159,8 +160,24 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
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->command_timeout.tv_sec = env->cfg->redis_timeout / 1000;
|
||||
moddata->command_timeout.tv_usec =
|
||||
(env->cfg->redis_timeout % 1000) * 1000;
|
||||
moddata->connect_timeout.tv_sec = env->cfg->redis_timeout / 1000;
|
||||
moddata->connect_timeout.tv_usec =
|
||||
(env->cfg->redis_timeout % 1000) * 1000;
|
||||
if(env->cfg->redis_command_timeout != 0) {
|
||||
moddata->command_timeout.tv_sec =
|
||||
env->cfg->redis_command_timeout / 1000;
|
||||
moddata->command_timeout.tv_usec =
|
||||
(env->cfg->redis_command_timeout % 1000) * 1000;
|
||||
}
|
||||
if(env->cfg->redis_connect_timeout != 0) {
|
||||
moddata->connect_timeout.tv_sec =
|
||||
env->cfg->redis_connect_timeout / 1000;
|
||||
moddata->connect_timeout.tv_usec =
|
||||
(env->cfg->redis_connect_timeout % 1000) * 1000;
|
||||
}
|
||||
moddata->logical_db = env->cfg->redis_logical_db;
|
||||
for(i = 0; i < moddata->numctxs; i++) {
|
||||
redisContext* ctx = redis_connect(moddata);
|
||||
|
||||
+109
@@ -1,5 +1,8 @@
|
||||
/* 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
|
||||
|
||||
@@ -57,6 +60,9 @@
|
||||
/* 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
|
||||
|
||||
@@ -123,6 +129,14 @@
|
||||
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
|
||||
@@ -406,12 +420,74 @@
|
||||
/* Define to 1 if you have the <net/if.h> header file. */
|
||||
#undef HAVE_NET_IF_H
|
||||
|
||||
/* Define to 1 if you have the <net/pfvar.h> header file. */
|
||||
#undef HAVE_NET_PFVAR_H
|
||||
|
||||
/* Define this to use nghttp2 client. */
|
||||
#undef HAVE_NGHTTP2
|
||||
|
||||
/* 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 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_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
|
||||
|
||||
@@ -566,6 +642,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
|
||||
|
||||
@@ -575,6 +654,9 @@
|
||||
/* 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
|
||||
|
||||
@@ -617,6 +699,23 @@
|
||||
/* 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
|
||||
|
||||
@@ -1484,6 +1583,10 @@ 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);
|
||||
@@ -1496,6 +1599,10 @@ 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 */
|
||||
@@ -1506,6 +1613,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
#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
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.71 for unbound 1.20.1.
|
||||
# Generated by GNU Autoconf 2.71 for unbound 1.22.0.
|
||||
#
|
||||
# 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.20.1'
|
||||
PACKAGE_STRING='unbound 1.20.1'
|
||||
PACKAGE_VERSION='1.22.0'
|
||||
PACKAGE_STRING='unbound 1.22.0'
|
||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -921,6 +921,7 @@ with_libevent
|
||||
with_libexpat
|
||||
with_libhiredis
|
||||
with_libnghttp2
|
||||
with_libngtcp2
|
||||
enable_static_exe
|
||||
enable_fully_static
|
||||
enable_lock_checks
|
||||
@@ -1508,7 +1509,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.20.1 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.22.0 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1574,7 +1575,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of unbound 1.20.1:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.22.0:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1596,7 +1597,8 @@ Optional Features:
|
||||
--disable-libtool-lock avoid locking (might break parallel builds)
|
||||
--disable-rpath disable hardcoded rpath (default=enabled)
|
||||
--disable-largefile omit support for large files
|
||||
--enable-systemd compile with systemd support
|
||||
--enable-systemd compile with systemd support (requires libsystemd,
|
||||
pkg-config)
|
||||
--enable-alloc-checks enable to memory allocation statistics, for debug
|
||||
purposes
|
||||
--enable-alloc-lite enable for lightweight alloc assertions, for debug
|
||||
@@ -1708,6 +1710,7 @@ 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
|
||||
@@ -1821,7 +1824,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
unbound configure 1.20.1
|
||||
unbound configure 1.22.0
|
||||
generated by GNU Autoconf 2.71
|
||||
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
@@ -2478,7 +2481,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.20.1, which was
|
||||
It was created by unbound $as_me 1.22.0, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
$ $0$ac_configure_args_raw
|
||||
@@ -3240,13 +3243,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
UNBOUND_VERSION_MAJOR=1
|
||||
|
||||
UNBOUND_VERSION_MINOR=20
|
||||
UNBOUND_VERSION_MINOR=22
|
||||
|
||||
UNBOUND_VERSION_MICRO=1
|
||||
UNBOUND_VERSION_MICRO=0
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=28
|
||||
LIBUNBOUND_REVISION=30
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -3341,7 +3344,9 @@ 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.20.1 had 9:28:1
|
||||
# 1.21.0 had 9:28:1
|
||||
# 1.21.1 had 9:29:1
|
||||
# 1.22.0 had 9:30:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -6975,6 +6980,10 @@ 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
|
||||
|
||||
|
||||
@@ -7022,6 +7031,79 @@ 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
|
||||
|
||||
|
||||
@@ -17624,7 +17706,8 @@ have_systemd=no
|
||||
if test "x$enable_systemd" != xno
|
||||
then :
|
||||
|
||||
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
have_systemd=no
|
||||
|
||||
pkg_failed=no
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5
|
||||
@@ -17684,11 +17767,31 @@ fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$SYSTEMD_PKG_ERRORS" >&5
|
||||
|
||||
have_systemd=no
|
||||
as_fn_error $? "Package requirements (libsystemd) were not met:
|
||||
|
||||
$SYSTEMD_PKG_ERRORS
|
||||
|
||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||
installed software in a non-standard prefix.
|
||||
|
||||
Alternatively, you may set the environment variables SYSTEMD_CFLAGS
|
||||
and SYSTEMD_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details." "$LINENO" 5
|
||||
elif test $pkg_failed = untried; then
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
have_systemd=no
|
||||
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||
as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
|
||||
Alternatively, you may set the environment variables SYSTEMD_CFLAGS
|
||||
and SYSTEMD_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details.
|
||||
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
|
||||
See \`config.log' for more details" "$LINENO" 5; }
|
||||
else
|
||||
SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS
|
||||
SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS
|
||||
@@ -17699,6 +17802,7 @@ fi
|
||||
if test "x$have_systemd" != "xyes"
|
||||
then :
|
||||
|
||||
have_systemd_daemon=no
|
||||
|
||||
pkg_failed=no
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD_DAEMON" >&5
|
||||
@@ -17758,11 +17862,31 @@ fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$SYSTEMD_DAEMON_PKG_ERRORS" >&5
|
||||
|
||||
have_systemd_daemon=no
|
||||
as_fn_error $? "Package requirements (libsystemd-daemon) were not met:
|
||||
|
||||
$SYSTEMD_DAEMON_PKG_ERRORS
|
||||
|
||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||
installed software in a non-standard prefix.
|
||||
|
||||
Alternatively, you may set the environment variables SYSTEMD_DAEMON_CFLAGS
|
||||
and SYSTEMD_DAEMON_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details." "$LINENO" 5
|
||||
elif test $pkg_failed = untried; then
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
have_systemd_daemon=no
|
||||
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||
as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
|
||||
Alternatively, you may set the environment variables SYSTEMD_DAEMON_CFLAGS
|
||||
and SYSTEMD_DAEMON_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details.
|
||||
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
|
||||
See \`config.log' for more details" "$LINENO" 5; }
|
||||
else
|
||||
SYSTEMD_DAEMON_CFLAGS=$pkg_cv_SYSTEMD_DAEMON_CFLAGS
|
||||
SYSTEMD_DAEMON_LIBS=$pkg_cv_SYSTEMD_DAEMON_LIBS
|
||||
@@ -17789,7 +17913,9 @@ printf "%s\n" "#define HAVE_SYSTEMD 1" >>confdefs.h
|
||||
*) :
|
||||
;;
|
||||
esac
|
||||
|
||||
else
|
||||
as_fn_error $? "systemd enabled but need pkg-config to configure for it" "$LINENO" 5
|
||||
fi
|
||||
|
||||
fi
|
||||
if test "x$have_systemd" = xyes; then
|
||||
@@ -19185,7 +19311,7 @@ fi
|
||||
|
||||
|
||||
if test -z "$PYTHON"; then
|
||||
as_fn_error $? "Cannot find python$PYTHON_VERSION in your system path" "$LINENO" 5
|
||||
as_fn_error $? "Cannot find 'python$PYTHON_VERSION' in your system path. You can use the environment variable 'PYTHON_VERSION=version_number' for an explicit version." "$LINENO" 5
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
|
||||
@@ -20656,6 +20782,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
|
||||
@@ -21190,7 +21322,25 @@ case "$enable_ecdsa" in
|
||||
;;
|
||||
*)
|
||||
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
||||
ac_fn_c_check_func "$LINENO" "ECDSA_sign" "ac_cv_func_ECDSA_sign"
|
||||
ac_fn_c_check_func "$LINENO" "EVP_PKEY_fromdata" "ac_cv_func_EVP_PKEY_fromdata"
|
||||
if test "x$ac_cv_func_EVP_PKEY_fromdata" = xyes
|
||||
then :
|
||||
|
||||
# with EVP_PKEY_fromdata, check if EC is not disabled
|
||||
ac_fn_check_decl "$LINENO" "OPENSSL_NO_EC" "ac_cv_have_decl_OPENSSL_NO_EC" "$ac_includes_default
|
||||
#include <openssl/evp.h>
|
||||
|
||||
" "$ac_c_undeclared_builtin_options" "CFLAGS"
|
||||
if test "x$ac_cv_have_decl_OPENSSL_NO_EC" = xyes
|
||||
then :
|
||||
as_fn_error $? "OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa" "$LINENO" 5
|
||||
|
||||
fi
|
||||
|
||||
else $as_nop
|
||||
|
||||
# without EVP_PKEY_fromdata, older openssl, check for support
|
||||
ac_fn_c_check_func "$LINENO" "ECDSA_sign" "ac_cv_func_ECDSA_sign"
|
||||
if test "x$ac_cv_func_ECDSA_sign" = xyes
|
||||
then :
|
||||
|
||||
@@ -21198,12 +21348,15 @@ else $as_nop
|
||||
as_fn_error $? "OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa" "$LINENO" 5
|
||||
fi
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "SHA384_Init" "ac_cv_func_SHA384_Init"
|
||||
ac_fn_c_check_func "$LINENO" "SHA384_Init" "ac_cv_func_SHA384_Init"
|
||||
if test "x$ac_cv_func_SHA384_Init" = xyes
|
||||
then :
|
||||
|
||||
else $as_nop
|
||||
as_fn_error $? "OpenSSL does not support SHA384: please upgrade or rerun with --disable-ecdsa" "$LINENO" 5
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_check_decl "$LINENO" "NID_X9_62_prime256v1" "ac_cv_have_decl_NID_X9_62_prime256v1" "$ac_includes_default
|
||||
@@ -22054,6 +22207,353 @@ 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_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_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"
|
||||
fi
|
||||
|
||||
{ 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
|
||||
|
||||
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_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
|
||||
|
||||
|
||||
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
|
||||
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=""
|
||||
@@ -23637,10 +24137,12 @@ 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
|
||||
@@ -23733,7 +24235,7 @@ then :
|
||||
|
||||
else $as_nop
|
||||
|
||||
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
|
||||
pkg_failed=no
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PROTOBUFC" >&5
|
||||
@@ -23794,36 +24296,36 @@ fi
|
||||
echo "$PROTOBUFC_PKG_ERRORS" >&5
|
||||
|
||||
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
as_fn_error $? "The protobuf-c package was not found with pkg-config. Please install protobuf-c!" "$LINENO" 5
|
||||
fi
|
||||
as_fn_error $? "The protobuf-c package was not found with pkg-config. Please install protobuf-c!" "$LINENO" 5
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
elif test $pkg_failed = untried; then
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
as_fn_error $? "The protobuf-c package was not found with pkg-config. Please install protobuf-c!" "$LINENO" 5
|
||||
fi
|
||||
as_fn_error $? "The protobuf-c package was not found with pkg-config. Please install protobuf-c!" "$LINENO" 5
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
else
|
||||
@@ -23832,11 +24334,21 @@ else
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
printf "%s\n" "yes" >&6; }
|
||||
|
||||
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
|
||||
LIBS="$LIBS $PROTOBUFC_LIBS"
|
||||
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
|
||||
LIBS="$LIBS $PROTOBUFC_LIBS"
|
||||
|
||||
fi
|
||||
|
||||
else
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
@@ -24235,7 +24747,21 @@ printf "%s\n" "#define USE_IPSET 1" >>confdefs.h
|
||||
IPSET_OBJ="ipset.lo"
|
||||
|
||||
|
||||
# mnl
|
||||
# BSD's pf
|
||||
for ac_header in net/pfvar.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "net/pfvar.h" "ac_cv_header_net_pfvar_h" "
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_header_net_pfvar_h" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_NET_PFVAR_H 1" >>confdefs.h
|
||||
|
||||
else $as_nop
|
||||
|
||||
# mnl
|
||||
|
||||
# Check whether --with-libmnl was given.
|
||||
if test ${with_libmnl+y}
|
||||
@@ -24245,13 +24771,13 @@ else $as_nop
|
||||
withval="yes"
|
||||
fi
|
||||
|
||||
found_libmnl="no"
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libmnl" >&5
|
||||
found_libmnl="no"
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libmnl" >&5
|
||||
printf %s "checking for libmnl... " >&6; }
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/libmnl/libmnl.h" -o -f "$dir/include/libmnl/libmnl/libmnl.h"; then
|
||||
found_libmnl="yes"
|
||||
extralibmnl=""
|
||||
@@ -24269,10 +24795,14 @@ printf "%s\n" "found in $dir" >&6; }
|
||||
LIBS="$LIBS -lmnl"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libmnl != x_yes; then
|
||||
as_fn_error $? "Could not find libmnl, libmnl.h" "$LINENO" 5
|
||||
fi
|
||||
done
|
||||
if test x_$found_libmnl != x_yes; then
|
||||
as_fn_error $? "Could not find libmnl, libmnl.h" "$LINENO" 5
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
;;
|
||||
no|*)
|
||||
# nothing
|
||||
@@ -24467,7 +24997,7 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 10240" >>confdefs.h
|
||||
|
||||
|
||||
|
||||
version=1.20.1
|
||||
version=1.22.0
|
||||
|
||||
date=`date +'%b %e, %Y'`
|
||||
|
||||
@@ -24979,7 +25509,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.20.1, which was
|
||||
This file was extended by unbound $as_me 1.22.0, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -25047,7 +25577,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.20.1
|
||||
unbound config.status 1.22.0
|
||||
configured by $0, generated by GNU Autoconf 2.71,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+150
-18
@@ -10,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],[20])
|
||||
m4_define([VERSION_MICRO],[1])
|
||||
m4_define([VERSION_MINOR],[22])
|
||||
m4_define([VERSION_MICRO],[0])
|
||||
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=28
|
||||
LIBUNBOUND_REVISION=30
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -113,7 +113,9 @@ 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.20.1 had 9:28:1
|
||||
# 1.21.0 had 9:28:1
|
||||
# 1.21.1 had 9:29:1
|
||||
# 1.22.0 had 9:30:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -339,6 +341,8 @@ 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
|
||||
|
||||
@@ -360,11 +364,54 @@ 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
|
||||
@@ -944,7 +991,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"
|
||||
@@ -1181,8 +1228,17 @@ case "$enable_ecdsa" in
|
||||
;;
|
||||
*)
|
||||
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
||||
AC_CHECK_FUNC(ECDSA_sign, [], [AC_MSG_ERROR([OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa])])
|
||||
AC_CHECK_FUNC(SHA384_Init, [], [AC_MSG_ERROR([OpenSSL does not support SHA384: please upgrade or rerun with --disable-ecdsa])])
|
||||
AC_CHECK_FUNC(EVP_PKEY_fromdata, [
|
||||
# with EVP_PKEY_fromdata, check if EC is not disabled
|
||||
AC_CHECK_DECL([OPENSSL_NO_EC], [AC_MSG_ERROR([OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa])
|
||||
], [], [AC_INCLUDES_DEFAULT
|
||||
#include <openssl/evp.h>
|
||||
])
|
||||
], [
|
||||
# without EVP_PKEY_fromdata, older openssl, check for support
|
||||
AC_CHECK_FUNC(ECDSA_sign, [], [AC_MSG_ERROR([OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa])])
|
||||
AC_CHECK_FUNC(SHA384_Init, [], [AC_MSG_ERROR([OpenSSL does not support SHA384: please upgrade or rerun with --disable-ecdsa])])
|
||||
])
|
||||
AC_CHECK_DECLS([NID_X9_62_prime256v1, NID_secp384r1], [], [AC_MSG_ERROR([OpenSSL does not support the ECDSA curves: please upgrade or rerun with --disable-ecdsa])], [AC_INCLUDES_DEFAULT
|
||||
#include <openssl/evp.h>
|
||||
])
|
||||
@@ -1523,6 +1579,64 @@ 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_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_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_conn_get_num_scid ngtcp2_conn_tls_early_data_rejected ngtcp2_conn_encode_0rtt_transport_params])
|
||||
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.])])
|
||||
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=""
|
||||
@@ -1838,10 +1952,12 @@ 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
|
||||
@@ -1922,15 +2038,17 @@ case "$enable_ipset" in
|
||||
IPSET_OBJ="ipset.lo"
|
||||
AC_SUBST(IPSET_OBJ)
|
||||
|
||||
# mnl
|
||||
AC_ARG_WITH(libmnl, AS_HELP_STRING([--with-libmnl=path],[specify explicit path for libmnl.]),
|
||||
# BSD's pf
|
||||
AC_CHECK_HEADERS([net/pfvar.h], [], [
|
||||
# mnl
|
||||
AC_ARG_WITH(libmnl, AS_HELP_STRING([--with-libmnl=path],[specify explicit path for libmnl.]),
|
||||
[ ],[ withval="yes" ])
|
||||
found_libmnl="no"
|
||||
AC_MSG_CHECKING(for libmnl)
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
found_libmnl="no"
|
||||
AC_MSG_CHECKING(for libmnl)
|
||||
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
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/libmnl/libmnl.h" -o -f "$dir/include/libmnl/libmnl/libmnl.h"; then
|
||||
found_libmnl="yes"
|
||||
dnl assume /usr is in default path.
|
||||
@@ -1948,10 +2066,14 @@ case "$enable_ipset" in
|
||||
LIBS="$LIBS -lmnl"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libmnl != x_yes; then
|
||||
AC_MSG_ERROR([Could not find libmnl, libmnl.h])
|
||||
fi
|
||||
done
|
||||
if test x_$found_libmnl != x_yes; then
|
||||
AC_MSG_ERROR([Could not find libmnl, libmnl.h])
|
||||
fi
|
||||
], [
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
])
|
||||
;;
|
||||
no|*)
|
||||
# nothing
|
||||
@@ -2269,6 +2391,10 @@ 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);
|
||||
@@ -2281,6 +2407,10 @@ 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 */
|
||||
@@ -2291,6 +2421,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
#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
|
||||
|
||||
@@ -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))
|
||||
+ super_iq->dp, 0))
|
||||
+ log_err("ASN-AAAA-filter: out of memory adding missing");
|
||||
+ dpns->resolved = 1; /* mark as failed */
|
||||
+ }
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
After=network.target
|
||||
Before=network-online.target nss-lookup.target
|
||||
After=network-online.target
|
||||
Before=nss-lookup.target
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
After=network.target
|
||||
Before=network-online.target nss-lookup.target
|
||||
After=network-online.target
|
||||
Before=nss-lookup.target
|
||||
Wants=nss-lookup.target
|
||||
|
||||
[Install]
|
||||
|
||||
+49
-8
@@ -344,7 +344,7 @@ static int setup_acl_for_ports(struct acl_list* list,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
daemon_open_shared_ports(struct daemon* daemon)
|
||||
{
|
||||
log_assert(daemon);
|
||||
@@ -444,6 +444,19 @@ daemon_open_shared_ports(struct daemon* daemon)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
daemon_privileged(struct daemon* daemon)
|
||||
{
|
||||
daemon->env->cfg = daemon->cfg;
|
||||
daemon->env->alloc = &daemon->superalloc;
|
||||
daemon->env->worker = NULL;
|
||||
if(!modstack_call_startup(&daemon->mods, daemon->cfg->module_conf,
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to startup modules");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup modules. setup module stack.
|
||||
* @param daemon: the daemon
|
||||
@@ -453,11 +466,15 @@ static void daemon_setup_modules(struct daemon* daemon)
|
||||
daemon->env->cfg = daemon->cfg;
|
||||
daemon->env->alloc = &daemon->superalloc;
|
||||
daemon->env->worker = NULL;
|
||||
daemon->env->need_to_validate = 0; /* set by module init below */
|
||||
if(!modstack_setup(&daemon->mods, daemon->cfg->module_conf,
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to setup modules");
|
||||
if(daemon->mods_inited) {
|
||||
modstack_call_deinit(&daemon->mods, daemon->env);
|
||||
}
|
||||
daemon->env->need_to_validate = 0; /* set by module init below */
|
||||
if(!modstack_call_init(&daemon->mods, daemon->cfg->module_conf,
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to init modules");
|
||||
}
|
||||
daemon->mods_inited = 1;
|
||||
log_edns_known_options(VERB_ALGO, daemon->env);
|
||||
}
|
||||
|
||||
@@ -503,7 +520,10 @@ daemon_clear_allocs(struct daemon* daemon)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
/* daemon->num may be different during reloads (after configuration
|
||||
* read). Use old_num which has the correct value used to setup the
|
||||
* worker_allocs */
|
||||
for(i=0; i<daemon->old_num; i++) {
|
||||
alloc_clear(daemon->worker_allocs[i]);
|
||||
free(daemon->worker_allocs[i]);
|
||||
}
|
||||
@@ -537,6 +557,12 @@ 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) {
|
||||
@@ -715,6 +741,14 @@ 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");
|
||||
@@ -858,7 +892,7 @@ daemon_cleanup(struct daemon* daemon)
|
||||
daemon->views = NULL;
|
||||
if(daemon->env->auth_zones)
|
||||
auth_zones_cleanup(daemon->env->auth_zones);
|
||||
/* key cache is cleared by module desetup during next daemon_fork() */
|
||||
/* key cache is cleared by module deinit during next daemon_fork() */
|
||||
daemon_remote_clear(daemon->rc);
|
||||
for(i=0; i<daemon->num; i++)
|
||||
worker_delete(daemon->workers[i]);
|
||||
@@ -878,6 +912,10 @@ 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;
|
||||
}
|
||||
@@ -888,7 +926,9 @@ daemon_delete(struct daemon* daemon)
|
||||
size_t i;
|
||||
if(!daemon)
|
||||
return;
|
||||
modstack_desetup(&daemon->mods, daemon->env);
|
||||
modstack_call_deinit(&daemon->mods, daemon->env);
|
||||
modstack_call_destartup(&daemon->mods, daemon->env);
|
||||
modstack_free(&daemon->mods);
|
||||
daemon_remote_delete(daemon->rc);
|
||||
for(i = 0; i < daemon->num_ports; i++)
|
||||
listening_ports_free(daemon->ports[i]);
|
||||
@@ -907,6 +947,7 @@ 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);
|
||||
|
||||
@@ -58,6 +58,8 @@ struct ub_randstate;
|
||||
struct daemon_remote;
|
||||
struct respip_set;
|
||||
struct shm_main_info;
|
||||
struct doq_table;
|
||||
struct cookie_secrets;
|
||||
|
||||
#include "dnstap/dnstap_config.h"
|
||||
#ifdef USE_DNSTAP
|
||||
@@ -115,6 +117,8 @@ struct daemon {
|
||||
struct module_env* env;
|
||||
/** stack of module callbacks */
|
||||
struct module_stack mods;
|
||||
/** The module stack has been inited */
|
||||
int mods_inited;
|
||||
/** access control, which client IPs are allowed to connect */
|
||||
struct acl_list* acl;
|
||||
/** access control, which interfaces are allowed to connect */
|
||||
@@ -144,8 +148,12 @@ 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;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -162,6 +170,15 @@ struct daemon* daemon_init(void);
|
||||
*/
|
||||
int daemon_open_shared_ports(struct daemon* daemon);
|
||||
|
||||
/**
|
||||
* Do daemon setup that needs privileges
|
||||
* like opening privileged ports or opening device files.
|
||||
* The cfg member pointer must have been set for the daemon.
|
||||
* @param daemon: the daemon.
|
||||
* @return: false on error.
|
||||
*/
|
||||
int daemon_privileged(struct daemon* daemon);
|
||||
|
||||
/**
|
||||
* Fork workers and start service.
|
||||
* When the routine exits, it is no longer forked.
|
||||
|
||||
+229
-1
@@ -88,6 +88,7 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "util/timeval_func.h"
|
||||
#include "util/edns.h"
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/cachedb.h"
|
||||
#endif
|
||||
@@ -301,7 +302,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
|
||||
/* open fd */
|
||||
fd = create_tcp_accept_sock(res, 1, &noproto, 0,
|
||||
cfg->ip_transparent, 0, 0, cfg->ip_freebind,
|
||||
cfg->use_systemd, cfg->ip_dscp);
|
||||
cfg->use_systemd, cfg->ip_dscp, "unbound-control");
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
|
||||
@@ -865,6 +866,10 @@ print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
|
||||
if(!print_longnum(ssl, "mem.http.response_buffer"SQ,
|
||||
(size_t)s->svr.mem_http2_response_buffer))
|
||||
return 0;
|
||||
#ifdef HAVE_NGTCP2
|
||||
if(!print_longnum(ssl, "mem.quic"SQ, (size_t)s->svr.mem_quic))
|
||||
return 0;
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -995,6 +1000,10 @@ print_ext(RES* ssl, struct ub_stats_info* s, int inhibit_zero)
|
||||
(unsigned long)s->svr.qipv6)) return 0;
|
||||
if(!ssl_printf(ssl, "num.query.https"SQ"%lu\n",
|
||||
(unsigned long)s->svr.qhttps)) return 0;
|
||||
#ifdef HAVE_NGTCP2
|
||||
if(!ssl_printf(ssl, "num.query.quic"SQ"%lu\n",
|
||||
(unsigned long)s->svr.qquic)) return 0;
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
/* flags */
|
||||
if(!ssl_printf(ssl, "num.query.flags.QR"SQ"%lu\n",
|
||||
(unsigned long)s->svr.qbit_QR)) return 0;
|
||||
@@ -1682,6 +1691,8 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
|
||||
#ifdef USE_CACHEDB
|
||||
if(remcachedb && worker->env.cachedb_enabled)
|
||||
cachedb_msg_remove_qinfo(&worker->env, &k);
|
||||
#else
|
||||
(void)remcachedb;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1950,6 +1961,8 @@ bogus_del_msg(struct lruhash_entry* e, void* arg)
|
||||
struct reply_info* d = (struct reply_info*)e->data;
|
||||
if(d->security == sec_status_bogus) {
|
||||
d->ttl = inf->expired;
|
||||
d->prefetch_ttl = inf->expired;
|
||||
d->serve_expired_ttl = inf->expired;
|
||||
inf->num_msgs++;
|
||||
#ifdef USE_CACHEDB
|
||||
if(inf->remcachedb && inf->worker->env.cachedb_enabled)
|
||||
@@ -2032,6 +2045,8 @@ negative_del_msg(struct lruhash_entry* e, void* arg)
|
||||
* or NOERROR rcode with ANCOUNT==0: a NODATA answer */
|
||||
if(FLAGS_GET_RCODE(d->flags) != 0 || d->an_numrrsets == 0) {
|
||||
d->ttl = inf->expired;
|
||||
d->prefetch_ttl = inf->expired;
|
||||
d->serve_expired_ttl = inf->expired;
|
||||
inf->num_msgs++;
|
||||
#ifdef USE_CACHEDB
|
||||
if(inf->remcachedb && inf->worker->env.cachedb_enabled)
|
||||
@@ -3193,6 +3208,210 @@ do_rpz_disable(RES* ssl, struct worker* worker, char* arg)
|
||||
do_rpz_enable_disable(ssl, worker, arg, 0);
|
||||
}
|
||||
|
||||
/** Write the cookie secrets to file, returns `0` on failure.
|
||||
* Caller has to hold the lock. */
|
||||
static int
|
||||
cookie_secret_file_dump(RES* ssl, struct worker* worker) {
|
||||
char const* secret_file = worker->env.cfg->cookie_secret_file;
|
||||
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
|
||||
char secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2 + 1];
|
||||
FILE* f;
|
||||
size_t i;
|
||||
if(secret_file == NULL || secret_file[0]==0) {
|
||||
(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
|
||||
return 0;
|
||||
}
|
||||
log_assert( secret_file != NULL );
|
||||
|
||||
/* open write only and truncate */
|
||||
if((f = fopen(secret_file, "w")) == NULL ) {
|
||||
(void)ssl_printf(ssl, "unable to open cookie secret file %s: %s",
|
||||
secret_file, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if(cookie_secrets == NULL) {
|
||||
/* nothing to write */
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for(i = 0; i < cookie_secrets->cookie_count; i++) {
|
||||
struct cookie_secret const* cs = &cookie_secrets->
|
||||
cookie_secrets[i];
|
||||
ssize_t const len = hex_ntop(cs->cookie_secret,
|
||||
UNBOUND_COOKIE_SECRET_SIZE, secret_hex,
|
||||
sizeof(secret_hex));
|
||||
(void)len; /* silence unused variable warning with -DNDEBUG */
|
||||
log_assert( len == UNBOUND_COOKIE_SECRET_SIZE * 2 );
|
||||
secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2] = '\0';
|
||||
fprintf(f, "%s\n", secret_hex);
|
||||
}
|
||||
explicit_bzero(secret_hex, sizeof(secret_hex));
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Activate cookie secret */
|
||||
static void
|
||||
do_activate_cookie_secret(RES* ssl, struct worker* worker) {
|
||||
char const* secret_file = worker->env.cfg->cookie_secret_file;
|
||||
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
|
||||
|
||||
if(secret_file == NULL || secret_file[0] == 0) {
|
||||
(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
|
||||
return;
|
||||
}
|
||||
if(cookie_secrets == NULL) {
|
||||
(void)ssl_printf(ssl, "error: there are no cookie_secrets.");
|
||||
return;
|
||||
}
|
||||
lock_basic_lock(&cookie_secrets->lock);
|
||||
|
||||
if(cookie_secrets->cookie_count <= 1 ) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
(void)ssl_printf(ssl, "error: no staging cookie secret to activate\n");
|
||||
return;
|
||||
}
|
||||
/* Only the worker 0 writes to file, the others update state. */
|
||||
if(worker->thread_num == 0 && !cookie_secret_file_dump(ssl, worker)) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
|
||||
secret_file);
|
||||
return;
|
||||
}
|
||||
activate_cookie_secret(cookie_secrets);
|
||||
if(worker->thread_num == 0)
|
||||
(void)cookie_secret_file_dump(ssl, worker);
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** Drop cookie secret */
|
||||
static void
|
||||
do_drop_cookie_secret(RES* ssl, struct worker* worker) {
|
||||
char const* secret_file = worker->env.cfg->cookie_secret_file;
|
||||
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
|
||||
|
||||
if(secret_file == NULL || secret_file[0] == 0) {
|
||||
(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
|
||||
return;
|
||||
}
|
||||
if(cookie_secrets == NULL) {
|
||||
(void)ssl_printf(ssl, "error: there are no cookie_secrets.");
|
||||
return;
|
||||
}
|
||||
lock_basic_lock(&cookie_secrets->lock);
|
||||
|
||||
if(cookie_secrets->cookie_count <= 1 ) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
(void)ssl_printf(ssl, "error: can not drop the currently active cookie secret\n");
|
||||
return;
|
||||
}
|
||||
/* Only the worker 0 writes to file, the others update state. */
|
||||
if(worker->thread_num == 0 && !cookie_secret_file_dump(ssl, worker)) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
|
||||
secret_file);
|
||||
return;
|
||||
}
|
||||
drop_cookie_secret(cookie_secrets);
|
||||
if(worker->thread_num == 0)
|
||||
(void)cookie_secret_file_dump(ssl, worker);
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** Add cookie secret */
|
||||
static void
|
||||
do_add_cookie_secret(RES* ssl, struct worker* worker, char* arg) {
|
||||
uint8_t secret[UNBOUND_COOKIE_SECRET_SIZE];
|
||||
char const* secret_file = worker->env.cfg->cookie_secret_file;
|
||||
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
|
||||
|
||||
if(secret_file == NULL || secret_file[0] == 0) {
|
||||
(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
|
||||
return;
|
||||
}
|
||||
if(cookie_secrets == NULL) {
|
||||
worker->daemon->cookie_secrets = cookie_secrets_create();
|
||||
if(!worker->daemon->cookie_secrets) {
|
||||
(void)ssl_printf(ssl, "error: out of memory");
|
||||
return;
|
||||
}
|
||||
cookie_secrets = worker->daemon->cookie_secrets;
|
||||
}
|
||||
lock_basic_lock(&cookie_secrets->lock);
|
||||
|
||||
if(*arg == '\0') {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
(void)ssl_printf(ssl, "error: missing argument (cookie_secret)\n");
|
||||
return;
|
||||
}
|
||||
if(strlen(arg) != 32) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
explicit_bzero(arg, strlen(arg));
|
||||
(void)ssl_printf(ssl, "invalid cookie secret: invalid argument length\n");
|
||||
(void)ssl_printf(ssl, "please provide a 128bit hex encoded secret\n");
|
||||
return;
|
||||
}
|
||||
if(hex_pton(arg, secret, UNBOUND_COOKIE_SECRET_SIZE) !=
|
||||
UNBOUND_COOKIE_SECRET_SIZE ) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
explicit_bzero(arg, strlen(arg));
|
||||
(void)ssl_printf(ssl, "invalid cookie secret: parse error\n");
|
||||
(void)ssl_printf(ssl, "please provide a 128bit hex encoded secret\n");
|
||||
return;
|
||||
}
|
||||
/* Only the worker 0 writes to file, the others update state. */
|
||||
if(worker->thread_num == 0 && !cookie_secret_file_dump(ssl, worker)) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
explicit_bzero(arg, strlen(arg));
|
||||
(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
|
||||
secret_file);
|
||||
return;
|
||||
}
|
||||
add_cookie_secret(cookie_secrets, secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
if(worker->thread_num == 0)
|
||||
(void)cookie_secret_file_dump(ssl, worker);
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
explicit_bzero(arg, strlen(arg));
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** Print cookie secrets */
|
||||
static void
|
||||
do_print_cookie_secrets(RES* ssl, struct worker* worker) {
|
||||
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
|
||||
char secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2 + 1];
|
||||
int i;
|
||||
|
||||
if(!cookie_secrets)
|
||||
return; /* Output is empty. */
|
||||
lock_basic_lock(&cookie_secrets->lock);
|
||||
for(i = 0; (size_t)i < cookie_secrets->cookie_count; i++) {
|
||||
struct cookie_secret const* cs = &cookie_secrets->
|
||||
cookie_secrets[i];
|
||||
ssize_t const len = hex_ntop(cs->cookie_secret,
|
||||
UNBOUND_COOKIE_SECRET_SIZE, secret_hex,
|
||||
sizeof(secret_hex));
|
||||
(void)len; /* silence unused variable warning with -DNDEBUG */
|
||||
log_assert( len == UNBOUND_COOKIE_SECRET_SIZE * 2 );
|
||||
secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2] = '\0';
|
||||
if (i == 0)
|
||||
(void)ssl_printf(ssl, "active : %s\n", secret_hex);
|
||||
else if (cookie_secrets->cookie_count == 2)
|
||||
(void)ssl_printf(ssl, "staging: %s\n", secret_hex);
|
||||
else
|
||||
(void)ssl_printf(ssl, "staging[%d]: %s\n", i,
|
||||
secret_hex);
|
||||
}
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
explicit_bzero(secret_hex, sizeof(secret_hex));
|
||||
}
|
||||
|
||||
/** check for name with end-of-string, space or tab after it */
|
||||
static int
|
||||
cmdcmp(char* p, const char* cmd, size_t len)
|
||||
@@ -3325,6 +3544,9 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
|
||||
} else if(cmdcmp(p, "view_local_datas", 16)) {
|
||||
do_view_datas_add(rc, ssl, worker, skipwhite(p+16));
|
||||
return;
|
||||
} else if(cmdcmp(p, "print_cookie_secrets", 20)) {
|
||||
do_print_cookie_secrets(ssl, worker);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef THREADS_DISABLED
|
||||
@@ -3389,6 +3611,12 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
|
||||
do_rpz_enable(ssl, worker, skipwhite(p+10));
|
||||
} else if(cmdcmp(p, "rpz_disable", 11)) {
|
||||
do_rpz_disable(ssl, worker, skipwhite(p+11));
|
||||
} else if(cmdcmp(p, "add_cookie_secret", 17)) {
|
||||
do_add_cookie_secret(ssl, worker, skipwhite(p+17));
|
||||
} else if(cmdcmp(p, "drop_cookie_secret", 18)) {
|
||||
do_drop_cookie_secret(ssl, worker);
|
||||
} else if(cmdcmp(p, "activate_cookie_secret", 22)) {
|
||||
do_activate_cookie_secret(ssl, worker);
|
||||
} else {
|
||||
(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
|
||||
}
|
||||
|
||||
+21
-2
@@ -346,6 +346,12 @@ 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);
|
||||
@@ -391,6 +397,13 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
else worker_send_cmd(who, worker_cmd_stats_noreset);
|
||||
verbose(VERB_ALGO, "wait for stats reply");
|
||||
if(tube_wait_timeout(worker->cmd, STATS_THREAD_WAIT) == 0) {
|
||||
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
|
||||
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
|
||||
unsigned long pthid = 0;
|
||||
if(verbosity >= VERB_OPS)
|
||||
memcpy(&pthid, &who->thr_id, sizeof(unsigned long));
|
||||
# endif
|
||||
#endif
|
||||
verbose(VERB_OPS, "no response from thread %d"
|
||||
#ifdef HAVE_GETTID
|
||||
" LWP %u"
|
||||
@@ -407,7 +420,7 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
#endif
|
||||
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
|
||||
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
|
||||
, (unsigned long)*((unsigned long*)&who->thr_id)
|
||||
, pthid
|
||||
# endif
|
||||
#endif
|
||||
);
|
||||
@@ -467,6 +480,7 @@ 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;
|
||||
@@ -526,7 +540,8 @@ 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) {
|
||||
stats->qtcp++;
|
||||
if(c->type != comm_doq)
|
||||
stats->qtcp++;
|
||||
if(c->ssl != NULL) {
|
||||
stats->qtls++;
|
||||
#ifdef HAVE_SSL
|
||||
@@ -535,6 +550,10 @@ 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))
|
||||
|
||||
@@ -473,7 +473,11 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
#endif
|
||||
#ifdef HAVE_GETPWNAM
|
||||
struct passwd *pwd = NULL;
|
||||
#endif
|
||||
|
||||
if(!daemon_privileged(daemon))
|
||||
fatal_exit("could not do privileged setup");
|
||||
#ifdef HAVE_GETPWNAM
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
if((pwd = getpwnam(cfg->username)) == NULL)
|
||||
fatal_exit("user '%s' does not exist.", cfg->username);
|
||||
|
||||
+33
-16
@@ -160,9 +160,11 @@ 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)
|
||||
+ forwards_get_mem(worker->env.fwds)
|
||||
+ hints_get_mem(worker->env.hints);
|
||||
+ 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));
|
||||
if(worker->thread_num == 0)
|
||||
me += acl_list_get_mem(worker->daemon->acl);
|
||||
if(cur_serv) {
|
||||
@@ -659,22 +661,18 @@ 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 &&
|
||||
!worker->env.cfg->serve_expired_client_timeout
|
||||
/* 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)
|
||||
#ifdef USE_CACHEDB
|
||||
&& !(worker->env.cachedb_enabled &&
|
||||
worker->env.cfg->cachedb_check_when_serve_expired)
|
||||
#endif
|
||||
) {
|
||||
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)
|
||||
if(!reply_info_can_answer_expired(rep, timenow))
|
||||
return 0;
|
||||
if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
|
||||
return 0;
|
||||
@@ -1571,7 +1569,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
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)) != 0) {
|
||||
worker->scratchpad,
|
||||
worker->daemon->cookie_secrets)) != 0) {
|
||||
struct edns_data reply_edns;
|
||||
verbose(VERB_ALGO, "worker parse edns: formerror.");
|
||||
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||
@@ -2175,7 +2174,9 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
cfg->harden_large_queries, cfg->http_max_streams,
|
||||
cfg->http_endpoint, cfg->http_notls_downstream,
|
||||
worker->daemon->tcl, worker->daemon->listen_sslctx,
|
||||
dtenv, worker_handle_request, worker);
|
||||
dtenv, worker->daemon->doq_table, worker->env.rnd,
|
||||
cfg->ssl_service_key, cfg->ssl_service_pem, cfg,
|
||||
worker_handle_request, worker);
|
||||
if(!worker->front) {
|
||||
log_err("could not create listening sockets");
|
||||
worker_delete(worker);
|
||||
@@ -2509,3 +2510,19 @@ 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
|
||||
|
||||
+6
-4
@@ -657,7 +657,7 @@ 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, 0, 0, NULL,
|
||||
0, qstate->prefetch_leeway, 0, NULL,
|
||||
qstate->query_flags, qstate->qstarttime))
|
||||
log_err("out of memory");
|
||||
|
||||
@@ -701,6 +701,7 @@ 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);
|
||||
@@ -846,6 +847,7 @@ 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)
|
||||
@@ -1006,7 +1008,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, 0, 0, NULL, super->query_flags, qstate->qstarttime))
|
||||
0, super->prefetch_leeway, 0, NULL, super->query_flags, qstate->qstarttime))
|
||||
log_err("out of memory");
|
||||
}
|
||||
|
||||
@@ -1044,8 +1046,8 @@ dns64_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block dns64_block = {
|
||||
"dns64",
|
||||
&dns64_init, &dns64_deinit, &dns64_operate, &dns64_inform_super,
|
||||
&dns64_clear, &dns64_get_mem
|
||||
NULL, NULL, &dns64_init, &dns64_deinit, &dns64_operate,
|
||||
&dns64_inform_super, &dns64_clear, &dns64_get_mem
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -86,6 +86,31 @@ dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** See if the message is sent due to dnstap sample rate */
|
||||
static int
|
||||
dt_sample_rate_limited(struct dt_env* env)
|
||||
{
|
||||
lock_basic_lock(&env->sample_lock);
|
||||
/* Sampling is every [n] packets. Where n==1, every packet is sent */
|
||||
if(env->sample_rate > 1) {
|
||||
int submit = 0;
|
||||
/* if sampling is engaged... */
|
||||
if (env->sample_rate_count > env->sample_rate) {
|
||||
/* once the count passes the limit */
|
||||
/* submit the message */
|
||||
submit = 1;
|
||||
/* and reset the count */
|
||||
env->sample_rate_count = 0;
|
||||
}
|
||||
/* increment count regardless */
|
||||
env->sample_rate_count++;
|
||||
lock_basic_unlock(&env->sample_lock);
|
||||
return !submit;
|
||||
}
|
||||
lock_basic_unlock(&env->sample_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
dt_send(const struct dt_env *env, void *buf, size_t len_buf)
|
||||
{
|
||||
@@ -146,6 +171,7 @@ dt_create(struct config_file* cfg)
|
||||
env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
|
||||
if (!env)
|
||||
return NULL;
|
||||
lock_basic_init(&env->sample_lock);
|
||||
|
||||
env->dtio = dt_io_thread_create();
|
||||
if(!env->dtio) {
|
||||
@@ -241,6 +267,12 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/FORWARDER_RESPONSE enabled");
|
||||
}
|
||||
lock_basic_lock(&env->sample_lock);
|
||||
if((env->sample_rate = (unsigned int)cfg->dnstap_sample_rate))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap SAMPLE_RATE enabled and set to \"%d\"", (int)env->sample_rate);
|
||||
}
|
||||
lock_basic_unlock(&env->sample_lock);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -273,6 +305,7 @@ dt_delete(struct dt_env *env)
|
||||
if (!env)
|
||||
return;
|
||||
dt_io_thread_delete(env->dtio);
|
||||
lock_basic_destroy(&env->sample_lock);
|
||||
free(env->identity);
|
||||
free(env->version);
|
||||
free(env);
|
||||
@@ -409,6 +442,9 @@ dt_msg_send_client_query(struct dt_env *env,
|
||||
struct dt_msg dm;
|
||||
struct timeval qtime;
|
||||
|
||||
if(dt_sample_rate_limited(env))
|
||||
return;
|
||||
|
||||
if(tstamp)
|
||||
memcpy(&qtime, tstamp, sizeof(qtime));
|
||||
else gettimeofday(&qtime, NULL);
|
||||
@@ -447,6 +483,9 @@ dt_msg_send_client_response(struct dt_env *env,
|
||||
struct dt_msg dm;
|
||||
struct timeval rtime;
|
||||
|
||||
if(dt_sample_rate_limited(env))
|
||||
return;
|
||||
|
||||
gettimeofday(&rtime, NULL);
|
||||
|
||||
/* type */
|
||||
@@ -484,6 +523,9 @@ dt_msg_send_outside_query(struct dt_env *env,
|
||||
struct timeval qtime;
|
||||
uint16_t qflags;
|
||||
|
||||
if(dt_sample_rate_limited(env))
|
||||
return;
|
||||
|
||||
gettimeofday(&qtime, NULL);
|
||||
qflags = sldns_buffer_read_u16_at(qmsg, 2);
|
||||
|
||||
@@ -537,6 +579,9 @@ dt_msg_send_outside_response(struct dt_env *env,
|
||||
struct dt_msg dm;
|
||||
uint16_t qflags;
|
||||
|
||||
if(dt_sample_rate_limited(env))
|
||||
return;
|
||||
|
||||
(void)qbuf_len; log_assert(qbuf_len >= sizeof(qflags));
|
||||
memcpy(&qflags, qbuf, sizeof(qflags));
|
||||
qflags = ntohs(qflags);
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
|
||||
#include "util/locks.h"
|
||||
struct config_file;
|
||||
struct sldns_buffer;
|
||||
struct dt_msg_queue;
|
||||
@@ -75,6 +76,13 @@ struct dt_env {
|
||||
unsigned log_forwarder_query_messages : 1;
|
||||
/** whether to log Message/FORWARDER_RESPONSE */
|
||||
unsigned log_forwarder_response_messages : 1;
|
||||
|
||||
/** lock on sample count */
|
||||
lock_basic_type sample_lock;
|
||||
/** rate limit value from config, samples 1/N messages */
|
||||
unsigned int sample_rate;
|
||||
/** rate limit counter */
|
||||
unsigned int sample_rate_count;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+28
-31
@@ -34,41 +34,38 @@ AC_DEFUN([dt_DNSTAP],
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
],
|
||||
[
|
||||
ifdef([PKG_CHECK_MODULES],
|
||||
[
|
||||
PKG_CHECK_MODULES([PROTOBUFC], [libprotobuf-c],
|
||||
[
|
||||
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
|
||||
LIBS="$LIBS $PROTOBUFC_LIBS"
|
||||
],
|
||||
[
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
PKG_CHECK_MODULES([PROTOBUFC], [libprotobuf-c],
|
||||
[
|
||||
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
|
||||
LIBS="$LIBS $PROTOBUFC_LIBS"
|
||||
],
|
||||
[
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
AC_MSG_ERROR([The protobuf-c package was not found with pkg-config. Please install protobuf-c!])
|
||||
fi
|
||||
AC_MSG_ERROR([The protobuf-c package was not found with pkg-config. Please install protobuf-c!])
|
||||
fi
|
||||
]
|
||||
)
|
||||
],
|
||||
[
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
fi
|
||||
]
|
||||
)
|
||||
else
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
fi
|
||||
]
|
||||
)
|
||||
fi
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [],
|
||||
|
||||
+45
-8
@@ -176,10 +176,7 @@ void
|
||||
mq_wakeup_cb(void* arg)
|
||||
{
|
||||
struct dt_msg_queue* mq = (struct dt_msg_queue*)arg;
|
||||
/* even if the dtio is already active, because perhaps much
|
||||
* traffic suddenly, we leave the timer running to save on
|
||||
* managing it, the once a second timer is less work then
|
||||
* starting and stopping the timer frequently */
|
||||
|
||||
lock_basic_lock(&mq->dtio->wakeup_timer_lock);
|
||||
mq->dtio->wakeup_timer_enabled = 0;
|
||||
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
|
||||
@@ -210,6 +207,8 @@ dt_msg_queue_start_timer(struct dt_msg_queue* mq, int wakeupnow)
|
||||
lock_basic_lock(&mq->dtio->wakeup_timer_lock);
|
||||
if(mq->dtio->wakeup_timer_enabled) {
|
||||
if(wakeupnow) {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
comm_timer_set(mq->wakeup_timer, &tv);
|
||||
}
|
||||
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
|
||||
@@ -221,8 +220,14 @@ dt_msg_queue_start_timer(struct dt_msg_queue* mq, int wakeupnow)
|
||||
if(!wakeupnow) {
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
/* If it is already set, keep it running. */
|
||||
if(!comm_timer_is_set(mq->wakeup_timer))
|
||||
comm_timer_set(mq->wakeup_timer, &tv);
|
||||
} else {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
comm_timer_set(mq->wakeup_timer, &tv);
|
||||
}
|
||||
comm_timer_set(mq->wakeup_timer, &tv);
|
||||
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
|
||||
}
|
||||
|
||||
@@ -260,8 +265,9 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len)
|
||||
|
||||
/* acquire lock */
|
||||
lock_basic_lock(&mq->lock);
|
||||
/* if list was empty, start timer for (eventual) wakeup */
|
||||
if(mq->first == NULL)
|
||||
/* if list was empty, start timer for (eventual) wakeup,
|
||||
* or if dtio is not writing now an eventual wakeup is needed. */
|
||||
if(mq->first == NULL || !mq->dtio->event_added_is_write)
|
||||
wakeupstarttimer = 1;
|
||||
/* if list contains more than wakeupnum elements, wakeup now,
|
||||
* or if list is (going to be) almost full */
|
||||
@@ -1259,6 +1265,13 @@ static void dtio_sleep(struct dt_io_thread* dtio)
|
||||
/* unregister the event polling for write, because there is
|
||||
* nothing to be written */
|
||||
(void)dtio_add_output_event_read(dtio);
|
||||
|
||||
/* Set wakeuptimer enabled off; so that the next worker thread that
|
||||
* wants to log starts a timer if needed, since the writer thread
|
||||
* has gone to sleep. */
|
||||
lock_basic_lock(&dtio->wakeup_timer_lock);
|
||||
dtio->wakeup_timer_enabled = 0;
|
||||
lock_basic_unlock(&dtio->wakeup_timer_lock);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
@@ -1322,7 +1335,11 @@ static int dtio_ssl_check_peer(struct dt_io_thread* dtio)
|
||||
if((SSL_get_verify_mode(dtio->ssl)&SSL_VERIFY_PEER)) {
|
||||
/* verification */
|
||||
if(SSL_get_verify_result(dtio->ssl) == X509_V_OK) {
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
X509* x = SSL_get1_peer_certificate(dtio->ssl);
|
||||
#else
|
||||
X509* x = SSL_get_peer_certificate(dtio->ssl);
|
||||
#endif
|
||||
if(!x) {
|
||||
verbose(VERB_ALGO, "dnstap io, %s, SSL "
|
||||
"connection failed no certificate",
|
||||
@@ -1347,7 +1364,11 @@ static int dtio_ssl_check_peer(struct dt_io_thread* dtio)
|
||||
#endif
|
||||
X509_free(x);
|
||||
} else {
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
X509* x = SSL_get1_peer_certificate(dtio->ssl);
|
||||
#else
|
||||
X509* x = SSL_get_peer_certificate(dtio->ssl);
|
||||
#endif
|
||||
if(x) {
|
||||
log_cert(VERB_ALGO, "dnstap io, peer "
|
||||
"certificate", x);
|
||||
@@ -1489,8 +1510,10 @@ 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(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;
|
||||
@@ -1513,8 +1536,22 @@ void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg)
|
||||
/* no messages on the first iteration,
|
||||
* the queues are all empty */
|
||||
dtio_sleep(dtio);
|
||||
/* After putting to sleep, see if
|
||||
* a message is in a message queue,
|
||||
* if so, resume service. Stops a
|
||||
* race condition where a thread could
|
||||
* have one message but the dtio
|
||||
* also just went to sleep. With the
|
||||
* message queued between the
|
||||
* dtio_find_msg and dtio_sleep
|
||||
* calls. */
|
||||
if(dtio_find_msg(dtio)) {
|
||||
if(!dtio_add_output_event_write(dtio))
|
||||
return;
|
||||
}
|
||||
}
|
||||
return; /* nothing to do */
|
||||
if(!dtio->cur_msg)
|
||||
return; /* nothing to do */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+269
-40
@@ -75,17 +75,18 @@
|
||||
static void usage(char* argv[])
|
||||
{
|
||||
printf("usage: %s [options]\n", argv[0]);
|
||||
printf(" Listen to dnstap messages\n");
|
||||
printf(" Listen to dnstap messages\n");
|
||||
printf("stdout has dnstap log, stderr has verbose server log\n");
|
||||
printf("-u <socketpath> listen to unix socket with this file name\n");
|
||||
printf("-s <serverip[@port]> listen for TCP on the IP and port\n");
|
||||
printf("-t <serverip[@port]> listen for TLS on IP and port\n");
|
||||
printf("-x <server.key> server key file for TLS service\n");
|
||||
printf("-y <server.pem> server cert file for TLS service\n");
|
||||
printf("-z <verify.pem> cert file to verify client connections\n");
|
||||
printf("-l long format for DNS printout\n");
|
||||
printf("-v more verbose log output\n");
|
||||
printf("-h this help text\n");
|
||||
printf("-u <socketpath> listen to unix socket with this file name\n");
|
||||
printf("-s <serverip[@port]> listen for TCP on the IP and port\n");
|
||||
printf("-t <serverip[@port]> listen for TLS on IP and port\n");
|
||||
printf("-x <server.key> server key file for TLS service\n");
|
||||
printf("-y <server.pem> server cert file for TLS service\n");
|
||||
printf("-z <verify.pem> cert file to verify client connections\n");
|
||||
printf("-l long format for DNS printout\n");
|
||||
printf("-v more verbose log output\n");
|
||||
printf("-c internal unit test and exit\n");
|
||||
printf("-h this help text\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -102,6 +103,14 @@ struct main_tap_data {
|
||||
struct tap_socket_list* acceptlist;
|
||||
};
|
||||
|
||||
/* list of data */
|
||||
struct tap_data_list {
|
||||
/** next in list */
|
||||
struct tap_data_list* next;
|
||||
/** the data */
|
||||
struct tap_data* d;
|
||||
};
|
||||
|
||||
/** tap callback variables */
|
||||
struct tap_data {
|
||||
/** the fd */
|
||||
@@ -128,6 +137,10 @@ struct tap_data {
|
||||
uint8_t* frame;
|
||||
/** length of this frame */
|
||||
size_t len;
|
||||
/** back pointer to the tap_data_list entry;
|
||||
* used to NULL the forward pointer to this data
|
||||
* when this data is freed. */
|
||||
struct tap_data_list* data_list;
|
||||
};
|
||||
|
||||
/** list of sockets */
|
||||
@@ -156,8 +169,89 @@ struct tap_socket {
|
||||
char* ip;
|
||||
/** for a TLS socket, the tls context */
|
||||
SSL_CTX* sslctx;
|
||||
/** dumb way to deal with memory leaks:
|
||||
* tap_data was only freed on errors and not during exit leading to
|
||||
* false positives when testing for memory leaks. */
|
||||
struct tap_data_list* data_list;
|
||||
};
|
||||
|
||||
/** try to delete tail entries from the list if all of them have no data */
|
||||
static void tap_data_list_try_to_free_tail(struct tap_data_list* list)
|
||||
{
|
||||
struct tap_data_list* current = list;
|
||||
log_assert(!list->d);
|
||||
if(!list->next) /* we are the last, we can't remove ourselves */
|
||||
return;
|
||||
list = list->next;
|
||||
while(list) {
|
||||
if(list->d) /* a tail entry still has data; return */
|
||||
return;
|
||||
list = list->next;
|
||||
}
|
||||
/* keep the next */
|
||||
list = current->next;
|
||||
/* the tail will be removed; but not ourselves */
|
||||
current->next = NULL;
|
||||
while(list) {
|
||||
current = list;
|
||||
list = list->next;
|
||||
free(current);
|
||||
}
|
||||
}
|
||||
|
||||
/** delete the tap structure */
|
||||
static void tap_data_free(struct tap_data* data, int free_tail)
|
||||
{
|
||||
if(!data)
|
||||
return;
|
||||
if(data->ev) {
|
||||
ub_event_del(data->ev);
|
||||
ub_event_free(data->ev);
|
||||
}
|
||||
#ifdef HAVE_SSL
|
||||
SSL_free(data->ssl);
|
||||
#endif
|
||||
sock_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);
|
||||
}
|
||||
free(data);
|
||||
}
|
||||
|
||||
/** insert tap_data in the tap_data_list */
|
||||
static int tap_data_list_insert(struct tap_data_list** liststart,
|
||||
struct tap_data* d)
|
||||
{
|
||||
struct tap_data_list* entry = (struct tap_data_list*)
|
||||
malloc(sizeof(*entry));
|
||||
if(!entry)
|
||||
return 0;
|
||||
entry->next = *liststart;
|
||||
entry->d = d;
|
||||
d->data_list = entry;
|
||||
*liststart = entry;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** delete the tap_data_list and free any remaining tap_data */
|
||||
static void tap_data_list_delete(struct tap_data_list* list)
|
||||
{
|
||||
struct tap_data_list* e = list, *next;
|
||||
while(e) {
|
||||
next = e->next;
|
||||
if(e->d) {
|
||||
tap_data_free(e->d, 0);
|
||||
e->d = NULL;
|
||||
}
|
||||
free(e);
|
||||
e = next;
|
||||
}
|
||||
}
|
||||
|
||||
/** del the tap event */
|
||||
static void tap_socket_delev(struct tap_socket* s)
|
||||
{
|
||||
@@ -173,7 +267,7 @@ static void tap_socket_close(struct tap_socket* s)
|
||||
{
|
||||
if(!s) return;
|
||||
if(s->fd == -1) return;
|
||||
close(s->fd);
|
||||
sock_close(s->fd);
|
||||
s->fd = -1;
|
||||
}
|
||||
|
||||
@@ -184,6 +278,7 @@ static void tap_socket_delete(struct tap_socket* s)
|
||||
#ifdef HAVE_SSL
|
||||
SSL_CTX_free(s->sslctx);
|
||||
#endif
|
||||
tap_data_list_delete(s->data_list);
|
||||
ub_event_free(s->ev);
|
||||
free(s->socketpath);
|
||||
free(s->ip);
|
||||
@@ -728,27 +823,12 @@ static ssize_t tap_receive(struct tap_data* data, void* buf, size_t len)
|
||||
return receive_bytes(data, data->fd, buf, len);
|
||||
}
|
||||
|
||||
/** delete the tap structure */
|
||||
static void tap_data_free(struct tap_data* data)
|
||||
{
|
||||
ub_event_del(data->ev);
|
||||
ub_event_free(data->ev);
|
||||
#ifdef HAVE_SSL
|
||||
SSL_free(data->ssl);
|
||||
#endif
|
||||
close(data->fd);
|
||||
free(data->id);
|
||||
free(data->frame);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/** reply with ACCEPT control frame to bidirectional client,
|
||||
* returns 0 on error */
|
||||
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);
|
||||
@@ -759,6 +839,8 @@ 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)
|
||||
@@ -769,6 +851,7 @@ 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));
|
||||
@@ -804,6 +887,7 @@ 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;
|
||||
@@ -815,6 +899,7 @@ 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));
|
||||
@@ -842,7 +927,11 @@ static int tap_check_peer(struct tap_data* data)
|
||||
if((SSL_get_verify_mode(data->ssl)&SSL_VERIFY_PEER)) {
|
||||
/* verification */
|
||||
if(SSL_get_verify_result(data->ssl) == X509_V_OK) {
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
X509* x = SSL_get1_peer_certificate(data->ssl);
|
||||
#else
|
||||
X509* x = SSL_get_peer_certificate(data->ssl);
|
||||
#endif
|
||||
if(!x) {
|
||||
if(verbosity) log_info("SSL connection %s"
|
||||
" failed no certificate", data->id);
|
||||
@@ -864,7 +953,11 @@ static int tap_check_peer(struct tap_data* data)
|
||||
#endif
|
||||
X509_free(x);
|
||||
} else {
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
X509* x = SSL_get1_peer_certificate(data->ssl);
|
||||
#else
|
||||
X509* x = SSL_get_peer_certificate(data->ssl);
|
||||
#endif
|
||||
if(x) {
|
||||
if(verbosity)
|
||||
log_cert(VERB_ALGO, "peer certificate", x);
|
||||
@@ -906,7 +999,7 @@ static int tap_handshake(struct tap_data* data)
|
||||
return 0;
|
||||
} else if(r == 0) {
|
||||
/* closed */
|
||||
tap_data_free(data);
|
||||
tap_data_free(data, 1);
|
||||
return 0;
|
||||
} else if(want == SSL_ERROR_SYSCALL) {
|
||||
/* SYSCALL and errno==0 means closed uncleanly */
|
||||
@@ -924,7 +1017,7 @@ static int tap_handshake(struct tap_data* data)
|
||||
if(!silent)
|
||||
log_err("SSL_handshake syscall: %s",
|
||||
strerror(errno));
|
||||
tap_data_free(data);
|
||||
tap_data_free(data, 1);
|
||||
return 0;
|
||||
} else {
|
||||
unsigned long err = ERR_get_error();
|
||||
@@ -934,7 +1027,7 @@ static int tap_handshake(struct tap_data* data)
|
||||
verbose(VERB_OPS, "ssl handshake failed "
|
||||
"from %s", data->id);
|
||||
}
|
||||
tap_data_free(data);
|
||||
tap_data_free(data, 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -942,7 +1035,7 @@ static int tap_handshake(struct tap_data* data)
|
||||
data->ssl_handshake_done = 1;
|
||||
if(!tap_check_peer(data)) {
|
||||
/* closed */
|
||||
tap_data_free(data);
|
||||
tap_data_free(data, 1);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -968,7 +1061,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);
|
||||
tap_data_free(data, 1);
|
||||
return;
|
||||
} else if(ret == -1) {
|
||||
/* continue later */
|
||||
@@ -990,7 +1083,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);
|
||||
tap_data_free(data, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1003,7 +1096,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);
|
||||
tap_data_free(data, 1);
|
||||
return;
|
||||
} else if(r == -1) {
|
||||
/* continue later */
|
||||
@@ -1028,13 +1121,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);
|
||||
tap_data_free(data, 1);
|
||||
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);
|
||||
tap_data_free(data, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1046,7 +1139,6 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
|
||||
data->len = 0;
|
||||
data->len_done = 0;
|
||||
data->data_done = 0;
|
||||
|
||||
}
|
||||
|
||||
/** callback for main listening file descriptor */
|
||||
@@ -1059,7 +1151,9 @@ 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 = accept(fd, (struct sockaddr*)&addr, &addrlen);
|
||||
int s;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
s = accept(fd, (struct sockaddr*)&addr, &addrlen);
|
||||
if(s == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
/* EINTR is signal interrupt. others are closed connection. */
|
||||
@@ -1129,6 +1223,8 @@ void dtio_mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg)
|
||||
&dtio_tap_callback, data);
|
||||
if(!data->ev) fatal_exit("could not ub_event_new");
|
||||
if(ub_event_add(data->ev, NULL) != 0) fatal_exit("could not ub_event_add");
|
||||
if(!tap_data_list_insert(&tap_sock->data_list, data))
|
||||
fatal_exit("could not tap_data_list_insert");
|
||||
}
|
||||
|
||||
/** setup local accept sockets */
|
||||
@@ -1243,6 +1339,114 @@ setup_and_run(struct config_strlist_head* local_list,
|
||||
free(maindata);
|
||||
}
|
||||
|
||||
/* internal unit tests */
|
||||
static int internal_unittest()
|
||||
{
|
||||
/* unit test tap_data_list_try_to_free_tail() */
|
||||
#define unit_tap_datas_max 5
|
||||
struct tap_data* datas[unit_tap_datas_max];
|
||||
struct tap_data_list* list;
|
||||
struct tap_socket* socket = calloc(1, sizeof(*socket));
|
||||
size_t i = 0;
|
||||
log_assert(socket);
|
||||
log_assert(unit_tap_datas_max>2); /* needed for the test */
|
||||
for(i=0; i<unit_tap_datas_max; 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==unit_tap_datas_max);
|
||||
|
||||
/* 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==unit_tap_datas_max);
|
||||
|
||||
/* Free the third to last data, tail cannot be erased */
|
||||
list = socket->data_list;
|
||||
for(i=0; i<unit_tap_datas_max-3; i++) 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==unit_tap_datas_max);
|
||||
|
||||
/* Free the second to last data, try to remove tail from the third
|
||||
* again, tail (last 2) should be removed */
|
||||
list = socket->data_list;
|
||||
for(i=0; i<unit_tap_datas_max-2; i++) list = list->next;
|
||||
free(list->d);
|
||||
list->d = NULL;
|
||||
list = socket->data_list;
|
||||
while(list->d) list = list->next;
|
||||
tap_data_list_try_to_free_tail(list);
|
||||
list = socket->data_list;
|
||||
for(i=0; list; i++) list = list->next;
|
||||
log_assert(i==unit_tap_datas_max-2);
|
||||
|
||||
/* Free all the remaining data, try to remove tail from the start,
|
||||
* only the start should remain */
|
||||
list = socket->data_list;
|
||||
while(list) {
|
||||
free(list->d);
|
||||
list->d = NULL;
|
||||
list = list->next;
|
||||
}
|
||||
tap_data_list_try_to_free_tail(socket->data_list);
|
||||
list = socket->data_list;
|
||||
for(i=0; list; i++) list = list->next;
|
||||
log_assert(i==1);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/** getopt global, in case header files fail to declare it. */
|
||||
extern int optind;
|
||||
/** getopt global, in case header files fail to declare it. */
|
||||
@@ -1293,7 +1497,7 @@ int main(int argc, char** argv)
|
||||
#endif
|
||||
|
||||
/* command line options */
|
||||
while( (c=getopt(argc, argv, "hls:t:u:vx:y:z:")) != -1) {
|
||||
while( (c=getopt(argc, argv, "hcls:t:u:vx:y:z:")) != -1) {
|
||||
switch(c) {
|
||||
case 'u':
|
||||
if(!cfg_strlist_append(&local_list,
|
||||
@@ -1329,14 +1533,20 @@ int main(int argc, char** argv)
|
||||
case 'v':
|
||||
verbosity++;
|
||||
break;
|
||||
case 'c':
|
||||
#ifndef UNBOUND_DEBUG
|
||||
fatal_exit("-c option needs compilation with "
|
||||
"--enable-debug");
|
||||
#endif
|
||||
return internal_unittest();
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
usage(argv);
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
/* argc -= optind; not using further arguments */
|
||||
/* argv += optind; not using further arguments */
|
||||
|
||||
if(usessl) {
|
||||
#ifdef HAVE_SSL
|
||||
@@ -1365,6 +1575,9 @@ 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();
|
||||
@@ -1572,3 +1785,19 @@ void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(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
|
||||
|
||||
+334
@@ -1,3 +1,337 @@
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
- Fix dnstap wakeup, a running wakeup timer is left to expire and not
|
||||
increased, a timer is started when the dtio thread is sleeping,
|
||||
the timer set disabled when the dtio thread goes to sleep, and
|
||||
after sleep the thread checks to see if there are messages to log
|
||||
immediately.
|
||||
|
||||
16 July 2024: Wouter
|
||||
- For #1103: Fix to drop mesh state reference for the http2 stream
|
||||
associated with the reply, not the currently active stream. And
|
||||
it does not remove it twice on a mesh_send_reply call. The reply
|
||||
h2_stream is NULL when not in use, for more initialisation.
|
||||
|
||||
15 July 2024: Wouter
|
||||
- For #1103: fix to also drop mesh state reference when the discard
|
||||
limit is reached, when there is an error making a new recursion
|
||||
state and when the connection is dropped with is_drop.
|
||||
|
||||
12 July 2024: Yorgos
|
||||
- Add RPZ tag tests in acl_interface.tdir.
|
||||
- For #1102: clearer text for using interface-* options for the
|
||||
loopback interface.
|
||||
|
||||
12 July 2024: Wouter
|
||||
- Fix #1103: unbound 1.20.0 segmentation fault with nghttp2.
|
||||
- For #1103: fix to also drop mesh state reference when a h2 reply is
|
||||
dropped.
|
||||
|
||||
10 July 2024: Wouter
|
||||
- For #773: In contrib/unbound.service.in set unbound to start after
|
||||
network-online.target. Also for contrib/unbound_portable.service.in.
|
||||
|
||||
9 July 2024: Yorgos
|
||||
- Update list of known EDE codes.
|
||||
|
||||
8 July 2024: Wouter
|
||||
- Fix that validation reason failure that uses string print uses
|
||||
separate buffer that is passed, from the scratch validation buffer.
|
||||
- Fixup algo_needs_reason string buffer length.
|
||||
- Fix shadowed error string variable in validator dnskey handling.
|
||||
|
||||
5 July 2024: Yorgos
|
||||
- Don't check for message TTL changes if the RRsets remain the same.
|
||||
|
||||
5 July 2024: Wouter
|
||||
- Fix for neater printout for error for missing DS response.
|
||||
- Fix neater printout.
|
||||
- Fix #1099: Unbound core dump on SIGSEGV.
|
||||
- Fix for #1099: Fix to check for deleted RRset when the contents
|
||||
is updated and fetched after it is stored, and also check for a
|
||||
changed RRset.
|
||||
|
||||
4 July 2024: Wouter
|
||||
- Fix to print details about the failure to lookup a DNSKEY record
|
||||
when validation fails due to the missing DNSKEY. Also for key prime
|
||||
and DS lookups.
|
||||
|
||||
3 July 2024: Yorgos
|
||||
- Fix for repeated use of a DNAME record: first overallocate and then
|
||||
move the exact size of the init value to avoid false positive heap
|
||||
overflow reads from address sanitizers.
|
||||
|
||||
3 July 2024: Wouter
|
||||
- Fix #144: Port ipset to BSD pf tables.
|
||||
- Add unit test skip files and bison and flex output to gitignore.
|
||||
- Fix to use modstack_init in zonemd unit test.
|
||||
- Fix to remove unneeded linebreak in fptr_wlist.c.
|
||||
- Fix compile warnings in fptr_wlist.c.
|
||||
|
||||
2 July 2024: Wouter
|
||||
- Fix to remove unused include from the readzone test program.
|
||||
- Fix unused variable warning in do_cache_remove.
|
||||
- Fix compile warning in worker pthread id printout.
|
||||
|
||||
17 June 2024: Wouter
|
||||
- Fix ip-ratelimit-cookie setting, it was not applied.
|
||||
|
||||
26 June 2024: Yorgos
|
||||
- Explicitly set the RD bit for the mesh query flags when prefetching.
|
||||
These queries have no waiting client but they need to be treated as
|
||||
recursive.
|
||||
|
||||
21 June 2024: Yorgos
|
||||
- Fix pkg-config availability check in dnstap/dnstap.m4 and
|
||||
systemd.m4.
|
||||
|
||||
19 June 2024: Yorgos
|
||||
- Fix #1092: Ubuntu 22.04 Jammy fails to compile unbound 1.20.0; by
|
||||
adding helpful text for the Python interpreter version and allowing
|
||||
the default pkg-config unavailability error message to be shown.
|
||||
|
||||
17 June 2024: Wouter
|
||||
- Fix #1091: Build fails with OpenSSL >= 3.0 built with
|
||||
OPENSSL_NO_DEPRECATED.
|
||||
|
||||
7 June 2024: Wouter
|
||||
- Add unit test for validation of repeated use of a DNAME record.
|
||||
|
||||
6 June 2024: Wouter
|
||||
- Fix memory leak in setup of dsa sig.
|
||||
- Fix typos for 'the the' in text.
|
||||
- Fix validation for repeated use of a DNAME record.
|
||||
|
||||
4 June 2024: Yorgos
|
||||
- Merge #1080: AddressSanitizer detection in tdir tests and memory leak
|
||||
fixes.
|
||||
- Fix memory leak when reload_keep_cache is used and num-threads
|
||||
changes.
|
||||
- Fix memory leak on exit for unbound-dnstap-socket; creates false
|
||||
negatives during testing.
|
||||
|
||||
3 June 2024: Wouter
|
||||
- Fix to squelch connection reset by peer errors from log. And fix
|
||||
that the tcp read errors are labeled as initial for the first calls.
|
||||
|
||||
+34
-2
@@ -187,6 +187,15 @@ 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: 128
|
||||
|
||||
# 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
|
||||
@@ -228,7 +237,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-tll applies if configured.
|
||||
# cache-min-ttl applies if configured.
|
||||
# cache-min-negative-ttl: 0
|
||||
|
||||
# the time to live (TTL) value for cached roundtrip times, lameness and
|
||||
@@ -452,6 +461,10 @@ 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
|
||||
|
||||
@@ -524,6 +537,9 @@ 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).
|
||||
@@ -904,6 +920,7 @@ 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"
|
||||
@@ -968,6 +985,9 @@ 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.
|
||||
@@ -1044,6 +1064,11 @@ 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
|
||||
|
||||
@@ -1284,6 +1309,10 @@ remote-control:
|
||||
# # 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.
|
||||
@@ -1329,6 +1358,8 @@ remote-control:
|
||||
# dnstap-identity: ""
|
||||
# # if "" it uses the package version.
|
||||
# dnstap-version: ""
|
||||
# # log only 1/N messages, if 0 it is disabled. default 0.
|
||||
# dnstap-sample-rate: 0
|
||||
# dnstap-log-resolver-query-messages: no
|
||||
# dnstap-log-resolver-response-messages: no
|
||||
# dnstap-log-client-query-messages: no
|
||||
@@ -1337,7 +1368,8 @@ remote-control:
|
||||
# dnstap-log-forwarder-response-messages: no
|
||||
|
||||
# Response Policy Zones
|
||||
# RPZ policies. Applied in order of configuration. QNAME, Response IP
|
||||
# RPZ policies. Applied in order of configuration. Any match from an earlier
|
||||
# RPZ zone will terminate the RPZ lookup. 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
|
||||
|
||||
@@ -350,6 +350,41 @@ Remove a list of \fIlocal_data\fR for given view from stdin. Like local_datas_re
|
||||
.TP
|
||||
.B view_local_datas \fIview\fR
|
||||
Add a list of \fIlocal_data\fR for given view from stdin. Like local_datas.
|
||||
.TP
|
||||
.B add_cookie_secret <secret>
|
||||
Add or replace a cookie secret persistently. <secret> needs to be an 128 bit
|
||||
hex string.
|
||||
.IP
|
||||
Cookie secrets can be either \fIactive\fR or \fIstaging\fR. \fIActive\fR cookie
|
||||
secrets are used to create DNS Cookies, but verification of a DNS Cookie
|
||||
succeeds with any of the \fIactive\fR or \fIstaging\fR cookie secrets. The
|
||||
state of the current cookie secrets can be printed with the
|
||||
\fBprint_cookie_secrets\fR command.
|
||||
.IP
|
||||
When there are no cookie secrets configured yet, the <secret> is added as
|
||||
\fIactive\fR. If there is already an \fIactive\fR cookie secret, the <secret>
|
||||
is added as \fIstaging\fR or replacing an existing \fIstaging\fR secret.
|
||||
.IP
|
||||
To "roll" a cookie secret used in an anycast set. The new secret has to be
|
||||
added as staging secret to \fBall\fR nodes in the anycast set. When \fBall\fR
|
||||
nodes can verify DNS Cookies with the new secret, the new secret can be
|
||||
activated with the \fBactivate_cookie_secret\fR command. After \fBall\fR nodes
|
||||
have the new secret \fIactive\fR for at least one hour, the previous secret can
|
||||
be dropped with the \fBdrop_cookie_secret\fR command.
|
||||
.IP
|
||||
Persistence is accomplished by writing to a file which if configured with the
|
||||
\fBcookie\-secret\-file\fR option in the server section of the config file.
|
||||
This is disabled by default, "".
|
||||
.TP
|
||||
.B drop_cookie_secret
|
||||
Drop the \fIstaging\fR cookie secret.
|
||||
.TP
|
||||
.B activate_cookie_secret
|
||||
Make the current \fIstaging\fR cookie secret \fIactive\fR, and the current
|
||||
\fIactive\fR cookie secret \fIstaging\fR.
|
||||
.TP
|
||||
.B print_cookie_secrets
|
||||
Show the current configured cookie secrets with their status.
|
||||
.SH "EXIT CODE"
|
||||
The unbound\-control program exits with status code 1 on error, 0 on success.
|
||||
.SH "SET UP"
|
||||
@@ -571,6 +606,10 @@ queries waiting for request stream completion.
|
||||
Memory in bytes used by the HTTP/2 response buffers. Containing DNS responses
|
||||
waiting to be written back to the clients.
|
||||
.TP
|
||||
.I mem.quic
|
||||
Memory in bytes used by QUIC. Containing connection information, stream
|
||||
information, queries read and responses written back to the clients.
|
||||
.TP
|
||||
.I histogram.<sec>.<usec>.to.<sec>.<usec>
|
||||
Shows a histogram, summed over all threads. Every element counts the
|
||||
recursive queries whose reply time fit between the lower and upper bound.
|
||||
@@ -619,6 +658,10 @@ Number of queries that were made using HTTPS towards the Unbound server.
|
||||
These are also counted in num.query.tcp and num.query.tls, because HTTPS
|
||||
uses TLS and TCP.
|
||||
.TP
|
||||
.I num.query.quic
|
||||
Number of queries that were made using QUIC towards the Unbound server.
|
||||
These are also counted in num.query.tls, because TLS is used for these queries.
|
||||
.TP
|
||||
.I num.query.ipv6
|
||||
Number of queries that were made using IPv6 towards the Unbound server.
|
||||
.TP
|
||||
|
||||
+102
-22
@@ -566,6 +566,9 @@ tls\-system\-cert to load CA certs, otherwise the connections cannot be
|
||||
authenticated. This option enables TLS for all of them, but if you do not set
|
||||
this you can configure TLS specifically for some forward zones with
|
||||
forward\-tls\-upstream. And also with stub\-tls\-upstream.
|
||||
If the tls\-upstream option is enabled, it is for all the forwards and stubs,
|
||||
where the forward\-tls\-upstream and stub\-tls\-upstream options are ignored,
|
||||
as if they had been set to yes.
|
||||
.TP
|
||||
.B ssl\-upstream: \fI<yes or no>
|
||||
Alternate syntax for \fBtls\-upstream\fR. If both are present in the config
|
||||
@@ -716,6 +719,18 @@ PROXYv2 is supported for UDP and TCP/TLS listening interfaces.
|
||||
There is no support for PROXYv2 on a DoH or DNSCrypt listening interface.
|
||||
Can list multiple, each on a new statement.
|
||||
.TP
|
||||
.B quic\-port: \fI<number>
|
||||
The port number on which to provide DNS-over-QUIC service, default 853, only
|
||||
interfaces configured with that port number as @number get the QUIC service.
|
||||
The interface uses QUIC for the UDP traffic on that port number.
|
||||
.TP
|
||||
.B quic\-size: \fI<size in bytes>
|
||||
Maximum number of bytes for all QUIC buffers and data combined. Default is 8
|
||||
megabytes. A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes,
|
||||
megabytes or gigabytes (1024*1024 bytes in a megabyte). New connections receive
|
||||
connection refused when the limit is exceeded. New streams are reset when the
|
||||
limit is exceeded.
|
||||
.TP
|
||||
.B use\-systemd: \fI<yes or no>
|
||||
Enable or disable systemd socket activation.
|
||||
Default is no.
|
||||
@@ -788,7 +803,8 @@ transports, regardless of the presence of an DNS Cookie and regardless of the
|
||||
UDP queries without a DNS Cookie receive REFUSED responses with the TC flag set,
|
||||
that may trigger fall back to TCP for those clients.
|
||||
.IP
|
||||
By default only localhost is \fIallow\fRed, the rest is \fIrefuse\fRd.
|
||||
By default only localhost (the 127.0.0.0/8 IP netblock, not the loopback
|
||||
interface) is implicitly \fIallow\fRed, the rest is \fIrefuse\fRd.
|
||||
The default is \fIrefuse\fRd, because that is protocol\-friendly. The DNS
|
||||
protocol is not designed to handle dropped packets due to policy, and
|
||||
dropping may result in (possibly excessive) retried queries.
|
||||
@@ -824,8 +840,12 @@ Similar to \fBaccess\-control:\fR but for interfaces.
|
||||
.IP
|
||||
The action is the same as the ones defined under \fBaccess\-control:\fR.
|
||||
Interfaces are \fIrefuse\fRd by default.
|
||||
By default only localhost (the IP netblock, not the loopback interface) is
|
||||
\fIallow\fRed through the default \fBaccess\-control:\fR behavior.
|
||||
By default only localhost (the 127.0.0.0/8 IP netblock, not the loopback
|
||||
interface) is implicitly \fIallow\fRed through the default
|
||||
\fBaccess\-control:\fR behavior.
|
||||
This also means that any attempt to use the \fBinterface-*:\fR options for the
|
||||
loopback interface will not work as they will be overridden by the implicit
|
||||
default "\fBaccess\-control:\fR 127.0.0.0/8 allow" option.
|
||||
.IP
|
||||
Note that the interface needs to be already specified with \fBinterface:\fR
|
||||
and that any \fBaccess-control*:\fR setting overrides all \fBinterface-*:\fR
|
||||
@@ -931,6 +951,10 @@ Sets logfile lines to use a timestamp in UTC ascii. Default is no, which
|
||||
prints the seconds since 1970 in brackets. No effect if using syslog, in
|
||||
that case syslog formats the timestamp printed into the log files.
|
||||
.TP
|
||||
.B log\-time\-iso:\fR <yes or no>
|
||||
Log time in ISO8601 format, if \fBlog\-time\-ascii:\fR yes is also set.
|
||||
Default is no.
|
||||
.TP
|
||||
.B log\-queries: \fI<yes or no>
|
||||
Prints one line per query to the log, with the log timestamp and IP address,
|
||||
name, type and class. Default is no. Note that it takes time to print these
|
||||
@@ -1043,6 +1067,11 @@ payload is very large.
|
||||
.B harden\-glue: \fI<yes or no>
|
||||
Will trust glue only if it is within the servers authority. Default is yes.
|
||||
.TP
|
||||
.B harden\-unverified\-glue: \fI<yes or no>
|
||||
Will trust only in-zone glue. Will try to resolve all out of zone
|
||||
(\fI<unverfied>) glue. Will fallback to the original glue if unable to resolve.
|
||||
Default is no.
|
||||
.TP
|
||||
.B harden\-dnssec\-stripped: \fI<yes or no>
|
||||
Require DNSSEC data for trust\-anchored zones, if such data is absent,
|
||||
the zone becomes bogus. If turned off, and no DNSSEC data is received
|
||||
@@ -1166,10 +1195,11 @@ IP6 ::1 and IP4 127.0.0.1/8. If no, then localhost can be used to send
|
||||
queries to. Default is yes.
|
||||
.TP
|
||||
.B prefetch: \fI<yes or no>
|
||||
If yes, message cache elements are prefetched before they expire to
|
||||
keep the cache up to date. Default is no. Turning it on gives about
|
||||
10 percent more traffic and load on the machine, but popular items do
|
||||
not expire from the cache.
|
||||
If yes, cache hits on message cache elements that are on their last 10 percent
|
||||
of their TTL value trigger a prefetch to keep the cache up to date.
|
||||
Default is no.
|
||||
Turning it on gives about 10 percent more traffic and load on the machine, but
|
||||
popular items do not expire from the cache.
|
||||
.TP
|
||||
.B prefetch\-key: \fI<yes or no>
|
||||
If yes, fetch the DNSKEYs earlier in the validation process, when a DS
|
||||
@@ -1189,12 +1219,13 @@ from the query ID, for speed and thread safety). Default is yes.
|
||||
.B minimal-responses: \fI<yes or no>
|
||||
If yes, Unbound does not insert authority/additional sections into response
|
||||
messages when those sections are not required. This reduces response
|
||||
size significantly, and may avoid TCP fallback for some responses.
|
||||
This may cause a slight speedup. The default is yes, even though the DNS
|
||||
size significantly, and may avoid TCP fallback for some responses which may
|
||||
cause a slight speedup. The default is yes, even though the DNS
|
||||
protocol RFCs mandate these sections, and the additional content could
|
||||
be of use and save roundtrips for clients. Because they are not used,
|
||||
and the saved roundtrips are easier saved with prefetch, whilst this is
|
||||
faster.
|
||||
save roundtrips for clients that use the additional content.
|
||||
However these sections are hardly used by clients.
|
||||
Enabling prefetch can benefit clients that need the additional content
|
||||
by trying to keep that content fresh in the cache.
|
||||
.TP
|
||||
.B disable-dnssec-lame-check: \fI<yes or no>
|
||||
If true, disables the DNSSEC lameness check in the iterator. This check
|
||||
@@ -1952,6 +1983,23 @@ Changing this value needs caution as it can allow long CNAME chains to be
|
||||
accepted, where Unbound needs to verify (resolve) each link individually.
|
||||
Default is 11.
|
||||
.TP 5
|
||||
.B iter\-scrub\-ns: \fI<number>
|
||||
Limit on the number of NS records allowed in an rrset of type NS, from the
|
||||
iterator scrubber. This protects the internals of the resolver from overly
|
||||
large NS sets. Default is 20.
|
||||
.TP 5
|
||||
.B iter\-scrub\-cname: \fI<number>
|
||||
Limit on the number of CNAME, DNAME records in an answer, from the iterator
|
||||
scrubber. This protects the internals of the resolver from overly long
|
||||
indirection chains. Clips off the remainder of the reply packet at that point.
|
||||
Default is 11.
|
||||
.TP 5
|
||||
.B max\-global\-quota: \fI<number>
|
||||
Limit on the number of upstream queries sent out for an incoming query and
|
||||
its subqueries from recursion. It is not reset during the resolution. When
|
||||
it is exceeded the query is failed and the lookup process stops.
|
||||
Default is 128.
|
||||
.TP 5
|
||||
.B fast\-server\-permil: \fI<number>
|
||||
Specify how many times out of 1000 to pick from the set of fastest servers.
|
||||
0 turns the feature off. A value of 900 would pick from the fastest
|
||||
@@ -1978,6 +2026,20 @@ Useful to explicitly set for servers in an anycast deployment that need to
|
||||
share the secret in order to verify each other's Server Cookies.
|
||||
An example hex string would be "000102030405060708090a0b0c0d0e0f".
|
||||
Default is a 128 bits random secret generated at startup time.
|
||||
This option is ignored if a \fBcookie\-secret\-file\fR is
|
||||
present. In that case the secrets from that file are used in DNS Cookie
|
||||
calculations.
|
||||
.TP 5
|
||||
.B cookie\-secret\-file: \fI<filename>
|
||||
File from which the secrets are read used in DNS Cookie calculations. When this
|
||||
file exists, the secrets in this file are used and the secret specified by the
|
||||
\fBcookie-secret\fR option is ignored.
|
||||
Enable it by setting a filename, like "/usr/local/etc/unbound_cookiesecrets.txt".
|
||||
The content of this file must be manipulated with the \fBadd_cookie_secret\fR,
|
||||
\fBdrop_cookie_secret\fR and \fBactivate_cookie_secret\fR commands to the
|
||||
\fIunbound\-control\fR(8) tool. Please see that manpage on how to perform a
|
||||
safe cookie secret rollover.
|
||||
Default is "" (disabled).
|
||||
.TP 5
|
||||
.B edns\-client\-string: \fI<IP netblock> <string>
|
||||
Include an EDNS0 option containing configured ascii string in queries with
|
||||
@@ -2769,6 +2831,14 @@ if the Redis server does not have the requested data, and will try to
|
||||
re-establish a new connection later.
|
||||
This option defaults to 100 milliseconds.
|
||||
.TP
|
||||
.B redis-command-timeout: \fI<msec>\fR
|
||||
The timeout to use for redis commands, in milliseconds. If 0, it uses the
|
||||
redis\-timeout value. The default is 0.
|
||||
.TP
|
||||
.B redis-connect-timeout: \fI<msec>\fR
|
||||
The timeout to use for redis connection set up, in milliseconds. If 0, it
|
||||
uses the redis\-timeout value. The default is 0.
|
||||
.TP
|
||||
.B redis-expire-records: \fI<yes or no>
|
||||
If Redis record expiration is enabled. If yes, Unbound sets timeout for Redis
|
||||
records so that Redis can evict keys that have expired automatically. If
|
||||
@@ -2847,6 +2917,13 @@ Default is "".
|
||||
The version to send with messages, if "" the package version is used.
|
||||
Default is "".
|
||||
.TP
|
||||
.B dnstap-sample-rate: \fI<number>
|
||||
The sample rate for log of messages, it logs only 1/N messages. With 0 it
|
||||
is disabled. Default is 0. This is useful in a high volume environment,
|
||||
where log functionality would otherwise not be reliable. For example 10
|
||||
would spend only 1/10th time on logging, and 100 would only spend a
|
||||
hundredth of the time on logging.
|
||||
.TP
|
||||
.B dnstap-log-resolver-query-messages: \fI<yes or no>
|
||||
Enable to log resolver query messages. Default is no.
|
||||
These are messages from Unbound to upstream servers.
|
||||
@@ -2871,9 +2948,11 @@ Enable to log forwarder response messages. Default is no.
|
||||
.SS Response Policy Zone Options
|
||||
.LP
|
||||
Response Policy Zones are configured with \fBrpz:\fR, and each one must have a
|
||||
\fBname:\fR. There can be multiple ones, by listing multiple rpz clauses, each
|
||||
with a different name. RPZ clauses are applied in order of configuration. The
|
||||
\fBrespip\fR module needs to be added to the \fBmodule-config\fR, e.g.:
|
||||
\fBname:\fR. There can be multiple ones, by listing multiple RPZ clauses, each
|
||||
with a different name. RPZ clauses are applied in order of configuration and
|
||||
any match from an earlier RPZ zone will terminate the RPZ lookup. Note that a
|
||||
PASSTHRU action is still considered a match.
|
||||
The \fBrespip\fR module needs to be added to the \fBmodule-config\fR, e.g.:
|
||||
\fBmodule-config: "respip validator iterator"\fR.
|
||||
.P
|
||||
QNAME, Response IP Address, nsdname, nsip and clientip triggers are supported.
|
||||
@@ -2881,12 +2960,13 @@ Supported actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp\-only
|
||||
and drop. RPZ QNAME triggers are applied after \fBlocal\-zones\fR and
|
||||
before \fBauth\-zones\fR.
|
||||
.P
|
||||
The rpz zone is formatted with a SOA start record as usual. The items in
|
||||
the zone are entries, that specify what to act on (the trigger) and what to
|
||||
do (the action). The trigger to act on is recorded in the name, the action
|
||||
to do is recorded as the resource record. The names all end in the zone
|
||||
name, so you could type the trigger names without a trailing dot in the
|
||||
zonefile.
|
||||
The RPZ zone is a regular DNS zone formatted with a SOA start record as usual.
|
||||
The items in the zone are entries, that specify what to act on (the trigger)
|
||||
and what to do (the action).
|
||||
The trigger to act on is recorded in the name, the action to do is recorded as
|
||||
the resource record.
|
||||
The names all end in the zone name, so you could type the trigger names without
|
||||
a trailing dot in the zonefile.
|
||||
.P
|
||||
An example RPZ record, that answers example.com with NXDOMAIN
|
||||
.nf
|
||||
@@ -2986,7 +3066,7 @@ externally blocked. Default is no.
|
||||
If enabled the zone is authoritatively answered for and queries for the RPZ
|
||||
zone information are answered to downstream clients. This is useful for
|
||||
monitoring scripts, that can then access the SOA information to check if
|
||||
the rpz information is up to date. Default is no.
|
||||
the RPZ information is up to date. Default is no.
|
||||
.TP
|
||||
.B tags: \fI<list of tags>
|
||||
Limit the policies from this RPZ clause to clients with a matching tag. Tags
|
||||
|
||||
+4
-4
@@ -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 @@ CLANG_ASSISTED_PARSING = 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 @@ CLANG_ADD_INC_PATHS = YES
|
||||
# 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 @@ CLANG_OPTIONS =
|
||||
# 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
|
||||
|
||||
@@ -297,8 +297,8 @@ inplace_cb_delete_wrapped(struct module_env* env, enum inplace_cb_list_type type
|
||||
*/
|
||||
static struct module_func_block dynlibmod_block = {
|
||||
"dynlib",
|
||||
&dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate, &dynlibmod_inform_super,
|
||||
&dynlibmod_clear, &dynlibmod_get_mem
|
||||
NULL, NULL, &dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate,
|
||||
&dynlibmod_inform_super, &dynlibmod_clear, &dynlibmod_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block* dynlibmod_get_funcblock(void)
|
||||
|
||||
@@ -995,7 +995,8 @@ subnetmod_get_mem(struct module_env *env, int id)
|
||||
* The module function block
|
||||
*/
|
||||
static struct module_func_block subnetmod_block = {
|
||||
"subnetcache", &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
|
||||
"subnetcache",
|
||||
NULL, NULL, &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
|
||||
&subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -615,7 +615,7 @@ ipsecmod_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block ipsecmod_block = {
|
||||
"ipsecmod",
|
||||
&ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate,
|
||||
NULL, NULL, &ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate,
|
||||
&ipsecmod_inform_super, &ipsecmod_clear, &ipsecmod_get_mem
|
||||
};
|
||||
|
||||
|
||||
+162
-47
@@ -17,9 +17,19 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/parseutil.h"
|
||||
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <net/pfvar.h>
|
||||
typedef intptr_t filter_dev;
|
||||
#else
|
||||
#include <libmnl/libmnl.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/ipset/ip_set.h>
|
||||
typedef struct mnl_socket * filter_dev;
|
||||
#endif
|
||||
|
||||
#define BUFF_LEN 256
|
||||
|
||||
@@ -41,24 +51,95 @@ static int error_response(struct module_qstate* qstate, int id, int rcode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mnl_socket * open_mnl_socket() {
|
||||
struct mnl_socket *mnl;
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
static void * open_filter() {
|
||||
filter_dev dev;
|
||||
|
||||
mnl = mnl_socket_open(NETLINK_NETFILTER);
|
||||
if (!mnl) {
|
||||
dev = open("/dev/pf", O_RDWR);
|
||||
if (dev == -1) {
|
||||
log_err("open(\"/dev/pf\") failed: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return (void *)dev;
|
||||
}
|
||||
#else
|
||||
static void * open_filter() {
|
||||
filter_dev dev;
|
||||
|
||||
dev = mnl_socket_open(NETLINK_NETFILTER);
|
||||
if (!dev) {
|
||||
log_err("ipset: could not open netfilter.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mnl_socket_bind(mnl, 0, MNL_SOCKET_AUTOPID) < 0) {
|
||||
mnl_socket_close(mnl);
|
||||
if (mnl_socket_bind(dev, 0, MNL_SOCKET_AUTOPID) < 0) {
|
||||
mnl_socket_close(dev);
|
||||
log_err("ipset: could not bind netfilter.");
|
||||
return NULL;
|
||||
}
|
||||
return mnl;
|
||||
return (void *)dev;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int add_to_ipset(struct mnl_socket *mnl, const char *setname, const void *ipaddr, int af) {
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
static int add_to_ipset(filter_dev dev, const char *setname, const void *ipaddr, int af) {
|
||||
struct pfioc_table io;
|
||||
struct pfr_addr addr;
|
||||
const char *p;
|
||||
int i;
|
||||
|
||||
bzero(&io, sizeof(io));
|
||||
bzero(&addr, sizeof(addr));
|
||||
|
||||
p = strrchr(setname, '/');
|
||||
if (p) {
|
||||
i = p - setname;
|
||||
if (i >= PATH_MAX) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
memcpy(io.pfrio_table.pfrt_anchor, setname, i);
|
||||
if (i < PATH_MAX)
|
||||
io.pfrio_table.pfrt_anchor[i] = '\0';
|
||||
p++;
|
||||
}
|
||||
else
|
||||
p = setname;
|
||||
|
||||
if (strlen(p) >= PF_TABLE_NAME_SIZE) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
strlcpy(io.pfrio_table.pfrt_name, p, PF_TABLE_NAME_SIZE);
|
||||
|
||||
io.pfrio_buffer = &addr;
|
||||
io.pfrio_size = 1;
|
||||
io.pfrio_esize = sizeof(addr);
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
addr.pfra_ip4addr = *(struct in_addr *)ipaddr;
|
||||
addr.pfra_net = 32;
|
||||
break;
|
||||
case AF_INET6:
|
||||
addr.pfra_ip6addr = *(struct in6_addr *)ipaddr;
|
||||
addr.pfra_net = 128;
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
addr.pfra_af = af;
|
||||
|
||||
if (ioctl(dev, DIOCRADDADDRS, &io) == -1) {
|
||||
log_err("ioctl failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int add_to_ipset(filter_dev dev, const char *setname, const void *ipaddr, int af) {
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfg;
|
||||
struct nlattr *nested[2];
|
||||
@@ -91,14 +172,15 @@ static int add_to_ipset(struct mnl_socket *mnl, const char *setname, const void
|
||||
mnl_attr_nest_end(nlh, nested[1]);
|
||||
mnl_attr_nest_end(nlh, nested[0]);
|
||||
|
||||
if (mnl_socket_sendto(mnl, nlh, nlh->nlmsg_len) < 0) {
|
||||
if (mnl_socket_sendto(dev, nlh, nlh->nlmsg_len) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
|
||||
ipset_add_rrset_data(struct ipset_env *ie,
|
||||
struct packed_rrset_data *d, const char* setname, int af,
|
||||
const char* dname)
|
||||
{
|
||||
@@ -123,12 +205,16 @@ ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
|
||||
snprintf(ip, sizeof(ip), "(inet_ntop_error)");
|
||||
verbose(VERB_QUERY, "ipset: add %s to %s for %s", ip, setname, dname);
|
||||
}
|
||||
ret = add_to_ipset(mnl, setname, rr_data + 2, af);
|
||||
ret = add_to_ipset((filter_dev)ie->dev, setname, rr_data + 2, af);
|
||||
if (ret < 0) {
|
||||
log_err("ipset: could not add %s into %s", dname, setname);
|
||||
|
||||
mnl_socket_close(mnl);
|
||||
ie->mnl = NULL;
|
||||
#if HAVE_NET_PFVAR_H
|
||||
/* don't close as we might not be able to open again due to dropped privs */
|
||||
#else
|
||||
mnl_socket_close((filter_dev)ie->dev);
|
||||
ie->dev = NULL;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -137,8 +223,8 @@ ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
|
||||
|
||||
static int
|
||||
ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
|
||||
struct mnl_socket *mnl, struct ub_packed_rrset_key *rrset,
|
||||
const char *qname, const int qlen, const char *setname, int af)
|
||||
struct ub_packed_rrset_key *rrset, const char *qname, int qlen,
|
||||
const char *setname, int af)
|
||||
{
|
||||
static char dname[BUFF_LEN];
|
||||
const char *ds, *qs;
|
||||
@@ -152,11 +238,20 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
|
||||
log_err("bad domain name");
|
||||
return -1;
|
||||
}
|
||||
if (dname[dlen - 1] == '.') {
|
||||
dlen--;
|
||||
}
|
||||
if (qname[qlen - 1] == '.') {
|
||||
qlen--;
|
||||
}
|
||||
|
||||
for (p = env->cfg->local_zones_ipset; p; p = p->next) {
|
||||
ds = NULL;
|
||||
qs = NULL;
|
||||
plen = strlen(p->str);
|
||||
if (p->str[plen - 1] == '.') {
|
||||
plen--;
|
||||
}
|
||||
|
||||
if (dlen == plen || (dlen > plen && dname[dlen - plen - 1] == '.' )) {
|
||||
ds = dname + (dlen - plen);
|
||||
@@ -167,8 +262,7 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
|
||||
if ((ds && strncasecmp(p->str, ds, plen) == 0)
|
||||
|| (qs && strncasecmp(p->str, qs, plen) == 0)) {
|
||||
d = (struct packed_rrset_data*)rrset->entry.data;
|
||||
ipset_add_rrset_data(ie, mnl, d, setname,
|
||||
af, dname);
|
||||
ipset_add_rrset_data(ie, d, setname, af, dname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -178,7 +272,6 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
|
||||
static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
|
||||
struct query_info qinfo, struct ipset_env *ie)
|
||||
{
|
||||
struct mnl_socket *mnl;
|
||||
size_t i;
|
||||
const char *setname;
|
||||
struct ub_packed_rrset_key *rrset;
|
||||
@@ -186,15 +279,17 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
|
||||
static char qname[BUFF_LEN];
|
||||
int qlen;
|
||||
|
||||
mnl = (struct mnl_socket *)ie->mnl;
|
||||
if (!mnl) {
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
#else
|
||||
if (!ie->dev) {
|
||||
/* retry to create mnl socket */
|
||||
mnl = open_mnl_socket();
|
||||
if (!mnl) {
|
||||
ie->dev = open_filter();
|
||||
if (!ie->dev) {
|
||||
log_warn("ipset open_filter failed");
|
||||
return -1;
|
||||
}
|
||||
ie->mnl = mnl;
|
||||
}
|
||||
#endif
|
||||
|
||||
qlen = sldns_wire2str_dname_buf(qinfo.qname, qinfo.qname_len,
|
||||
qname, BUFF_LEN);
|
||||
@@ -217,8 +312,8 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
|
||||
}
|
||||
|
||||
if (setname) {
|
||||
if(ipset_check_zones_for_rrset(env, ie, mnl, rrset,
|
||||
qname, qlen, setname, af) == -1)
|
||||
if(ipset_check_zones_for_rrset(env, ie, rrset, qname,
|
||||
qlen, setname, af) == -1)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -226,7 +321,7 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipset_init(struct module_env* env, int id) {
|
||||
int ipset_startup(struct module_env* env, int id) {
|
||||
struct ipset_env *ipset_env;
|
||||
|
||||
ipset_env = (struct ipset_env *)calloc(1, sizeof(struct ipset_env));
|
||||
@@ -237,7 +332,43 @@ int ipset_init(struct module_env* env, int id) {
|
||||
|
||||
env->modinfo[id] = (void *)ipset_env;
|
||||
|
||||
ipset_env->mnl = NULL;
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
ipset_env->dev = open_filter();
|
||||
if (!ipset_env->dev) {
|
||||
log_err("ipset open_filter failed");
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
ipset_env->dev = NULL;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ipset_destartup(struct module_env* env, int id) {
|
||||
filter_dev dev;
|
||||
struct ipset_env *ipset_env;
|
||||
|
||||
if (!env || !env->modinfo[id]) {
|
||||
return;
|
||||
}
|
||||
ipset_env = (struct ipset_env*)env->modinfo[id];
|
||||
|
||||
dev = (filter_dev)ipset_env->dev;
|
||||
if (dev) {
|
||||
#if HAVE_NET_PFVAR_H
|
||||
close(dev);
|
||||
#else
|
||||
mnl_socket_close(dev);
|
||||
#endif
|
||||
ipset_env->dev = NULL;
|
||||
}
|
||||
|
||||
free(ipset_env);
|
||||
env->modinfo[id] = NULL;
|
||||
}
|
||||
|
||||
int ipset_init(struct module_env* env, int id) {
|
||||
struct ipset_env *ipset_env = env->modinfo[id];
|
||||
|
||||
ipset_env->name_v4 = env->cfg->ipset_name_v4;
|
||||
ipset_env->name_v6 = env->cfg->ipset_name_v6;
|
||||
@@ -253,24 +384,8 @@ int ipset_init(struct module_env* env, int id) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ipset_deinit(struct module_env *env, int id) {
|
||||
struct mnl_socket *mnl;
|
||||
struct ipset_env *ipset_env;
|
||||
|
||||
if (!env || !env->modinfo[id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
ipset_env = (struct ipset_env *)env->modinfo[id];
|
||||
|
||||
mnl = (struct mnl_socket *)ipset_env->mnl;
|
||||
if (mnl) {
|
||||
mnl_socket_close(mnl);
|
||||
ipset_env->mnl = NULL;
|
||||
}
|
||||
|
||||
free(ipset_env);
|
||||
env->modinfo[id] = NULL;
|
||||
void ipset_deinit(struct module_env *ATTR_UNUSED(env), int ATTR_UNUSED(id)) {
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static int ipset_new(struct module_qstate* qstate, int id) {
|
||||
@@ -376,8 +491,8 @@ size_t ipset_get_mem(struct module_env *env, int id) {
|
||||
*/
|
||||
static struct module_func_block ipset_block = {
|
||||
"ipset",
|
||||
&ipset_init, &ipset_deinit, &ipset_operate,
|
||||
&ipset_inform_super, &ipset_clear, &ipset_get_mem
|
||||
&ipset_startup, &ipset_destartup, &ipset_init, &ipset_deinit,
|
||||
&ipset_operate, &ipset_inform_super, &ipset_clear, &ipset_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block * ipset_get_funcblock(void) {
|
||||
|
||||
+5
-1
@@ -37,7 +37,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
struct ipset_env {
|
||||
void* mnl;
|
||||
void* dev;
|
||||
|
||||
int v4_enabled;
|
||||
int v6_enabled;
|
||||
@@ -50,6 +50,10 @@ struct ipset_qstate {
|
||||
int dummy;
|
||||
};
|
||||
|
||||
/** Startup the ipset module */
|
||||
int ipset_startup(struct module_env* env, int id);
|
||||
/** Destartup the ipset module */
|
||||
void ipset_destartup(struct module_env* env, int id);
|
||||
/** Init the ipset module */
|
||||
int ipset_init(struct module_env* env, int id);
|
||||
/** Deinit the ipset module */
|
||||
|
||||
@@ -367,6 +367,47 @@ 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
|
||||
@@ -387,6 +428,7 @@ 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)
|
||||
@@ -401,6 +443,16 @@ 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,
|
||||
@@ -420,6 +472,7 @@ 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 */
|
||||
@@ -460,6 +513,7 @@ 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 &&
|
||||
@@ -507,6 +561,10 @@ 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;
|
||||
}
|
||||
@@ -522,6 +580,11 @@ 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 */
|
||||
@@ -578,6 +641,25 @@ 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 */
|
||||
@@ -789,6 +871,7 @@ 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;
|
||||
@@ -894,6 +977,16 @@ 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);
|
||||
@@ -906,6 +999,26 @@ 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;
|
||||
}
|
||||
|
||||
@@ -1564,3 +1564,45 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,4 +428,11 @@ 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
#endif /* ITERATOR_ITER_UTILS_H */
|
||||
|
||||
+67
-16
@@ -70,6 +70,8 @@
|
||||
#include "sldns/parseutil.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
/* number of packets */
|
||||
int MAX_GLOBAL_QUOTA = 128;
|
||||
/* in msec */
|
||||
int UNKNOWN_SERVER_NICENESS = 376;
|
||||
/* in msec */
|
||||
@@ -252,7 +254,7 @@ 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))
|
||||
super->region, super_iq->dp, 0))
|
||||
log_err("out of memory adding missing");
|
||||
}
|
||||
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
|
||||
@@ -320,16 +322,21 @@ 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_ttl_reset)) != NULL) {
|
||||
qstate->env->cfg->serve_expired)) != NULL) {
|
||||
struct reply_info* rep = (struct reply_info*)msg->entry.data;
|
||||
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 "
|
||||
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 "
|
||||
"response in cache");
|
||||
rep->serve_expired_ttl = *qstate->env->now +
|
||||
qstate->env->cfg->serve_expired_ttl;
|
||||
rep->serve_expired_norec_ttl = NORR_TTL +
|
||||
*qstate->env->now;
|
||||
}
|
||||
if(rep && (FLAGS_GET_RCODE(rep->flags) ==
|
||||
LDNS_RCODE_NOERROR ||
|
||||
@@ -407,8 +414,11 @@ 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*));
|
||||
@@ -421,8 +431,11 @@ 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,
|
||||
@@ -760,6 +773,14 @@ 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
|
||||
@@ -1560,6 +1581,11 @@ 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
|
||||
@@ -2137,6 +2163,15 @@ 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);
|
||||
}
|
||||
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;
|
||||
@@ -2179,7 +2214,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))
|
||||
qstate->region, iq->dp, 0))
|
||||
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");
|
||||
@@ -3008,6 +3043,17 @@ 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+1];
|
||||
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);
|
||||
@@ -3400,7 +3446,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)) {
|
||||
qstate->region, iq->dp, 0)) {
|
||||
errinf(qstate, "malloc failure, copy extra info into delegation point");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
@@ -3969,6 +4015,8 @@ 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 --;
|
||||
@@ -4331,7 +4379,10 @@ 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) {
|
||||
@@ -4489,8 +4540,8 @@ iter_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block iter_block = {
|
||||
"iterator",
|
||||
&iter_init, &iter_deinit, &iter_operate, &iter_inform_super,
|
||||
&iter_clear, &iter_get_mem
|
||||
NULL, NULL, &iter_init, &iter_deinit, &iter_operate,
|
||||
&iter_inform_super, &iter_clear, &iter_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block*
|
||||
|
||||
@@ -55,6 +55,9 @@ 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
|
||||
@@ -248,6 +251,9 @@ 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,
|
||||
|
||||
@@ -75,7 +75,9 @@ context_finalize(struct ub_ctx* ctx)
|
||||
ctx->pipe_pid = getpid();
|
||||
cfg_apply_local_port_policy(cfg, 65536);
|
||||
config_apply(cfg);
|
||||
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
if(!modstack_call_startup(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
return UB_INITFAIL;
|
||||
if(!modstack_call_init(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
return UB_INITFAIL;
|
||||
listen_setup_locks();
|
||||
log_edns_known_options(VERB_ALGO, ctx->env);
|
||||
@@ -393,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, sizeof(uint32_t), 2);
|
||||
uint8_t* p = (uint8_t*)reallocarray(NULL, 2, sizeof(uint32_t));
|
||||
if(!p) return NULL;
|
||||
*len = 2*sizeof(uint32_t);
|
||||
sldns_write_uint32(p, UB_LIBCMD_CANCEL);
|
||||
|
||||
@@ -188,7 +188,9 @@ ub_ctx_create(void)
|
||||
int e = errno;
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
config_delete(ctx->env->cfg);
|
||||
modstack_desetup(&ctx->mods, ctx->env);
|
||||
modstack_call_deinit(&ctx->mods, ctx->env);
|
||||
modstack_call_destartup(&ctx->mods, ctx->env);
|
||||
modstack_free(&ctx->mods);
|
||||
listen_desetup_locks();
|
||||
edns_known_options_delete(ctx->env);
|
||||
edns_strings_delete(ctx->env->edns_strings);
|
||||
@@ -202,7 +204,9 @@ ub_ctx_create(void)
|
||||
tube_delete(ctx->qq_pipe);
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
config_delete(ctx->env->cfg);
|
||||
modstack_desetup(&ctx->mods, ctx->env);
|
||||
modstack_call_deinit(&ctx->mods, ctx->env);
|
||||
modstack_call_destartup(&ctx->mods, ctx->env);
|
||||
modstack_free(&ctx->mods);
|
||||
listen_desetup_locks();
|
||||
edns_known_options_delete(ctx->env);
|
||||
edns_strings_delete(ctx->env->edns_strings);
|
||||
@@ -360,7 +364,9 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
||||
}
|
||||
libworker_delete_event(ctx->event_worker);
|
||||
|
||||
modstack_desetup(&ctx->mods, ctx->env);
|
||||
modstack_call_deinit(&ctx->mods, ctx->env);
|
||||
modstack_call_destartup(&ctx->mods, ctx->env);
|
||||
modstack_free(&ctx->mods);
|
||||
a = ctx->alloc_list;
|
||||
while(a) {
|
||||
na = a->super;
|
||||
|
||||
@@ -292,6 +292,7 @@ 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);
|
||||
@@ -1057,3 +1058,19 @@ 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
|
||||
|
||||
@@ -30,6 +30,7 @@ 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")
|
||||
|
||||
@@ -845,6 +845,10 @@ 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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ Generate a distribution tar file for unbound.
|
||||
(which will then be unbound-<version>rc<number>)
|
||||
-u git_url Retrieve the source from the specified repository url.
|
||||
Detected from the working copy if not specified.
|
||||
-b git_branch Retrieve the the specified branch or tag.
|
||||
-b git_branch Retrieve the specified branch or tag.
|
||||
Detected from the working copy if not specified.
|
||||
-wssl openssl.xx.tar.gz Also build openssl from tarball for windows dist.
|
||||
-wxp expat.xx.tar.gz Also build expat from tarball for windows dist.
|
||||
|
||||
@@ -176,6 +176,10 @@ 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.
|
||||
|
||||
@@ -1009,6 +1009,7 @@ 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;
|
||||
|
||||
@@ -777,8 +777,8 @@ size_t pythonmod_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block pythonmod_block = {
|
||||
"python",
|
||||
&pythonmod_init, &pythonmod_deinit, &pythonmod_operate, &pythonmod_inform_super,
|
||||
&pythonmod_clear, &pythonmod_get_mem
|
||||
NULL, NULL, &pythonmod_init, &pythonmod_deinit, &pythonmod_operate,
|
||||
&pythonmod_inform_super, &pythonmod_clear, &pythonmod_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block* pythonmod_get_funcblock(void)
|
||||
|
||||
+2
-2
@@ -1259,8 +1259,8 @@ respip_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block respip_block = {
|
||||
"respip",
|
||||
&respip_init, &respip_deinit, &respip_operate, &respip_inform_super,
|
||||
&respip_clear, &respip_get_mem
|
||||
NULL, NULL, &respip_init, &respip_deinit, &respip_operate,
|
||||
&respip_inform_super, &respip_clear, &respip_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block*
|
||||
|
||||
+63
-24
@@ -3684,6 +3684,29 @@ 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,
|
||||
@@ -5516,7 +5539,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
||||
if(!xfr->task_transfer->cp) {
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
addr_port_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "cannot create http cp "
|
||||
"connection for %s to %s", zname, as);
|
||||
return 0;
|
||||
@@ -5525,7 +5548,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
addr_port_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 */
|
||||
@@ -5548,7 +5571,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
||||
if(!xfr->task_transfer->cp) {
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
addr_port_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "cannot create tcp cp connection for "
|
||||
"xfr %s to %s", zname, as);
|
||||
return 0;
|
||||
@@ -5557,7 +5580,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
addr_port_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);
|
||||
}
|
||||
@@ -5660,7 +5683,7 @@ xfr_master_add_addrs(struct auth_master* m, struct ub_packed_rrset_key* rrset,
|
||||
}
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char s[64];
|
||||
addr_to_str(&a->addr, a->addrlen, s, sizeof(s));
|
||||
addr_port_to_str(&a->addr, a->addrlen, s, sizeof(s));
|
||||
verbose(VERB_ALGO, "auth host %s lookup %s",
|
||||
m->host, s);
|
||||
}
|
||||
@@ -6406,7 +6429,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
if(!xfr->task_probe->cp) {
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
addr_port_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "cannot create udp cp for "
|
||||
"probe %s to %s", zname, as);
|
||||
return 0;
|
||||
@@ -6426,7 +6449,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
(struct sockaddr*)&addr, addrlen, 0)) {
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
addr_port_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "failed to send soa probe for %s to %s",
|
||||
zname, as);
|
||||
return 0;
|
||||
@@ -6434,7 +6457,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_to_str(&addr, addrlen, as, sizeof(as));
|
||||
addr_port_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "auth zone %s soa probe sent to %s", zname,
|
||||
as);
|
||||
}
|
||||
@@ -7778,7 +7801,8 @@ static void auth_zone_log(uint8_t* name, enum verbosity_value level,
|
||||
static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
|
||||
struct module_env* env, struct module_stack* mods,
|
||||
struct ub_packed_rrset_key* dnskey, struct auth_data* node,
|
||||
struct auth_rrset* rrset, char** why_bogus, uint8_t* sigalg)
|
||||
struct auth_rrset* rrset, char** why_bogus, uint8_t* sigalg,
|
||||
char* reasonbuf, size_t reasonlen)
|
||||
{
|
||||
struct ub_packed_rrset_key pk;
|
||||
enum sec_status sec;
|
||||
@@ -7808,7 +7832,7 @@ static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
|
||||
"zonemd: verify %s RRset with DNSKEY", typestr);
|
||||
}
|
||||
sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, sigalg, why_bogus, NULL,
|
||||
LDNS_SECTION_ANSWER, NULL, &verified);
|
||||
LDNS_SECTION_ANSWER, NULL, &verified, reasonbuf, reasonlen);
|
||||
if(sec == sec_status_secure) {
|
||||
return 1;
|
||||
}
|
||||
@@ -7851,7 +7875,8 @@ static int nsec3_of_param_has_type(struct auth_rrset* nsec3, int algo,
|
||||
static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
||||
struct module_env* env, struct module_stack* mods,
|
||||
struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
|
||||
char** reason, char** why_bogus, uint8_t* sigalg)
|
||||
char** reason, char** why_bogus, uint8_t* sigalg, char* reasonbuf,
|
||||
size_t reasonlen)
|
||||
{
|
||||
struct auth_rrset* nsec = NULL;
|
||||
if(!apex) {
|
||||
@@ -7863,7 +7888,7 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
||||
struct ub_packed_rrset_key pk;
|
||||
/* dnssec verify the NSEC */
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
|
||||
nsec, why_bogus, sigalg)) {
|
||||
nsec, why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||
*reason = "DNSSEC verify failed for NSEC RRset";
|
||||
return 0;
|
||||
}
|
||||
@@ -7906,7 +7931,7 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
||||
}
|
||||
/* dnssec verify the NSEC3 */
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, match,
|
||||
nsec3, why_bogus, sigalg)) {
|
||||
nsec3, why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||
*reason = "DNSSEC verify failed for NSEC3 RRset";
|
||||
return 0;
|
||||
}
|
||||
@@ -7928,7 +7953,7 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
|
||||
struct module_env* env, struct module_stack* mods,
|
||||
struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
|
||||
struct auth_rrset* zonemd_rrset, char** reason, char** why_bogus,
|
||||
uint8_t* sigalg)
|
||||
uint8_t* sigalg, char* reasonbuf, size_t reasonlen)
|
||||
{
|
||||
struct auth_rrset* soa;
|
||||
if(!apex) {
|
||||
@@ -7941,12 +7966,12 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
|
||||
return 0;
|
||||
}
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex, soa,
|
||||
why_bogus, sigalg)) {
|
||||
why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||
*reason = "DNSSEC verify failed for SOA RRset";
|
||||
return 0;
|
||||
}
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
|
||||
zonemd_rrset, why_bogus, sigalg)) {
|
||||
zonemd_rrset, why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||
*reason = "DNSSEC verify failed for ZONEMD RRset";
|
||||
return 0;
|
||||
}
|
||||
@@ -8014,6 +8039,7 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||
struct module_stack* mods, struct ub_packed_rrset_key* dnskey,
|
||||
int is_insecure, char** result, uint8_t* sigalg)
|
||||
{
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL, *why_bogus = NULL;
|
||||
struct auth_data* apex = NULL;
|
||||
struct auth_rrset* zonemd_rrset = NULL;
|
||||
@@ -8042,7 +8068,8 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||
} else if(!zonemd_rrset && dnskey && !is_insecure) {
|
||||
/* fetch, DNSSEC verify, and check NSEC/NSEC3 */
|
||||
if(!zonemd_check_dnssec_absence(z, env, mods, dnskey, apex,
|
||||
&reason, &why_bogus, sigalg)) {
|
||||
&reason, &why_bogus, sigalg, reasonbuf,
|
||||
sizeof(reasonbuf))) {
|
||||
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
||||
return;
|
||||
}
|
||||
@@ -8050,7 +8077,8 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||
} else if(zonemd_rrset && dnskey && !is_insecure) {
|
||||
/* check DNSSEC verify of SOA and ZONEMD */
|
||||
if(!zonemd_check_dnssec_soazonemd(z, env, mods, dnskey, apex,
|
||||
zonemd_rrset, &reason, &why_bogus, sigalg)) {
|
||||
zonemd_rrset, &reason, &why_bogus, sigalg, reasonbuf,
|
||||
sizeof(reasonbuf))) {
|
||||
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
||||
return;
|
||||
}
|
||||
@@ -8107,6 +8135,8 @@ 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.
|
||||
*/
|
||||
@@ -8114,7 +8144,8 @@ static struct ub_packed_rrset_key*
|
||||
zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env,
|
||||
struct module_stack* mods, struct trust_anchor* anchor,
|
||||
int* is_insecure, char** why_bogus,
|
||||
struct ub_packed_rrset_key* keystorage)
|
||||
struct ub_packed_rrset_key* keystorage, char* reasonbuf,
|
||||
size_t reasonlen)
|
||||
{
|
||||
struct auth_data* apex;
|
||||
struct auth_rrset* dnskey_rrset;
|
||||
@@ -8150,7 +8181,8 @@ zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env,
|
||||
auth_zone_log(z->name, VERB_QUERY,
|
||||
"zonemd: verify DNSKEY RRset with trust anchor");
|
||||
sec = val_verify_DNSKEY_with_TA(env, ve, keystorage, anchor->ds_rrset,
|
||||
anchor->dnskey_rrset, NULL, why_bogus, NULL, NULL);
|
||||
anchor->dnskey_rrset, NULL, why_bogus, NULL, NULL, reasonbuf,
|
||||
reasonlen);
|
||||
regional_free_all(env->scratch);
|
||||
if(sec == sec_status_secure) {
|
||||
/* success */
|
||||
@@ -8173,7 +8205,8 @@ static struct ub_packed_rrset_key*
|
||||
auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
|
||||
struct module_env* env, struct module_stack* mods,
|
||||
struct ub_packed_rrset_key* ds, int* is_insecure, char** why_bogus,
|
||||
struct ub_packed_rrset_key* keystorage, uint8_t* sigalg)
|
||||
struct ub_packed_rrset_key* keystorage, uint8_t* sigalg,
|
||||
char* reasonbuf, size_t reasonlen)
|
||||
{
|
||||
struct auth_data* apex;
|
||||
struct auth_rrset* dnskey_rrset;
|
||||
@@ -8209,7 +8242,7 @@ auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
|
||||
keystorage->rk.rrset_class = htons(z->dclass);
|
||||
auth_zone_log(z->name, VERB_QUERY, "zonemd: verify zone DNSKEY with DS");
|
||||
sec = val_verify_DNSKEY_with_DS(env, ve, keystorage, ds, sigalg,
|
||||
why_bogus, NULL, NULL);
|
||||
why_bogus, NULL, NULL, reasonbuf, reasonlen);
|
||||
regional_free_all(env->scratch);
|
||||
if(sec == sec_status_secure) {
|
||||
/* success */
|
||||
@@ -8235,6 +8268,7 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
{
|
||||
struct auth_zone* z = (struct auth_zone*)arg;
|
||||
struct module_env* env;
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL, *ds_bogus = NULL, *typestr="DNSKEY";
|
||||
struct ub_packed_rrset_key* dnskey = NULL, *ds = NULL;
|
||||
int is_insecure = 0, downprot;
|
||||
@@ -8346,7 +8380,8 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
if(!reason && !is_insecure && !dnskey && ds) {
|
||||
dnskey = auth_zone_verify_zonemd_key_with_ds(z, env,
|
||||
&env->mesh->mods, ds, &is_insecure, &ds_bogus,
|
||||
&keystorage, downprot?sigalg:NULL);
|
||||
&keystorage, downprot?sigalg:NULL, reasonbuf,
|
||||
sizeof(reasonbuf));
|
||||
if(!dnskey && !is_insecure && !reason)
|
||||
reason = "DNSKEY verify with DS failed";
|
||||
}
|
||||
@@ -8354,6 +8389,7 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
if(reason) {
|
||||
auth_zone_zonemd_fail(z, env, reason, ds_bogus, NULL);
|
||||
lock_rw_unlock(&z->lock);
|
||||
regional_free_all(env->scratch);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8438,6 +8474,7 @@ zonemd_lookup_dnskey(struct auth_zone* z, struct module_env* env)
|
||||
void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
|
||||
struct module_stack* mods, char** result, int offline, int only_online)
|
||||
{
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL, *why_bogus = NULL;
|
||||
struct trust_anchor* anchor = NULL;
|
||||
struct ub_packed_rrset_key* dnskey = NULL;
|
||||
@@ -8472,7 +8509,8 @@ void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
|
||||
}
|
||||
/* equal to trustanchor, no need for online lookups */
|
||||
dnskey = zonemd_get_dnskey_from_anchor(z, env, mods, anchor,
|
||||
&is_insecure, &why_bogus, &keystorage);
|
||||
&is_insecure, &why_bogus, &keystorage, reasonbuf,
|
||||
sizeof(reasonbuf));
|
||||
lock_basic_unlock(&anchor->lock);
|
||||
if(!dnskey && !reason && !is_insecure) {
|
||||
reason = "verify DNSKEY RRset with trust anchor failed";
|
||||
@@ -8498,6 +8536,7 @@ void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
|
||||
|
||||
if(reason) {
|
||||
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
||||
regional_free_all(env->scratch);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+67
-25
@@ -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 */
|
||||
@@ -96,7 +96,8 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
||||
struct ub_packed_rrset_key* ck;
|
||||
lock_rw_rdlock(&rep->ref[i].key->entry.lock);
|
||||
/* if deleted rrset, do not copy it */
|
||||
if(rep->ref[i].key->id == 0)
|
||||
if(rep->ref[i].key->id == 0 ||
|
||||
rep->ref[i].id != rep->ref[i].key->id)
|
||||
ck = NULL;
|
||||
else ck = packed_rrset_copy_region(
|
||||
rep->ref[i].key, region, now);
|
||||
@@ -109,14 +110,22 @@ 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;
|
||||
/* ref was updated; make sure the message ttl is
|
||||
* updated to the minimum of the current rrsets. */
|
||||
lock_rw_rdlock(&rep->ref[i].key->entry.lock);
|
||||
/* if deleted, skip ttl update. */
|
||||
if(rep->ref[i].key->id != 0 &&
|
||||
rep->ref[i].id == rep->ref[i].key->id) {
|
||||
ttl = ((struct packed_rrset_data*)
|
||||
rep->rrsets[i]->entry.data)->ttl;
|
||||
if(ttl < min_ttl) min_ttl = ttl;
|
||||
}
|
||||
lock_rw_unlock(&rep->ref[i].key->entry.lock);
|
||||
}
|
||||
/* if ref was updated make sure the message ttl is updated to
|
||||
* the minimum of the current rrsets. */
|
||||
ttl = ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)->ttl;
|
||||
if(ttl < min_ttl) min_ttl = ttl;
|
||||
}
|
||||
if(min_ttl < rep->ttl) {
|
||||
rep->ttl = min_ttl;
|
||||
@@ -153,7 +162,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;
|
||||
}
|
||||
@@ -188,6 +197,7 @@ 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);
|
||||
@@ -337,6 +347,13 @@ 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);
|
||||
@@ -349,7 +366,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)
|
||||
struct regional* region, struct delegpt* dp, uint32_t flags)
|
||||
{
|
||||
struct delegpt_ns* ns;
|
||||
struct msgreply_entry* neg;
|
||||
@@ -360,7 +377,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, 0, now, 0);
|
||||
ns->namelen, LDNS_RR_TYPE_A, qclass, flags, now, 0);
|
||||
if(akey) {
|
||||
if(!delegpt_add_rrset_A(dp, region, akey, ns->lame,
|
||||
NULL)) {
|
||||
@@ -381,7 +398,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, 0, now, 0);
|
||||
ns->namelen, LDNS_RR_TYPE_AAAA, qclass, flags, now, 0);
|
||||
if(akey) {
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame,
|
||||
NULL)) {
|
||||
@@ -396,6 +413,13 @@ 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);
|
||||
@@ -584,22 +608,8 @@ 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) {
|
||||
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 {
|
||||
if(!allow_expired || !reply_info_can_answer_expired(r, now))
|
||||
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;
|
||||
@@ -618,6 +628,7 @@ 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;
|
||||
@@ -701,6 +712,7 @@ 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;
|
||||
@@ -740,6 +752,7 @@ 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;
|
||||
@@ -1047,6 +1060,35 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
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, 0);
|
||||
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)) {
|
||||
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)
|
||||
|
||||
Vendored
+2
-1
@@ -202,10 +202,11 @@ 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);
|
||||
struct regional* region, struct delegpt* dp, uint32_t flags);
|
||||
|
||||
/**
|
||||
* Utility, create new, unpacked data structure for cache response.
|
||||
|
||||
Vendored
+2
@@ -357,6 +357,7 @@ infra_create(struct config_file* cfg)
|
||||
return NULL;
|
||||
}
|
||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||
infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
|
||||
infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
|
||||
INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
|
||||
&ip_rate_compfunc, &ip_rate_delkeyfunc, &ip_rate_deldatafunc, NULL);
|
||||
@@ -408,6 +409,7 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
|
||||
infra->infra_keep_probing = cfg->infra_keep_probing;
|
||||
infra_dp_ratelimit = cfg->ratelimit;
|
||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||
infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
|
||||
maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
|
||||
sizeof(struct infra_data)+INFRA_BYTES_NAME);
|
||||
/* divide cachesize by slabs and multiply by slabs, because if the
|
||||
|
||||
Vendored
+1
-1
@@ -234,7 +234,7 @@ struct infra_cache* infra_adjust(struct infra_cache* infra,
|
||||
struct config_file* cfg);
|
||||
|
||||
/**
|
||||
* Plain find infra data function (used by the the other functions)
|
||||
* Plain find infra data function (used by the other functions)
|
||||
* @param infra: infrastructure cache.
|
||||
* @param addr: host address.
|
||||
* @param addrlen: length of addr.
|
||||
|
||||
Vendored
+5
-5
@@ -128,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, current data is better */
|
||||
if( newd->ttl < timenow && cached->ttl >= timenow)
|
||||
/* o if new data is expired, cached data is better */
|
||||
if( newd->ttl < timenow && timenow <= cached->ttl)
|
||||
return 0;
|
||||
/* o store if rrset has been validated
|
||||
* everything better than bogus data
|
||||
@@ -140,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 current RRset is more trustworthy - insert it */
|
||||
/* o if new RRset is more trustworthy - insert it */
|
||||
if( newd->trust > cached->trust ) {
|
||||
/* if the cached rrset is bogus, and this one equal,
|
||||
/* if the cached rrset is bogus, and new is equal,
|
||||
* do not update the TTL - let it expire. */
|
||||
if(equal && cached->ttl >= timenow &&
|
||||
cached->security == sec_status_bogus)
|
||||
@@ -155,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 old TTL for the new data, and
|
||||
* the NS RRset, but use the cached 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) {
|
||||
|
||||
+2501
-35
File diff suppressed because it is too large
Load Diff
+401
-4
@@ -43,10 +43,16 @@
|
||||
#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>
|
||||
#endif
|
||||
struct listen_list;
|
||||
struct config_file;
|
||||
struct addrinfo;
|
||||
@@ -100,7 +106,9 @@ 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
|
||||
listen_type_http,
|
||||
/** DNS over QUIC */
|
||||
listen_type_doq
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -188,6 +196,11 @@ int resolve_interface_names(char** ifs, int num_ifs,
|
||||
* @param tcp_conn_limit: TCP connection limit info.
|
||||
* @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 ssl_service_key: the SSL service key file.
|
||||
* @param ssl_service_pem: the SSL service pem file.
|
||||
* @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.
|
||||
@@ -198,8 +211,10 @@ 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* sslctx, struct dt_env* dtenv, comm_point_callback_type* cb,
|
||||
void *cb_arg);
|
||||
void* sslctx, struct dt_env* dtenv, struct doq_table* doq_table,
|
||||
struct ub_randstate* rnd, const char* ssl_service_key,
|
||||
const char* ssl_service_pem, struct config_file* cfg,
|
||||
comm_point_callback_type* cb, void *cb_arg);
|
||||
|
||||
/**
|
||||
* delete the listening structure
|
||||
@@ -278,11 +293,12 @@ 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);
|
||||
int use_systemd, int dscp, const char* additional);
|
||||
|
||||
/**
|
||||
* Create and bind local listening socket
|
||||
@@ -452,6 +468,377 @@ 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 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;
|
||||
#ifdef 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
|
||||
/** 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_socket server tls context */
|
||||
int doq_socket_setup_ctx(struct doq_server_socket* doq_socket);
|
||||
|
||||
/** 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
|
||||
@@ -459,4 +846,14 @@ 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 */
|
||||
|
||||
+41
-13
@@ -311,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)
|
||||
struct query_info* lookup_qinfo, int* is_expired)
|
||||
{
|
||||
hashvalue_type h;
|
||||
struct lruhash_entry* e;
|
||||
@@ -321,6 +321,7 @@ 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);
|
||||
@@ -328,6 +329,7 @@ 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)
|
||||
@@ -413,6 +415,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
int timeout = mesh->env->cfg->serve_expired?
|
||||
mesh->env->cfg->serve_expired_client_timeout:0;
|
||||
struct sldns_buffer* r_buffer = rep->c->buffer;
|
||||
uint16_t mesh_flags = qflags&(BIT_RD|BIT_CD);
|
||||
if(rep->c->tcp_req_info) {
|
||||
r_buffer = rep->c->tcp_req_info->spool_buffer;
|
||||
}
|
||||
@@ -425,7 +428,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
return;
|
||||
}
|
||||
if(!unique)
|
||||
s = mesh_area_find(mesh, cinfo, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_area_find(mesh, cinfo, qinfo, mesh_flags, 0, 0);
|
||||
/* does this create a new reply state? */
|
||||
if(!s || s->list_select == mesh_no_list) {
|
||||
if(!mesh_make_new_space(mesh, rep->c->buffer)) {
|
||||
@@ -453,7 +456,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, cinfo,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
log_err("mesh_state_create: out of memory; SERVFAIL");
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
|
||||
@@ -565,6 +568,8 @@ servfail_mem:
|
||||
edns->opt_list_inplace_cb_out = NULL;
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
if(rep->c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->c->h2_stream);
|
||||
comm_point_send_reply(rep);
|
||||
if(added)
|
||||
mesh_state_delete(&s->s);
|
||||
@@ -583,8 +588,9 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
int was_detached = 0;
|
||||
int was_noreply = 0;
|
||||
int added = 0;
|
||||
uint16_t mesh_flags = qflags&(BIT_RD|BIT_CD);
|
||||
if(!unique)
|
||||
s = mesh_area_find(mesh, NULL, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_area_find(mesh, NULL, qinfo, mesh_flags, 0, 0);
|
||||
|
||||
/* there are no limits on the number of callbacks */
|
||||
|
||||
@@ -594,7 +600,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
@@ -673,8 +679,12 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||
struct query_info* qinfo, uint16_t qflags, time_t leeway, int run,
|
||||
int rpz_passthru)
|
||||
{
|
||||
/* Explicitly set the BIT_RD regardless of the client's flags. This is
|
||||
* for a prefetch query (no client attached) but it needs to be treated
|
||||
* as a recursion query. */
|
||||
uint16_t mesh_flags = BIT_RD|(qflags&BIT_CD);
|
||||
struct mesh_state* s = mesh_area_find(mesh, NULL, qinfo,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
mesh_flags, 0, 0);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
@@ -694,8 +704,7 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||
return;
|
||||
}
|
||||
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
log_err("prefetch mesh_state_create: out of memory");
|
||||
return;
|
||||
@@ -756,14 +765,17 @@ static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
/* Explicitly set the BIT_RD regardless of the client's flags. This is
|
||||
* for a prefetch query (no client attached) but it needs to be treated
|
||||
* as a recursion query. */
|
||||
uint16_t mesh_flags = BIT_RD|(qflags&BIT_CD);
|
||||
if(!mesh_make_new_space(mesh, NULL)) {
|
||||
verbose(VERB_ALGO, "Too many queries. dropped prefetch.");
|
||||
mesh->stats_dropped ++;
|
||||
return;
|
||||
}
|
||||
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
log_err("prefetch_subnet mesh_state_create: out of memory");
|
||||
return;
|
||||
@@ -966,6 +978,8 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
for(; rep; rep=rep->next) {
|
||||
infra_wait_limit_dec(mesh->env->infra_cache,
|
||||
&rep->query_reply, mesh->env->cfg);
|
||||
if(rep->query_reply.c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->h2_stream);
|
||||
comm_point_drop_reply(&rep->query_reply);
|
||||
log_assert(mesh->num_reply_addrs > 0);
|
||||
mesh->num_reply_addrs--;
|
||||
@@ -1522,6 +1536,8 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
mstate->reply_list = NULL;
|
||||
if(r->query_reply.c->use_h2)
|
||||
http2_stream_remove_mesh_state(r->h2_stream);
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
mstate->s.env->mesh->stats_dropped++;
|
||||
@@ -1554,6 +1570,9 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
mstate->reply_list = NULL;
|
||||
if(r->query_reply.c->use_h2) {
|
||||
http2_stream_remove_mesh_state(r->h2_stream);
|
||||
}
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
} else {
|
||||
@@ -1568,6 +1587,8 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||
r_buffer = NULL;
|
||||
}
|
||||
/* mesh_send_reply removed mesh state from
|
||||
* http2_stream. */
|
||||
prev = r;
|
||||
prev_buffer = r_buffer;
|
||||
}
|
||||
@@ -1720,6 +1741,7 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||
return 0;
|
||||
if(rep->c->use_h2)
|
||||
r->h2_stream = rep->c->h2_stream;
|
||||
else r->h2_stream = NULL;
|
||||
|
||||
/* Data related to local alias stored in 'qinfo' (if any) is ephemeral
|
||||
* and can be different for different original queries (even if the
|
||||
@@ -2156,6 +2178,7 @@ mesh_serve_expired_callback(void* arg)
|
||||
int must_validate = (!(qstate->query_flags&BIT_CD)
|
||||
|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
|
||||
int i = 0;
|
||||
int is_expired;
|
||||
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);
|
||||
@@ -2173,7 +2196,7 @@ mesh_serve_expired_callback(void* arg)
|
||||
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);
|
||||
lookup_qinfo, &is_expired);
|
||||
if(!msg)
|
||||
return;
|
||||
/* Reset these in case we pass a second time from here. */
|
||||
@@ -2243,6 +2266,8 @@ mesh_serve_expired_callback(void* arg)
|
||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
mstate->reply_list = NULL;
|
||||
if(r->query_reply.c->use_h2)
|
||||
http2_stream_remove_mesh_state(r->h2_stream);
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
mstate->s.env->mesh->stats_dropped++;
|
||||
@@ -2263,8 +2288,10 @@ 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) {
|
||||
if(r->edns.edns_present &&
|
||||
qstate->env->cfg->ede_serve_expired &&
|
||||
qstate->env->cfg->ede &&
|
||||
is_expired) {
|
||||
edns_opt_list_append_ede(&r->edns.opt_list_out,
|
||||
mstate->s.region, LDNS_EDE_STALE_ANSWER, NULL);
|
||||
}
|
||||
@@ -2276,6 +2303,7 @@ mesh_serve_expired_callback(void* arg)
|
||||
r, r_buffer, prev, prev_buffer);
|
||||
if(r->query_reply.c->tcp_req_info)
|
||||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||
/* mesh_send_reply removed mesh state from http2_stream. */
|
||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
prev = r;
|
||||
|
||||
+2
-1
@@ -673,11 +673,12 @@ 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);
|
||||
struct query_info* lookup_qinfo, int* is_expired);
|
||||
|
||||
/**
|
||||
* See if the mesh has space for more queries. You can allocate queries
|
||||
|
||||
+69
-9
@@ -95,6 +95,16 @@ modstack_init(struct module_stack* stack)
|
||||
stack->mod = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
modstack_free(struct module_stack* stack)
|
||||
{
|
||||
if(!stack)
|
||||
return;
|
||||
stack->num = 0;
|
||||
free(stack->mod);
|
||||
stack->mod = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
modstack_config(struct module_stack* stack, const char* module_conf)
|
||||
{
|
||||
@@ -222,18 +232,59 @@ module_func_block* module_factory(const char** str)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
modstack_setup(struct module_stack* stack, const char* module_conf,
|
||||
int
|
||||
modstack_call_startup(struct module_stack* stack, const char* module_conf,
|
||||
struct module_env* env)
|
||||
{
|
||||
int i;
|
||||
if(stack->num != 0)
|
||||
modstack_desetup(stack, env);
|
||||
fatal_exit("unexpected already initialised modules");
|
||||
/* fixed setup of the modules */
|
||||
if(!modstack_config(stack, module_conf)) {
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i<stack->num; i++) {
|
||||
if(stack->mod[i]->startup == NULL)
|
||||
continue;
|
||||
verbose(VERB_OPS, "startup module %d: %s",
|
||||
i, stack->mod[i]->name);
|
||||
fptr_ok(fptr_whitelist_mod_startup(stack->mod[i]->startup));
|
||||
if(!(*stack->mod[i]->startup)(env, i)) {
|
||||
log_err("module startup for module %s failed",
|
||||
stack->mod[i]->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
modstack_call_init(struct module_stack* stack, const char* module_conf,
|
||||
struct module_env* env)
|
||||
{
|
||||
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))
|
||||
module_conf++;
|
||||
if(strncmp(stack->mod[i]->name, module_conf,
|
||||
strlen(stack->mod[i]->name))) {
|
||||
if(stack->mod[i]->startup || stack->mod[i]->destartup) {
|
||||
log_err("changed module ordering during reload not supported, for module that needs startup");
|
||||
return 0;
|
||||
} else {
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
module_conf += strlen(stack->mod[i]->name);
|
||||
}
|
||||
if(changed) {
|
||||
modstack_free(stack);
|
||||
if(!modstack_config(stack, module_conf)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<stack->num; i++) {
|
||||
verbose(VERB_OPS, "init module %d: %s",
|
||||
i, stack->mod[i]->name);
|
||||
@@ -247,20 +298,29 @@ modstack_setup(struct module_stack* stack, const char* module_conf,
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
modstack_desetup(struct module_stack* stack, struct module_env* env)
|
||||
void
|
||||
modstack_call_deinit(struct module_stack* stack, struct module_env* env)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<stack->num; i++) {
|
||||
fptr_ok(fptr_whitelist_mod_deinit(stack->mod[i]->deinit));
|
||||
(*stack->mod[i]->deinit)(env, i);
|
||||
}
|
||||
stack->num = 0;
|
||||
free(stack->mod);
|
||||
stack->mod = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
modstack_call_destartup(struct module_stack* stack, struct module_env* env)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<stack->num; i++) {
|
||||
if(stack->mod[i]->destartup == NULL)
|
||||
continue;
|
||||
fptr_ok(fptr_whitelist_mod_destartup(stack->mod[i]->destartup));
|
||||
(*stack->mod[i]->destartup)(env, i);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
modstack_find(struct module_stack* stack, const char* name)
|
||||
{
|
||||
int i;
|
||||
|
||||
+31
-7
@@ -60,6 +60,23 @@ struct module_stack {
|
||||
*/
|
||||
void modstack_init(struct module_stack* stack);
|
||||
|
||||
/**
|
||||
* Free the stack of modules
|
||||
* @param stack: stack that frees up memory.
|
||||
*/
|
||||
void modstack_free(struct module_stack* stack);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* environment should have a superalloc, cfg,
|
||||
* @return on false a module init failed.
|
||||
*/
|
||||
int modstack_call_startup(struct module_stack* stack, const char* module_conf,
|
||||
struct module_env* env);
|
||||
|
||||
/**
|
||||
* Read config file module settings and set up the modfunc block
|
||||
* @param stack: the stack of modules (empty before call).
|
||||
@@ -83,24 +100,31 @@ struct module_func_block* module_factory(const char** str);
|
||||
const char** module_list_avail(void);
|
||||
|
||||
/**
|
||||
* Setup modules. Assigns ids and calls module_init.
|
||||
* @param stack: if not empty beforehand, it will be desetup()ed.
|
||||
* It is then modstack_configged().
|
||||
* @param module_conf: string what modules to insert.
|
||||
* Init modules. Calls module_init().
|
||||
* @param stack: It is modstack_setupped().
|
||||
* @param module_conf: module ordering to check against the ordering in stack.
|
||||
* fails on changed ordering.
|
||||
* @param env: module environment which is inited by the modules.
|
||||
* environment should have a superalloc, cfg,
|
||||
* env.need_to_validate is set by the modules.
|
||||
* @return on false a module init failed.
|
||||
*/
|
||||
int modstack_setup(struct module_stack* stack, const char* module_conf,
|
||||
int modstack_call_init(struct module_stack* stack, const char* module_conf,
|
||||
struct module_env* env);
|
||||
|
||||
/**
|
||||
* Desetup the modules, deinit, delete.
|
||||
* Deinit the modules.
|
||||
* @param stack: made empty.
|
||||
* @param env: module env for module deinit() calls.
|
||||
*/
|
||||
void modstack_desetup(struct module_stack* stack, struct module_env* env);
|
||||
void modstack_call_deinit(struct module_stack* stack, struct module_env* env);
|
||||
|
||||
/**
|
||||
* Destartup the modules, close, delete.
|
||||
* @param stack: made empty.
|
||||
* @param env: module env for module destartup() calls.
|
||||
*/
|
||||
void modstack_call_destartup(struct module_stack* stack, struct module_env* env);
|
||||
|
||||
/**
|
||||
* Find index of module by name.
|
||||
|
||||
@@ -3466,7 +3466,10 @@ 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->reply)) {
|
||||
&qstate->qinfo,
|
||||
qstate->mesh_info->reply_list
|
||||
?&qstate->mesh_info->reply_list->query_reply
|
||||
:NULL)) {
|
||||
/* Can we pass through with slip factor? */
|
||||
if(env->cfg->ratelimit_factor == 0 ||
|
||||
ub_random_max(env->rnd,
|
||||
|
||||
+37
-6
@@ -242,10 +242,14 @@ 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: /* fallthrough */
|
||||
case RPZ_LOCAL_DATA_ACTION:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect;
|
||||
case RPZ_TCP_ONLY_ACTION: return local_zone_truncate;
|
||||
case RPZ_INVALID_ACTION: /* fallthrough */
|
||||
case RPZ_INVALID_ACTION:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
default: return local_zone_invalid;
|
||||
}
|
||||
}
|
||||
@@ -258,10 +262,14 @@ 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: /* fallthrough */
|
||||
case RPZ_LOCAL_DATA_ACTION:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect;
|
||||
case RPZ_TCP_ONLY_ACTION: return respip_truncate;
|
||||
case RPZ_INVALID_ACTION: /* fallthrough */
|
||||
case RPZ_INVALID_ACTION:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
default: return respip_invalid;
|
||||
}
|
||||
}
|
||||
@@ -276,7 +284,9 @@ 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: /* fallthrough */
|
||||
case local_zone_invalid:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
default: return RPZ_INVALID_ACTION;
|
||||
}
|
||||
}
|
||||
@@ -291,7 +301,9 @@ 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: /* fallthrough */
|
||||
case respip_invalid:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
default: return RPZ_INVALID_ACTION;
|
||||
}
|
||||
}
|
||||
@@ -1957,6 +1969,7 @@ 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 */
|
||||
@@ -1987,6 +2000,7 @@ rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms,
|
||||
0, /* ttl */
|
||||
0, /* prettl */
|
||||
0, /* expttl */
|
||||
0, /* norecttl */
|
||||
0, /* an */
|
||||
0, /* ns */
|
||||
0, /* ar */
|
||||
@@ -2019,6 +2033,7 @@ 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 */
|
||||
@@ -2164,6 +2179,7 @@ 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 */
|
||||
@@ -2276,15 +2292,18 @@ 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
|
||||
@@ -2294,11 +2313,13 @@ 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;
|
||||
@@ -2306,6 +2327,7 @@ 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'",
|
||||
@@ -2340,9 +2362,11 @@ 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
|
||||
@@ -2352,11 +2376,13 @@ 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;
|
||||
@@ -2364,6 +2390,7 @@ 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'",
|
||||
@@ -2567,9 +2594,11 @@ 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
|
||||
@@ -2579,11 +2608,13 @@ 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;
|
||||
|
||||
+3
-3
@@ -106,7 +106,7 @@ ssize_t sldns_bget_token(struct sldns_buffer *b, char *token, const char *delim,
|
||||
* \param[in] k_del keyword delimiter
|
||||
* \param[out] data the data found
|
||||
* \param[in] d_del the data delimiter
|
||||
* \param[in] data_limit maximum size the the data buffer
|
||||
* \param[in] data_limit maximum size the data buffer
|
||||
* \return the number of character read
|
||||
*/
|
||||
ssize_t sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
|
||||
@@ -119,7 +119,7 @@ ssize_t sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del,
|
||||
* \param[in] k_del keyword delimiter
|
||||
* \param[out] data the data found
|
||||
* \param[in] d_del the data delimiter
|
||||
* \param[in] data_limit maximum size the the data buffer
|
||||
* \param[in] data_limit maximum size the data buffer
|
||||
* \param[in] line_nr pointer to an integer containing the current line number (for
|
||||
debugging purposes)
|
||||
* \return the number of character read
|
||||
@@ -134,7 +134,7 @@ ssize_t sldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_de
|
||||
* \param[in] k_del keyword delimiter
|
||||
* \param[out] data the data found
|
||||
* \param[in] d_del the data delimiter
|
||||
* \param[in] data_limit maximum size the the data buffer
|
||||
* \param[in] data_limit maximum size the data buffer
|
||||
* \return the number of character read
|
||||
*/
|
||||
ssize_t sldns_bget_keyword_data(struct sldns_buffer *b, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
|
||||
|
||||
@@ -436,11 +436,13 @@ sldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
|
||||
|
||||
/* ........ ........ ....4444 4....... ........ */
|
||||
c = src[3] >> 7 ;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 3: dst[4] = b32[(src[2] & 0x0f) << 1 | c];
|
||||
|
||||
/* ........ .......3 3333.... ........ ........ */
|
||||
c = src[2] >> 4 ;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2: dst[3] = b32[(src[1] & 0x01) << 4 | c];
|
||||
|
||||
@@ -449,6 +451,7 @@ sldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
|
||||
|
||||
/* .....111 11...... ........ ........ ........ */
|
||||
c = src[1] >> 6 ;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 1: dst[1] = b32[(src[0] & 0x07) << 2 | c];
|
||||
|
||||
@@ -460,11 +463,14 @@ sldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
|
||||
switch (src_sz) {
|
||||
case 1: dst[2] = '=';
|
||||
dst[3] = '=';
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2: dst[4] = '=';
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 3: dst[5] = '=';
|
||||
dst[6] = '=';
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 4: dst[7] = '=';
|
||||
}
|
||||
@@ -577,17 +583,20 @@ sldns_b32_pton_base(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz,
|
||||
/* ........ ........ ........ .55555.. ........ */
|
||||
/* ........ ........ ....4444 4....... ........ */
|
||||
dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
|
||||
case 5: /* ........ ........ ....4444 4....... ........ */
|
||||
/* ........ .......3 3333.... ........ ........ */
|
||||
dst[2] = buf[3] << 4 | buf[4] >> 1;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
|
||||
case 4: /* ........ .......3 3333.... ........ ........ */
|
||||
/* ........ ..22222. ........ ........ ........ */
|
||||
/* .....111 11...... ........ ........ ........ */
|
||||
dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
|
||||
case 2: /* .....111 11...... ........ ........ ........ */
|
||||
|
||||
@@ -470,6 +470,11 @@ enum sldns_enum_ede_code
|
||||
LDNS_EDE_NO_REACHABLE_AUTHORITY = 22,
|
||||
LDNS_EDE_NETWORK_ERROR = 23,
|
||||
LDNS_EDE_INVALID_DATA = 24,
|
||||
LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID = 25,
|
||||
LDNS_EDE_TOO_EARLY = 26,
|
||||
LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS = 27,
|
||||
LDNS_EDE_BADPROXYPOLICY = 28,
|
||||
LDNS_EDE_SYNTHESIZED = 29
|
||||
};
|
||||
typedef enum sldns_enum_ede_code sldns_ede_code;
|
||||
|
||||
|
||||
@@ -228,6 +228,11 @@ static sldns_lookup_table sldns_edns_ede_codes_data[] = {
|
||||
{ LDNS_EDE_NO_REACHABLE_AUTHORITY, "No Reachable Authority" },
|
||||
{ LDNS_EDE_NETWORK_ERROR, "Network Error" },
|
||||
{ LDNS_EDE_INVALID_DATA, "Invalid Data" },
|
||||
{ LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID, "Signature Expired Before Valid" },
|
||||
{ LDNS_EDE_TOO_EARLY, "Non-Replayable Transactions Received in 0-RTT Data" },
|
||||
{ LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS, "Unsupported NSEC3 Iterations Value" },
|
||||
{ LDNS_EDE_BADPROXYPOLICY, "Unable to Conform to Policy" },
|
||||
{ LDNS_EDE_SYNTHESIZED, "Synthesized Answer" },
|
||||
{ 0, NULL}
|
||||
};
|
||||
sldns_lookup_table* sldns_edns_ede_codes = sldns_edns_ede_codes_data;
|
||||
@@ -1236,6 +1241,7 @@ int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* sl
|
||||
r = sldns_wire2str_svcparam_ech2str(s, slen, data_len, *d);
|
||||
break;
|
||||
case SVCB_KEY_DOHPATH:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
default:
|
||||
r = sldns_str_print(s, slen, "=\"");
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
#define HTTPS_PORT 443
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
/* sneakily reuse the the wsa_strerror function, on windows */
|
||||
/* sneakily reuse the wsa_strerror function, on windows */
|
||||
char* wsa_strerror(int err);
|
||||
#endif
|
||||
|
||||
@@ -183,7 +183,9 @@ static const char DS_TRUST_ANCHOR[] =
|
||||
/* The anchors must start on a new line with ". IN DS and end with \n"[;]
|
||||
* because the makedist script greps on the source here */
|
||||
/* anchor 20326 is from 2017 */
|
||||
". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n";
|
||||
". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n"
|
||||
/* anchor 38696 is from 2024 */
|
||||
". IN DS 38696 8 2 683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16\n";
|
||||
|
||||
/** verbosity for this application */
|
||||
static int verb = 0;
|
||||
@@ -805,7 +807,11 @@ TLS_initiate(SSL_CTX* sslctx, int fd, const char* urlname, int use_sni)
|
||||
}
|
||||
/* wants to be called again */
|
||||
}
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
x = SSL_get1_peer_certificate(ssl);
|
||||
#else
|
||||
x = SSL_get_peer_certificate(ssl);
|
||||
#endif
|
||||
if(!x) {
|
||||
if(verb) printf("Server presented no peer certificate\n");
|
||||
SSL_free(ssl);
|
||||
|
||||
@@ -140,10 +140,13 @@ check_mod(struct config_file* cfg, struct module_func_block* fb)
|
||||
fatal_exit("out of memory");
|
||||
if(!edns_known_options_init(&env))
|
||||
fatal_exit("out of memory");
|
||||
if(!(*fb->init)(&env, 0)) {
|
||||
fatal_exit("bad config for %s module", fb->name);
|
||||
}
|
||||
if(fb->startup && !(*fb->startup)(&env, 0))
|
||||
fatal_exit("bad config during startup for %s module", fb->name);
|
||||
if(!(*fb->init)(&env, 0))
|
||||
fatal_exit("bad config during init for %s module", fb->name);
|
||||
(*fb->deinit)(&env, 0);
|
||||
if(fb->destartup)
|
||||
(*fb->destartup)(&env, 0);
|
||||
sldns_buffer_free(env.scratch_buffer);
|
||||
regional_destroy(env.scratch);
|
||||
edns_known_options_delete(&env);
|
||||
|
||||
@@ -104,7 +104,7 @@ while getopts 'd:hr' arg; do
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if ! openssl >/dev/null 2>&1; then
|
||||
if ! openssl version </dev/null >/dev/null 2>&1; then
|
||||
echo "$0 requires openssl to be installed for keys/certificates generation." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -186,6 +186,10 @@ usage(void)
|
||||
printf(" rpz_enable zone Enable the RPZ zone if it had previously\n");
|
||||
printf(" been disabled\n");
|
||||
printf(" rpz_disable zone Disable the RPZ zone\n");
|
||||
printf(" add_cookie_secret <secret> add (or replace) a new cookie secret <secret>\n");
|
||||
printf(" drop_cookie_secret drop a staging cookie secret\n");
|
||||
printf(" activate_cookie_secret make a staging cookie secret active\n");
|
||||
printf(" print_cookie_secrets show all cookie secrets with their status\n");
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||
@@ -289,6 +293,9 @@ static void print_mem(struct ub_shm_stat_info* shm_stat,
|
||||
PR_LL("mem.streamwait", s->svr.mem_stream_wait);
|
||||
PR_LL("mem.http.query_buffer", s->svr.mem_http2_query_buffer);
|
||||
PR_LL("mem.http.response_buffer", s->svr.mem_http2_response_buffer);
|
||||
#ifdef HAVE_NGTCP2
|
||||
PR_LL("mem.quic", s->svr.mem_quic);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** print histogram */
|
||||
@@ -355,6 +362,9 @@ static void print_extended(struct ub_stats_info* s, int inhibit_zero)
|
||||
PR_UL("num.query.tls_resume", s->svr.qtls_resume);
|
||||
PR_UL("num.query.ipv6", s->svr.qipv6);
|
||||
PR_UL("num.query.https", s->svr.qhttps);
|
||||
#ifdef HAVE_NGTCP2
|
||||
PR_UL("num.query.quic", s->svr.qquic);
|
||||
#endif
|
||||
|
||||
/* flags */
|
||||
PR_UL("num.query.flags.QR", s->svr.qbit_QR);
|
||||
@@ -759,7 +769,11 @@ setup_ssl(SSL_CTX* ctx, int fd)
|
||||
/* check authenticity of server */
|
||||
if(SSL_get_verify_result(ssl) != X509_V_OK)
|
||||
ssl_err("SSL verification failed");
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
x = SSL_get1_peer_certificate(ssl);
|
||||
#else
|
||||
x = SSL_get_peer_certificate(ssl);
|
||||
#endif
|
||||
if(!x)
|
||||
ssl_err("Server presented no peer certificate");
|
||||
X509_free(x);
|
||||
|
||||
@@ -50,6 +50,8 @@
|
||||
#undef calloc
|
||||
#undef free
|
||||
#undef realloc
|
||||
#undef reallocarray
|
||||
#undef strdup
|
||||
#endif
|
||||
#ifdef UNBOUND_ALLOC_LITE
|
||||
#undef malloc
|
||||
@@ -492,7 +494,11 @@ int main(int argc, char* argv[])
|
||||
if(strcmp(use_syslog, "yes") == 0) /* disable use-syslog */
|
||||
check_ub_res(ub_ctx_set_option(ctx,
|
||||
"use-syslog:", "no"));
|
||||
#ifdef UNBOUND_ALLOC_STATS
|
||||
unbound_stat_free_log(use_syslog, __FILE__, __LINE__, __func__);
|
||||
#else
|
||||
free(use_syslog);
|
||||
#endif
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
@@ -255,3 +255,19 @@ 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
|
||||
|
||||
+8
-6
@@ -2,17 +2,19 @@
|
||||
# Copyright 2015, Sami Kerola, CloudFlare.
|
||||
# BSD licensed.
|
||||
AC_ARG_ENABLE([systemd],
|
||||
[AS_HELP_STRING([--enable-systemd], [compile with systemd support])],
|
||||
[AS_HELP_STRING([--enable-systemd], [compile with systemd support (requires libsystemd, pkg-config)])],
|
||||
[], [enable_systemd=no])
|
||||
have_systemd=no
|
||||
AS_IF([test "x$enable_systemd" != xno], [
|
||||
ifdef([PKG_CHECK_MODULES], [
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
dnl systemd v209 or newer
|
||||
PKG_CHECK_MODULES([SYSTEMD], [libsystemd], [have_systemd=yes], [have_systemd=no])
|
||||
have_systemd=no
|
||||
PKG_CHECK_MODULES([SYSTEMD], [libsystemd], [have_systemd=yes], [])
|
||||
dnl old systemd library
|
||||
AS_IF([test "x$have_systemd" != "xyes"], [
|
||||
have_systemd_daemon=no
|
||||
PKG_CHECK_MODULES([SYSTEMD_DAEMON], [libsystemd-daemon],
|
||||
[have_systemd_daemon=yes], [have_systemd_daemon=no])
|
||||
[have_systemd_daemon=yes], [])
|
||||
AS_IF([test "x$have_systemd_daemon" = "xyes"],
|
||||
[have_systemd=yes])
|
||||
])
|
||||
@@ -24,8 +26,8 @@ AS_IF([test "x$enable_systemd" != xno], [
|
||||
LIBS="$LIBS $SYSTEMD_LIBS"
|
||||
]
|
||||
)
|
||||
], [
|
||||
else
|
||||
AC_MSG_ERROR([systemd enabled but need pkg-config to configure for it])
|
||||
])
|
||||
fi
|
||||
])
|
||||
AM_CONDITIONAL([USE_SYSTEMD], [test "x$have_systemd" = xyes])
|
||||
|
||||
+18
-2
@@ -68,6 +68,8 @@ static struct thr_check* thread_infos[THRDEBUG_MAX_THREADS];
|
||||
int check_locking_order = 1;
|
||||
/** the pid of this runset, reasonably unique. */
|
||||
static pid_t check_lock_pid;
|
||||
/** the name of the output file */
|
||||
static const char* output_name = "ublocktrace";
|
||||
/**
|
||||
* Should checklocks print a trace of the lock and unlock calls.
|
||||
* It uses fprintf for that because the log function uses a lock and that
|
||||
@@ -142,7 +144,8 @@ acquire_locklock(struct checked_lock* lock,
|
||||
|
||||
/** add protected region */
|
||||
void
|
||||
lock_protect(void *p, void* area, size_t size)
|
||||
lock_protect_place(void* p, void* area, size_t size, const char* def_func,
|
||||
const char* def_file, int def_line, const char* def_area)
|
||||
{
|
||||
struct checked_lock* lock = *(struct checked_lock**)p;
|
||||
struct protected_area* e = (struct protected_area*)malloc(
|
||||
@@ -151,6 +154,10 @@ lock_protect(void *p, void* area, size_t size)
|
||||
fatal_exit("lock_protect: out of memory");
|
||||
e->region = area;
|
||||
e->size = size;
|
||||
e->def_func = def_func;
|
||||
e->def_file = def_file;
|
||||
e->def_line = def_line;
|
||||
e->def_area = def_area;
|
||||
e->hold = malloc(size);
|
||||
if(!e->hold)
|
||||
fatal_exit("lock_protect: out of memory");
|
||||
@@ -203,6 +210,9 @@ prot_check(struct checked_lock* lock,
|
||||
if(memcmp(p->hold, p->region, p->size) != 0) {
|
||||
log_hex("memory prev", p->hold, p->size);
|
||||
log_hex("memory here", p->region, p->size);
|
||||
log_err("lock_protect on %s %s:%d %s failed",
|
||||
p->def_func, p->def_file, p->def_line,
|
||||
p->def_area);
|
||||
lock_error(lock, func, file, line,
|
||||
"protected area modified");
|
||||
}
|
||||
@@ -675,13 +685,19 @@ checklock_unlock(enum check_lock_type type, struct checked_lock* lock,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
checklock_set_output_name(const char* name)
|
||||
{
|
||||
output_name = name;
|
||||
}
|
||||
|
||||
/** open order info debug file, thr->num must be valid */
|
||||
static void
|
||||
open_lockorder(struct thr_check* thr)
|
||||
{
|
||||
char buf[24];
|
||||
time_t t;
|
||||
snprintf(buf, sizeof(buf), "ublocktrace.%d", thr->num);
|
||||
snprintf(buf, sizeof(buf), "%s.%d", output_name, thr->num);
|
||||
thr->order_info = fopen(buf, "w");
|
||||
if(!thr->order_info)
|
||||
fatal_exit("could not open %s: %s", buf, strerror(errno));
|
||||
|
||||
+23
-1
@@ -90,6 +90,14 @@ struct protected_area {
|
||||
void* hold;
|
||||
/** next protected area in list */
|
||||
struct protected_area* next;
|
||||
/** the place where the lock_protect is made, at init. */
|
||||
const char* def_func;
|
||||
/** the file where the lock_protect is made */
|
||||
const char* def_file;
|
||||
/** the line number where the lock_protect is made */
|
||||
int def_line;
|
||||
/** the text string for the area that is protected, at init call. */
|
||||
const char* def_area;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -181,12 +189,19 @@ struct checked_lock {
|
||||
* It demangles the lock itself (struct checked_lock**).
|
||||
* @param area: ptr to mem.
|
||||
* @param size: length of area.
|
||||
* @param def_func: function where the lock_protect() line is.
|
||||
* @param def_file: file where the lock_protect() line is.
|
||||
* @param def_line: line where the lock_protect() line is.
|
||||
* @param def_area: area string
|
||||
* You can call it multiple times with the same lock to give several areas.
|
||||
* Call it when you are done initializing the area, since it will be copied
|
||||
* at this time and protected right away against unauthorised changes until
|
||||
* the next lock() call is done.
|
||||
*/
|
||||
void lock_protect(void* lock, void* area, size_t size);
|
||||
void lock_protect_place(void* lock, void* area, size_t size,
|
||||
const char* def_func, const char* def_file, int def_line,
|
||||
const char* def_area);
|
||||
#define lock_protect(lock, area, size) lock_protect_place(lock, area, size, __func__, __FILE__, __LINE__, #area)
|
||||
|
||||
/**
|
||||
* Remove protected area from lock.
|
||||
@@ -203,6 +218,13 @@ void lock_unprotect(void* lock, void* area);
|
||||
*/
|
||||
size_t lock_get_mem(void* lock);
|
||||
|
||||
/**
|
||||
* Set the output name, prefix, of the lock check output file(s).
|
||||
* Call it before the checklock_start or thread creation. Pass a fixed string.
|
||||
* @param name: string to use for output data file names.
|
||||
*/
|
||||
void checklock_set_output_name(const char* name);
|
||||
|
||||
/**
|
||||
* Initialise checklock. Sets up internal debug structures.
|
||||
*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -939,6 +939,11 @@ listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
|
||||
int ATTR_UNUSED(http_notls),
|
||||
struct tcl_list* ATTR_UNUSED(tcp_conn_limit),
|
||||
void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv),
|
||||
struct doq_table* ATTR_UNUSED(table),
|
||||
struct ub_randstate* ATTR_UNUSED(rnd),
|
||||
const char* ATTR_UNUSED(ssl_service_key),
|
||||
const char* ATTR_UNUSED(ssl_service_pem),
|
||||
struct config_file* ATTR_UNUSED(cfg),
|
||||
comm_point_callback_type* cb, void *cb_arg)
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)base;
|
||||
@@ -1655,6 +1660,12 @@ void comm_timer_set(struct comm_timer* timer, struct timeval* tv)
|
||||
timeval_add(&t->tv, &t->runtime->now_tv);
|
||||
}
|
||||
|
||||
int comm_timer_is_set(struct comm_timer* timer)
|
||||
{
|
||||
struct fake_timer* t = (struct fake_timer*)timer;
|
||||
return t->enabled;
|
||||
}
|
||||
|
||||
void comm_timer_delete(struct comm_timer* timer)
|
||||
{
|
||||
struct fake_timer* t = (struct fake_timer*)timer;
|
||||
@@ -1978,4 +1989,8 @@ void http2_stream_add_meshstate(struct http2_stream* ATTR_UNUSED(h2_stream),
|
||||
{
|
||||
}
|
||||
|
||||
void http2_stream_remove_mesh_state(struct http2_stream* ATTR_UNUSED(h2_stream))
|
||||
{
|
||||
}
|
||||
|
||||
/*********** End of Dummy routines ***********/
|
||||
|
||||
@@ -127,6 +127,7 @@ dir=$name.$$
|
||||
result=result.$name
|
||||
done=.done-$name
|
||||
skip=.skip-$name
|
||||
asan_text="SUMMARY: AddressSanitizer"
|
||||
success="no"
|
||||
if test -x "`which bash`"; then
|
||||
shell="bash"
|
||||
@@ -200,6 +201,16 @@ if test -f $name.post -a ! -f ../$skip; then
|
||||
echo "Warning: $name.post did not exit successfully"
|
||||
fi
|
||||
fi
|
||||
# Check if there were any AddressSanitizer errors
|
||||
# if compiled with -fsanitize=address
|
||||
if grep "$asan_text" $result >/dev/null 2>&1; then
|
||||
if test -f ../$done; then
|
||||
rm ../$done
|
||||
fi
|
||||
echo "$name: FAILED (AddressSanitizer)" >> $result
|
||||
echo "$name: FAILED (AddressSanitizer)"
|
||||
success="no"
|
||||
fi
|
||||
echo "DateRunEnd: "`date "+%s" 2>/dev/null` >> $result
|
||||
|
||||
mv $result ..
|
||||
|
||||
+3
-3
@@ -220,7 +220,7 @@ perfsetup(struct perfinfo* info)
|
||||
#endif
|
||||
signal(SIGTERM, perf_sigh) == SIG_ERR)
|
||||
fatal_exit("could not bind to signal");
|
||||
info->io = (struct perfio*)calloc(sizeof(struct perfio), info->io_num);
|
||||
info->io = (struct perfio*)calloc(info->io_num, sizeof(struct perfio));
|
||||
if(!info->io) fatal_exit("out of memory");
|
||||
#ifndef S_SPLINT_S
|
||||
FD_ZERO(&info->rset);
|
||||
@@ -501,8 +501,8 @@ qlist_grow_capacity(struct perfinfo* info)
|
||||
{
|
||||
size_t newcap = (size_t)((info->qlist_capacity==0)?16:
|
||||
info->qlist_capacity*2);
|
||||
uint8_t** d = (uint8_t**)calloc(sizeof(uint8_t*), newcap);
|
||||
size_t* l = (size_t*)calloc(sizeof(size_t), newcap);
|
||||
uint8_t** d = (uint8_t**)calloc(newcap, sizeof(uint8_t*));
|
||||
size_t* l = (size_t*)calloc(newcap, sizeof(size_t));
|
||||
if(!d || !l) fatal_exit("out of memory");
|
||||
if(info->qlist_data && info->qlist_capacity)
|
||||
memcpy(d, info->qlist_data, sizeof(uint8_t*)*
|
||||
|
||||
+1
-1
@@ -256,7 +256,7 @@ setup_ctx(char* key, char* cert)
|
||||
#if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO
|
||||
if (!SSL_CTX_set_ecdh_auto(ctx,1))
|
||||
if(verb>=1) printf("failed to set_ecdh_auto, not enabling ECDHE\n");
|
||||
#elif defined(USE_ECDSA)
|
||||
#elif defined(USE_ECDSA) && defined(HAVE_SSL_CTX_SET_TMP_ECDH)
|
||||
if(1) {
|
||||
EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
|
||||
if (!ecdh) {
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sldns/str2wire.h"
|
||||
#include "sldns/wire2str.h"
|
||||
|
||||
|
||||
@@ -471,7 +471,11 @@ send_em(const char* svr, const char* pp2_client, int udp, int usessl,
|
||||
}
|
||||
}
|
||||
if(1) {
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
X509* x = SSL_get1_peer_certificate(ssl);
|
||||
#else
|
||||
X509* x = SSL_get_peer_certificate(ssl);
|
||||
#endif
|
||||
if(!x) printf("SSL: no peer certificate\n");
|
||||
else {
|
||||
X509_print_fp(stdout, x);
|
||||
|
||||
+50
-18
@@ -72,23 +72,6 @@ int daemon_main(int argc, char* argv[]);
|
||||
/** config files (removed at exit) */
|
||||
static struct config_strlist* cfgfiles = NULL;
|
||||
|
||||
#ifdef UNBOUND_ALLOC_STATS
|
||||
# define strdup(s) unbound_stat_strdup_log(s, __FILE__, __LINE__, __func__)
|
||||
char* unbound_stat_strdup_log(char* s, const char* file, int line,
|
||||
const char* func);
|
||||
char* unbound_stat_strdup_log(char* s, const char* file, int line,
|
||||
const char* func) {
|
||||
char* result;
|
||||
size_t len;
|
||||
if(!s) return NULL;
|
||||
len = strlen(s);
|
||||
log_info("%s:%d %s strdup(%u)", file, line, func, (unsigned)len+1);
|
||||
result = unbound_stat_malloc(len+1);
|
||||
memmove(result, s, len+1);
|
||||
return result;
|
||||
}
|
||||
#endif /* UNBOUND_ALLOC_STATS */
|
||||
|
||||
/** give commandline usage for testbound. */
|
||||
static void
|
||||
testbound_usage(void)
|
||||
@@ -519,7 +502,7 @@ struct listen_port* daemon_remote_open_ports(struct config_file*
|
||||
|
||||
struct daemon_remote* daemon_remote_create(struct config_file* ATTR_UNUSED(cfg))
|
||||
{
|
||||
return (struct daemon_remote*)calloc(1,1);
|
||||
return (struct daemon_remote*)calloc(1, sizeof(struct daemon_remote));
|
||||
}
|
||||
|
||||
void daemon_remote_delete(struct daemon_remote* rc)
|
||||
@@ -617,3 +600,52 @@ void listen_desetup_locks(void)
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
#ifdef HAVE_NGTCP2
|
||||
void comm_point_doq_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(event),
|
||||
void* ATTR_UNUSED(arg))
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
int doq_conn_cmp(const void* ATTR_UNUSED(key1), const void* ATTR_UNUSED(key2))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int doq_conid_cmp(const void* ATTR_UNUSED(key1), const void* ATTR_UNUSED(key2))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int doq_timer_cmp(const void* ATTR_UNUSED(key1), const void* ATTR_UNUSED(key2))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int doq_stream_cmp(const void* ATTR_UNUSED(key1), const void* ATTR_UNUSED(key2))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct doq_table* doq_table_create(struct config_file* ATTR_UNUSED(cfg),
|
||||
struct ub_randstate* ATTR_UNUSED(rnd))
|
||||
{
|
||||
return calloc(1, sizeof(struct doq_table));
|
||||
}
|
||||
|
||||
void doq_table_delete(struct doq_table* table)
|
||||
{
|
||||
free(table);
|
||||
}
|
||||
|
||||
void doq_timer_cb(void* ATTR_UNUSED(arg))
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
size_t doq_table_quic_size_get(struct doq_table* ATTR_UNUSED(table))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* testcode/unitdoq.c - unit test for doq routines.
|
||||
*
|
||||
* Copyright (c) 2022, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Calls doq related unit tests. Exits with code 1 on a failure.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_NGTCP2
|
||||
|
||||
#include "util/netevent.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "testcode/unitmain.h"
|
||||
|
||||
/** check the size of a connection for doq */
|
||||
static void
|
||||
doq_size_conn_check()
|
||||
{
|
||||
/* Printout the size of one doq connection, in memory usage.
|
||||
* A connection with a couple cids, of type doq_conid, and
|
||||
* it has one stream, and that has a query and an answer. */
|
||||
size_t answer_size = 233; /* size of www.nlnetlabs.nl minimal answer
|
||||
with dnssec and one A record. The unsigned answer is 176 with
|
||||
additional data, 61 bytes minimal response one A record. */
|
||||
size_t query_size = 45; /* size of query for www.nlnetlabs.nl, with
|
||||
an EDNS record with DO flag. */
|
||||
size_t conn_size = sizeof(struct doq_conn);
|
||||
size_t conid_size = sizeof(struct doq_conid);
|
||||
size_t stream_size = sizeof(struct doq_stream);
|
||||
|
||||
conn_size += 16; /* DCID len in the conn key */
|
||||
conn_size += 0; /* the size of the ngtcp2_conn */
|
||||
conn_size += 0; /* the size of the SSL record */
|
||||
conn_size += 0; /* size of the close pkt,
|
||||
but we do not count it here. Only if the conn gets closed. */
|
||||
conid_size += 16; /* the dcid of the conn key */
|
||||
conid_size += 16; /* the cid */
|
||||
stream_size += query_size; /* size of in buffer */
|
||||
stream_size += answer_size; /* size of out buffer */
|
||||
printf("doq connection size %u bytes\n", (unsigned)(conn_size +
|
||||
conid_size*3 + stream_size));
|
||||
}
|
||||
|
||||
void doq_test(void)
|
||||
{
|
||||
unit_show_feature("doq");
|
||||
doq_size_conn_check();
|
||||
}
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
+5
-2
@@ -1117,7 +1117,7 @@ static void edns_ede_encode_encodedecode(struct query_info* qinfo,
|
||||
sldns_buffer_skip(pkt, 2 + 2);
|
||||
/* decode */
|
||||
unit_assert(parse_edns_from_query_pkt(pkt, edns, NULL, NULL, NULL, 0,
|
||||
region) == 0);
|
||||
region, NULL) == 0);
|
||||
}
|
||||
|
||||
static void edns_ede_encode_check(struct edns_data* edns, int* found_ede,
|
||||
@@ -1232,7 +1232,7 @@ static void edns_ede_answer_encode_test(void)
|
||||
unit_assert(region);
|
||||
rep = construct_reply_info_base(region,
|
||||
LDNS_RCODE_NOERROR | BIT_QR, 1,
|
||||
3600, 3600, 3600,
|
||||
3600, 3600, 3600, 0,
|
||||
0, 0, 0, 0,
|
||||
sec_status_unchecked, LDNS_EDE_NONE);
|
||||
unit_assert(rep);
|
||||
@@ -1432,6 +1432,9 @@ main(int argc, char* argv[])
|
||||
#ifdef CLIENT_SUBNET
|
||||
ecs_test();
|
||||
#endif /* CLIENT_SUBNET */
|
||||
#ifdef HAVE_NGTCP2
|
||||
doq_test();
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
if(log_get_lock()) {
|
||||
lock_basic_destroy((lock_basic_type*)log_get_lock());
|
||||
}
|
||||
|
||||
@@ -84,5 +84,7 @@ void authzone_test(void);
|
||||
void zonemd_test(void);
|
||||
/** unit test for tcp_reuse functions */
|
||||
void tcpreuse_test(void);
|
||||
/** unit test for doq functions */
|
||||
void doq_test(void);
|
||||
|
||||
#endif /* TESTCODE_UNITMAIN_H */
|
||||
|
||||
@@ -178,6 +178,7 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct query_info* qinfo)
|
||||
{
|
||||
enum sec_status sec;
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL;
|
||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||
int verified = 0;
|
||||
@@ -188,8 +189,9 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
|
||||
}
|
||||
setup_sigalg(dnskey, sigalg); /* check all algorithms in the dnskey */
|
||||
/* ok to give null as qstate here, won't be used for answer section. */
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason, NULL,
|
||||
LDNS_SECTION_ANSWER, NULL, &verified);
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason,
|
||||
NULL, LDNS_SECTION_ANSWER, NULL, &verified, reasonbuf,
|
||||
sizeof(reasonbuf));
|
||||
if(vsig) {
|
||||
printf("verify outcome is: %s %s\n", sec_status_to_string(sec),
|
||||
reason?reason:"");
|
||||
|
||||
+11
-7
@@ -108,7 +108,7 @@ static void zonemd_generate_test(const char* zname, char* zfile,
|
||||
digestdup = strdup(digest);
|
||||
unit_assert(digestdup);
|
||||
for(i=0; i<strlen(digestdup); i++) {
|
||||
digestdup[i] = toupper(digestdup[i]);
|
||||
digestdup[i] = toupper((unsigned char)digestdup[i]);
|
||||
}
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[255+1];
|
||||
@@ -165,9 +165,10 @@ static void zonemd_generate_tests(void)
|
||||
1, 1, "1291b78ddf7669b1a39d014d87626b709b55774c5d7d58fadc556439889a10eaf6f11d615900a4f996bd46279514e473");
|
||||
|
||||
/* https://tools.ietf.org/html/draft-ietf-dnsop-dns-zone-digest-12
|
||||
* from section A.5 */
|
||||
* from section A.5.
|
||||
* Adjusted with renumbered B.root. */
|
||||
zonemd_generate_test("root-servers.net", SRCDIRSTR "/testdata/zonemd.example_a5.zone",
|
||||
1, 1, "f1ca0ccd91bd5573d9f431c00ee0101b2545c97602be0a978a3b11dbfc1c776d5b3e86ae3d973d6b5349ba7f04340f79");
|
||||
1, 1, "5a9521d88984ee123d9626191e2a327a43a16fd4339dd4ecc13d8672d5bae527d066d33645e35778677800005247d199");
|
||||
}
|
||||
|
||||
/** test the zonemd check routine */
|
||||
@@ -256,7 +257,6 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr,
|
||||
struct auth_zone* z;
|
||||
|
||||
/* setup test harness */
|
||||
memset(&mods, 0, sizeof(mods));
|
||||
memset(&env, 0, sizeof(env));
|
||||
env.scratch = regional_create();
|
||||
if(!env.scratch)
|
||||
@@ -288,8 +288,10 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr,
|
||||
if(!env.auth_zones)
|
||||
fatal_exit("out of memory");
|
||||
modstack_init(&mods);
|
||||
if(!modstack_setup(&mods, env.cfg->module_conf, &env))
|
||||
fatal_exit("could not modstack_setup");
|
||||
if(!modstack_call_startup(&mods, env.cfg->module_conf, &env))
|
||||
fatal_exit("could not modstack_startup");
|
||||
if(!modstack_call_init(&mods, env.cfg->module_conf, &env))
|
||||
fatal_exit("could not modstack_call_init");
|
||||
env.mesh = mesh_create(&mods, &env);
|
||||
if(!env.mesh)
|
||||
fatal_exit("out of memory");
|
||||
@@ -327,7 +329,9 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr,
|
||||
|
||||
/* desetup test harness */
|
||||
mesh_delete(env.mesh);
|
||||
modstack_desetup(&mods, &env);
|
||||
modstack_call_deinit(&mods, &env);
|
||||
modstack_call_destartup(&mods, &env);
|
||||
modstack_free(&mods);
|
||||
auth_zones_delete(env.auth_zones);
|
||||
anchors_delete(env.anchors);
|
||||
config_delete(env.cfg);
|
||||
|
||||
+55
-43
@@ -7,57 +7,69 @@
|
||||
. ../common.sh
|
||||
PRE="../.."
|
||||
get_make
|
||||
(cd $PRE ; $MAKE unittest; $MAKE lock-verify)
|
||||
(cd $PRE ; $MAKE unittest; $MAKE lock-verify; $MAKE unbound-dnstap-socket)
|
||||
|
||||
if test -f $PRE/unbound_do_valgrind_in_test; then
|
||||
do_valgrind=yes
|
||||
DO_VALGRIND=yes
|
||||
else
|
||||
do_valgrind=no
|
||||
DO_VALGRIND=no
|
||||
fi
|
||||
VALGRIND_FLAGS="--leak-check=full --show-leak-kinds=all"
|
||||
|
||||
if test $do_valgrind = "yes"; then
|
||||
echo "valgrind yes"
|
||||
echo
|
||||
tmpout=/tmp/tmpout.$$
|
||||
if (cd $PRE; valgrind $VALGRIND_FLAGS ./unittest >$tmpout 2>&1); then
|
||||
echo "unit test worked."
|
||||
# Run a unit test; it exits on failure
|
||||
# $1: the command to start the unit test
|
||||
run_unittest () {
|
||||
unit_cmd=$1
|
||||
echo "> testing $unit_cmd"
|
||||
if test $DO_VALGRIND = "yes"; then
|
||||
echo "valgrind yes"
|
||||
echo
|
||||
tmpout=/tmp/tmpout.$$
|
||||
if (cd $PRE; valgrind $VALGRIND_FLAGS ./$unit_cmd >$tmpout 2>&1); then
|
||||
echo "unit test worked."
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
fi
|
||||
if grep "All heap blocks were freed -- no leaks are possible" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Memory leaked in unit test"
|
||||
grep "in use at exit" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
if grep "ERROR SUMMARY: 0 errors from 0 contexts" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Errors in unit test"
|
||||
grep "ERROR SUMMARY" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
rm -f $tmpout
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
# without valgrind
|
||||
if (cd $PRE; ./$unit_cmd); then
|
||||
echo "unit test worked."
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if grep "All heap blocks were freed -- no leaks are possible" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Memory leaked in unittest"
|
||||
grep "in use at exit" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
if grep "ERROR SUMMARY: 0 errors from 0 contexts" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Errors in unittest"
|
||||
grep "ERROR SUMMARY" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
rm -f $tmpout
|
||||
else
|
||||
# without valgrind
|
||||
if (cd $PRE; ./unittest); then
|
||||
echo "unit test worked."
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if test -f $PRE/ublocktrace.0; then
|
||||
if (cd $PRE; ./lock-verify ublocktrace.*); then
|
||||
echo "lock-verify test worked."
|
||||
else
|
||||
echo "lock-verify test failed."
|
||||
exit 1
|
||||
if test -f $PRE/ublocktrace.0; then
|
||||
if (cd $PRE; ./lock-verify ublocktrace.*); then
|
||||
echo "lock-verify test worked."
|
||||
else
|
||||
echo "lock-verify test failed."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
run_unittest "unittest"
|
||||
if grep "define UNBOUND_DEBUG" $PRE/config.h >/dev/null; then
|
||||
run_unittest "unbound-dnstap-socket -c"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
+50
-16
@@ -73,12 +73,53 @@ control_command () {
|
||||
$PRE/unbound-control $@ > outfile
|
||||
}
|
||||
|
||||
# Reload the server and check the reload has finished processing
|
||||
# when a lot of debug is enabled, a lot of log needs to be printed.
|
||||
control_reload () {
|
||||
prelines=`wc -l unbound.log | awk '{print $1;}'`
|
||||
cmd="$1"
|
||||
if test -z "$cmd"; then cmd="reload"; fi
|
||||
control_command -c ub.conf $cmd
|
||||
expect_exit_value 0
|
||||
# see if the reload has completed.
|
||||
lines1=`wc -l unbound.log | awk '{print $1;}'`
|
||||
count=0
|
||||
lines2=`wc -l unbound.log | awk '{print $1;}'`
|
||||
# See if the log finishes up without sleeping too long.
|
||||
while test "$lines1" -ne "$lines2"; do
|
||||
lines1=`wc -l unbound.log | awk '{print $1;}'`
|
||||
# There is no sleep here. The add and compare are a
|
||||
# brief wait.
|
||||
count=`expr "$count" + 1`
|
||||
if test "$count" -gt 30; then
|
||||
break;
|
||||
fi
|
||||
lines2=`wc -l unbound.log | awk '{print $1;}'`
|
||||
done
|
||||
if test "$lines1" -ne "$lines2"; then
|
||||
count=0
|
||||
while test "$lines1" -ne "$lines2"; do
|
||||
tail -1 unbound.log
|
||||
lines1=`wc -l unbound.log | awk '{print $1;}'`
|
||||
sleep 1
|
||||
count=`expr "$count" + 1`
|
||||
if test "$count" -gt 30; then
|
||||
echo "reload is taking too long"
|
||||
exit 1
|
||||
fi
|
||||
lines2=`wc -l unbound.log | awk '{print $1;}'`
|
||||
done
|
||||
if test "$count" -ne "0"; then
|
||||
echo "reload done with $count sec"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Reload the server for a clean state
|
||||
clean_reload () {
|
||||
echo "> Reloading the server for a clean state"
|
||||
cp main.conf ub.conf
|
||||
control_command -c ub.conf reload
|
||||
expect_exit_value 0
|
||||
control_reload
|
||||
}
|
||||
|
||||
# Reload the server for a clean state and populate the cache
|
||||
@@ -175,8 +216,7 @@ expect_exit_value 1
|
||||
# local-data element in the server.
|
||||
teststep "reload the server"
|
||||
echo "server: local-data: 'afterreload. IN A 5.6.7.8'" >> ub.conf
|
||||
control_command -c ub.conf reload
|
||||
expect_exit_value 0
|
||||
control_reload
|
||||
query afterreload.
|
||||
expect_answer "5.6.7.8"
|
||||
|
||||
@@ -336,16 +376,14 @@ fi
|
||||
clean_reload_and_fill_cache
|
||||
|
||||
teststep "reload and check cache - should be empty"
|
||||
control_command -c ub.conf reload
|
||||
expect_exit_value 0
|
||||
control_reload
|
||||
query www.example.com +nordflag
|
||||
fail_answer "10.20.30.40"
|
||||
|
||||
clean_reload_and_fill_cache
|
||||
|
||||
teststep "reload_keep_cache and check cache - should not be empty"
|
||||
control_command -c ub.conf reload_keep_cache
|
||||
expect_exit_value 0
|
||||
control_reload reload_keep_cache
|
||||
query www.example.com +nordflag
|
||||
expect_answer "10.20.30.40"
|
||||
|
||||
@@ -353,8 +391,7 @@ clean_reload_and_fill_cache
|
||||
|
||||
teststep "change msg-cache-size and reload_keep_cache - should be empty"
|
||||
echo "server: msg-cache-size: 2m" >> ub.conf
|
||||
control_command -c ub.conf reload_keep_cache
|
||||
expect_exit_value 0
|
||||
control_reload reload_keep_cache
|
||||
query www.example.com +nordflag
|
||||
fail_answer "10.20.30.40"
|
||||
|
||||
@@ -362,8 +399,7 @@ clean_reload_and_fill_cache
|
||||
|
||||
teststep "change rrset-cache-size and reload_keep_cache - should be empty"
|
||||
echo "server: rrset-cache-size: 2m" >> ub.conf
|
||||
control_command -c ub.conf reload_keep_cache
|
||||
expect_exit_value 0
|
||||
control_reload reload_keep_cache
|
||||
query www.example.com +nordflag
|
||||
fail_answer "10.20.30.40"
|
||||
|
||||
@@ -375,8 +411,7 @@ clean_reload_and_fill_cache
|
||||
|
||||
teststep "change num-threads and reload_keep_cache - should be empty"
|
||||
echo "server: num-threads: 2" >> ub.conf
|
||||
control_command -c ub.conf reload_keep_cache
|
||||
expect_exit_value 0
|
||||
control_reload reload_keep_cache
|
||||
query www.example.com +nordflag
|
||||
fail_answer "10.20.30.40"
|
||||
|
||||
@@ -384,8 +419,7 @@ clean_reload_and_fill_cache
|
||||
|
||||
teststep "change minimal-responses and reload_keep_cache - should not be empty"
|
||||
echo "server: minimal-responses: no" >> ub.conf
|
||||
control_command -c ub.conf reload_keep_cache
|
||||
expect_exit_value 0
|
||||
control_reload reload_keep_cache
|
||||
query www.example.com +nordflag
|
||||
expect_answer "10.20.30.40"
|
||||
|
||||
|
||||
+45
-1
@@ -5,9 +5,10 @@ server:
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
module-config: "respip validator iterator" # respip for the RPZ part
|
||||
do-not-query-localhost: no
|
||||
use-caps-for-id: no
|
||||
define-tag: "one two refuse"
|
||||
define-tag: "one two refuse rpz-one rpz-two rpz-nx"
|
||||
|
||||
# Interface configuration for IPv4
|
||||
interface: @IPV4_ADDR@@@PORT_ALLOW@
|
||||
@@ -16,6 +17,9 @@ server:
|
||||
interface: @IPV4_ADDR@@@PORT_TAG_1@
|
||||
interface: @IPV4_ADDR@@@PORT_TAG_2@
|
||||
interface: @IPV4_ADDR@@@PORT_TAG_3@
|
||||
interface: @IPV4_ADDR@@@PORT_RPZ_1@
|
||||
interface: @IPV4_ADDR@@@PORT_RPZ_2@
|
||||
interface: @IPV4_ADDR@@@PORT_RPZ_NX@
|
||||
interface: @IPV4_ADDR@@@PORT_VIEW_INT@
|
||||
interface: @IPV4_ADDR@@@PORT_VIEW_EXT@
|
||||
interface: @IPV4_ADDR@@@PORT_VIEW_INTEXT@
|
||||
@@ -26,6 +30,9 @@ server:
|
||||
interface-action: @IPV4_ADDR@@@PORT_TAG_1@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_TAG_2@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_TAG_3@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_RPZ_1@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_RPZ_2@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_RPZ_NX@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_VIEW_INT@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_VIEW_EXT@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_VIEW_INTEXT@ allow
|
||||
@@ -33,6 +40,9 @@ server:
|
||||
interface-tag: @IPV4_ADDR@@@PORT_TAG_1@ "one"
|
||||
interface-tag: @IPV4_ADDR@@@PORT_TAG_2@ "two"
|
||||
interface-tag: @IPV4_ADDR@@@PORT_TAG_3@ "refuse"
|
||||
interface-tag: @IPV4_ADDR@@@PORT_RPZ_1@ "rpz-one"
|
||||
interface-tag: @IPV4_ADDR@@@PORT_RPZ_2@ "rpz-two"
|
||||
interface-tag: @IPV4_ADDR@@@PORT_RPZ_NX@ "rpz-nx"
|
||||
interface-tag-action: @IPV4_ADDR@@@PORT_TAG_1@ one redirect
|
||||
interface-tag-data: @IPV4_ADDR@@@PORT_TAG_1@ one "A 1.1.1.1"
|
||||
interface-tag-action: @IPV4_ADDR@@@PORT_TAG_2@ two redirect
|
||||
@@ -50,6 +60,9 @@ server:
|
||||
interface: @IPV6_ADDR@@@PORT_TAG_1@
|
||||
interface: @IPV6_ADDR@@@PORT_TAG_2@
|
||||
interface: @IPV6_ADDR@@@PORT_TAG_3@
|
||||
interface: @IPV6_ADDR@@@PORT_RPZ_1@
|
||||
interface: @IPV6_ADDR@@@PORT_RPZ_2@
|
||||
interface: @IPV6_ADDR@@@PORT_RPZ_NX@
|
||||
interface: @IPV6_ADDR@@@PORT_VIEW_INT@
|
||||
interface: @IPV6_ADDR@@@PORT_VIEW_EXT@
|
||||
interface: @IPV6_ADDR@@@PORT_VIEW_INTEXT@
|
||||
@@ -60,6 +73,9 @@ server:
|
||||
interface-action: @IPV6_ADDR@@@PORT_TAG_1@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_TAG_2@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_TAG_3@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_RPZ_1@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_RPZ_2@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_RPZ_NX@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_VIEW_INT@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_VIEW_EXT@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_VIEW_INTEXT@ allow
|
||||
@@ -67,6 +83,9 @@ server:
|
||||
interface-tag: @IPV6_ADDR@@@PORT_TAG_1@ "one"
|
||||
interface-tag: @IPV6_ADDR@@@PORT_TAG_2@ "two"
|
||||
interface-tag: @IPV6_ADDR@@@PORT_TAG_3@ "refuse"
|
||||
interface-tag: @IPV6_ADDR@@@PORT_RPZ_1@ "rpz-one"
|
||||
interface-tag: @IPV6_ADDR@@@PORT_RPZ_2@ "rpz-two"
|
||||
interface-tag: @IPV6_ADDR@@@PORT_RPZ_NX@ "rpz-nx"
|
||||
interface-tag-action: @IPV6_ADDR@@@PORT_TAG_1@ one redirect
|
||||
interface-tag-data: @IPV6_ADDR@@@PORT_TAG_1@ one "A 1.1.1.1"
|
||||
interface-tag-action: @IPV6_ADDR@@@PORT_TAG_2@ two redirect
|
||||
@@ -84,6 +103,9 @@ server:
|
||||
interface: @INTERFACE@@@PORT_TAG_1@
|
||||
interface: @INTERFACE@@@PORT_TAG_2@
|
||||
interface: @INTERFACE@@@PORT_TAG_3@
|
||||
interface: @INTERFACE@@@PORT_RPZ_1@
|
||||
interface: @INTERFACE@@@PORT_RPZ_2@
|
||||
interface: @INTERFACE@@@PORT_RPZ_NX@
|
||||
interface: @INTERFACE@@@PORT_VIEW_INT@
|
||||
interface: @INTERFACE@@@PORT_VIEW_EXT@
|
||||
interface: @INTERFACE@@@PORT_VIEW_INTEXT@
|
||||
@@ -94,6 +116,9 @@ server:
|
||||
interface-action: @INTERFACE@@@PORT_TAG_1@ allow
|
||||
interface-action: @INTERFACE@@@PORT_TAG_2@ allow
|
||||
interface-action: @INTERFACE@@@PORT_TAG_3@ allow
|
||||
interface-action: @INTERFACE@@@PORT_RPZ_1@ allow
|
||||
interface-action: @INTERFACE@@@PORT_RPZ_2@ allow
|
||||
interface-action: @INTERFACE@@@PORT_RPZ_NX@ allow
|
||||
interface-action: @INTERFACE@@@PORT_VIEW_INT@ allow
|
||||
interface-action: @INTERFACE@@@PORT_VIEW_EXT@ allow
|
||||
interface-action: @INTERFACE@@@PORT_VIEW_INTEXT@ allow
|
||||
@@ -101,6 +126,9 @@ server:
|
||||
interface-tag: @INTERFACE@@@PORT_TAG_1@ "one"
|
||||
interface-tag: @INTERFACE@@@PORT_TAG_2@ "two"
|
||||
interface-tag: @INTERFACE@@@PORT_TAG_3@ "refuse"
|
||||
interface-tag: @INTERFACE@@@PORT_RPZ_1@ "rpz-one"
|
||||
interface-tag: @INTERFACE@@@PORT_RPZ_2@ "rpz-two"
|
||||
interface-tag: @INTERFACE@@@PORT_RPZ_NX@ "rpz-nx"
|
||||
interface-tag-action: @INTERFACE@@@PORT_TAG_1@ one redirect
|
||||
interface-tag-data: @INTERFACE@@@PORT_TAG_1@ one "A 1.1.1.1"
|
||||
interface-tag-action: @INTERFACE@@@PORT_TAG_2@ two redirect
|
||||
@@ -130,6 +158,22 @@ view:
|
||||
name: "intext"
|
||||
view-first: yes
|
||||
|
||||
# RPZ configuration
|
||||
rpz:
|
||||
name: "rpz-one"
|
||||
zonefile: "rpz-one.zone"
|
||||
tags: "rpz-one"
|
||||
|
||||
rpz:
|
||||
name: "rpz-two"
|
||||
zonefile: "rpz-two.zone"
|
||||
tags: "rpz-two"
|
||||
|
||||
rpz:
|
||||
name: "rpz-nx"
|
||||
zonefile: "rpz-nx.zone"
|
||||
tags: "rpz-nx"
|
||||
|
||||
# Stubs configuration
|
||||
forward-zone:
|
||||
name: "."
|
||||
|
||||
+12
-3
@@ -7,7 +7,7 @@ if test ! -x "`which unshare 2>&1`"; then
|
||||
skip_test "no unshare (from util-linux package) available, skip test"
|
||||
fi
|
||||
|
||||
get_random_port 11
|
||||
get_random_port 14
|
||||
|
||||
PORT_ALLOW=$RND_PORT
|
||||
PORT_DENY=$(($RND_PORT + 1))
|
||||
@@ -18,8 +18,11 @@ PORT_TAG_3=$(($RND_PORT + 5))
|
||||
PORT_VIEW_INT=$(($RND_PORT + 6))
|
||||
PORT_VIEW_EXT=$(($RND_PORT + 7))
|
||||
PORT_VIEW_INTEXT=$(($RND_PORT + 8))
|
||||
FORWARD_PORT=$(($RND_PORT + 9))
|
||||
STUB_PORT=$(($RND_PORT + 10))
|
||||
PORT_RPZ_1=$(($RND_PORT + 9))
|
||||
PORT_RPZ_2=$(($RND_PORT + 10))
|
||||
PORT_RPZ_NX=$(($RND_PORT + 11))
|
||||
FORWARD_PORT=$(($RND_PORT + 12))
|
||||
STUB_PORT=$(($RND_PORT + 13))
|
||||
|
||||
IPV4_ADDR=192.168.1.1
|
||||
IPV6_ADDR=2001:db8::1
|
||||
@@ -41,6 +44,9 @@ sed \
|
||||
-e 's/@PORT_VIEW_INT\@/'$PORT_VIEW_INT'/' \
|
||||
-e 's/@PORT_VIEW_EXT\@/'$PORT_VIEW_EXT'/' \
|
||||
-e 's/@PORT_VIEW_INTEXT\@/'$PORT_VIEW_INTEXT'/' \
|
||||
-e 's/@PORT_RPZ_1\@/'$PORT_RPZ_1'/' \
|
||||
-e 's/@PORT_RPZ_2\@/'$PORT_RPZ_2'/' \
|
||||
-e 's/@PORT_RPZ_NX\@/'$PORT_RPZ_NX'/' \
|
||||
-e 's/@FORWARD_PORT\@/'$FORWARD_PORT'/' \
|
||||
-e 's/@STUB_PORT\@/'$STUB_PORT'/' \
|
||||
-e 's/@IPV4_ADDR\@/'$IPV4_ADDR'/' \
|
||||
@@ -63,6 +69,9 @@ echo "PORT_TAG_3=$PORT_TAG_3" >> .tpkg.var.test
|
||||
echo "PORT_VIEW_INT=$PORT_VIEW_INT" >> .tpkg.var.test
|
||||
echo "PORT_VIEW_EXT=$PORT_VIEW_EXT" >> .tpkg.var.test
|
||||
echo "PORT_VIEW_INTEXT=$PORT_VIEW_INTEXT" >> .tpkg.var.test
|
||||
echo "PORT_RPZ_1=$PORT_RPZ_1" >> .tpkg.var.test
|
||||
echo "PORT_RPZ_2=$PORT_RPZ_2" >> .tpkg.var.test
|
||||
echo "PORT_RPZ_NX=$PORT_RPZ_NX" >> .tpkg.var.test
|
||||
echo "FORWARD_PORT=$FORWARD_PORT" >> .tpkg.var.test
|
||||
echo "STUB_PORT=$STUB_PORT" >> .tpkg.var.test
|
||||
echo "IPV4_ADDR=$IPV4_ADDR" >> .tpkg.var.test
|
||||
|
||||
@@ -78,6 +78,16 @@ expect_refused () {
|
||||
fi
|
||||
}
|
||||
|
||||
expect_nx_answer () {
|
||||
echo "> check answer for NXDOMAIN"
|
||||
if grep "NXDOMAIN" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
end 1
|
||||
fi
|
||||
}
|
||||
|
||||
expect_external_answer () {
|
||||
echo "> check external answer"
|
||||
if grep "1.2.3.4" outfile; then
|
||||
@@ -118,6 +128,26 @@ expect_tag_two_answer () {
|
||||
fi
|
||||
}
|
||||
|
||||
expect_rpz_one_answer () {
|
||||
echo "> check tag 'one' answer"
|
||||
if grep "11.11.11.11" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
end 1
|
||||
fi
|
||||
}
|
||||
|
||||
expect_rpz_two_answer () {
|
||||
echo "> check tag 'two' answer"
|
||||
if grep "22.22.22.22" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
end 1
|
||||
fi
|
||||
}
|
||||
|
||||
# do the test
|
||||
|
||||
for i in 4 6; do
|
||||
@@ -142,6 +172,15 @@ for i in 4 6; do
|
||||
query $i $PORT_TAG_3 "local"
|
||||
expect_refused
|
||||
|
||||
query $i $PORT_RPZ_1 "local"
|
||||
expect_rpz_one_answer
|
||||
|
||||
query $i $PORT_RPZ_2 "local"
|
||||
expect_rpz_two_answer
|
||||
|
||||
query $i $PORT_RPZ_NX "local"
|
||||
expect_nx_answer
|
||||
|
||||
query $i $PORT_VIEW_INT "www.internal"
|
||||
expect_internal_answer
|
||||
|
||||
@@ -183,6 +222,15 @@ for addr in $INTERFACE_ADDR_1 $INTERFACE_ADDR_2 $INTERFACE_ADDR_3 $INTERFACE_ADD
|
||||
query_addr $addr $PORT_TAG_3 "local"
|
||||
expect_refused
|
||||
|
||||
query_addr $addr $PORT_RPZ_1 "local"
|
||||
expect_rpz_one_answer
|
||||
|
||||
query_addr $addr $PORT_RPZ_2 "local"
|
||||
expect_rpz_two_answer
|
||||
|
||||
query_addr $addr $PORT_RPZ_NX "local"
|
||||
expect_nx_answer
|
||||
|
||||
query_addr $addr $PORT_VIEW_INT "www.internal"
|
||||
expect_internal_answer
|
||||
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
$ORIGIN rpz-nx.
|
||||
@ IN SOA no.no no.no 1 2 3 4 5
|
||||
local IN CNAME .
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
$ORIGIN rpz-one.
|
||||
@ IN SOA no.no no.no 1 2 3 4 5
|
||||
local IN A 11.11.11.11
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
$ORIGIN rpz-two.
|
||||
@ IN SOA no.no no.no 1 2 3 4 5
|
||||
local IN A 22.22.22.22
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
BaseName: auth_tls
|
||||
Version: 1.0
|
||||
Description: Perform AXFR over tls for authority zone
|
||||
CreationDate: Thu 29 Aug 09:35:40 CEST 2024
|
||||
Maintainer: dr. W.C.A. Wijngaards
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: auth_tls.pre
|
||||
Post: auth_tls.post
|
||||
Test: auth_tls.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
server:
|
||||
logfile: "/dev/stderr"
|
||||
xfrdfile: xfrd.state
|
||||
username: ""
|
||||
chroot: ""
|
||||
zonesdir: ""
|
||||
pidfile: "nsd.pid"
|
||||
zonelistfile: "zone.list"
|
||||
verbosity: 5
|
||||
port: @NSD_PORT@
|
||||
interface: 127.0.0.1@@NSD_PORT@
|
||||
|
||||
tls-port: @NSD_PORT@
|
||||
tls-service-key: "nsd_server.key"
|
||||
tls-service-pem: "nsd_server.pem"
|
||||
|
||||
zone:
|
||||
name: "example.com"
|
||||
zonefile: "example.com.zone"
|
||||
provide-xfr: 0.0.0.0/0 NOKEY
|
||||
provide-xfr: ::0/0 NOKEY
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
# #-- auth_tls.post --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# source the test var file when it's there
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
#
|
||||
# do your teardown here
|
||||
. ../common.sh
|
||||
kill_pid $NSD_PID
|
||||
kill_pid $UNBOUND_PID
|
||||
echo "nsd.log"
|
||||
cat nsd.log
|
||||
echo "unbound.log"
|
||||
cat unbound.log
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user