mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
197
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d67ca6bfed | ||
|
|
9735e34f89 | ||
|
|
ac9ca8c5af | ||
|
|
1d18f34c79 | ||
|
|
17f64b818e | ||
|
|
9cf1344960 | ||
|
|
098200ba5a | ||
|
|
daa016e3e4 | ||
|
|
039f69e735 | ||
|
|
b39009e487 | ||
|
|
933769ee73 | ||
|
|
57bff79627 | ||
|
|
1b5559d534 | ||
|
|
9d271c5343 | ||
|
|
74cc49e6c4 | ||
|
|
d414ebf0c7 | ||
|
|
08a2734e91 | ||
|
|
14264c9ed9 | ||
|
|
76f0bb8ba2 | ||
|
|
051fef8456 | ||
|
|
b8c96862cb | ||
|
|
9b123d1b78 | ||
|
|
37b71261a2 | ||
|
|
d99a4375bf | ||
|
|
4426db4d3d | ||
|
|
fe10bc7682 | ||
|
|
67d2eae28c | ||
|
|
9010a7075e | ||
|
|
5582fbc443 | ||
|
|
a72374000e | ||
|
|
cea8f493b2 | ||
|
|
285b5aa461 | ||
|
|
cc6dbc9f38 | ||
|
|
a50dd4e407 | ||
|
|
966801a984 | ||
|
|
6084171db7 | ||
|
|
4baa2ccc9c | ||
|
|
4198343dbe | ||
|
|
08600d68e8 | ||
|
|
18e098285e | ||
|
|
f1b35bab4b | ||
|
|
84ed77238d | ||
|
|
adb0374a4d | ||
|
|
b0b634558b | ||
|
|
8546247292 | ||
|
|
44659cb3bf | ||
|
|
a1ac2d0252 | ||
|
|
5c7a26b615 | ||
|
|
09d352b917 | ||
|
|
0793bb9835 | ||
|
|
10b8398f02 | ||
|
|
797d9569c3 | ||
|
|
dfa358dc8d | ||
|
|
6dd48dadc9 | ||
|
|
d34733a69b | ||
|
|
e1faea02de | ||
|
|
fdd0ada3c9 | ||
|
|
ed3606d99d | ||
|
|
b9df07d8bb | ||
|
|
ea9c957213 | ||
|
|
828b05c956 | ||
|
|
3b2a2e2440 | ||
|
|
0557fdb940 | ||
|
|
c0522043f0 | ||
|
|
b858801feb | ||
|
|
588db09928 | ||
|
|
5c66c48a1b | ||
|
|
83336477c6 | ||
|
|
e3e5eb66cf | ||
|
|
00d3b97dbb | ||
|
|
0f43b0ea6c | ||
|
|
e6d92f458f | ||
|
|
a31b9d50e2 | ||
|
|
fceb4e8585 | ||
|
|
98f4257890 | ||
|
|
0a15118aff | ||
|
|
e887a79a92 | ||
|
|
f9b9050ab8 | ||
|
|
94735384fd | ||
|
|
5dab0609e5 | ||
|
|
024c921dbf | ||
|
|
1a808e2978 | ||
|
|
56ded934de | ||
|
|
98952f11d1 | ||
|
|
cb4b3de62f | ||
|
|
c8dcfc0853 | ||
|
|
2bb28fdf12 | ||
|
|
6ad26909dd | ||
|
|
9602973c86 | ||
|
|
713b1783d4 | ||
|
|
e06b7eb3f1 | ||
|
|
1cb9595a42 | ||
|
|
fbed3f30b2 | ||
|
|
2001d9fd15 | ||
|
|
b3be0fe943 | ||
|
|
f04ee9767e | ||
|
|
899ad30ad9 | ||
|
|
6c501b9aa2 | ||
|
|
1cde7b2cbb | ||
|
|
72e2e711c2 | ||
|
|
cdb4b7c3b0 | ||
|
|
e6657ae284 | ||
|
|
9cf702f09f | ||
|
|
a0e33aa77d | ||
|
|
ded06e8b60 | ||
|
|
c0a06a5d24 | ||
|
|
0fec18796a | ||
|
|
990b27550e | ||
|
|
7742270e39 | ||
|
|
7021d91348 | ||
|
|
150cf78ff2 | ||
|
|
5e1a98027c | ||
|
|
1140e39a78 | ||
|
|
13f7893805 | ||
|
|
87f5a51618 | ||
|
|
7672d9768b | ||
|
|
5b46b5a972 | ||
|
|
0827064414 | ||
|
|
8284af6690 | ||
|
|
b89eed2902 | ||
|
|
0dcaaf332d | ||
|
|
2bd88e8f70 | ||
|
|
5d9cc00f0a | ||
|
|
2536b35d38 | ||
|
|
e312575b87 | ||
|
|
5cd0c63593 | ||
|
|
152e4e9e63 | ||
|
|
30bc4e5bd7 | ||
|
|
e70edac733 | ||
|
|
4e1f1db6c9 | ||
|
|
e45531d68f | ||
|
|
1a898ff9bc | ||
|
|
f190903e3b | ||
|
|
f6b4582eec | ||
|
|
aa21e38b3a | ||
|
|
964848b94a | ||
|
|
a4dd321fd8 | ||
|
|
d23a28a693 | ||
|
|
5423c0a8e9 | ||
|
|
6a5385f291 | ||
|
|
16f3478048 | ||
|
|
c8860a5fb6 | ||
|
|
735c96aac7 | ||
|
|
3e71cf89cb | ||
|
|
0929d0e2e4 | ||
|
|
0c3b3d00f9 | ||
|
|
a75ea01a15 | ||
|
|
3bb8888e9e | ||
|
|
d8c5dbd6d8 | ||
|
|
eef91474cd | ||
|
|
426d56795f | ||
|
|
54ac686476 | ||
|
|
21f02a0865 | ||
|
|
e017d66fc1 | ||
|
|
09efa55f81 | ||
|
|
3018f073d2 | ||
|
|
a489ad2b4f | ||
|
|
a48d1a51b5 | ||
|
|
25e7e6ec72 | ||
|
|
adaf5dab49 | ||
|
|
feeebc95f8 | ||
|
|
187aa52859 | ||
|
|
f1fea8dc46 | ||
|
|
0c01257d1d | ||
|
|
50a11ebcc8 | ||
|
|
1e2dc657a1 | ||
|
|
843124852f | ||
|
|
5e2fdff8e5 | ||
|
|
499a3a7a61 | ||
|
|
2024c1d050 | ||
|
|
6cd595a816 | ||
|
|
74cf81e9a7 | ||
|
|
35f6fd47fb | ||
|
|
270e099aab | ||
|
|
64645e1401 | ||
|
|
421d317a64 | ||
|
|
0b8ed987de | ||
|
|
9511797487 | ||
|
|
0b7bb75152 | ||
|
|
88c688ec10 | ||
|
|
81fd1dc71c | ||
|
|
69217cf675 | ||
|
|
7c28f1b99c | ||
|
|
fa6340cfa5 | ||
|
|
e471e15774 | ||
|
|
ec3db03121 | ||
|
|
e2bf773089 | ||
|
|
3017a0aa52 | ||
|
|
8419e9780e | ||
|
|
f2af8a3cd7 | ||
|
|
c429c4ab96 | ||
|
|
bc61034f60 | ||
|
|
73e408f1d0 | ||
|
|
d521135f66 | ||
|
|
1d3d78dff5 | ||
|
|
c88eed83d9 | ||
|
|
50fcf71f04 |
@@ -12,6 +12,7 @@ jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- name: GCC on Linux
|
||||
@@ -48,15 +49,6 @@ jobs:
|
||||
os: ubuntu-latest
|
||||
config: 'CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=address" --disable-flto --disable-static'
|
||||
make_test: "yes"
|
||||
- name: Apple iPhone on iOS, armv7
|
||||
os: macos-latest
|
||||
AUTOTOOLS_HOST: armv7-apple-ios
|
||||
OPENSSL_HOST: ios-cross
|
||||
IOS_SDK: iPhoneOS
|
||||
IOS_CPU: armv7s
|
||||
test_ios: "yes"
|
||||
config: "no"
|
||||
make: "no"
|
||||
- name: Apple iPhone on iOS, arm64
|
||||
os: macos-latest
|
||||
AUTOTOOLS_HOST: aarch64-apple-ios
|
||||
@@ -84,15 +76,6 @@ jobs:
|
||||
test_ios: "yes"
|
||||
config: "no"
|
||||
make: "no"
|
||||
- name: iPhoneSimulator on OS X, i386
|
||||
os: macos-latest
|
||||
AUTOTOOLS_HOST: i386-apple-ios
|
||||
OPENSSL_HOST: iphoneos-cross
|
||||
IOS_SDK: iPhoneSimulator
|
||||
IOS_CPU: i386
|
||||
test_ios: "yes"
|
||||
config: "no"
|
||||
make: "no"
|
||||
- name: iPhoneSimulator on OS X, x86_64
|
||||
os: macos-latest
|
||||
AUTOTOOLS_HOST: x86_64-apple-ios
|
||||
@@ -192,8 +175,38 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: false
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
- name: test_windows_configure
|
||||
if: ${{ matrix.test_windows == 'yes' }}
|
||||
shell: bash
|
||||
run: |
|
||||
# The run starts with mount points for /c, /d, and
|
||||
# C:/Program Files/Git on /
|
||||
# C:/Program Files/Git/usr/bin on /bin
|
||||
# C:/Users/RUNNER~1/AppData/Local/Temp on /tmp
|
||||
echo "mount"
|
||||
mount || echo "ignored"
|
||||
echo "mount -o bind /c/msys64/usr /usr"
|
||||
mount -o bind /c/msys64/usr /usr || echo "ignored"
|
||||
# Now there is:
|
||||
# C:/msys64 on /
|
||||
# C:/msys64/usr/bin on /bin
|
||||
# And those mount points should go away for the next 'run:' shell.
|
||||
echo "mount"
|
||||
mount || echo "ignored"
|
||||
# probably installs to C:\msys64\usr\bin\bash.exe
|
||||
echo "pacman -S --noconfirm autotools"
|
||||
C:/msys64/usr/bin/pacman -S --noconfirm autotools
|
||||
echo "rm -f aclocal.m4"
|
||||
rm -f aclocal.m4
|
||||
# The paths are mounted, so that /c/msys64/usr/share/autoconf-..,
|
||||
# /c/msys64/usr/share/aclocal-.., /c/msys64/usr/share/automake-..
|
||||
# are in /usr. Also for /usr/bin, autoreconf is from
|
||||
# /c/msys64/usr/bin.
|
||||
echo "autoreconf -fi"
|
||||
#PATH="/c/msys64/usr/bin:$PATH" autoreconf -fi || echo "ignored"
|
||||
autoreconf -fi
|
||||
- name: test_windows
|
||||
if: ${{ matrix.test_windows == 'yes' }}
|
||||
env:
|
||||
@@ -206,6 +219,9 @@ jobs:
|
||||
cd ..
|
||||
export prepath=`pwd`
|
||||
echo prepath=${prepath}
|
||||
# The mount should have the git directories.
|
||||
echo "mount"
|
||||
mount || echo "ignored"
|
||||
echo "choco install winflexbison3"
|
||||
choco install winflexbison3
|
||||
echo 'LEX="win_flex"'
|
||||
@@ -223,7 +239,7 @@ jobs:
|
||||
#sed -e 's/use Pod::Usage//' < Configure > Configure.fix
|
||||
# ./Configure.fix no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix="$prepath/openssl"
|
||||
# pacman is used to install for msys2, with
|
||||
# C:/msys64/usr/bin/pacman -S perl
|
||||
# C:/msys64/usr/bin/pacman -S --noconfirm perl
|
||||
echo "C:/msys64/usr/bin/perl ./Configure no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix=\""$prepath/openssl"\" PERL=\"C:/msys64/usr/bin/perl\""
|
||||
C:/msys64/usr/bin/perl ./Configure no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix="$prepath/openssl" PERL="C:/msys64/usr/bin/perl"
|
||||
# make the libs only, build faster
|
||||
@@ -312,6 +328,8 @@ jobs:
|
||||
./contrib/android/install_expat.sh
|
||||
echo "::endgroup::"
|
||||
echo "::group::configure"
|
||||
echo "autoreconf -fi"
|
||||
autoreconf -fi
|
||||
echo "./configure ${CONFIG_OPTS}"
|
||||
./configure ${CONFIG_OPTS}
|
||||
echo "::endgroup::"
|
||||
@@ -331,6 +349,7 @@ jobs:
|
||||
IOS_CPU: ${{ matrix.IOS_CPU }}
|
||||
run: |
|
||||
#(already installed) ./contrib/ios/install_tools.sh
|
||||
brew install autoconf automake libtool make
|
||||
export AUTOTOOLS_BUILD="$(./config.guess)"
|
||||
echo AUTOTOOLS_BUILD=${AUTOTOOLS_BUILD}
|
||||
export IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
|
||||
@@ -352,6 +371,8 @@ jobs:
|
||||
./contrib/ios/install_expat.sh
|
||||
echo "::endgroup::"
|
||||
echo "::group::configure"
|
||||
echo "autoreconf -fi"
|
||||
autoreconf -fi
|
||||
echo "./configure ${CONFIG_OPTS}"
|
||||
./configure ${CONFIG_OPTS}
|
||||
echo "::endgroup::"
|
||||
@@ -377,10 +398,12 @@ jobs:
|
||||
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
|
||||
if test "$CROSS_PLATFORM_OS" = "freebsd"; then sudo pkg install -y autoconf automake libtool pkgconf openssl libevent expat; fi
|
||||
if test "$CROSS_PLATFORM_OS" = "openbsd"; then sudo pkg_add autoconf-2.71 automake-1.16.5 libtool pkgconf libevent; export AUTOCONF_VERSION="2.71"; export AUTOMAKE_VERSION="1.16"; fi
|
||||
if test "$CROSS_PLATFORM_OS" = "netbsd"; then sudo pkgin -y install autoconf automake libtool pkgconf libevent; export LDFLAGS="-Wl,--rpath=/usr/pkg/lib"; fi
|
||||
echo "::group::configure"
|
||||
rm -f aclocal.m4
|
||||
autoreconf -fi
|
||||
./configure ${{ matrix.cross_platform_config }}
|
||||
echo "::endgroup::"
|
||||
echo "::group::make"
|
||||
@@ -394,10 +417,15 @@ jobs:
|
||||
run: sudo apt-get install libevent-dev
|
||||
- name: install expat
|
||||
if: ${{ matrix.install_expat == 'yes' }}
|
||||
run: brew install expat
|
||||
run: |
|
||||
brew install expat
|
||||
brew install autoconf automake libtool make
|
||||
- name: configure
|
||||
if: ${{ matrix.config != 'no' }}
|
||||
run: ./configure ${{ matrix.config }}
|
||||
run: |
|
||||
if test `uname` = "Linux"; then sudo apt-get install autoconf automake libtool make; fi
|
||||
autoreconf -fi
|
||||
./configure ${{ matrix.config }}
|
||||
- name: make
|
||||
if: ${{ matrix.make != 'no' }}
|
||||
run: make
|
||||
|
||||
@@ -14,9 +14,14 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
- name: install packages
|
||||
run: sudo apt-get install autoconf automake libtool make
|
||||
- name: configure
|
||||
run: ./configure --enable-debug
|
||||
run: |
|
||||
autoreconf -fi
|
||||
./configure --enable-debug
|
||||
- name: make
|
||||
run: make
|
||||
- name: make test
|
||||
|
||||
@@ -3,11 +3,17 @@
|
||||
/.libs/
|
||||
/.source
|
||||
/Makefile
|
||||
/aclocal.m4
|
||||
/autom4te.cache/
|
||||
/config.guess
|
||||
/config.h
|
||||
/config.h.in
|
||||
/config.h.in~
|
||||
/config.log
|
||||
/config.status
|
||||
/config.sub
|
||||
/configure
|
||||
/configure~
|
||||
/dnstap/dnstap_config.h
|
||||
/dnscrypt/dnscrypt_config.h
|
||||
/util/configlexer.c
|
||||
@@ -22,8 +28,10 @@
|
||||
/doc/unbound-host.1
|
||||
/doc/unbound.8
|
||||
/doc/unbound.conf.5
|
||||
/install-sh
|
||||
/libtool
|
||||
/libunbound.la
|
||||
/ltmain.sh
|
||||
/_unbound.la
|
||||
/smallapp/unbound-control-setup.sh
|
||||
/unbound
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "simdzone"]
|
||||
path = simdzone
|
||||
url = https://github.com/NLnetLabs/simdzone.git
|
||||
+52
-23
@@ -56,7 +56,7 @@ YACC=@YACC@
|
||||
LEX=@LEX@
|
||||
STRIP=@STRIP@
|
||||
CC=@CC@
|
||||
CPPFLAGS=-I. @CPPFLAGS@
|
||||
CPPFLAGS=-I. @CPPFLAGS@ -Isimdzone/include -I@srcdir@/simdzone/include
|
||||
PYTHON_CPPFLAGS=-I. -I$(srcdir) @PYTHON_CPPFLAGS@
|
||||
CFLAGS=-DSRCDIR=$(srcdir) @CFLAGS@
|
||||
LDFLAGS=@LDFLAGS@
|
||||
@@ -267,6 +267,7 @@ LIBUNBOUND_SRC=libunbound/context.c libunbound/libunbound.c \
|
||||
libunbound/libworker.c
|
||||
LIBUNBOUND_OBJ=context.lo libunbound.lo libworker.lo ub_event_pluggable.lo
|
||||
LIBUNBOUND_OBJ_LINK=$(LIBUNBOUND_OBJ) $(COMMON_OBJ_WITHOUT_UB_EVENT) $(SLDNS_OBJ) $(COMPAT_OBJ)
|
||||
SIMDZONE_OBJ=@SIMDZONE_OBJ@
|
||||
|
||||
# win apps or "" if not on windows
|
||||
WINAPPS=@WINAPPS@
|
||||
@@ -364,19 +365,24 @@ longtest: tests
|
||||
if test ! $(srcdir)/testdata -ef ./testdata; then rm -rf testcode testdata; mkdir testcode testdata; cp -R $(srcdir)/testdata/*.sh $(srcdir)/testdata/*.tdir $(srcdir)/testdata/*.rpl $(srcdir)/testdata/*.crpl testdata; cp $(srcdir)/testcode/*.sh testcode; if test ! -d util; then mkdir util; fi; cp $(srcdir)/util/iana_ports.inc util; fi
|
||||
if test -x "`which bash`"; then bash testcode/do-tests.sh; else sh testcode/do-tests.sh; fi
|
||||
|
||||
simdzone/libzone.la:
|
||||
$(MAKE) -C simdzone
|
||||
|
||||
simdzone/include/zone/export.h: simdzone/libzone.la
|
||||
|
||||
lib: libunbound.la unbound.h
|
||||
|
||||
libunbound.la: $(LIBUNBOUND_OBJ_LINK)
|
||||
$(LINK_LIB) $(UBSYMS) -o $@ $(LIBUNBOUND_OBJ_LINK) -rpath $(libdir) $(SSLLIB) $(LIBS)
|
||||
libunbound.la: simdzone/libzone.la $(LIBUNBOUND_OBJ_LINK)
|
||||
$(LINK_LIB) $(UBSYMS) -o $@ $(LIBUNBOUND_OBJ_LINK) $(SIMDZONE_OBJ) -rpath $(libdir) $(SSLLIB) $(LIBS)
|
||||
|
||||
unbound$(EXEEXT): $(DAEMON_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
|
||||
$(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
|
||||
|
||||
unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
unbound-control$(EXEEXT): $(CONTROL_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(CONTROL_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(CONTROL_OBJ_LINK) $(EXTRALINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
unbound-host$(EXEEXT): $(HOST_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(HOST_OBJ_LINK) libunbound.la $(SSLLIB) $(LIBS)
|
||||
@@ -394,43 +400,43 @@ anchor-update$(EXEEXT): $(ANCHORUPD_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(ANCHORUPD_OBJ_LINK) libunbound.la $(LIBS)
|
||||
|
||||
unittest$(EXEEXT): $(UNITTEST_OBJ_LINK)
|
||||
$(LINK) -o $@ $(UNITTEST_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(UNITTEST_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
testbound$(EXEEXT): $(TESTBOUND_OBJ_LINK)
|
||||
$(LINK) -o $@ $(TESTBOUND_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(TESTBOUND_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
lock-verify$(EXEEXT): $(LOCKVERIFY_OBJ_LINK)
|
||||
$(LINK) -o $@ $(LOCKVERIFY_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(LOCKVERIFY_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
petal$(EXEEXT): $(PETAL_OBJ_LINK)
|
||||
$(LINK) -o $@ $(PETAL_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
|
||||
pktview$(EXEEXT): $(PKTVIEW_OBJ_LINK)
|
||||
$(LINK) -o $@ $(PKTVIEW_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(PKTVIEW_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
memstats$(EXEEXT): $(MEMSTATS_OBJ_LINK)
|
||||
$(LINK) -o $@ $(MEMSTATS_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(MEMSTATS_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
asynclook$(EXEEXT): $(ASYNCLOOK_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) libunbound.la $(SSLLIB) $(LIBS)
|
||||
|
||||
streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK)
|
||||
$(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
dohclient$(EXEEXT): $(DOHCLIENT_OBJ_LINK)
|
||||
$(LINK) -o $@ $(DOHCLIENT_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(DOHCLIENT_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
doqclient$(EXEEXT): $(DOQCLIENT_OBJ_LINK)
|
||||
$(LINK) -o $@ $(DOQCLIENT_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(DOQCLIENT_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
perf$(EXEEXT): $(PERF_OBJ_LINK)
|
||||
$(LINK) -o $@ $(PERF_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(PERF_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
delayer$(EXEEXT): $(DELAYER_OBJ_LINK)
|
||||
$(LINK) -o $@ $(DELAYER_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(DELAYER_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
readzone$(EXEEXT): $(READZONE_OBJ_LINK)
|
||||
$(LINK) -o $@ $(READZONE_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(READZONE_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
signit$(EXEEXT): testcode/signit.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@ -o $@ testcode/signit.c $(LDFLAGS) -lldns $(SSLLIB) $(LIBS)
|
||||
@@ -458,7 +464,7 @@ dnstap/dnstap.pb-c.h: dnstap/dnstap.pb-c.c
|
||||
touch $@
|
||||
|
||||
unbound-dnstap-socket$(EXEEXT): $(DNSTAP_SOCKET_OBJ_LINK)
|
||||
$(LINK) -o $@ $(DNSTAP_SOCKET_OBJ_LINK) $(SSLLIB) $(LIBS)
|
||||
$(LINK) -o $@ $(DNSTAP_SOCKET_OBJ_LINK) $(SIMDZONE_OBJ) $(SSLLIB) $(LIBS)
|
||||
|
||||
dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h
|
||||
dtstream.lo dtstream.o: $(srcdir)/dnstap/dtstream.c config.h $(srcdir)/dnstap/dtstream.h
|
||||
@@ -522,7 +528,9 @@ util/configparser.c: $(srcdir)/util/configparser.y
|
||||
util/configparser.h: util/configparser.c
|
||||
touch $@
|
||||
|
||||
clean:
|
||||
.PHONY: .clean .distclean .maintainer-clean .realclean .devclean
|
||||
|
||||
.clean:
|
||||
rm -f *.o *.d *.lo *~ tags
|
||||
rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
|
||||
rm -f $(ALL_SRC:.c=.lint)
|
||||
@@ -530,19 +538,37 @@ clean:
|
||||
rm -f libunbound.a
|
||||
rm -rf autom4te.cache .libs build doc/html doc/xml
|
||||
|
||||
distclean: clean
|
||||
.distclean: .clean
|
||||
rm -f config.status config.log config.h
|
||||
rm -f doc/example.conf doc/libunbound.3 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound-control.8 doc/unbound.8 doc/unbound.conf.5 doc/unbound-host.1
|
||||
rm -f smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service
|
||||
rm -f $(TEST_BIN)
|
||||
rm -f Makefile
|
||||
|
||||
maintainer-clean: distclean
|
||||
.maintainer-clean: .distclean
|
||||
rm -f util/configlexer.c util/configparser.c util/configparser.h
|
||||
|
||||
realclean: maintainer-clean
|
||||
.realclean: .maintainer-clean
|
||||
rm -f configure config.h.in config.sub config.guess ltmain.sh aclocal.m4 libtool
|
||||
|
||||
.devclean: .realclean
|
||||
rm -f config.h.in configure
|
||||
|
||||
clean: .clean
|
||||
$(MAKE) -C simdzone clean
|
||||
|
||||
distclean: .distclean
|
||||
$(MAKE) -C simdzone distclean
|
||||
|
||||
realclean: .realclean
|
||||
$(MAKE) -C simdzone realclean
|
||||
|
||||
maintainer-clean: .maintainer-clean
|
||||
$(MAKE) -C simdzone maintainer-clean
|
||||
|
||||
devclean: .devclean
|
||||
$(MAKE) -C simdzone devclean
|
||||
|
||||
.SUFFIXES: .lint
|
||||
.c.lint:
|
||||
$(LINT) $(LINTFLAGS) -I. -I$(srcdir) $<
|
||||
@@ -703,6 +729,7 @@ depend:
|
||||
-e 's?$$(srcdir)/edns-subnet/subnetmod.h $$(srcdir)/edns-subnet/subnet-whitelist.h $$(srcdir)/edns-subnet/edns-subnet.h $$(srcdir)/edns-subnet/addrtree.h?$$(SUBNET_HEADER)?g' \
|
||||
-e 's?$$(srcdir)/ipsecmod/ipsecmod.h $$(srcdir)/ipsecmod/ipsecmod-whitelist.h?$$(IPSECMOD_HEADER)?g' \
|
||||
-e 's?$$(srcdir)/dynlibmod/dynlibmod.h?$$(DYNLIBMOD_HEADER)?g' \
|
||||
-e 's?$$(srcdir)/simdzone/include/zone/export.h?simdzone/include/zone/export.h?g' \
|
||||
-e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' \
|
||||
> $(DEPEND_TMP)
|
||||
cp $(DEPEND_TARGET) $(DEPEND_TMP2)
|
||||
@@ -1000,7 +1027,9 @@ authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/service
|
||||
$(srcdir)/services/listen_dnsport.h $(srcdir)/daemon/acl_list.h \
|
||||
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h \
|
||||
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_secalgo.h \
|
||||
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_utils.h
|
||||
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_utils.h \
|
||||
$(srcdir)/simdzone/include/zone.h $(srcdir)/simdzone/include/zone/attributes.h \
|
||||
simdzone/include/zone/export.h
|
||||
fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/fptr_wlist.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
|
||||
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
Unbound README
|
||||
* From source repository: git submodule update --init && autoreconf -fi
|
||||
* ./configure && make && make install
|
||||
* You can use libevent if you want. libevent is useful when using
|
||||
many (10000) outgoing ports. By default max 256 ports are opened at
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[](https://repology.org/project/unbound/versions)
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:unbound)
|
||||
[](https://unbound.readthedocs.io/en/latest/?badge=latest)
|
||||
[](https://fosstodon.org/@nlnetlabs)
|
||||
[](https://social.nlnetlabs.nl/@nlnetlabs)
|
||||
|
||||
Unbound is a validating, recursive, caching DNS resolver. It is designed to be
|
||||
fast and lean and incorporates modern features based on open standards. If you
|
||||
@@ -19,24 +19,35 @@ You can learn more about Unbound by reading our
|
||||
Make sure you have the C toolchain, OpenSSL and its include files, and libexpat
|
||||
installed.
|
||||
If building from the repository source you also need flex and bison installed.
|
||||
If building from the repository source, also init the git submodule and
|
||||
create the configure script with:
|
||||
|
||||
```
|
||||
git submodule update --init
|
||||
autoreconf -fi
|
||||
```
|
||||
|
||||
Unbound can be compiled and installed using:
|
||||
|
||||
```
|
||||
./configure && make && make install
|
||||
```
|
||||
|
||||
You can use libevent if you want. libevent is useful when using many (10000)
|
||||
outgoing ports. By default max 256 ports are opened at the same time and the
|
||||
builtin alternative is equally capable and a little faster.
|
||||
|
||||
You can use libevent if you want. libevent is useful when using many (e.g.,
|
||||
10000) outgoing ports.
|
||||
Use the `--with-libevent` configure option to compile Unbound with libevent
|
||||
support.
|
||||
|
||||
If not, the default builtin alternative opens max 256 ports at the same time
|
||||
and is equally capable and a little faster.
|
||||
|
||||
|
||||
## Unbound configuration
|
||||
|
||||
All of Unbound's configuration options are described in the man pages, which
|
||||
will be installed and are available on the Unbound
|
||||
[documentation page](https://unbound.docs.nlnetlabs.nl/).
|
||||
All of Unbound's configuration options are described in the `unbound.conf(5)`
|
||||
man page, which will be installed and is also available on the Unbound
|
||||
[documentation page](https://unbound.docs.nlnetlabs.nl/en/latest/manpages/unbound.conf.html)
|
||||
for the latest version.
|
||||
|
||||
An example configuration file is located in
|
||||
An example configuration file, with minimal documentation, is located in
|
||||
[doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in).
|
||||
|
||||
Vendored
-9440
File diff suppressed because it is too large
Load Diff
+65
-12
@@ -2,7 +2,12 @@
|
||||
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
|
||||
# BSD licensed.
|
||||
#
|
||||
# Version 48
|
||||
# Version 51
|
||||
# 2025-11-06 Fix ACX_CHECK_NONSTRING_ATTRIBUTE to reject clang, that prints
|
||||
# a warning for 'unknown attribute' when nonstring is used.
|
||||
# 2025-09-29 add ac_cv_func_malloc_0_nonnull as a cache value for the malloc(0)
|
||||
# check by ACX_FUNC_MALLOC.
|
||||
# 2025-09-29 add ACX_CHECK_NONSTRING_ATTRIBUTE, AHX_CONFIG_NONSTRING_ATTRIBUTE.
|
||||
# 2024-01-16 fix to add -l:libssp.a to -lcrypto link check.
|
||||
# and check for getaddrinfo with only header.
|
||||
# 2024-01-15 fix to add crypt32 to -lcrypto link check when checking for gdi32.
|
||||
@@ -71,6 +76,7 @@
|
||||
# ACX_DEPFLAG - find cc dependency flags.
|
||||
# ACX_DETERMINE_EXT_FLAGS_UNBOUND - find out which flags enable BSD and POSIX.
|
||||
# ACX_CHECK_FORMAT_ATTRIBUTE - find cc printf format syntax.
|
||||
# ACX_CHECK_NONSTRING_ATTRIBUTE - find cc nonstring attribute syntax.
|
||||
# ACX_CHECK_UNUSED_ATTRIBUTE - find cc variable unused syntax.
|
||||
# ACX_CHECK_FLTO - see if cc supports -flto and use it if so.
|
||||
# ACX_LIBTOOL_C_ONLY - create libtool for C only, improved.
|
||||
@@ -92,6 +98,7 @@
|
||||
# ACX_FUNC_IOCTLSOCKET - find ioctlsocket, portably.
|
||||
# ACX_FUNC_MALLOC - check malloc, define replacement .
|
||||
# AHX_CONFIG_FORMAT_ATTRIBUTE - config.h text for format.
|
||||
# AHX_CONFIG_NONSTRING_ATTRIBUTE - config.h text for nonstring.
|
||||
# AHX_CONFIG_UNUSED_ATTRIBUTE - config.h text for unused.
|
||||
# AHX_CONFIG_FSEEKO - define fseeko, ftello fallback.
|
||||
# AHX_CONFIG_RAND_MAX - define RAND_MAX if needed.
|
||||
@@ -490,7 +497,7 @@ AC_DEFUN([AHX_CONFIG_FORMAT_ATTRIBUTE],
|
||||
])
|
||||
|
||||
dnl Check how to mark function arguments as unused.
|
||||
dnl result in HAVE_ATTR_UNUSED.
|
||||
dnl result in HAVE_ATTR_UNUSED.
|
||||
dnl Make sure you include AHX_CONFIG_UNUSED_ATTRIBUTE also.
|
||||
AC_DEFUN([ACX_CHECK_UNUSED_ATTRIBUTE],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
@@ -525,6 +532,49 @@ if test $ac_cv_c_unused_attribute = yes; then
|
||||
fi
|
||||
])dnl
|
||||
|
||||
dnl Check how to mark function arguments as nonstring.
|
||||
dnl result in HAVE_ATTR_NONSTRING.
|
||||
dnl Make sure you include AHX_CONFIG_NONSTRING_ATTRIBUTE also.
|
||||
AC_DEFUN([ACX_CHECK_NONSTRING_ATTRIBUTE],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([ACX_CHECK_ERROR_FLAGS])
|
||||
BAKCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $ERRFLAG"
|
||||
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "nonstring" attribute)
|
||||
AC_CACHE_VAL(ac_cv_c_nonstring_attribute,
|
||||
[ac_cv_c_nonstring_attribute=no
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
|
||||
struct test {
|
||||
char __attribute__((nonstring)) s[1];
|
||||
};
|
||||
]], [[
|
||||
struct test t = { "1" };
|
||||
(void) t;
|
||||
]])],[ac_cv_c_nonstring_attribute="yes"],[ac_cv_c_nonstring_attribute="no"])
|
||||
CFLAGS="$BAKCFLAGS"
|
||||
])
|
||||
|
||||
dnl Setup ATTR_NONSTRING config.h parts.
|
||||
dnl make sure you call ACX_CHECK_NONSTRING_ATTRIBUTE also.
|
||||
AC_DEFUN([AHX_CONFIG_NONSTRING_ATTRIBUTE],
|
||||
[
|
||||
#if defined(DOXYGEN)
|
||||
# define ATTR_NONSTRING(x) x
|
||||
#elif defined(__cplusplus)
|
||||
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
|
||||
#elif defined(HAVE_ATTR_NONSTRING)
|
||||
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
|
||||
#else /* !HAVE_ATTR_NONSTRING */
|
||||
# define ATTR_NONSTRING(x) x
|
||||
#endif /* !HAVE_ATTR_NONSTRING */
|
||||
])
|
||||
|
||||
AC_MSG_RESULT($ac_cv_c_nonstring_attribute)
|
||||
if test $ac_cv_c_nonstring_attribute = yes; then
|
||||
AC_DEFINE(HAVE_ATTR_NONSTRING, 1, [Whether the C compiler accepts the "nonstring" attribute])
|
||||
fi
|
||||
])dnl
|
||||
|
||||
dnl Pre-fun for ACX_LIBTOOL_C_ONLY
|
||||
AC_DEFUN([ACX_LIBTOOL_C_PRE], [
|
||||
# skip these tests, we do not need them.
|
||||
@@ -1190,8 +1240,9 @@ dnl detect malloc and provide malloc compat prototype.
|
||||
dnl $1: unique name for compat code
|
||||
AC_DEFUN([ACX_FUNC_MALLOC],
|
||||
[
|
||||
AC_MSG_CHECKING([for GNU libc compatible malloc])
|
||||
AC_RUN_IFELSE([AC_LANG_PROGRAM(
|
||||
AC_CACHE_CHECK([for GNU libc compatible malloc],[ac_cv_func_malloc_0_nonnull],
|
||||
[
|
||||
AC_RUN_IFELSE([AC_LANG_PROGRAM(
|
||||
[[#if defined STDC_HEADERS || defined HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
@@ -1199,14 +1250,16 @@ char *malloc ();
|
||||
#endif
|
||||
]], [ if(malloc(0) != 0) return 1;])
|
||||
],
|
||||
[AC_MSG_RESULT([no])
|
||||
AC_LIBOBJ(malloc)
|
||||
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] ,
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])],
|
||||
[AC_MSG_RESULT([no (crosscompile)])
|
||||
AC_LIBOBJ(malloc)
|
||||
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] )
|
||||
[ac_cv_func_malloc_0_nonnull=no],
|
||||
[ac_cv_func_malloc_0_nonnull=yes],
|
||||
[ac_cv_func_malloc_0_nonnull="no (crosscompile)"])
|
||||
])
|
||||
AS_IF([test "$ac_cv_func_malloc_0_nonnull" = yes],
|
||||
[AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])],
|
||||
[
|
||||
AC_LIBOBJ(malloc)
|
||||
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])
|
||||
])
|
||||
])
|
||||
|
||||
dnl Define fallback for fseeko and ftello if needed.
|
||||
|
||||
+51
-42
@@ -401,12 +401,9 @@ prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
|
||||
LDNS_RCODE_YXDOMAIN)
|
||||
return 0;
|
||||
/* We don't store the reply if its TTL is 0 unless serve-expired is
|
||||
* enabled. Such a reply won't be reusable and simply be a waste for
|
||||
* the backend. It's also compatible with the default behavior of
|
||||
* dns_cache_store_msg(). */
|
||||
if(qstate->return_msg->rep->ttl == 0 &&
|
||||
!qstate->env->cfg->serve_expired)
|
||||
/* We don't store the reply if its TTL is 0. This is probably coming
|
||||
* from upstream and it is not meant to be stored. */
|
||||
if(qstate->return_msg->rep->ttl == 0)
|
||||
return 0;
|
||||
|
||||
/* The EDE is added to the out-list so it is encoded in the cached message */
|
||||
@@ -460,7 +457,7 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
* - serve_expired needs to be set
|
||||
* - if SERVE_EXPIRED_TTL is set make sure that the record is not older
|
||||
* than that. */
|
||||
if((time_t)expiry < *qstate->env->now &&
|
||||
if(TTL_IS_EXPIRED((time_t)expiry, *qstate->env->now) &&
|
||||
(!qstate->env->cfg->serve_expired ||
|
||||
(SERVE_EXPIRED_TTL &&
|
||||
*qstate->env->now - (time_t)expiry > SERVE_EXPIRED_TTL)))
|
||||
@@ -472,7 +469,8 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
/* Adjust the TTL of the given RRset by 'subtract'. If 'subtract' is
|
||||
* negative, set the TTL to 0. */
|
||||
static void
|
||||
packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
|
||||
packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract,
|
||||
time_t timestamp)
|
||||
{
|
||||
size_t i;
|
||||
size_t total = data->count + data->rrsig_count;
|
||||
@@ -484,13 +482,13 @@ packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
|
||||
data->rr_ttl[i] -= subtract;
|
||||
else data->rr_ttl[i] = 0;
|
||||
}
|
||||
data->ttl_add = (subtract < data->ttl_add) ? (data->ttl_add - subtract) : 0;
|
||||
data->ttl_add = timestamp;
|
||||
}
|
||||
|
||||
/* Adjust the TTL of a DNS message and its RRs by 'adjust'. If 'adjust' is
|
||||
* negative, set the TTLs to 0. */
|
||||
static void
|
||||
adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
|
||||
adjust_msg_ttl(struct dns_msg* msg, time_t adjust, time_t timestamp)
|
||||
{
|
||||
size_t i;
|
||||
if(adjust >= 0 && msg->rep->ttl > adjust)
|
||||
@@ -502,13 +500,13 @@ adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
|
||||
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
packed_rrset_ttl_subtract((struct packed_rrset_data*)msg->
|
||||
rep->rrsets[i]->entry.data, adjust);
|
||||
rep->rrsets[i]->entry.data, adjust, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the TTL of the given RRset to fixed value. */
|
||||
static void
|
||||
packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl)
|
||||
packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl, time_t timestamp)
|
||||
{
|
||||
size_t i;
|
||||
size_t total = data->count + data->rrsig_count;
|
||||
@@ -516,12 +514,12 @@ packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl)
|
||||
for(i=0; i<total; i++) {
|
||||
data->rr_ttl[i] = ttl;
|
||||
}
|
||||
data->ttl_add = 0;
|
||||
data->ttl_add = timestamp;
|
||||
}
|
||||
|
||||
/* Set the TTL of a DNS message and its RRs by to a fixed value. */
|
||||
static void
|
||||
set_msg_ttl(struct dns_msg* msg, time_t ttl)
|
||||
set_msg_ttl(struct dns_msg* msg, time_t ttl, time_t timestamp)
|
||||
{
|
||||
size_t i;
|
||||
msg->rep->ttl = ttl;
|
||||
@@ -530,14 +528,14 @@ set_msg_ttl(struct dns_msg* msg, time_t ttl)
|
||||
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
packed_rrset_ttl_set((struct packed_rrset_data*)msg->
|
||||
rep->rrsets[i]->entry.data, ttl);
|
||||
rep->rrsets[i]->entry.data, ttl, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
/** convert dns message in buffer to return_msg */
|
||||
static int
|
||||
parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
|
||||
int* msg_expired)
|
||||
int* msg_expired, time_t* msg_timestamp, time_t* msg_expiry)
|
||||
{
|
||||
struct msg_parse* prs;
|
||||
struct edns_data edns;
|
||||
@@ -554,6 +552,9 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
|
||||
×tamp, sizeof(timestamp));
|
||||
expiry = be64toh(expiry);
|
||||
timestamp = be64toh(timestamp);
|
||||
log_assert(timestamp <= expiry);
|
||||
*msg_expiry = (time_t)expiry;
|
||||
*msg_timestamp = (time_t)timestamp;
|
||||
|
||||
/* parse DNS packet */
|
||||
regional_free_all(qstate->env->scratch);
|
||||
@@ -605,11 +606,9 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
|
||||
return 1; /* message from the future (clock skew?) */
|
||||
}
|
||||
adjust = *qstate->env->now - (time_t)timestamp;
|
||||
if(qstate->return_msg->rep->ttl < adjust) {
|
||||
if(TTL_IS_EXPIRED((time_t)expiry, *qstate->env->now)) {
|
||||
verbose(VERB_ALGO, "cachedb msg expired");
|
||||
*msg_expired = 1;
|
||||
/* If serve-expired is enabled, we still use an expired message
|
||||
* setting the TTL to 0. */
|
||||
if(!qstate->env->cfg->serve_expired ||
|
||||
(FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
|
||||
!= LDNS_RCODE_NOERROR &&
|
||||
@@ -618,23 +617,21 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
|
||||
FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
|
||||
!= LDNS_RCODE_YXDOMAIN))
|
||||
return 0; /* message expired */
|
||||
else
|
||||
adjust = -1;
|
||||
/* If serve-expired is enabled, we still use an expired message.
|
||||
* Set the TTL to 0 now and it will be handled specially later
|
||||
* when we need to store it internally. */
|
||||
adjust = -1;
|
||||
}
|
||||
adjust_msg_ttl(qstate->return_msg, adjust, timestamp);
|
||||
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
|
||||
* refetch will be scheduled. The comparison between 'expiry' and
|
||||
* 'now' should be redundant given how these values were calculated,
|
||||
* but we check it just in case as does good_expiry_and_qinfo(). */
|
||||
if(qstate->env->cfg->serve_expired &&
|
||||
!qstate->env->cfg->serve_expired_client_timeout &&
|
||||
(adjust == -1 || (time_t)expiry < *qstate->env->now)) {
|
||||
* refetch will be scheduled. */
|
||||
if(*msg_expired && !qstate->env->cfg->serve_expired_client_timeout) {
|
||||
qstate->need_refetch = 1;
|
||||
}
|
||||
|
||||
@@ -647,7 +644,7 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
|
||||
*/
|
||||
static int
|
||||
cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie,
|
||||
int* msg_expired)
|
||||
int* msg_expired, time_t* msg_timestamp, time_t* msg_expiry)
|
||||
{
|
||||
char key[(CACHEDB_HASHSIZE/8)*2+1];
|
||||
calc_hash(&qstate->qinfo, qstate->env, key, sizeof(key));
|
||||
@@ -664,7 +661,8 @@ cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie,
|
||||
}
|
||||
|
||||
/* parse dns message into return_msg */
|
||||
if( !parse_data(qstate, qstate->env->scratch_buffer, msg_expired) ) {
|
||||
if( !parse_data(qstate, qstate->env->scratch_buffer, msg_expired,
|
||||
msg_timestamp, msg_expiry) ) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -736,20 +734,24 @@ cachedb_intcache_lookup(struct module_qstate* qstate, struct cachedb_env* cde)
|
||||
* Store query into the internal cache of unbound.
|
||||
*/
|
||||
static void
|
||||
cachedb_intcache_store(struct module_qstate* qstate, int msg_expired)
|
||||
cachedb_intcache_store(struct module_qstate* qstate, int msg_expired,
|
||||
time_t msg_timestamp, time_t msg_expiry)
|
||||
{
|
||||
uint32_t store_flags = qstate->query_flags;
|
||||
int serve_expired = qstate->env->cfg->serve_expired;
|
||||
|
||||
if(qstate->env->cfg->serve_expired)
|
||||
store_flags |= DNSCACHE_STORE_ZEROTTL;
|
||||
if(!qstate->return_msg)
|
||||
return;
|
||||
if(serve_expired && msg_expired) {
|
||||
/* Set TTLs to a value such that value + *env->now is
|
||||
* going to be now-3 seconds. Making it expired
|
||||
* in the cache. */
|
||||
set_msg_ttl(qstate->return_msg, (time_t)-3);
|
||||
time_t original_ttl = msg_expiry - msg_timestamp;
|
||||
store_flags |= DNSCACHE_STORE_EXPIRED_MSG_CACHEDB;
|
||||
/* Pass the original TTL of the expired message and signal with
|
||||
* the DNSCACHE_STORE_EXPIRED_MSG_CACHEDB flag that
|
||||
* dns_cache_store_msg() needs to set absolute expired TTLs
|
||||
* based on the original message TTL.
|
||||
* Results as expired message in the cache */
|
||||
set_msg_ttl(qstate->return_msg, original_ttl, 0);
|
||||
verbose(VERB_ALGO, "cachedb expired msg set to be expired now "
|
||||
"(original ttl: %d)", (int)original_ttl);
|
||||
/* The expired entry does not get checked by the validator
|
||||
* and we need a validation value for it. */
|
||||
if(qstate->env->cfg->cachedb_check_when_serve_expired)
|
||||
@@ -767,12 +769,14 @@ cachedb_intcache_store(struct module_qstate* qstate, int msg_expired)
|
||||
* of cache. */
|
||||
return;
|
||||
}
|
||||
/* set TTLs to zero again */
|
||||
adjust_msg_ttl(qstate->return_msg, -1);
|
||||
/* Send serve expired responses based on the cachedb
|
||||
* returned message, that was just stored in the cache.
|
||||
* It can then continue to work on this query. */
|
||||
mesh_respond_serve_expired(qstate->mesh_info);
|
||||
/* set TTLs as expired for this return_msg in case it is used
|
||||
* later on */
|
||||
set_msg_ttl(qstate->return_msg,
|
||||
EXPIRED_REPLY_TTL_CALC(msg_expiry, msg_timestamp), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,6 +794,7 @@ cachedb_handle_query(struct module_qstate* qstate,
|
||||
struct cachedb_env* ie, int id)
|
||||
{
|
||||
int msg_expired = 0;
|
||||
time_t msg_timestamp, msg_expiry;
|
||||
qstate->is_cachedb_answer = 0;
|
||||
/* check if we are enabled, and skip if so */
|
||||
if(!ie->enabled) {
|
||||
@@ -824,13 +829,15 @@ cachedb_handle_query(struct module_qstate* qstate,
|
||||
}
|
||||
|
||||
/* ask backend cache to see if we have data */
|
||||
if(cachedb_extcache_lookup(qstate, ie, &msg_expired)) {
|
||||
if(cachedb_extcache_lookup(qstate, ie, &msg_expired, &msg_timestamp,
|
||||
&msg_expiry)) {
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg(ie->backend->name,
|
||||
&qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep);
|
||||
/* store this result in internal cache */
|
||||
cachedb_intcache_store(qstate, msg_expired);
|
||||
cachedb_intcache_store(qstate,
|
||||
msg_expired, msg_timestamp, msg_expiry);
|
||||
/* 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.
|
||||
@@ -850,6 +857,8 @@ cachedb_handle_query(struct module_qstate* qstate,
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
/* No 0TTL answers escaping from external cache. */
|
||||
log_assert(qstate->return_msg->rep->ttl > 0);
|
||||
qstate->is_cachedb_answer = 1;
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
|
||||
@@ -143,6 +143,12 @@ redis_connect(const char* host, int port, const char* path,
|
||||
{
|
||||
struct timeval now_val;
|
||||
redisContext* ctx;
|
||||
#ifdef THREADS_DISABLED
|
||||
/* Fix attribute unused warning.
|
||||
* wait_lock is only used with lock_basic_* functions that are nop'ed
|
||||
* when compiled without thread support. */
|
||||
(void)wait_lock;
|
||||
#endif /* THREADS_DISABLED */
|
||||
|
||||
/* See if the redis server is down, and reconnect has to wait. */
|
||||
if(*reconnect_attempts > REDIS_RECONNECT_ATTEMPT_LIMIT) {
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
#ifndef UB_ON_WINDOWS
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#ifdef __QNX__
|
||||
#include "util/log.h"
|
||||
#endif /* __QNX__ */
|
||||
|
||||
#define KEYSTREAM_ONLY
|
||||
#include "chacha_private.h"
|
||||
@@ -187,7 +190,11 @@ _rs_stir(void)
|
||||
if(errno != ENOSYS ||
|
||||
fallback_getentropy_urandom(rnd, sizeof rnd) == -1) {
|
||||
#ifdef SIGKILL
|
||||
#ifndef __QNX__
|
||||
raise(SIGKILL);
|
||||
#else /* !__QNX__ */
|
||||
fatal_exit("failed to getentropy");
|
||||
#endif /* __QNX__ */
|
||||
#else
|
||||
exit(9); /* windows */
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,9 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/resource.h>
|
||||
#ifndef __QNX__
|
||||
#include <sys/syscall.h>
|
||||
#endif /* !__QNX__ */
|
||||
#ifdef SYS__sysctl
|
||||
#include <linux/sysctl.h>
|
||||
#endif
|
||||
@@ -42,7 +44,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#ifndef __QNX__
|
||||
#include <link.h>
|
||||
#endif /* __QNX__ */
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
@@ -60,12 +64,14 @@
|
||||
#define SHA512_Final(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r)
|
||||
#endif
|
||||
|
||||
#ifndef __QNX__
|
||||
#include <linux/types.h>
|
||||
#include <linux/random.h>
|
||||
#ifdef HAVE_GETAUXVAL
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
#include <sys/vfs.h>
|
||||
#endif /* !__QNX__ */
|
||||
#ifndef MAP_ANON
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
@@ -94,8 +100,10 @@ static int getentropy_urandom(void *buf, size_t len);
|
||||
#ifdef SYS__sysctl
|
||||
static int getentropy_sysctl(void *buf, size_t len);
|
||||
#endif
|
||||
#ifndef __QNX__
|
||||
static int getentropy_fallback(void *buf, size_t len);
|
||||
static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
|
||||
#endif /* !__QNX__ */
|
||||
|
||||
int
|
||||
getentropy(void *buf, size_t len)
|
||||
@@ -178,6 +186,7 @@ getentropy(void *buf, size_t len)
|
||||
* sysctl ABI, or consider providing a new failsafe API which
|
||||
* works in a chroot or when file descriptors are exhausted.
|
||||
*/
|
||||
#ifndef __QNX__
|
||||
#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
|
||||
#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
|
||||
raise(SIGKILL);
|
||||
@@ -185,6 +194,9 @@ getentropy(void *buf, size_t len)
|
||||
ret = getentropy_fallback(buf, len);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
#else /* !__QNX__ */
|
||||
fatal_exit("failed to read from /dev/urandom");
|
||||
#endif /* __QNX__ */
|
||||
|
||||
errno = EIO;
|
||||
return (ret);
|
||||
@@ -214,7 +226,11 @@ getentropy_urandom(void *buf, size_t len)
|
||||
{
|
||||
struct stat st;
|
||||
size_t i;
|
||||
#ifndef __QNX__
|
||||
int fd, cnt, flags;
|
||||
#else /* !__QNX__ */
|
||||
int fd, flags;
|
||||
#endif /* __QNX__ */
|
||||
int save_errno = errno;
|
||||
|
||||
start:
|
||||
@@ -241,10 +257,12 @@ start:
|
||||
close(fd);
|
||||
goto nodevrandom;
|
||||
}
|
||||
#ifndef __QNX__
|
||||
if (ioctl(fd, RNDGETENTCNT, &cnt) == -1) {
|
||||
close(fd);
|
||||
goto nodevrandom;
|
||||
}
|
||||
#endif /* !__QNX__ */
|
||||
for (i = 0; i < len; ) {
|
||||
size_t wanted = len - i;
|
||||
ssize_t ret = read(fd, (char *)buf + i, wanted);
|
||||
@@ -265,6 +283,7 @@ nodevrandom:
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#ifndef __QNX__
|
||||
#ifdef SYS__sysctl
|
||||
static int
|
||||
getentropy_sysctl(void *buf, size_t len)
|
||||
@@ -537,3 +556,4 @@ getentropy_fallback(void *buf, size_t len)
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
}
|
||||
#endif /* !__QNX__ */
|
||||
|
||||
Vendored
-1812
File diff suppressed because it is too large
Load Diff
-1640
File diff suppressed because it is too large
Load Diff
Vendored
-1971
File diff suppressed because it is too large
Load Diff
+70
-19
@@ -12,14 +12,14 @@ sinclude(dnscrypt/dnscrypt.m4)
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[24])
|
||||
m4_define([VERSION_MICRO],[2])
|
||||
m4_define([VERSION_MICRO],[3])
|
||||
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=34
|
||||
LIBUNBOUND_REVISION=36
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -122,6 +122,7 @@ LIBUNBOUND_AGE=1
|
||||
# 1.24.0 had 9:33:1
|
||||
# 1.24.1 had 9:34:1
|
||||
# 1.24.2 had 9:35:1
|
||||
# 1.24.3 had 9:36:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -176,6 +177,12 @@ else
|
||||
else on_mingw="no"; fi
|
||||
fi
|
||||
|
||||
dnl install the install-sh file with libtoolize -ci, and autoreconf -fi.
|
||||
AC_REQUIRE_AUX_FILE([install-sh])
|
||||
if test ! -f install-sh; then
|
||||
AC_MSG_WARN([./install-sh is missing, use `libtoolize -ci` or `autoreconf -fi` to add it])
|
||||
fi
|
||||
|
||||
#
|
||||
# Determine configuration file
|
||||
# the eval is to evaluate shell expansion twice
|
||||
@@ -330,6 +337,7 @@ fi
|
||||
AC_C_INLINE
|
||||
ACX_CHECK_FORMAT_ATTRIBUTE
|
||||
ACX_CHECK_UNUSED_ATTRIBUTE
|
||||
ACX_CHECK_NONSTRING_ATTRIBUTE
|
||||
|
||||
AC_DEFUN([CHECK_WEAK_ATTRIBUTE],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
@@ -360,7 +368,14 @@ AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "noreturn" attribu
|
||||
AC_CACHE_VAL(ac_cv_c_noreturn_attribute,
|
||||
[ac_cv_c_noreturn_attribute=no
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h>
|
||||
__attribute__((noreturn)) void f(int x) { printf("%d", x); }
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
# endif
|
||||
#endif
|
||||
__attribute__((noreturn)) void f(int x) { printf("%d", x); exit(1); }
|
||||
]], [[
|
||||
f(1);
|
||||
]])],[ac_cv_c_noreturn_attribute="yes"],[ac_cv_c_noreturn_attribute="no"])
|
||||
@@ -635,19 +650,19 @@ AC_ARG_ENABLE(alloc-nonregional, AS_HELP_STRING([--enable-alloc-nonregional],[ e
|
||||
if test x_$enable_alloc_nonregional = x_yes; then
|
||||
AC_DEFINE(UNBOUND_ALLOC_NONREGIONAL, 1, [use malloc not regions, for debug use])
|
||||
fi
|
||||
if test x_$enable_alloc_checks = x_yes; then
|
||||
AS_IF([test x_$enable_alloc_checks = x_yes],[
|
||||
AC_DEFINE(UNBOUND_ALLOC_STATS, 1, [use statistics for allocs and frees, for debug use])
|
||||
SLDNS_ALLOCCHECK_EXTRA_OBJ="alloc.lo log.lo"
|
||||
AC_SUBST(SLDNS_ALLOCCHECK_EXTRA_OBJ)
|
||||
ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ="alloc.lo"
|
||||
AC_SUBST(ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ)
|
||||
else
|
||||
if test x_$enable_alloc_lite = x_yes; then
|
||||
],[
|
||||
AS_IF([test x_$enable_alloc_lite = x_yes],[
|
||||
AC_DEFINE(UNBOUND_ALLOC_LITE, 1, [use to enable lightweight alloc assertions, for debug use])
|
||||
else
|
||||
],[
|
||||
ACX_FUNC_MALLOC([unbound])
|
||||
fi
|
||||
fi
|
||||
])
|
||||
])
|
||||
|
||||
# check windows threads (we use them, not pthreads, on windows).
|
||||
if test "$on_mingw" = "yes"; then
|
||||
@@ -1253,7 +1268,7 @@ case "$enable_ecdsa" in
|
||||
# see if OPENSSL 1.0.0 or later (has EVP MD and Verify independency)
|
||||
AC_MSG_CHECKING([if openssl supports SHA2 and ECDSA with EVP])
|
||||
if grep OPENSSL_VERSION_TEXT $ssldir_include/openssl/opensslv.h | grep "OpenSSL" >/dev/null; then
|
||||
if grep OPENSSL_VERSION_NUMBER $ssldir_include/openssl/opensslv.h | grep 0x0 >/dev/null; then
|
||||
if grep OPENSSL_VERSION_TEXT $ssldir_include/openssl/opensslv.h | grep "OpenSSL 0\." >/dev/null; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_DEFINE_UNQUOTED([USE_ECDSA_EVP_WORKAROUND], [1], [Define this to enable an EVP workaround for older openssl])
|
||||
else
|
||||
@@ -1673,10 +1688,12 @@ if test x_$enable_static_exe = x_yes; then
|
||||
LIBS="$LIBS -lgdi32"
|
||||
fi
|
||||
AC_CHECK_LIB([z], [compress], [ LIBS="$LIBS -lz" ])
|
||||
if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
|
||||
:
|
||||
else
|
||||
LIBS="$LIBS -l:libssp.a"
|
||||
if echo "$host" | $GREP -i -e linux >/dev/null; then
|
||||
if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
|
||||
:
|
||||
else
|
||||
LIBS="$LIBS -l:libssp.a"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -1694,10 +1711,12 @@ if test x_$enable_fully_static = x_yes; then
|
||||
LIBS="$LIBS -lgdi32"
|
||||
fi
|
||||
AC_CHECK_LIB([z], [compress], [ LIBS="$LIBS -lz" ])
|
||||
if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
|
||||
:
|
||||
else
|
||||
LIBS="$LIBS -l:libssp.a"
|
||||
if echo "$host" | $GREP -i -e linux >/dev/null; then
|
||||
if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
|
||||
:
|
||||
else
|
||||
LIBS="$LIBS -l:libssp.a"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -2023,6 +2042,9 @@ dt_DNSTAP([$UNBOUND_RUN_DIR/dnstap.sock],
|
||||
AC_SUBST([ENABLE_DNSTAP], [0])
|
||||
]
|
||||
)
|
||||
dnstap_config="dnstap/dnstap_config.h.tmp:dnstap/dnstap_config.h.in"
|
||||
dnstap_config_tmp="dnstap/dnstap_config.h.tmp"
|
||||
dnstap_config_out="dnstap/dnstap_config.h"
|
||||
|
||||
# check for dnscrypt if requested
|
||||
dnsc_DNSCRYPT([
|
||||
@@ -2293,6 +2315,7 @@ dnl includes
|
||||
|
||||
AHX_CONFIG_FORMAT_ATTRIBUTE
|
||||
AHX_CONFIG_UNUSED_ATTRIBUTE
|
||||
AHX_CONFIG_NONSTRING_ATTRIBUTE
|
||||
AHX_CONFIG_FSEEKO
|
||||
AHX_CONFIG_MAXHOSTNAMELEN
|
||||
#if !defined(HAVE_SNPRINTF) || defined(SNPRINTF_RET_BROKEN)
|
||||
@@ -2476,6 +2499,34 @@ AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO])
|
||||
AX_BUILD_DATE_EPOCH(date, [[%b %e, %Y]])
|
||||
AC_SUBST(date)
|
||||
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service])
|
||||
AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh $dnstap_config dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
# Arguments introduced specifically for simdzone.
|
||||
AC_ARG_ENABLE(westmere, AS_HELP_STRING([--disable-westmere], [Disable Westmere (SSE4.2) parser kernel]))
|
||||
AC_ARG_ENABLE(haswell, AS_HELP_STRING([--disable-haswell], [Disable Haswell (AVX2) parser kernel]))
|
||||
if test ! -f simdzone/configure.ac; then AC_MSG_ERROR([There is no "simdzone/configure.ac" file. The simdzone directory has not been fetched, perhaps get it with 'git submodule update --init'.]); fi
|
||||
if test ! -f simdzone/configure; then AC_MSG_ERROR([There is no "simdzone/configure" file. The simdzone directory has no configure script file, perhaps run 'autoreconf -fi'.]); fi
|
||||
AC_CONFIG_SUBDIRS([simdzone])
|
||||
|
||||
AC_OUTPUT
|
||||
# Pick up the objects for simdzone.
|
||||
SIMDZONE_OBJ=`(cd simdzone; make list_objs) | sed -e 's?src?simdzone/src?g'`
|
||||
AC_SUBST(SIMDZONE_OBJ)
|
||||
sed -e 's?^SIMDZONE_OBJ=.*$?SIMDZONE_OBJ='"$SIMDZONE_OBJ"'?' < Makefile > Makefile.tmp.$$
|
||||
mv -f Makefile.tmp.$$ Makefile
|
||||
# If dnstap config has changed, overwrite it.
|
||||
if test -n "$dnstap_config"; then
|
||||
if test ! -f "$dnstap_config_out"; then
|
||||
mv "$dnstap_config_tmp" "$dnstap_config_out" || AC_MSG_ERROR([Could not create $dnstap_config_out])
|
||||
else if diff "$dnstap_config_out" "$dnstap_config_tmp" >/dev/null 2>&1; then
|
||||
if test "x$opt_dnstap" != "xno"; then
|
||||
AC_MSG_NOTICE([In $srcdir: $dnstap_config_out is unchanged])
|
||||
fi
|
||||
rm -f "$dnstap_config_tmp"
|
||||
else
|
||||
rm -f "$dnstap_config_out"
|
||||
mv "$dnstap_config_tmp" "$dnstap_config_out" || AC_MSG_ERROR([Could not create $dnstap_config_out])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
#!/usr/bin/env bash
|
||||
OPENSSL_VERSION=1.1.1d
|
||||
|
||||
echo "Downloading OpenSSL"
|
||||
if ! curl -L -k -s -o openssl-1.1.1d.tar.gz https://www.openssl.org/source/openssl-1.1.1d.tar.gz;
|
||||
if ! curl -L -k -s -o openssl-$OPENSSL_VERSION.tar.gz https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz;
|
||||
then
|
||||
echo "Failed to download OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Unpacking OpenSSL"
|
||||
rm -rf ./openssl-1.1.1d
|
||||
if ! tar -xf openssl-1.1.1d.tar.gz;
|
||||
rm -rf ./openssl-$OPENSSL_VERSION
|
||||
if ! tar -xf openssl-$OPENSSL_VERSION.tar.gz;
|
||||
then
|
||||
echo "Failed to unpack OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd openssl-1.1.1d || exit 1
|
||||
cd openssl-$OPENSSL_VERSION || exit 1
|
||||
|
||||
if ! cp ../contrib/ios/15-ios.conf Configurations/; then
|
||||
echo "Failed to copy OpenSSL ios config"
|
||||
@@ -27,7 +28,8 @@ fi
|
||||
# Also see https://github.com/openssl/openssl/issues/7607.
|
||||
if ! patch -u -p0 < ../contrib/ios/openssl.patch; then
|
||||
echo "Failed to patch OpenSSL"
|
||||
exit 1
|
||||
# the partial patch may be useful.
|
||||
#exit 1
|
||||
fi
|
||||
|
||||
echo "Configuring OpenSSL"
|
||||
|
||||
@@ -175,6 +175,7 @@ fi
|
||||
# For example, remove 4.3, 6.2, and 6.1 if they are not installed. We go back to
|
||||
# the 1.0 SDKs because Apple WatchOS uses low numbers, like 2.0 and 2.1.
|
||||
XCODE_SDK=
|
||||
if test -z "$SDK_VERSION"; then
|
||||
for i in $(seq -f "%.1f" 30.0 -0.1 1.0)
|
||||
do
|
||||
if [ -d "$XCODE_DEVELOPER_SDK/Developer/SDKs/$IOS_SDK$i.sdk" ]; then
|
||||
@@ -182,6 +183,10 @@ do
|
||||
break
|
||||
fi
|
||||
done
|
||||
else
|
||||
i="$SDK_VERSION"
|
||||
XCODE_SDK="$IOS_SDK$i.sdk"
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ -z "$XCODE_SDK" ]; then
|
||||
|
||||
@@ -59,7 +59,7 @@ ExecReload=+/bin/kill -HUP $MAINPID
|
||||
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
|
||||
NotifyAccess=main
|
||||
Type=notify
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_ADMIN
|
||||
MemoryDenyWriteExecute=true
|
||||
NoNewPrivileges=true
|
||||
PrivateDevices=true
|
||||
|
||||
@@ -26,7 +26,7 @@ ExecReload=+/bin/kill -HUP $MAINPID
|
||||
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
|
||||
NotifyAccess=main
|
||||
Type=notify
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
|
||||
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_ADMIN
|
||||
MemoryDenyWriteExecute=true
|
||||
NoNewPrivileges=true
|
||||
PrivateDevices=true
|
||||
|
||||
+34
-7
@@ -558,9 +558,11 @@ daemon_create_workers(struct daemon* daemon)
|
||||
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");
|
||||
if (cfg_has_quic(daemon->cfg)) {
|
||||
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);
|
||||
@@ -631,6 +633,25 @@ static void close_other_pipes(struct daemon* daemon, int thr)
|
||||
}
|
||||
#endif /* THREADS_DISABLED */
|
||||
|
||||
/**
|
||||
* Function to set the thread local log ID.
|
||||
* Either the internal thread number, or the LWP ID on Linux based on
|
||||
* configuration.
|
||||
*/
|
||||
static void
|
||||
set_log_thread_id(struct worker* worker, struct config_file* cfg)
|
||||
{
|
||||
(void)cfg;
|
||||
log_assert(worker);
|
||||
#if defined(HAVE_GETTID) && !defined(THREADS_DISABLED)
|
||||
worker->thread_tid = gettid();
|
||||
if(cfg->log_thread_id)
|
||||
log_thread_set(&worker->thread_tid);
|
||||
else
|
||||
#endif
|
||||
log_thread_set(&worker->thread_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to start one thread.
|
||||
* @param arg: user argument.
|
||||
@@ -641,7 +662,7 @@ thread_start(void* arg)
|
||||
{
|
||||
struct worker* worker = (struct worker*)arg;
|
||||
int port_num = 0;
|
||||
log_thread_set(&worker->thread_num);
|
||||
set_log_thread_id(worker, worker->daemon->cfg);
|
||||
ub_thread_blocksigs();
|
||||
#ifdef THREADS_DISABLED
|
||||
/* close pipe ends used by main */
|
||||
@@ -801,9 +822,13 @@ daemon_fork(struct daemon* daemon)
|
||||
fatal_exit("RPZ requires the respip module");
|
||||
|
||||
/* first create all the worker structures, so we can pass
|
||||
* them to the newly created threads.
|
||||
* them to the newly created threads.
|
||||
*/
|
||||
daemon_create_workers(daemon);
|
||||
/* Set it for the first (main) worker since it does not take part in
|
||||
* the thread_start() procedure.
|
||||
*/
|
||||
set_log_thread_id(daemon->workers[0], daemon->cfg);
|
||||
|
||||
#if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
|
||||
/* in libev the first inited base gets signals */
|
||||
@@ -917,8 +942,10 @@ daemon_cleanup(struct daemon* daemon)
|
||||
daemon->dnscenv = NULL;
|
||||
#endif
|
||||
#ifdef HAVE_NGTCP2
|
||||
doq_table_delete(daemon->doq_table);
|
||||
daemon->doq_table = NULL;
|
||||
if (daemon->doq_table) {
|
||||
doq_table_delete(daemon->doq_table);
|
||||
daemon->doq_table = NULL;
|
||||
}
|
||||
#endif
|
||||
daemon->cfg = NULL;
|
||||
}
|
||||
|
||||
+60
-3
@@ -153,7 +153,7 @@ remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg)
|
||||
log_crypto_err("could not SSL_CTX_new");
|
||||
return 0;
|
||||
}
|
||||
if(!listen_sslctx_setup(rc->ctx)) {
|
||||
if(!listen_sslctx_setup(rc->ctx, cfg->tls_use_system_policy_versions)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -801,6 +801,8 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s)
|
||||
(unsigned long)s->svr.num_queries_cookie_invalid)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.queries_discard_timeout"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries_discard_timeout)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.queries_replyaddr_limit"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries_replyaddr_limit)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.queries_wait_limit"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries_wait_limit)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.cachehits"SQ"%lu\n", nm,
|
||||
@@ -845,6 +847,8 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s)
|
||||
(unsigned long)s->mesh_num_states)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.requestlist.current.user"SQ"%lu\n", nm,
|
||||
(unsigned long)s->mesh_num_reply_states)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.requestlist.current.replies"SQ"%lu\n", nm,
|
||||
(unsigned long)s->mesh_num_reply_addrs)) return 0;
|
||||
#ifndef S_SPLINT_S
|
||||
sumwait.tv_sec = s->mesh_replies_sum_wait_sec;
|
||||
sumwait.tv_usec = s->mesh_replies_sum_wait_usec;
|
||||
@@ -1335,7 +1339,7 @@ perform_zone_add(RES* ssl, struct local_zones* zones, char* arg)
|
||||
return 1;
|
||||
}
|
||||
if(!local_zones_add_zone(zones, nm, nmlen,
|
||||
nmlabs, LDNS_RR_CLASS_IN, t)) {
|
||||
nmlabs, LDNS_RR_CLASS_IN, t, NULL)) {
|
||||
lock_rw_unlock(&zones->lock);
|
||||
ssl_printf(ssl, "error out of memory\n");
|
||||
return 0;
|
||||
@@ -5870,6 +5874,7 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
|
||||
COPY_VAR_ptr(tls_ciphers);
|
||||
COPY_VAR_ptr(tls_ciphersuites);
|
||||
COPY_VAR_int(tls_use_sni);
|
||||
COPY_VAR_int(tls_use_system_policy_versions);
|
||||
COPY_VAR_int(https_port);
|
||||
COPY_VAR_ptr(http_endpoint);
|
||||
COPY_VAR_uint32_t(http_max_streams);
|
||||
@@ -5967,6 +5972,7 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
|
||||
COPY_VAR_int(log_servfail);
|
||||
COPY_VAR_ptr(log_identity);
|
||||
COPY_VAR_int(log_destaddr);
|
||||
COPY_VAR_int(log_thread_id);
|
||||
COPY_VAR_int(hide_identity);
|
||||
COPY_VAR_int(hide_version);
|
||||
COPY_VAR_int(hide_trustanchor);
|
||||
@@ -6176,6 +6182,9 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
|
||||
COPY_VAR_ptr(ipset_name_v6);
|
||||
#endif
|
||||
COPY_VAR_int(ede);
|
||||
COPY_VAR_int(iter_scrub_ns);
|
||||
COPY_VAR_int(iter_scrub_cname);
|
||||
COPY_VAR_int(max_global_quota);
|
||||
COPY_VAR_int(iter_scrub_promiscuous);
|
||||
}
|
||||
#endif /* ATOMIC_POINTER_LOCK_FREE && HAVE_LINK_ATOMIC_STORE */
|
||||
@@ -6626,7 +6635,14 @@ static void* fast_reload_thread_main(void* arg)
|
||||
struct fast_reload_thread* fast_reload_thread = (struct fast_reload_thread*)arg;
|
||||
struct timeval time_start, time_read, time_construct, time_reload,
|
||||
time_end;
|
||||
log_thread_set(&fast_reload_thread->threadnum);
|
||||
|
||||
#if defined(HAVE_GETTID) && !defined(THREADS_DISABLED)
|
||||
fast_reload_thread->thread_tid = gettid();
|
||||
if(fast_reload_thread->thread_tid_log)
|
||||
log_thread_set(&fast_reload_thread->thread_tid);
|
||||
else
|
||||
#endif
|
||||
log_thread_set(&fast_reload_thread->threadnum);
|
||||
|
||||
verbose(VERB_ALGO, "start fast reload thread");
|
||||
if(fast_reload_thread->fr_verb >= 1) {
|
||||
@@ -7014,6 +7030,9 @@ fast_reload_thread_setup(struct worker* worker, int fr_verb, int fr_nopause,
|
||||
lock_basic_init(&fr->fr_output_lock);
|
||||
lock_protect(&fr->fr_output_lock, fr->fr_output,
|
||||
sizeof(*fr->fr_output));
|
||||
#ifdef HAVE_GETTID
|
||||
fr->thread_tid_log = worker->env.cfg->log_thread_id;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -7611,6 +7630,41 @@ fr_worker_pickup_outside_network(struct worker* worker)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
/** Fast reload, the worker picks up changes to DNSTAP configuration. */
|
||||
static void
|
||||
fr_worker_pickup_dnstap_changes(struct worker* worker)
|
||||
{
|
||||
struct dt_env* w_dtenv = &worker->dtenv;
|
||||
struct dt_env* d_dtenv = worker->daemon->dtenv;
|
||||
log_assert(d_dtenv != NULL || !worker->daemon->cfg->dnstap);
|
||||
if(d_dtenv == NULL) {
|
||||
/* There is no environment when DNSTAP was not enabled
|
||||
* in the configuration. */
|
||||
return;
|
||||
}
|
||||
w_dtenv->identity = d_dtenv->identity;
|
||||
w_dtenv->len_identity = d_dtenv->len_identity;
|
||||
w_dtenv->version = d_dtenv->version;
|
||||
w_dtenv->len_version = d_dtenv->len_version;
|
||||
w_dtenv->log_resolver_query_messages =
|
||||
d_dtenv->log_resolver_query_messages;
|
||||
w_dtenv->log_resolver_response_messages =
|
||||
d_dtenv->log_resolver_response_messages;
|
||||
w_dtenv->log_client_query_messages =
|
||||
d_dtenv->log_client_query_messages;
|
||||
w_dtenv->log_client_response_messages =
|
||||
d_dtenv->log_client_response_messages;
|
||||
w_dtenv->log_forwarder_query_messages =
|
||||
d_dtenv->log_forwarder_query_messages;
|
||||
w_dtenv->log_forwarder_response_messages =
|
||||
d_dtenv->log_forwarder_response_messages;
|
||||
lock_basic_lock(&d_dtenv->sample_lock);
|
||||
w_dtenv->sample_rate = d_dtenv->sample_rate;
|
||||
lock_basic_unlock(&d_dtenv->sample_lock);
|
||||
}
|
||||
#endif /* USE_DNSTAP */
|
||||
|
||||
void
|
||||
fast_reload_worker_pickup_changes(struct worker* worker)
|
||||
{
|
||||
@@ -7639,6 +7693,9 @@ fast_reload_worker_pickup_changes(struct worker* worker)
|
||||
worker->env.cachedb_enabled = worker->daemon->env->cachedb_enabled;
|
||||
#endif
|
||||
fr_worker_pickup_outside_network(worker);
|
||||
#ifdef USE_DNSTAP
|
||||
fr_worker_pickup_dnstap_changes(worker);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** fast reload thread, handle reload_stop notification, send reload stop
|
||||
|
||||
@@ -206,6 +206,12 @@ struct fast_reload_thread {
|
||||
int commpair[2];
|
||||
/** thread id, of the io thread */
|
||||
ub_thread_type tid;
|
||||
#ifdef HAVE_GETTID
|
||||
/** thread tid, the LWP id */
|
||||
pid_t thread_tid;
|
||||
/** if logging should include the LWP id */
|
||||
int thread_tid_log;
|
||||
#endif
|
||||
/** if the io processing has started */
|
||||
int started;
|
||||
/** if the thread has to quit */
|
||||
|
||||
@@ -262,6 +262,7 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
|
||||
s->svr = worker->stats;
|
||||
s->mesh_num_states = (long long)worker->env.mesh->all.count;
|
||||
s->mesh_num_reply_states = (long long)worker->env.mesh->num_reply_states;
|
||||
s->mesh_num_reply_addrs = (long long)worker->env.mesh->num_reply_addrs;
|
||||
s->mesh_jostled = (long long)worker->env.mesh->stats_jostled;
|
||||
s->mesh_dropped = (long long)worker->env.mesh->stats_dropped;
|
||||
s->mesh_replies_sent = (long long)worker->env.mesh->replies_sent;
|
||||
@@ -284,6 +285,8 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
|
||||
NUM_BUCKETS_HIST);
|
||||
s->svr.num_queries_discard_timeout +=
|
||||
(long long)worker->env.mesh->num_queries_discard_timeout;
|
||||
s->svr.num_queries_replyaddr_limit +=
|
||||
(long long)worker->env.mesh->num_queries_replyaddr_limit;
|
||||
s->svr.num_queries_wait_limit +=
|
||||
(long long)worker->env.mesh->num_queries_wait_limit;
|
||||
s->svr.num_dns_error_reports +=
|
||||
@@ -448,6 +451,8 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
total->svr.num_queries_cookie_invalid += a->svr.num_queries_cookie_invalid;
|
||||
total->svr.num_queries_discard_timeout +=
|
||||
a->svr.num_queries_discard_timeout;
|
||||
total->svr.num_queries_replyaddr_limit +=
|
||||
a->svr.num_queries_replyaddr_limit;
|
||||
total->svr.num_queries_wait_limit += a->svr.num_queries_wait_limit;
|
||||
total->svr.num_dns_error_reports += a->svr.num_dns_error_reports;
|
||||
total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
|
||||
@@ -519,6 +524,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
|
||||
total->mesh_num_states += a->mesh_num_states;
|
||||
total->mesh_num_reply_states += a->mesh_num_reply_states;
|
||||
total->mesh_num_reply_addrs += a->mesh_num_reply_addrs;
|
||||
total->mesh_jostled += a->mesh_jostled;
|
||||
total->mesh_dropped += a->mesh_dropped;
|
||||
total->mesh_replies_sent += a->mesh_replies_sent;
|
||||
|
||||
+1
-1
@@ -473,7 +473,7 @@ setup_listen_sslctx(void** ctx, int is_dot, int is_doh, struct config_file* cfg)
|
||||
cfg->tls_ciphers, cfg->tls_ciphersuites,
|
||||
(cfg->tls_session_ticket_keys.first &&
|
||||
cfg->tls_session_ticket_keys.first->str[0] != 0),
|
||||
is_dot, is_doh))) {
|
||||
is_dot, is_doh, cfg->tls_use_system_policy_versions))) {
|
||||
fatal_exit("could not set up listen SSL_CTX");
|
||||
}
|
||||
}
|
||||
|
||||
+23
-8
@@ -746,7 +746,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
*partial_repp = NULL; /* avoid accidental further pass */
|
||||
|
||||
/* Check TTL */
|
||||
if(rep->ttl < timenow) {
|
||||
if(TTL_IS_EXPIRED(rep->ttl, timenow)) {
|
||||
/* Check if we need to serve expired now */
|
||||
if(worker->env.cfg->serve_expired &&
|
||||
/* if serve-expired-client-timeout is set, serve
|
||||
@@ -1444,6 +1444,24 @@ check_ip_ratelimit(struct worker* worker, struct sockaddr_storage* addr,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the callback function when a request arrives. It is passed
|
||||
* the packet and user argument. Return true to send a reply.
|
||||
* This is of type comm_point_callback_type. The struct comm_point contains
|
||||
* more comments on the comm_point.callback member about the function.
|
||||
* @param c: the comm_point where the request arrives on.
|
||||
* @param arg: the user argument for the callback, the worker.
|
||||
* @param error: This can be NETEVENT_NOERROR, NETEVENT_TIMEOUT,
|
||||
* NETEVENT_CLOSED or other comm point callback error values.
|
||||
* @param repinfo: The reply info, use it to send a reply. If the reply
|
||||
* is immediate, return 1. If the reply is later on return 0 and save
|
||||
* the repinfo, to call comm_point_send_reply on.
|
||||
* @return 1 to sent a reply straight away, for like cache response so that
|
||||
* no allocation needs to be done. And only internal preallocated buffers
|
||||
* are used. Return 0 and save the repinfo to reply later, for responses
|
||||
* that need to be looked up. Return 0 and call comm_point_drop_reply on
|
||||
* the repinfo to drop the response.
|
||||
*/
|
||||
int
|
||||
worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
struct comm_reply* repinfo)
|
||||
@@ -1929,11 +1947,11 @@ lookup_cache:
|
||||
if((worker->env.cfg->prefetch &&
|
||||
rep->prefetch_ttl <= *worker->env.now) ||
|
||||
(worker->env.cfg->serve_expired &&
|
||||
rep->ttl < *worker->env.now &&
|
||||
TTL_IS_EXPIRED(rep->ttl, *worker->env.now) &&
|
||||
!(*worker->env.now < rep->serve_expired_norec_ttl))) {
|
||||
time_t leeway = rep->ttl - *worker->env.now;
|
||||
if(rep->ttl < *worker->env.now)
|
||||
leeway = 0;
|
||||
time_t leeway =
|
||||
TTL_IS_EXPIRED(rep->ttl, *worker->env.now)
|
||||
? 0 : rep->ttl - *worker->env.now;
|
||||
lock_rw_unlock(&e->lock);
|
||||
|
||||
reply_and_prefetch(worker, lookup_qinfo,
|
||||
@@ -2184,9 +2202,6 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
struct dt_env* dtenv = &worker->dtenv;
|
||||
#else
|
||||
void* dtenv = NULL;
|
||||
#endif
|
||||
#ifdef HAVE_GETTID
|
||||
worker->thread_tid = gettid();
|
||||
#endif
|
||||
worker->need_to_exit = 0;
|
||||
worker->base = comm_base_create(do_sigs);
|
||||
|
||||
+12
-11
@@ -366,22 +366,23 @@ static int
|
||||
dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
|
||||
{
|
||||
struct config_strlist* s;
|
||||
verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix);
|
||||
if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix :
|
||||
DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr,
|
||||
const char* dns64_prefix = cfg->dns64_prefix ?
|
||||
cfg->dns64_prefix : DEFAULT_DNS64_PREFIX;
|
||||
verbose(VERB_ALGO, "dns64-prefix: %s", dns64_prefix);
|
||||
if (!netblockstrtoaddr(dns64_prefix, 0, &dns64_env->prefix_addr,
|
||||
&dns64_env->prefix_addrlen, &dns64_env->prefix_net)) {
|
||||
log_err("cannot parse dns64-prefix netblock: %s", cfg->dns64_prefix);
|
||||
log_err("cannot parse dns64-prefix netblock: %s", dns64_prefix);
|
||||
return 0;
|
||||
}
|
||||
if (!addr_is_ip6(&dns64_env->prefix_addr, dns64_env->prefix_addrlen)) {
|
||||
log_err("dns64_prefix is not IPv6: %s", cfg->dns64_prefix);
|
||||
log_err("dns64_prefix is not IPv6: %s", dns64_prefix);
|
||||
return 0;
|
||||
}
|
||||
if (dns64_env->prefix_net != 32 && dns64_env->prefix_net != 40 &&
|
||||
dns64_env->prefix_net != 48 && dns64_env->prefix_net != 56 &&
|
||||
dns64_env->prefix_net != 64 && dns64_env->prefix_net != 96 ) {
|
||||
log_err("dns64-prefix length it not 32, 40, 48, 56, 64 or 96: %s",
|
||||
cfg->dns64_prefix);
|
||||
log_err("dns64-prefix length is not 32, 40, 48, 56, 64 or 96: %s",
|
||||
dns64_prefix);
|
||||
return 0;
|
||||
}
|
||||
for(s = cfg->dns64_ignore_aaaa; s; s = s->next) {
|
||||
@@ -496,8 +497,8 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
|
||||
|
||||
/* Create the new sub-query. */
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, 0,
|
||||
&subq))
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->client_info,
|
||||
qstate->query_flags, 0, 0, &subq))
|
||||
return module_error;
|
||||
if (subq) {
|
||||
subq->curmod = id;
|
||||
@@ -522,8 +523,8 @@ generate_type_A_query(struct module_qstate* qstate, int id)
|
||||
|
||||
/* Start the sub-query. */
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
|
||||
0, &subq))
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->client_info,
|
||||
qstate->query_flags, 0, 0, &subq))
|
||||
{
|
||||
verbose(VERB_ALGO, "dns64: sub-query creation failed");
|
||||
return module_error;
|
||||
|
||||
+11
-1
@@ -448,6 +448,9 @@ int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg)
|
||||
dtio->tls_use_sni = cfg->tls_use_sni;
|
||||
#endif /* HAVE_SSL */
|
||||
}
|
||||
#ifdef HAVE_GETTID
|
||||
dtio->thread_tid_log = cfg->log_thread_id;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2130,7 +2133,14 @@ static void* dnstap_io(void* arg)
|
||||
struct dt_io_thread* dtio = (struct dt_io_thread*)arg;
|
||||
time_t secs = 0;
|
||||
struct timeval now;
|
||||
log_thread_set(&dtio->threadnum);
|
||||
|
||||
#if defined(HAVE_GETTID) && !defined(THREADS_DISABLED)
|
||||
dtio->thread_tid = gettid();
|
||||
if(dtio->thread_tid_log)
|
||||
log_thread_set(&dtio->thread_tid);
|
||||
else
|
||||
#endif
|
||||
log_thread_set(&dtio->threadnum);
|
||||
|
||||
/* setup */
|
||||
verbose(VERB_ALGO, "start dnstap io thread");
|
||||
|
||||
@@ -131,6 +131,12 @@ struct dt_io_thread {
|
||||
struct dt_io_list_item* io_list_iter;
|
||||
/** thread id, of the io thread */
|
||||
ub_thread_type tid;
|
||||
#ifdef HAVE_GETTID
|
||||
/** thread tid, the LWP id */
|
||||
pid_t thread_tid;
|
||||
/** if logging should include the LWP id */
|
||||
int thread_tid_log;
|
||||
#endif
|
||||
/** if the io processing has started */
|
||||
int started;
|
||||
/** ssl context for the io thread, for tls connections. type SSL_CTX* */
|
||||
|
||||
@@ -347,7 +347,7 @@ static struct tap_socket* tap_socket_new_tlsaccept(char* ip,
|
||||
s->ev_cb = ev_cb;
|
||||
s->data = data;
|
||||
s->sslctx = listen_sslctx_create(server_key, server_cert, verifypem,
|
||||
NULL, NULL, 0, 0, 0);
|
||||
NULL, NULL, 0, 0, 0, 0);
|
||||
if(!s->sslctx) {
|
||||
log_err("could not create ssl context");
|
||||
free(s->ip);
|
||||
|
||||
+224
@@ -1,3 +1,227 @@
|
||||
27 January 2026: Wouter
|
||||
- Add test for allow-notify with a host name.
|
||||
|
||||
26 January 2026: Wouter
|
||||
- Fix that allow-notify entries with hostnames are copied after IPv4
|
||||
and IPv6 lookup.
|
||||
- Fix to not skip allow-notify hostname lookups when there are only
|
||||
urls.
|
||||
|
||||
23 January 2026: Yorgos
|
||||
- Merge #1396: Log Linux thread ID.
|
||||
- On Linux systems log the system-wide unique thread ID instead of
|
||||
Unbound's internal thread counter.
|
||||
- Introduce the 'log-thread-id' configuration option to manage logging
|
||||
the system-wide Linux thread ID for easier debugging with system
|
||||
tools.
|
||||
- Update generated man pages.
|
||||
|
||||
22 January 2026: Wouter
|
||||
- Fix that fast reload copies the iter_scrub_ns, iter_scrub_cname
|
||||
and max_global_quota options.
|
||||
- Fix http test tool petal to not print errors when there is no
|
||||
error.
|
||||
|
||||
21 January 2026: Wouter
|
||||
- Merge #1388: QNX Porting support for unbound.
|
||||
|
||||
19 January 2026: Wouter
|
||||
- Merge #1392: Include "V" (version) option in synopsis.
|
||||
|
||||
15 January 2026: Wouter
|
||||
- Fix documentation for requestlist.overwritten and
|
||||
requestlist.exceeded, it explains which query was dropped.
|
||||
|
||||
8 January 2026: Wouter
|
||||
- Merge #1381: Do not initialize quic_table unless it is enabled.
|
||||
|
||||
6 January 2026: Wouter
|
||||
- Fix edns subnet, that scope zero queries, when there is a
|
||||
subquery without subnet, and the forward-no-cache or
|
||||
stub-no-cache option is set, it is not stored in cache due to
|
||||
the forward or stub option.
|
||||
|
||||
6 January 2026: Yorgos
|
||||
- Merge #1391 from Götz Görisch: Fix documentation to adhere to
|
||||
RFC5952.
|
||||
|
||||
31 December 2025: Yorgos
|
||||
- Update the unbound-anchor man page to note write permissions of the
|
||||
generated file if it is to be used with Unbound's
|
||||
auto-trust-anchor-file option.
|
||||
- Use the same EDE removal logic when encoding errors as when encoding
|
||||
replies.
|
||||
|
||||
30 December 2025: Yorgos
|
||||
- Mark "THROWAWAY" and "(DNSSEC) LAME" responses clearly as Unbound's
|
||||
categorization in the log output.
|
||||
|
||||
24 December 2025: Yorgos
|
||||
- More specific wording in the unbound.conf man page for stub-first
|
||||
and forward-first options.
|
||||
|
||||
3 December 2025: Wouter
|
||||
- Fix http2 drop handling to clear the postpone_drop state so that
|
||||
other streams on the http2 session are not affected by a drop,
|
||||
and can clean up properly if also dropped. Fix http2 send reply
|
||||
so that when there is a send failure is does not recurse into
|
||||
the mesh functions and also does not drop the connection due to
|
||||
the condition of one stream.
|
||||
|
||||
2 December 2025: Wouter
|
||||
- Fix to remove http2 stream mesh state when mesh new request is
|
||||
dropping the new request.
|
||||
|
||||
1 December 2025: Wouter
|
||||
- Fix to add EDNS CO flag to testbound and debug message log.
|
||||
- Fix header comment about EDE reference in validator/val_sigcrypt.h.
|
||||
|
||||
28 November 2025: Yorgos
|
||||
- For #1375, there is no DNSTAP environment if it wasn't configured.
|
||||
|
||||
26 November 2025: Yorgos
|
||||
- Tag for 1.24.2 release.
|
||||
The repository continues with version 1.24.3.
|
||||
|
||||
13 November 2025: Wouter
|
||||
- Merge #1374: Mesh reply counters.
|
||||
This adds the statistics num.queries.replyaddr_limit and
|
||||
requestlist.current.replies.
|
||||
- Merge #1375: Copy DNSTAP changes from daemon to workers after
|
||||
fast_reload.
|
||||
|
||||
12 November 2025: Wouter
|
||||
- Fix that when discard timeout drops packet, they are accounted as
|
||||
less reply addresses in use in the mesh area.
|
||||
- iana portlist updated.
|
||||
|
||||
6 November 2025: Wouter
|
||||
- Fix add comment to worker_handle_request function that explain it.
|
||||
- Fix configure test for noreturn attribute so it compiles without
|
||||
warning.
|
||||
- Fix configure test for nonstring attribute so that it does not
|
||||
accept when the compiler prints a warning about an unknown
|
||||
attribute.
|
||||
|
||||
4 November 2025: Wouter
|
||||
- Fix dns64 log output to log the default instead of a null string.
|
||||
|
||||
1 November 2025: Yorgos
|
||||
- Fix #1366: Infra cache does not work correctly for NAT64, by
|
||||
moving the NAT64 synthesis from the iterator when selecting a target
|
||||
address, to the delegation point itself when adding target
|
||||
addresses.
|
||||
|
||||
27 October 2025: Yorgos
|
||||
- Merge #1331 from Jitka Plesníková: Replace deprecated $function by
|
||||
new $action, for SWIG.
|
||||
- Fix #1165, document the possible circular dependency when using
|
||||
host names instead of IP addresses for name servers in stub/forward
|
||||
zones and log a warning when spotted in the configuration.
|
||||
|
||||
24 October 2025: Yorgos
|
||||
- unbound.conf man page updates to include a preview of the section
|
||||
clauses and some reformatting around the use of "clause", "option"
|
||||
and "attributes". Based on Havard Eidnes' suggestions on the
|
||||
mailing list.
|
||||
- Fix unused attribute warning in redis.c when threads are not
|
||||
supported.
|
||||
- For #1364, use OPENSSL_VERSION_TEXT instead of OPENSSL_VERSION_NUMBER
|
||||
for part of the configure script. OPENSSL_VERSION_TEXT is more
|
||||
consistent across versions.
|
||||
|
||||
22 October 2025: Yorgos
|
||||
- Tag for 1.24.1 release.
|
||||
The repository continues with version 1.24.2.
|
||||
|
||||
15 October 2025: Wouter
|
||||
- Fix to drop UDP for discard-timeout, but not stream connections.
|
||||
- Fix to reply with SERVFAIL when the wait-limit is exceeded.
|
||||
- Add extended dns error code for invalid query type to definition
|
||||
list.
|
||||
- Fix unbound.conf man page entry for root-hints to say it can
|
||||
be used without strongly recommending it.
|
||||
- Remove iPhone armv7s, and iPhoneSimulator i386 from ios ci.
|
||||
The lib system does not provide symbols for it on the new macos
|
||||
runner.
|
||||
- Fix to exclude libssp for windows compiles.
|
||||
|
||||
10 October 2025: Wouter
|
||||
- Fix #1358 Enabling FIPS in OpenSSL causes unit test to fail.
|
||||
|
||||
3 October 2025: Yorgos
|
||||
- Note 'respip' and 'dns64' module order in the unbound.conf
|
||||
man page.
|
||||
- Note clearly that 'wait-limit: 0' disables all wait limits.
|
||||
- 'wait-limit-cookie: 0' can now disable cookie validated wait
|
||||
limits.
|
||||
|
||||
2 October 2025: Wouter
|
||||
- Fix that https is set up as enabled when the port is listed in
|
||||
interface-automatic-ports. Also for the set up of quic it is
|
||||
enabled when listed there.
|
||||
|
||||
30 September 2025: Wouter
|
||||
- Fix for #1344: Fix that respip and dns64 can be enabled at the
|
||||
same time, the client info is copied for attach_sub and add_sub
|
||||
calls. That makes respip work on dns64 synthesized answers, and
|
||||
also makes RPZ work with DNS64. The order for the modules is
|
||||
module-config: "respip dns64 validator iterator".
|
||||
|
||||
29 September 2025: Wouter
|
||||
- Rebuild configure script from its sources.
|
||||
- Fix modstack_call_init to use the original string when it has
|
||||
changed, to call modstack_config with. And skip the changed name
|
||||
in the string correctly. Thanks to Jan Komissar.
|
||||
- Neaten up the change in acx_nlnetlabs.m4 to version 49.
|
||||
- Fix fr_atomic_copy_cfg.
|
||||
- Rebuild configure script from its sources.
|
||||
- Fix #1353: auth-zone can not use empty label for $ORIGIN when
|
||||
http download.
|
||||
- Fix #1344: module conf 'respip dns64 validator cachedb iterator'
|
||||
is not known to work.
|
||||
|
||||
29 September 2025: Yorgos
|
||||
- Merge #1349: Fix #1346: [FR] Please allow back TLS 1.2.
|
||||
- Merge #1351: ac_cv_func_malloc_0_nonnull for malloc(0) check.
|
||||
|
||||
26 September 2025: Yorgos
|
||||
- Test for nonstring attribute in configure and add
|
||||
nonstring attribute annotations.
|
||||
|
||||
24 September 2025: Yorgos
|
||||
- Avoid calling mesh_detect_cycle_found() when there is no mesh state
|
||||
to begin with.
|
||||
|
||||
23 September 2025: Yorgos
|
||||
- Merge #1352 from Petr Vaganov: pythonmod: fix HANDLE_LEAK on
|
||||
pythonmod_init.
|
||||
- For #1352, align with the current Python<3 code.
|
||||
- Merge #1350 from Maryse47: unbound.service.in: allow CAP_NET_ADMIN.
|
||||
- For #1350, same CAP_NET_ADMIN change for unbound_portable.service.in
|
||||
as well.
|
||||
|
||||
19 September 2025: Wouter
|
||||
- Fix to remove configure~ from release tarballs.
|
||||
|
||||
19 September 2025: Yorgos
|
||||
- Update README.man with clearer text.
|
||||
- Merge #1337: 0 TTL cached replies and some TTL behavior changes.
|
||||
- TTL change: Cached records that reach TTL 0 are expired.
|
||||
- TTL change: TTL 0 upstream answers are no longer cached by
|
||||
cachedb, as they should.
|
||||
- TTL change: 'serve-expired-reply-ttl' is now capped by the original
|
||||
TTL value of the record to try and make some sense when replying
|
||||
with expired records.
|
||||
- TTL change: TTL decoding was updated to adhere to RFC8767 section 4
|
||||
where a 'set high-order bit' means the value is positive instead of
|
||||
0.
|
||||
- unbound.conf manpage: explicitly mention RFC6891.
|
||||
|
||||
18 September 2025: Wouter
|
||||
- Tag for 1.24.0 release. Includes the fixes below after rc1.
|
||||
The repository continues with version 1.24.1.
|
||||
|
||||
17 September 2025: Yorgos
|
||||
- Too many quotes for the EDE message debug printout.
|
||||
|
||||
|
||||
+3
-3
@@ -13,7 +13,7 @@ If you're not using DNSSEC then you may remove "validator".
|
||||
|
||||
2. The "dns64-prefix" directive indicates your DNS64 prefix. For example:
|
||||
|
||||
dns64-prefix: 64:FF9B::/96
|
||||
dns64-prefix: 64:ff9b::/96
|
||||
|
||||
The prefix must be a /96 or shorter.
|
||||
|
||||
@@ -42,9 +42,9 @@ To enable NAT64 in Unbound, add to unbound.conf's "server" section:
|
||||
do-nat64: yes
|
||||
|
||||
The NAT64 prefix defaults to the DNS64 prefix, which in turn defaults to the
|
||||
standard 64:FF9B::/96 prefix. You can reconfigure it with:
|
||||
standard 64:ff9b::/96 prefix. You can reconfigure it with:
|
||||
|
||||
nat64-prefix: 64:FF9B::/96
|
||||
nat64-prefix: 64:ff9b::/96
|
||||
|
||||
To test NAT64 operation, pick a domain that only has IPv4 reachability for its
|
||||
nameservers and try resolving any names in that domain.
|
||||
|
||||
+8
-3
@@ -6,11 +6,16 @@ and makes it easier to maintain and contribute to the documentation.
|
||||
The templated man pages (*.in) are still part of the code repository as to not
|
||||
alter current procedures that could be in place by users/packagers.
|
||||
|
||||
These man pages (*.in) are still the ones being used when
|
||||
configuring/installing Unbound.
|
||||
Packagers/users do not have to generate any man pages themselves, this is done
|
||||
by the core developers during development and upon releasing new versions.
|
||||
|
||||
The templated man pages (*.in) are generated by Sphinx (used for the online
|
||||
documentation).
|
||||
The online documentation has its own repository at
|
||||
https://github.com/NLnetLabs/unbound-manual.
|
||||
|
||||
In the README.md there (branch test-auto for now), there are further simple
|
||||
instructions on how to generate the templated man pages there and update them
|
||||
in this repository.
|
||||
In that README.md (https://github.com/NLnetLabs/unbound-manual/README.md)
|
||||
there are further simple instructions on how to generate the templated man
|
||||
pages there and update them in this repository.
|
||||
|
||||
+50
-18
@@ -54,7 +54,7 @@ server:
|
||||
# interface: 192.0.2.153
|
||||
# interface: 192.0.2.154
|
||||
# interface: 192.0.2.154@5003
|
||||
# interface: 2001:DB8::5
|
||||
# interface: 2001:db8::5
|
||||
# interface: eth0@5003
|
||||
|
||||
# enable this feature to copy the source address of queries to reply.
|
||||
@@ -72,12 +72,12 @@ server:
|
||||
# server from by ip-address. If none, the default (all) interface
|
||||
# is used. Specify every interface on a 'outgoing-interface:' line.
|
||||
# outgoing-interface: 192.0.2.153
|
||||
# outgoing-interface: 2001:DB8::5
|
||||
# outgoing-interface: 2001:DB8::6
|
||||
# outgoing-interface: 2001:db8::5
|
||||
# outgoing-interface: 2001:db8::6
|
||||
|
||||
# Specify a netblock to use remainder 64 bits as random bits for
|
||||
# upstream queries. Uses freebind option (Linux).
|
||||
# outgoing-interface: 2001:DB8::/64
|
||||
# outgoing-interface: 2001:db8::/64
|
||||
# Also (Linux:) ip -6 addr add 2001:db8::/64 dev lo
|
||||
# And: ip -6 route add local 2001:db8::/64 dev lo
|
||||
# And set prefer-ip6: yes to use the ip6 randomness from a netblock.
|
||||
@@ -379,7 +379,7 @@ server:
|
||||
# interface-action: 192.0.2.153 allow
|
||||
# interface-action: 192.0.2.154 allow
|
||||
# interface-action: 192.0.2.154@5003 allow
|
||||
# interface-action: 2001:DB8::5 allow
|
||||
# interface-action: 2001:db8::5 allow
|
||||
# interface-action: eth0@5003 allow
|
||||
|
||||
# Similar to 'access-control-tag:' but for interfaces.
|
||||
@@ -496,6 +496,10 @@ server:
|
||||
# print log lines that say why queries return SERVFAIL to clients.
|
||||
# log-servfail: no
|
||||
|
||||
# log system-wide Linux thread ID, insted of Unbound's internal thread
|
||||
# counter. Only on Linux and only when threads are available.
|
||||
# log-thread-id: no
|
||||
|
||||
# the pid file. Can be an absolute path outside of chroot/work dir.
|
||||
# pidfile: "@UNBOUND_PIDFILE@"
|
||||
|
||||
@@ -756,6 +760,7 @@ server:
|
||||
# serve-expired-ttl-reset: no
|
||||
#
|
||||
# TTL value to use when replying with expired data.
|
||||
# Capped by the original TTL of the record.
|
||||
# serve-expired-reply-ttl: 30
|
||||
#
|
||||
# Time in milliseconds before replying to the client with expired data.
|
||||
@@ -925,6 +930,22 @@ server:
|
||||
# add a netblock specific override to a localzone, with zone type
|
||||
# local-zone-override: "example.com" 192.0.2.0/24 refuse
|
||||
|
||||
# Action to apply when the IP address in an AAAA or A RR in the answer
|
||||
# section of a response matches the specified IP netblock.
|
||||
# Requires use of the respip module.
|
||||
# response-ip: 192.0.2.0/24 redirect
|
||||
|
||||
# Redirect as specified by the "resource record string" when the IP
|
||||
# address in an AAAA or A RR in the answer section of a response
|
||||
# matches the specified IP netblock.
|
||||
# Requires use of the respip module.
|
||||
# response-ip-data: 192.0.2.0/24 "example. A 192.0.2.1"
|
||||
|
||||
# Apply tag(s) when the IP address in an AAAA or A RR in the answer
|
||||
# section of a response matches the specified IP netblock.
|
||||
# Requires use of the respip module.
|
||||
# response-ip-tag: 192.0.2.0/24 "tag1 tag2"
|
||||
|
||||
# service clients over TLS (on the TCP sockets) with plain DNS inside
|
||||
# the TLS stream, and over HTTPS using HTTP/2 as specified in RFC8484.
|
||||
# Give the certificate to use and private key.
|
||||
@@ -935,21 +956,26 @@ server:
|
||||
# https-port: 443
|
||||
# quic-port: 853
|
||||
|
||||
# Also serve tls on these port numbers (eg. 443, ...), by listing
|
||||
# tls-additional-port: portno for each of the port numbers.
|
||||
|
||||
# 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"
|
||||
# cipher setting for TLSv1.3
|
||||
# tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
|
||||
|
||||
# Pad responses to padded queries received over TLS
|
||||
# pad-responses: yes
|
||||
|
||||
# Padded responses will be padded to the closest multiple of this size.
|
||||
# pad-responses-block-size: 468
|
||||
|
||||
# Use the SNI extension for TLS connections. Default is yes.
|
||||
# Changing the value requires a reload.
|
||||
# tls-use-sni: yes
|
||||
|
||||
# Allow general-purpose version-flexible TLS server configuration that
|
||||
# may be further restricted by the system's policy.
|
||||
# Use only if you want to support legacy TLS client connections.
|
||||
# Default is no and Unbound will only use the latest available TLS
|
||||
# version.
|
||||
# Changing the value requires a reload.
|
||||
# tls-use-system-policy-versions: no
|
||||
|
||||
# Add the secret file for TLS Session Ticket.
|
||||
# Secret file must be 80 bytes of random data.
|
||||
# First key use to encrypt and decrypt TLS session tickets.
|
||||
@@ -970,15 +996,18 @@ server:
|
||||
# and on other systems, the default openssl certificates
|
||||
# tls-system-cert: no
|
||||
|
||||
# Pad responses to padded queries received over TLS
|
||||
# pad-responses: yes
|
||||
|
||||
# Padded responses will be padded to the closest multiple of this size.
|
||||
# pad-responses-block-size: 468
|
||||
|
||||
# Pad queries over TLS upstreams
|
||||
# pad-queries: yes
|
||||
|
||||
# Padded queries will be padded to the closest multiple of this size.
|
||||
# pad-queries-block-size: 128
|
||||
|
||||
# Also serve tls on these port numbers (eg. 443, ...), by listing
|
||||
# tls-additional-port: portno for each of the port numbers.
|
||||
|
||||
# HTTP endpoint to provide DNS-over-HTTPS service on.
|
||||
# http-endpoint: "/dns-query"
|
||||
|
||||
@@ -1261,10 +1290,11 @@ remote-control:
|
||||
# zonefile: "example.org.zone"
|
||||
|
||||
# Views
|
||||
# Create named views. Name must be unique. Map views to requests using
|
||||
# the access-control-view option. Views can contain zero or more local-zone
|
||||
# and local-data options. Options from matching views will override global
|
||||
# options. Global options will be used if no matching view is found.
|
||||
# Create named views. Name must be unique.
|
||||
# Map views to requests using the access-control-view/interface-view options.
|
||||
# Views can contain zero or more local-zone and local-data options.
|
||||
# Options from matching views will override global options.
|
||||
# Global options will be used if no matching view is found.
|
||||
# With view-first yes, it will try to answer using the global local-zone and
|
||||
# local-data elements if there is no view specific match.
|
||||
# view:
|
||||
@@ -1272,6 +1302,8 @@ remote-control:
|
||||
# local-zone: "example.com" redirect
|
||||
# local-data: "example.com A 192.0.2.3"
|
||||
# local-data-ptr: "192.0.2.3 www.example.com"
|
||||
# response-ip: 192.0.2.0/24 redirect
|
||||
# response-ip-data: 192.0.2.0/24 "example. A 192.0.2.1"
|
||||
# view-first: no
|
||||
# view:
|
||||
# name: "anotherview"
|
||||
|
||||
+1
-1
@@ -416,6 +416,6 @@ on a function return with file read failure.
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
+13
-4
@@ -39,9 +39,17 @@ unbound-anchor \- Unbound @version@ anchor utility.
|
||||
validation.
|
||||
The program fetches the trust anchor with the method from \fI\%RFC 7958\fP when
|
||||
regular \fI\%RFC 5011\fP update fails to bring it up to date.
|
||||
It can be run (as root) from the commandline, or run as part of startup
|
||||
scripts.
|
||||
Before you start the \fI\%unbound(8)\fP DNS server.
|
||||
It can be run from the commandline, or run as part of startup scripts before
|
||||
you start the \fI\%unbound(8)\fP DNS server.
|
||||
.sp
|
||||
Note that if you want to use \fI\%RFC 5011\fP with Unbound (i.e., the
|
||||
\fI\%auto\-trust\-anchor\-file\fP option) so
|
||||
that trust anchor information is automatically tracked by Unbound during
|
||||
operation, the user that Unbound runs under (by default \(aqunbound\(aq) must have
|
||||
write permissions to the file and the directory the file lives in (for creating
|
||||
temporary files).
|
||||
In this case you would probably want to run this program as the designated
|
||||
Unbound user.
|
||||
.sp
|
||||
Suggested usage:
|
||||
.INDENT 0.0
|
||||
@@ -52,6 +60,7 @@ Suggested usage:
|
||||
# in the init scripts.
|
||||
# provide or update the root anchor (if necessary)
|
||||
unbound\-anchor \-a \(dq@UNBOUND_ROOTKEY_FILE@\(dq
|
||||
|
||||
# Please note usage of this root anchor is at your own risk
|
||||
# and under the terms of our LICENSE (see source).
|
||||
#
|
||||
@@ -295,6 +304,6 @@ Signature on the root key information.
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
+12
-3
@@ -51,9 +51,17 @@ Description
|
||||
validation.
|
||||
The program fetches the trust anchor with the method from :rfc:`7958` when
|
||||
regular :rfc:`5011` update fails to bring it up to date.
|
||||
It can be run (as root) from the commandline, or run as part of startup
|
||||
scripts.
|
||||
Before you start the :doc:`unbound(8)</manpages/unbound>` DNS server.
|
||||
It can be run from the commandline, or run as part of startup scripts before
|
||||
you start the :doc:`unbound(8)</manpages/unbound>` DNS server.
|
||||
|
||||
Note that if you want to use :rfc:`5011` with Unbound (i.e., the
|
||||
:ref:`auto-trust-anchor-file<unbound.conf.auto-trust-anchor-file>` option) so
|
||||
that trust anchor information is automatically tracked by Unbound during
|
||||
operation, the user that Unbound runs under (by default 'unbound') must have
|
||||
write permissions to the file and the directory the file lives in (for creating
|
||||
temporary files).
|
||||
In this case you would probably want to run this program as the designated
|
||||
Unbound user.
|
||||
|
||||
Suggested usage:
|
||||
|
||||
@@ -62,6 +70,7 @@ Suggested usage:
|
||||
# in the init scripts.
|
||||
# provide or update the root anchor (if necessary)
|
||||
unbound-anchor -a "@UNBOUND_ROOTKEY_FILE@"
|
||||
|
||||
# Please note usage of this root anchor is at your own risk
|
||||
# and under the terms of our LICENSE (see source).
|
||||
#
|
||||
|
||||
@@ -88,6 +88,6 @@ Unbound configuration file.
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
@@ -880,6 +880,11 @@ number of queries removed due to discard\-timeout by thread
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B threadX.num.queries_replyaddr_limit
|
||||
number of queries removed due to replyaddr limits by thread
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B threadX.num.queries_wait_limit
|
||||
number of queries removed due to wait\-limit by thread
|
||||
.UNINDENT
|
||||
@@ -973,6 +978,10 @@ Number of requests in the request list that were overwritten by newer
|
||||
entries.
|
||||
This happens if there is a flood of queries that recursive processing and
|
||||
the server has a hard time.
|
||||
The counter is increased when during the flood the
|
||||
\fI\%jostle\-timeout\fP
|
||||
allows a query to be removed in favor of a new incoming query.
|
||||
The older query is then dropped to make space.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -980,6 +989,12 @@ the server has a hard time.
|
||||
Queries that were dropped because the request list was full.
|
||||
This happens if a flood of queries need recursive processing, and the
|
||||
server can not keep up.
|
||||
The counter is increased when during the flood there is no space
|
||||
to be made with the jostle out of an older query, and the new query
|
||||
is dropped.
|
||||
Since no older queries are removed, see
|
||||
\fI\%jostle\-timeout\fP setting, there
|
||||
is no space for the new query.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -994,6 +1009,13 @@ Current size of the request list, only the requests from client queries.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B threadX.requestlist.current.replies
|
||||
Current count of the number of reply entries waiting on request list
|
||||
entries. Because a request list entry can send results to multiple reply
|
||||
addresses, this number may be larger than the size of the request list.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B threadX.recursion.time.avg
|
||||
Average time it took to answer queries that needed recursive processing.
|
||||
Note that queries that were answered from the cache are not in this average.
|
||||
@@ -1048,6 +1070,11 @@ summed over threads.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B total.num.queries_replyaddr_limit
|
||||
summed over threads.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B total.num.queries_wait_limit
|
||||
summed over threads.
|
||||
.UNINDENT
|
||||
@@ -1138,6 +1165,16 @@ summed over threads.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B total.requestlist.current.user
|
||||
summed over threads.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B total.requestlist.current.replies
|
||||
summed over threads.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B total.recursion.time.median
|
||||
averaged over threads.
|
||||
.UNINDENT
|
||||
@@ -1543,6 +1580,6 @@ directory with private keys (\fBunbound_server.key\fP and
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
@@ -815,6 +815,10 @@ number of statistic counters:
|
||||
number of queries removed due to discard-timeout by thread
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@threadX.num.queries_replyaddr_limit@@
|
||||
number of queries removed due to replyaddr limits by thread
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@threadX.num.queries_wait_limit@@
|
||||
number of queries removed due to wait-limit by thread
|
||||
|
||||
@@ -893,12 +897,22 @@ number of statistic counters:
|
||||
entries.
|
||||
This happens if there is a flood of queries that recursive processing and
|
||||
the server has a hard time.
|
||||
The counter is increased when during the flood the
|
||||
:ref:`jostle-timeout<unbound.conf.jostle-timeout>`
|
||||
allows a query to be removed in favor of a new incoming query.
|
||||
The older query is then dropped to make space.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@threadX.requestlist.exceeded@@
|
||||
Queries that were dropped because the request list was full.
|
||||
This happens if a flood of queries need recursive processing, and the
|
||||
server can not keep up.
|
||||
The counter is increased when during the flood there is no space
|
||||
to be made with the jostle out of an older query, and the new query
|
||||
is dropped.
|
||||
Since no older queries are removed, see
|
||||
:ref:`jostle-timeout<unbound.conf.jostle-timeout>` setting, there
|
||||
is no space for the new query.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@threadX.requestlist.current.all@@
|
||||
@@ -910,6 +924,12 @@ number of statistic counters:
|
||||
Current size of the request list, only the requests from client queries.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@threadX.requestlist.current.replies@@
|
||||
Current count of the number of reply entries waiting on request list
|
||||
entries. Because a request list entry can send results to multiple reply
|
||||
addresses, this number may be larger than the size of the request list.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@threadX.recursion.time.avg@@
|
||||
Average time it took to answer queries that needed recursive processing.
|
||||
Note that queries that were answered from the cache are not in this average.
|
||||
@@ -955,6 +975,10 @@ number of statistic counters:
|
||||
summed over threads.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@total.num.queries_replyaddr_limit@@
|
||||
summed over threads.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@total.num.queries_wait_limit@@
|
||||
summed over threads.
|
||||
|
||||
@@ -1027,6 +1051,14 @@ number of statistic counters:
|
||||
summed over threads.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@total.requestlist.current.user@@
|
||||
summed over threads.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@total.requestlist.current.replies@@
|
||||
summed over threads.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@total.recursion.time.median@@
|
||||
averaged over threads.
|
||||
|
||||
|
||||
@@ -185,6 +185,6 @@ encountered a fatal error.
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
unbound \- Unbound DNS validating resolver @version@.
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
\fBunbound\fP [\fB\-hdpv\fP] [\fB\-c <cfgfile>\fP]
|
||||
\fBunbound\fP [\fB\-hdpVv\fP] [\fB\-c <cfgfile>\fP]
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
\fBunbound\fP is a caching DNS resolver.
|
||||
@@ -118,6 +118,6 @@ Show the version number and build options, and exit.
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
+342
-141
@@ -36,44 +36,49 @@ unbound.conf \- Unbound @version@ configuration file.
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
\fBunbound.conf\fP is used to configure \fI\%unbound(8)\fP\&.
|
||||
The file format has attributes and values.
|
||||
Some attributes have attributes inside them.
|
||||
The notation is: \fBattribute: value\fP\&.
|
||||
.sp
|
||||
Comments start with \fB#\fP and last to the end of line.
|
||||
Empty lines are ignored as is whitespace at the beginning of a line.
|
||||
.sp
|
||||
The utility \fI\%unbound\-checkconf(8)\fP can be
|
||||
used to check \fBunbound.conf\fP prior to usage.
|
||||
.SH FILE FORMAT
|
||||
.sp
|
||||
Whitespace is used to separate keywords.
|
||||
Whitespace indentation is insignificant, but is still recommended for visual
|
||||
clarity.
|
||||
Comments start with \fB#\fP and last to the end of line.
|
||||
Empty lines are ignored, as is whitespace at the beginning of a line.
|
||||
.sp
|
||||
Attribute keywords end with a colon (\fB:\fP) and they are either options or
|
||||
section clauses (group options together).
|
||||
.sp
|
||||
The configuration file is logically divided into \fBsections\fP where each section
|
||||
is introduced by a \fI\%section clause\fP\&.
|
||||
.SH EXAMPLE
|
||||
.sp
|
||||
An example config file is shown below.
|
||||
Copy this to \fB/etc/unbound/unbound.conf\fP and start the server with:
|
||||
An example minimal config file is shown below; most settings are the defaults.
|
||||
Copy this to \fB@ub_conf_file@\fP and start the server with:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
$ unbound \-c /etc/unbound/unbound.conf
|
||||
$ unbound \-c @ub_conf_file@
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
Most settings are the defaults.
|
||||
Stop the server with:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
$ kill \(gacat /etc/unbound/unbound.pid\(ga
|
||||
$ kill \(gacat @UNBOUND_PIDFILE@\(ga
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
Below is a minimal config file.
|
||||
The source distribution contains an extensive \fBexample.conf\fP file with
|
||||
all the options.
|
||||
.INDENT 0.0
|
||||
@@ -83,33 +88,87 @@ all the options.
|
||||
.ft C
|
||||
# unbound.conf(5) config file for unbound(8).
|
||||
server:
|
||||
directory: \(dq/etc/unbound\(dq
|
||||
directory: \(dq@UNBOUND_RUN_DIR@\(dq
|
||||
username: unbound
|
||||
# make sure unbound can access entropy from inside the chroot.
|
||||
# e.g. on linux the use these commands (on BSD, devfs(8) is used):
|
||||
# mount \-\-bind \-n /dev/urandom /etc/unbound/dev/urandom
|
||||
# and mount \-\-bind \-n /dev/log /etc/unbound/dev/log
|
||||
chroot: \(dq/etc/unbound\(dq
|
||||
# logfile: \(dq/etc/unbound/unbound.log\(dq #uncomment to use logfile.
|
||||
pidfile: \(dq/etc/unbound/unbound.pid\(dq
|
||||
# mount \-\-bind \-n /dev/urandom @UNBOUND_RUN_DIR@/dev/urandom
|
||||
# and mount \-\-bind \-n /dev/log @UNBOUND_RUN_DIR@/dev/log
|
||||
chroot: \(dq@UNBOUND_CHROOT_DIR@\(dq
|
||||
# logfile: \(dq@UNBOUND_RUN_DIR@/unbound.log\(dq #uncomment to use logfile.
|
||||
pidfile: \(dq@UNBOUND_PIDFILE@\(dq
|
||||
# verbosity: 1 # uncomment and increase to get more logging.
|
||||
# listen on all interfaces, answer queries from the local subnet.
|
||||
interface: 0.0.0.0
|
||||
interface: ::0
|
||||
access\-control: 10.0.0.0/8 allow
|
||||
access\-control: 2001:DB8::/64 allow
|
||||
access\-control: 2001:db8::/64 allow
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.SH FILE FORMAT
|
||||
.SH SECTION CLAUSES
|
||||
.sp
|
||||
There must be whitespace between keywords.
|
||||
Attribute keywords end with a colon \fB\(aq:\(aq\fP\&.
|
||||
An attribute is followed by a value, or its containing attributes in which case
|
||||
it is referred to as a clause.
|
||||
Clauses can be repeated throughout the file (or included files) to group
|
||||
attributes under the same clause.
|
||||
The recognized section clauses are:
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B \fI\%server:\fP
|
||||
Most of the configuration is found in this section.
|
||||
.TP
|
||||
.B \fI\%remote\-control:\fP
|
||||
Configuration for the facility used by
|
||||
\fI\%unbound\-control(8)\fP\&.
|
||||
.TP
|
||||
.B \fI\%stub\-zone:\fP
|
||||
Configuration for a zone that redirects to specific authoritative name
|
||||
servers, e.g. for zones not generally available on the greater
|
||||
Internet.
|
||||
.TP
|
||||
.B \fI\%forward\-zone:\fP
|
||||
Configuration for a zone that forwards to specific DNS resolvers.
|
||||
.TP
|
||||
.B \fI\%auth\-zone:\fP
|
||||
Configuration for local authoritative zones.
|
||||
.TP
|
||||
.B \fI\%view:\fP
|
||||
Overriding a small subset of configuration for incoming requests.
|
||||
Requests are mapped to views with
|
||||
\fI\%access\-control\-view\fP and
|
||||
\fI\%interface\-view\fP\&.
|
||||
.TP
|
||||
.B \fI\%python:\fP
|
||||
Configuration for the optional \fBpython\fP script module.
|
||||
.TP
|
||||
.B \fI\%dynlib:\fP
|
||||
Configuration for the optional \fBdynlib\fP module that loads dynamic
|
||||
libraries into Unbound.
|
||||
.TP
|
||||
.B \fI\%dnscrypt:\fP
|
||||
Configuration for the optional DNSCrypt feature.
|
||||
.TP
|
||||
.B \fI\%cachedb:\fP
|
||||
Configuration for the optional \fBcachedb\fP module that can interface
|
||||
with second level caches, currently Redis or Redis\-complatible
|
||||
databases.
|
||||
.TP
|
||||
.B \fI\%dnstap:\fP
|
||||
Configuration of the optional dnstap logging feature; a flexible,
|
||||
structured binary log format for DNS software.
|
||||
.TP
|
||||
.B \fI\%rpz:\fP
|
||||
Configuration for Response Policy Zones that allows for DNS filtering.
|
||||
Requires the \fBrespip\fP module.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
Section clauses can be repeated throughout the file (or included files) to
|
||||
logically group options in one visually cohesive group.
|
||||
This may be particularly useful for the \fBserver:\fP clause with its myriad of
|
||||
options.
|
||||
.SH INCLUDING FILES
|
||||
.sp
|
||||
Files can be included using the \fBinclude:\fP directive.
|
||||
It can appear anywhere, it accepts a single file name as argument.
|
||||
@@ -124,11 +183,11 @@ Wildcards can be used to include multiple files, see \fIglob(7)\fP\&.
|
||||
.sp
|
||||
For a more structural include option, the \fBinclude\-toplevel:\fP directive can
|
||||
be used.
|
||||
This closes whatever clause is currently active (if any) and forces the use of
|
||||
clauses in the included files and right after this directive.
|
||||
.SS Server Options
|
||||
This closes whatever section clause is currently active (if any) and forces the
|
||||
use of section clauses in the included files and right after this directive.
|
||||
.SH SERVER OPTIONS
|
||||
.sp
|
||||
These options are part of the \fBserver:\fP clause.
|
||||
These options are part of the \fBserver:\fP section.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B verbosity: \fI<number>\fP
|
||||
@@ -539,6 +598,9 @@ Default: 376
|
||||
The wait time in msec where recursion requests are dropped.
|
||||
This is to stop a large number of replies from accumulating.
|
||||
They receive no reply, the work item continues to recurse.
|
||||
For UDP the replies are dropped, for stream connections the reply
|
||||
is not dropped if the stream connection is still open ready to receive
|
||||
answers.
|
||||
It is nice to be a bit larger than
|
||||
\fI\%serve\-expired\-client\-timeout\fP
|
||||
if that is enabled.
|
||||
@@ -554,7 +616,7 @@ The number of replies that can wait for recursion, for an IP address.
|
||||
This makes a ratelimit per IP address of waiting replies for recursion.
|
||||
It stops very large amounts of queries waiting to be returned to one
|
||||
destination.
|
||||
The value \fB0\fP disables wait limits.
|
||||
The value \fB0\fP disables all wait limits.
|
||||
.sp
|
||||
Default: 1000
|
||||
.UNINDENT
|
||||
@@ -563,7 +625,11 @@ Default: 1000
|
||||
.B wait\-limit\-cookie: \fI<number>\fP
|
||||
The number of replies that can wait for recursion, for an IP address
|
||||
that sent the query with a valid DNS Cookie.
|
||||
Since the cookie validates the client address, this limit can be higher.
|
||||
Since the cookie already validates the client address, this option allows
|
||||
to override a configured
|
||||
\fI\%wait\-limit\fP value usually with a higher one
|
||||
for cookie validated queries.
|
||||
The value \fB0\fP disables wait limits for cookie validated queries.
|
||||
.sp
|
||||
Default: 10000
|
||||
.UNINDENT
|
||||
@@ -1153,8 +1219,8 @@ Default: no
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B tls\-system\-cert: \fI<yes or no>\fP
|
||||
This the same attribute as the
|
||||
\fI\%tls\-win\-cert\fP attribute, under a
|
||||
This the same as the
|
||||
\fI\%tls\-win\-cert\fP option, under a
|
||||
different name.
|
||||
Because it is not windows specific.
|
||||
.UNINDENT
|
||||
@@ -1218,6 +1284,47 @@ Default: \(dq\(dq
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B tls\-use\-sni: \fI<yes or no>\fP
|
||||
Enable or disable sending the SNI extension on TLS connections.
|
||||
.sp
|
||||
\fBNOTE:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
Changing the value requires a reload.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
Default: yes
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B tls\-use\-system\-policy\-versions: \fI<yes or no>\fP
|
||||
Enable or disable general\-puspose version\-flexible TLS server configuration
|
||||
when serving TLS.
|
||||
This will allow the whole list of available TLS versions provided by the
|
||||
crypto library, which may have been further restricted by the system\(aqs
|
||||
crypto policy.
|
||||
.sp
|
||||
By default Unbound only uses the latest available TLS version.
|
||||
.sp
|
||||
\fBCAUTION:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
Use only if you want to support legacy TLS client connections.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBNOTE:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
Changing the value requires a reload.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
Default: no
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B pad\-responses: \fI<yes or no>\fP
|
||||
If enabled, TLS serviced queries that contained an EDNS Padding option will
|
||||
cause responses padded to the closest multiple of the size specified in
|
||||
@@ -1251,20 +1358,6 @@ Default: 128
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B tls\-use\-sni: \fI<yes or no>\fP
|
||||
Enable or disable sending the SNI extension on TLS connections.
|
||||
.sp
|
||||
\fBNOTE:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
Changing the value requires a reload.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
Default: yes
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B https\-port: \fI<number>\fP
|
||||
The port number on which to provide DNS\-over\-HTTPS service.
|
||||
Only interfaces configured with that port number as @number get the HTTPS
|
||||
@@ -1357,6 +1450,9 @@ The port number on which to provide DNS\-over\-QUIC service.
|
||||
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.
|
||||
If it is set to 0, the server does not init QUIC code, and QUIC is
|
||||
disabled.
|
||||
This is similar to if QUIC is not in use, but then explicitly.
|
||||
.sp
|
||||
Default: 853
|
||||
.UNINDENT
|
||||
@@ -1580,8 +1676,8 @@ implicit default \(dqaccess\-control: 127.0.0.0/8 allow\(dq option.
|
||||
.INDENT 3.5
|
||||
The interface needs to be already specified with
|
||||
\fI\%interface\fP and that any
|
||||
\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP
|
||||
attributes for targeted clients.
|
||||
\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP
|
||||
options for targeted clients.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
@@ -1596,8 +1692,8 @@ for interfaces.
|
||||
.INDENT 3.5
|
||||
The interface needs to be already specified with
|
||||
\fI\%interface\fP and that any
|
||||
\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP
|
||||
attributes for targeted clients.
|
||||
\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP
|
||||
options for targeted clients.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
@@ -1613,8 +1709,8 @@ but for interfaces.
|
||||
.INDENT 3.5
|
||||
The interface needs to be already specified with
|
||||
\fI\%interface\fP and that any
|
||||
\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP
|
||||
attributes for targeted clients.
|
||||
\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP
|
||||
options for targeted clients.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
@@ -1630,8 +1726,8 @@ for interfaces.
|
||||
.INDENT 3.5
|
||||
The interface needs to be already specified with
|
||||
\fI\%interface\fP and that any
|
||||
\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP
|
||||
attributes for targeted clients.
|
||||
\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP
|
||||
options for targeted clients.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
@@ -1646,8 +1742,8 @@ but for interfaces.
|
||||
.INDENT 3.5
|
||||
The interface needs to be already specified with
|
||||
\fI\%interface\fP and that any
|
||||
\fBaccess\-control*:\fP attribute overrides all \fBinterface\-*:\fP
|
||||
attributes for targeted clients.
|
||||
\fBaccess\-control*:\fP option overrides all \fBinterface\-*:\fP
|
||||
options for targeted clients.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
@@ -1724,7 +1820,7 @@ The logfile is appended to, in the following format:
|
||||
.UNINDENT
|
||||
.sp
|
||||
If this option is given, the \fI\%use\-syslog\fP
|
||||
attribute is internally set to \fBno\fP\&.
|
||||
option is internally set to \fBno\fP\&.
|
||||
.sp
|
||||
The logfile is reopened (for append) when the config file is reread, on
|
||||
SIGHUP.
|
||||
@@ -1834,6 +1930,16 @@ Default: no
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B log\-thread\-id: \fI<yes or no>\fP
|
||||
(Only on Linux and only when threads are available)
|
||||
Logs the system\-wide Linux thread ID instead of Unbound\(aqs internal thread
|
||||
counter.
|
||||
Can be useful when debugging with system tools.
|
||||
.sp
|
||||
Default: no
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B pidfile: \fI<filename>\fP
|
||||
The process id is written to the file.
|
||||
Default is \fB\(dq@UNBOUND_PIDFILE@\(dq\fP\&.
|
||||
@@ -1872,8 +1978,8 @@ Read the root hints from this file.
|
||||
Default is nothing, using builtin hints for the IN class.
|
||||
The file has the format of zone files, with root nameserver names and
|
||||
addresses only.
|
||||
The default may become outdated, when servers change, therefore it is good
|
||||
practice to use a root hints file.
|
||||
The default may become outdated, when servers change, and then it is
|
||||
possible to use a root hints file with specific servers.
|
||||
.sp
|
||||
Default: \(dq\(dq
|
||||
.UNINDENT
|
||||
@@ -1969,7 +2075,7 @@ Default: \(dq3 2 1 0 0\(dq
|
||||
.B harden\-short\-bufsize: \fI<yes or no>\fP
|
||||
Very small EDNS buffer sizes from queries are ignored.
|
||||
.sp
|
||||
Default: yes (as described in the standard)
|
||||
Default: yes (per \fI\%RFC 6891\fP)
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -2600,6 +2706,12 @@ If
|
||||
\fI\%serve\-expired\-client\-timeout\fP
|
||||
is also used then it is RECOMMENDED to use 30 as the value (\fI\%RFC 8767\fP).
|
||||
.sp
|
||||
This value is capped by the original TTL of the record.
|
||||
This means that records with higher original TTL than this value will use
|
||||
this value for expired replies.
|
||||
Records with lower original TTL than this value will use their original TTL
|
||||
for expired replies.
|
||||
.sp
|
||||
Default: 30
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
@@ -3278,7 +3390,7 @@ zone section below.
|
||||
Configure local data shorthand for a PTR record with the reversed IPv4 or
|
||||
IPv6 address and the host name.
|
||||
For example \fB\(dq192.0.2.4 www.example.com\(dq\fP\&.
|
||||
TTL can be inserted like this: \fB\(dq2001:DB8::4 7200 www.example.com\(dq\fP
|
||||
TTL can be inserted like this: \fB\(dq2001:db8::4 7200 www.example.com\(dq\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -3335,7 +3447,7 @@ This specifies the action data for
|
||||
\fI\%response\-ip\fP with action being to redirect
|
||||
as specified by \fI<\(dqresource record string\(dq>\fP\&.
|
||||
\fI<\(dqResource record string\(dq>\fP is similar to that of
|
||||
\fI\%access\-control\-tag\-action\fP,
|
||||
\fI\%access\-control\-tag\-data\fP,
|
||||
but it must be of either AAAA, A or CNAME types.
|
||||
If the \fI<IP\-netblock>\fP is an IPv6/IPv4 prefix, the record must be AAAA/A
|
||||
respectively, unless it is a CNAME (which can be used for both versions of
|
||||
@@ -3805,17 +3917,18 @@ enabled to increase privacy on the outgoing reports.
|
||||
.sp
|
||||
Default: no
|
||||
.UNINDENT
|
||||
.SS Remote Control Options
|
||||
.SH REMOTE CONTROL OPTIONS
|
||||
.sp
|
||||
These options are part of the \fBremote\-control:\fP section and are the
|
||||
declarations for the remote control facility.
|
||||
.sp
|
||||
In the \fBremote\-control:\fP clause are the declarations for the remote control
|
||||
facility.
|
||||
If this is enabled, the \fI\%unbound\-control(8)\fP
|
||||
utility can be used to send commands to the running Unbound server.
|
||||
The server uses these clauses to setup TLSv1 security for the connection.
|
||||
The \fI\%unbound\-control(8)\fP utility also reads the
|
||||
\fBremote\-control:\fP section for options.
|
||||
The server uses these options to setup TLS security for the connection.
|
||||
The \fI\%unbound\-control(8)\fP utility also reads
|
||||
this \fBremote\-control:\fP section for options.
|
||||
To setup the correct self\-signed certificates use the
|
||||
\fIunbound\-control\-setup(8)\fP utility.
|
||||
\fBunbound\-control\-setup(8)\fP utility.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B control\-enable: \fI<yes or no>\fP
|
||||
@@ -3915,9 +4028,11 @@ This file is used by \fI\%unbound\-control(8)\fP\&.
|
||||
.sp
|
||||
Default: unbound_control.pem
|
||||
.UNINDENT
|
||||
.SS Stub Zone Options
|
||||
.SH STUB ZONE OPTIONS
|
||||
.sp
|
||||
There may be multiple \fBstub\-zone:\fP clauses.
|
||||
These options are part of the \fBstub\-zone:\fP section.
|
||||
.sp
|
||||
There may be multiple \fBstub\-zone:\fP sections.
|
||||
Each with a \fI\%name\fP and zero or more hostnames or
|
||||
IP addresses.
|
||||
For the stub zone this list of nameservers is used.
|
||||
@@ -3956,9 +4071,10 @@ Consider adding \fI\%server\fP statements for
|
||||
\fI\%domain\-insecure\fP and for
|
||||
\fI\%local\-zone: <name> nodefault\fP
|
||||
for the zone if it is a locally served zone.
|
||||
The insecure clause stops DNSSEC from invalidating the zone.
|
||||
The \fI\%domain\-insecure\fP option stops DNSSEC
|
||||
from invalidating the zone.
|
||||
The \fI\%local\-zone: nodefault\fP (or
|
||||
\fI\%transparent\fP) clause makes the
|
||||
\fI\%transparent\fP) option makes the
|
||||
(reverse\-) zone bypass Unbound\(aqs filtering of \fI\%RFC 1918\fP zones.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -3972,6 +4088,23 @@ This is the full domain name of the zone.
|
||||
Name of stub zone nameserver.
|
||||
Is itself resolved before it is used.
|
||||
.sp
|
||||
\fBCAUTION:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
If the domain (or a subdomain) from this zone is used as the host, it
|
||||
will unavoidably introduce a circular dependency on retrieving the IP
|
||||
addresses of the name server.
|
||||
In that case, it is suggested to use
|
||||
\fI\%stub\-addr\fP instead.
|
||||
Alternatively,
|
||||
\fI\%stub\-first: yes\fP can also work
|
||||
around the circular dependency by trying resolution outside of this
|
||||
zone.
|
||||
However this has the caveat that it would allow escaping this zone when
|
||||
any resolution attempt fails within this zone.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
To use a non\-default port for DNS communication append \fB\(aq@\(aq\fP with the
|
||||
port number.
|
||||
.sp
|
||||
@@ -4012,9 +4145,12 @@ Default: no
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B stub\-first: \fI<yes or no>\fP
|
||||
If enabled, a query is attempted without the stub clause if it fails.
|
||||
If enabled, a query is attempted without this stub section if it fails.
|
||||
The data could not be retrieved and would have caused SERVFAIL because the
|
||||
servers are unreachable, instead it is tried without this clause.
|
||||
servers are unreachable, instead it is tried without this stub section.
|
||||
This can lead to using less specific configured forward/stub/auth zones if
|
||||
any, or end up to otherwise normal recursive resolution for that particular
|
||||
query.
|
||||
.sp
|
||||
Default: no
|
||||
.UNINDENT
|
||||
@@ -4047,9 +4183,11 @@ This is useful when you want immediate changes to be visible.
|
||||
.sp
|
||||
Default: no
|
||||
.UNINDENT
|
||||
.SS Forward Zone Options
|
||||
.SH FORWARD ZONE OPTIONS
|
||||
.sp
|
||||
There may be multiple \fBforward\-zone:\fP clauses.
|
||||
These options are part of the \fBforward\-zone:\fP section.
|
||||
.sp
|
||||
There may be multiple \fBforward\-zone:\fP sections.
|
||||
Each with a \fI\%name\fP and zero or more hostnames
|
||||
or IP addresses.
|
||||
For the forward zone this list of nameservers is used to forward the queries
|
||||
@@ -4080,6 +4218,23 @@ This is the full domain name of the zone.
|
||||
Name of server to forward to.
|
||||
Is itself resolved before it is used.
|
||||
.sp
|
||||
\fBCAUTION:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
If the domain (or a subdomain) from this zone is used as the host, it
|
||||
will unavoidably introduce a circular dependency on retrieving the IP
|
||||
addresses of the name server.
|
||||
In that case, it is suggested to use
|
||||
\fI\%forward\-addr\fP instead.
|
||||
Alternatively,
|
||||
\fI\%forward\-first: yes\fP can also
|
||||
work around the circular dependency by trying resolution outside of
|
||||
this zone.
|
||||
However this has the caveat that it would allow escaping this zone when
|
||||
any resolution attempt fails within this zone.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
To use a non\-default port for DNS communication append \fB\(aq@\(aq\fP with the
|
||||
port number.
|
||||
.sp
|
||||
@@ -4116,9 +4271,11 @@ The cert must also match a CA from the
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B forward\-first: \fI<yes or no>\fP
|
||||
If a forwarded query is met with a SERVFAIL error, and this option is
|
||||
enabled, Unbound will fall back to normal recursive resolution for this
|
||||
query as if no query forwarding had been specified.
|
||||
If a forwarded query is met with a SERVFAIL error and this option is
|
||||
enabled Unbound will fall back to less specific resolution.
|
||||
This can lead to using less specific configured forward/stub/auth zones if
|
||||
any, or end up to otherwise normal recursive resolution for that particular
|
||||
query.
|
||||
.sp
|
||||
Default: no
|
||||
.UNINDENT
|
||||
@@ -4156,12 +4313,14 @@ This is useful when you want immediate changes to be visible.
|
||||
.sp
|
||||
Default: no
|
||||
.UNINDENT
|
||||
.SS Authority Zone Options
|
||||
.SH AUTHORITY ZONE OPTIONS
|
||||
.sp
|
||||
These options are part of the \fBauth\-zone:\fP section.
|
||||
.sp
|
||||
Authority zones are configured with \fBauth\-zone:\fP, and each one must have a
|
||||
\fI\%name\fP\&.
|
||||
There can be multiple ones, by listing multiple auth\-zone clauses, each with a
|
||||
different name, pertaining to that part of the namespace.
|
||||
There can be multiple ones, by listing multiple \fBauth\-zone\fP section clauses,
|
||||
each with a different name, pertaining to that part of the namespace.
|
||||
The authority zone with the name closest to the name looked up is used.
|
||||
Authority zones can be processed on two distinct, non\-exclusive, configurable
|
||||
stages.
|
||||
@@ -4192,7 +4351,7 @@ consult the local zone data while resolving.
|
||||
In this case, the aforementioned CNAME example will result in a thoroughly
|
||||
resolved answer.
|
||||
.sp
|
||||
Authority zones can be read from zonefile.
|
||||
Authority zones can be read from a zonefile.
|
||||
And can be kept updated via AXFR and IXFR.
|
||||
After update the zonefile is rewritten.
|
||||
The update mechanism uses the SOA timer values and performs SOA UDP queries to
|
||||
@@ -4229,9 +4388,15 @@ does not support AXFR/IXFR for the zone, but if you used
|
||||
\fI\%url\fP to download the zonefile as a text file
|
||||
from a webserver that would work.
|
||||
.sp
|
||||
If you specify the hostname, you cannot use the domain from the zonefile,
|
||||
because it may not have that when retrieving that data, instead use a plain
|
||||
IP address to avoid a circular dependency on retrieving that IP address.
|
||||
\fBCAUTION:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
If you specify the hostname, you cannot use the domain from the
|
||||
zonefile, because it may not have that when retrieving that data,
|
||||
instead use a plain IP address to avoid a circular dependency on
|
||||
retrieving that IP address.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -4377,18 +4542,20 @@ If not given then no zonefile is used.
|
||||
If the file does not exist or is empty, Unbound will attempt to fetch zone
|
||||
data (eg. from the primary servers).
|
||||
.UNINDENT
|
||||
.SS View Options
|
||||
.SH VIEW OPTIONS
|
||||
.sp
|
||||
There may be multiple \fBview:\fP clauses.
|
||||
These options are part of the \fBview:\fP section.
|
||||
.sp
|
||||
There may be multiple \fBview:\fP sections.
|
||||
Each with a \fI\%name\fP and zero or more
|
||||
\fI\%local\-zone\fP and
|
||||
\fI\%local\-data\fP attributes.
|
||||
\fI\%local\-data\fP options.
|
||||
Views can also contain \fI\%view\-first\fP,
|
||||
\fI\%response\-ip\fP,
|
||||
\fI\%response\-ip\-data\fP and
|
||||
\fI\%local\-data\-ptr\fP attributes.
|
||||
\fI\%local\-data\-ptr\fP options.
|
||||
View can be mapped to requests by specifying the view name in an
|
||||
\fI\%access\-control\-view\fP attribute.
|
||||
\fI\%access\-control\-view\fP option.
|
||||
Options from matching views will override global options.
|
||||
Global options will be used if no matching view is found, or when the matching
|
||||
view does not have the option specified.
|
||||
@@ -4398,7 +4565,7 @@ view does not have the option specified.
|
||||
Name of the view.
|
||||
Must be unique.
|
||||
This name is used in the
|
||||
\fI\%access\-control\-view\fP attribute.
|
||||
\fI\%access\-control\-view\fP option.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -4431,6 +4598,22 @@ Has the same behaviour as the global
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B response\-ip: \fI<IP\-netblock> <action>\fP
|
||||
This requires use of the \fBrespip\fP module.
|
||||
.sp
|
||||
Similar to \fI\%response\-ip\fP but
|
||||
only applies to this view.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B response\-ip\-data: \fI<IP\-netblock> <\(dqresource record string\(dq>\fP
|
||||
This requires use of the \fBrespip\fP module.
|
||||
.sp
|
||||
Similar to \fI\%response\-ip\-data\fP but
|
||||
only applies to this view.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B view\-first: \fI<yes or no>\fP
|
||||
If enabled, it attempts to use the global
|
||||
\fI\%local\-zone\fP and
|
||||
@@ -4439,9 +4622,11 @@ view specific options.
|
||||
.sp
|
||||
Default: no
|
||||
.UNINDENT
|
||||
.SS Python Module Options
|
||||
.SH PYTHON MODULE OPTIONS
|
||||
.sp
|
||||
The \fBpython:\fP clause gives the settings for the \fIpython(1)\fP script module.
|
||||
These options are part of the \fBpython:\fP section.
|
||||
.sp
|
||||
The \fBpython:\fP section gives the settings for the \fIpython(1)\fP script module.
|
||||
This module acts like the iterator and validator modules do, on queries and
|
||||
answers.
|
||||
To enable the script module it has to be compiled into the daemon, and the word
|
||||
@@ -4464,14 +4649,16 @@ The script file to load.
|
||||
Repeat this option for every python module instance added to the
|
||||
\fI\%module\-config\fP option.
|
||||
.UNINDENT
|
||||
.SS Dynamic Library Module Options
|
||||
.SH DYNAMIC LIBRARY MODULE OPTIONS
|
||||
.sp
|
||||
The \fBdynlib:\fP clause gives the settings for the \fBdynlib\fP module.
|
||||
These options are part of the \fBdynlib:\fP section.
|
||||
.sp
|
||||
The \fBdynlib:\fP section gives the settings for the \fBdynlib\fP module.
|
||||
This module is only a very small wrapper that allows dynamic modules to be
|
||||
loaded on runtime instead of being compiled into the application.
|
||||
To enable the dynlib module it has to be compiled into the daemon, and the word
|
||||
\fBdynlib\fP has to be put in the
|
||||
\fI\%module\-config\fP attribute.
|
||||
\fI\%module\-config\fP option.
|
||||
Multiple instances of dynamic libraries are supported by adding the word
|
||||
\fBdynlib\fP more than once.
|
||||
.sp
|
||||
@@ -4486,7 +4673,9 @@ The dynamic library file to load.
|
||||
Repeat this option for every dynlib module instance added to the
|
||||
\fI\%module\-config\fP option.
|
||||
.UNINDENT
|
||||
.SS DNS64 Module Options
|
||||
.SH DNS64 MODULE OPTIONS
|
||||
.sp
|
||||
These options are part of the \fBserver:\fP section.
|
||||
.sp
|
||||
The \fBdns64\fP module must be configured in the
|
||||
\fI\%module\-config\fP directive, e.g.:
|
||||
@@ -4506,7 +4695,11 @@ and be compiled into the daemon to be enabled.
|
||||
\fBNOTE:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
These settings go in the \fI\%server:\fP section.
|
||||
If combining the \fBrespip\fP and \fBdns64\fP modules, the \fBrespip\fP module
|
||||
needs to appear before the \fBdns64\fP module in the
|
||||
\fI\%module\-config\fP
|
||||
configuration option so that response IP and/or RPZ feeds can properly
|
||||
filter responses regardless of DNS64 synthesis.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
@@ -4542,12 +4735,12 @@ Can be entered multiple times, list a new domain for which it applies, one
|
||||
per line.
|
||||
Applies also to names underneath the name given.
|
||||
.UNINDENT
|
||||
.SS NAT64 Operation
|
||||
.SH NAT64 OPTIONS
|
||||
.sp
|
||||
These options are part of the \fBserver:\fP section.
|
||||
.sp
|
||||
NAT64 operation allows using a NAT64 prefix for outbound requests to IPv4\-only
|
||||
servers.
|
||||
It is controlled by two options in the
|
||||
\fI\%server:\fP section:
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B do\-nat64: \fI<yes or no>\fP
|
||||
@@ -4565,9 +4758,11 @@ The prefix length must be one of /32, /40, /48, /56, /64 or /96.
|
||||
.sp
|
||||
Default: 64:ff9b::/96 (same as \fI\%dns64\-prefix\fP)
|
||||
.UNINDENT
|
||||
.SS DNSCrypt Options
|
||||
.SH DNSCRYPT OPTIONS
|
||||
.sp
|
||||
The \fBdnscrypt:\fP clause gives the settings of the dnscrypt channel.
|
||||
These options are part of the \fBdnscrypt:\fP section.
|
||||
.sp
|
||||
The \fBdnscrypt:\fP section gives the settings of the dnscrypt channel.
|
||||
While those options are available, they are only meaningful if Unbound was
|
||||
compiled with \fB\-\-enable\-dnscrypt\fP\&.
|
||||
Currently certificate and secret/public keys cannot be generated by Unbound.
|
||||
@@ -4697,7 +4892,9 @@ If left unconfigured, it will be configured automatically to be a power of
|
||||
.sp
|
||||
Default: (unconfigured)
|
||||
.UNINDENT
|
||||
.SS EDNS Client Subnet Module Options
|
||||
.SH EDNS CLIENT SUBNET MODULE OPTIONS
|
||||
.sp
|
||||
These options are part of the \fBserver:\fP section.
|
||||
.sp
|
||||
The ECS module must be configured in the
|
||||
\fI\%module\-config\fP directive, e.g.:
|
||||
@@ -4714,13 +4911,6 @@ module\-config: \(dqsubnetcache validator iterator\(dq
|
||||
.sp
|
||||
and be compiled into the daemon to be enabled.
|
||||
.sp
|
||||
\fBNOTE:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
These settings go in the \fI\%server:\fP section.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
If the destination address is allowed in the configuration Unbound will add the
|
||||
EDNS0 option to the query containing the relevant part of the client\(aqs address.
|
||||
When an answer contains the ECS option the response and the option are placed
|
||||
@@ -4842,7 +5032,9 @@ This number applies for each qname/qclass/qtype tuple.
|
||||
.sp
|
||||
Default: 100
|
||||
.UNINDENT
|
||||
.SS Opportunistic IPsec Support Module Options
|
||||
.SH OPPORTUNISTIC IPSEC SUPPORT MODULE OPTIONS
|
||||
.sp
|
||||
These options are part of the \fBserver:\fP section.
|
||||
.sp
|
||||
The IPsec module must be configured in the
|
||||
\fI\%module\-config\fP directive, e.g.:
|
||||
@@ -4859,13 +5051,6 @@ module\-config: \(dqipsecmod validator iterator\(dq
|
||||
.sp
|
||||
and be compiled into Unbound by using \fB\-\-enable\-ipsecmod\fP to be enabled.
|
||||
.sp
|
||||
\fBNOTE:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
These settings go in the \fI\%server:\fP section.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
When Unbound receives an A/AAAA query that is not in the cache and finds a
|
||||
valid answer, it will withhold returning the answer and instead will generate
|
||||
an IPSECKEY subquery for the same domain name.
|
||||
@@ -4963,7 +5148,9 @@ If the option is not specified, all domains are treated as being allowed
|
||||
.B ipsecmod\-whitelist: \fI<domain>\fP
|
||||
Alternate syntax for \fI\%ipsecmod\-allow\fP\&.
|
||||
.UNINDENT
|
||||
.SS Cache DB Module Options
|
||||
.SH CACHE DB MODULE OPTIONS
|
||||
.sp
|
||||
These options are part of the \fBcachedb:\fP section.
|
||||
.sp
|
||||
The Cache DB module must be configured in the
|
||||
\fI\%module\-config\fP directive, e.g.:
|
||||
@@ -5025,7 +5212,7 @@ If connection close or timeout happens too often, Unbound will be effectively
|
||||
unusable with this backend.
|
||||
It\(aqs the administrator\(aqs responsibility to make the assumption hold.
|
||||
.sp
|
||||
The \fBcachedb:\fP clause gives custom settings of the cache DB module.
|
||||
The \fBcachedb:\fP section gives custom settings of the cache DB module.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B backend: \fI<backend name>\fP
|
||||
@@ -5253,10 +5440,13 @@ for the Redis replica server.
|
||||
.sp
|
||||
Default: 0
|
||||
.UNINDENT
|
||||
.SS DNSTAP Logging Options
|
||||
.SH DNSTAP OPTIONS
|
||||
.sp
|
||||
DNSTAP support, when compiled in by using \fB\-\-enable\-dnstap\fP, is enabled in
|
||||
the \fBdnstap:\fP section.
|
||||
These options are part of the \fBdnstap:\fP section.
|
||||
.sp
|
||||
DNSTAP is a flexible, structured binary log format for DNS software.
|
||||
When compiled in by using \fB\-\-enable\-dnstap\fP, it can be enabled in the
|
||||
\fBdnstap:\fP section.
|
||||
This starts an extra thread (when compiled with threading) that writes the log
|
||||
information to the destination.
|
||||
If Unbound is compiled without threading it does not spawn a thread, but
|
||||
@@ -5422,15 +5612,18 @@ Enable to log forwarder response messages.
|
||||
.sp
|
||||
Default: no
|
||||
.UNINDENT
|
||||
.SS Response Policy Zone Options
|
||||
.SH RESPONSE POLICY ZONE OPTIONS
|
||||
.sp
|
||||
Response Policy Zones are configured with \fBrpz:\fP, and each one must have a
|
||||
\fI\%name\fP attribute.
|
||||
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.
|
||||
These options are part of the \fBrpz:\fP section.
|
||||
.sp
|
||||
Response Policy Zones are configured with \fBrpz:\fP section clauses, and each
|
||||
one must have a \fI\%name\fP option.
|
||||
There can be multiple ones, by listing multiple \fBrpz:\fP section clauses, each
|
||||
with a different name.
|
||||
RPZ sections 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.
|
||||
.sp
|
||||
The respip module needs to be added to the
|
||||
\fI\%module\-config\fP, e.g.:
|
||||
.INDENT 0.0
|
||||
@@ -5444,6 +5637,17 @@ module\-config: \(dqrespip validator iterator\(dq
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBNOTE:\fP
|
||||
.INDENT 0.0
|
||||
.INDENT 3.5
|
||||
If combining the \fBrespip\fP and \fBdns64\fP modules, the \fBrespip\fP module
|
||||
needs to appear before the \fBdns64\fP module in the
|
||||
\fI\%module\-config\fP
|
||||
configuration option so that response IP and/or RPZ feeds can properly
|
||||
filter responses regardless of DNS64 synthesis.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
QNAME, Response IP Address, nsdname, nsip and clientip triggers are supported.
|
||||
Supported actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp\-only
|
||||
and drop.
|
||||
@@ -5512,9 +5716,6 @@ A 192.0.2.1 answer with this IP address
|
||||
.sp
|
||||
Other records like AAAA, TXT and other CNAMEs (not rpz\-..) can also be used to
|
||||
answer queries with that content.
|
||||
.sp
|
||||
The RPZ zones can be configured in the config file with these settings in the
|
||||
\fBrpz:\fP block.
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B name: \fI<zone name>\fP
|
||||
@@ -5653,7 +5854,7 @@ Default: no
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B tags: \fI\(dq<list of tags>\(dq\fP
|
||||
Limit the policies from this RPZ clause to clients with a matching tag.
|
||||
Limit the policies from this RPZ section to clients with a matching tag.
|
||||
.sp
|
||||
Tags need to be defined in \fI\%define\-tag\fP and
|
||||
can be assigned to client addresses using
|
||||
@@ -5661,7 +5862,7 @@ can be assigned to client addresses using
|
||||
\fI\%interface\-tag\fP\&.
|
||||
Enclose list of tags in quotes (\fB\(dq\(dq\fP) and put spaces between tags.
|
||||
.sp
|
||||
If no tags are specified the policies from this clause will be applied for
|
||||
If no tags are specified the policies from this section will be applied for
|
||||
all clients.
|
||||
.UNINDENT
|
||||
.SH MEMORY CONTROL EXAMPLE
|
||||
@@ -5730,6 +5931,6 @@ Default is to log to \fIsyslog(3)\fP\&.
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
+323
-136
@@ -46,34 +46,41 @@ Description
|
||||
-----------
|
||||
|
||||
**unbound.conf** is used to configure :doc:`unbound(8)</manpages/unbound>`.
|
||||
The file format has attributes and values.
|
||||
Some attributes have attributes inside them.
|
||||
The notation is: ``attribute: value``.
|
||||
|
||||
Comments start with ``#`` and last to the end of line.
|
||||
Empty lines are ignored as is whitespace at the beginning of a line.
|
||||
|
||||
The utility :doc:`unbound-checkconf(8)</manpages/unbound-checkconf>` can be
|
||||
used to check ``unbound.conf`` prior to usage.
|
||||
|
||||
File Format
|
||||
-----------
|
||||
|
||||
Whitespace is used to separate keywords.
|
||||
Whitespace indentation is insignificant, but is still recommended for visual
|
||||
clarity.
|
||||
Comments start with ``#`` and last to the end of line.
|
||||
Empty lines are ignored, as is whitespace at the beginning of a line.
|
||||
|
||||
Attribute keywords end with a colon (``:``) and they are either options or
|
||||
section clauses (group options together).
|
||||
|
||||
The configuration file is logically divided into **sections** where each section
|
||||
is introduced by a :ref:`section clause<unbound.conf.clauses>`.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
An example config file is shown below.
|
||||
Copy this to :file:`/etc/unbound/unbound.conf` and start the server with:
|
||||
An example minimal config file is shown below; most settings are the defaults.
|
||||
Copy this to ``@ub_conf_file@`` and start the server with:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ unbound -c /etc/unbound/unbound.conf
|
||||
$ unbound -c @ub_conf_file@
|
||||
|
||||
Most settings are the defaults.
|
||||
Stop the server with:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
$ kill `cat /etc/unbound/unbound.pid`
|
||||
$ kill `cat @UNBOUND_PIDFILE@`
|
||||
|
||||
Below is a minimal config file.
|
||||
The source distribution contains an extensive :file:`example.conf` file with
|
||||
all the options.
|
||||
|
||||
@@ -81,35 +88,87 @@ all the options.
|
||||
|
||||
# unbound.conf(5) config file for unbound(8).
|
||||
server:
|
||||
directory: "/etc/unbound"
|
||||
directory: "@UNBOUND_RUN_DIR@"
|
||||
username: unbound
|
||||
# make sure unbound can access entropy from inside the chroot.
|
||||
# e.g. on linux the use these commands (on BSD, devfs(8) is used):
|
||||
# mount --bind -n /dev/urandom /etc/unbound/dev/urandom
|
||||
# and mount --bind -n /dev/log /etc/unbound/dev/log
|
||||
chroot: "/etc/unbound"
|
||||
# logfile: "/etc/unbound/unbound.log" #uncomment to use logfile.
|
||||
pidfile: "/etc/unbound/unbound.pid"
|
||||
# mount --bind -n /dev/urandom @UNBOUND_RUN_DIR@/dev/urandom
|
||||
# and mount --bind -n /dev/log @UNBOUND_RUN_DIR@/dev/log
|
||||
chroot: "@UNBOUND_CHROOT_DIR@"
|
||||
# logfile: "@UNBOUND_RUN_DIR@/unbound.log" #uncomment to use logfile.
|
||||
pidfile: "@UNBOUND_PIDFILE@"
|
||||
# verbosity: 1 # uncomment and increase to get more logging.
|
||||
# listen on all interfaces, answer queries from the local subnet.
|
||||
interface: 0.0.0.0
|
||||
interface: ::0
|
||||
access-control: 10.0.0.0/8 allow
|
||||
access-control: 2001:DB8::/64 allow
|
||||
access-control: 2001:db8::/64 allow
|
||||
|
||||
File Format
|
||||
-----------
|
||||
.. _unbound.conf.clauses:
|
||||
|
||||
There must be whitespace between keywords.
|
||||
Attribute keywords end with a colon ``':'``.
|
||||
An attribute is followed by a value, or its containing attributes in which case
|
||||
it is referred to as a clause.
|
||||
Clauses can be repeated throughout the file (or included files) to group
|
||||
attributes under the same clause.
|
||||
Section Clauses
|
||||
---------------
|
||||
|
||||
The recognized section clauses are:
|
||||
|
||||
:ref:`server:<unbound.conf.server>`
|
||||
Most of the configuration is found in this section.
|
||||
|
||||
:ref:`remote-control:<unbound.conf.remote>`
|
||||
Configuration for the facility used by
|
||||
:doc:`unbound-control(8)</manpages/unbound-control>`.
|
||||
|
||||
:ref:`stub-zone:<unbound.conf.stub>`
|
||||
Configuration for a zone that redirects to specific authoritative name
|
||||
servers, e.g. for zones not generally available on the greater
|
||||
Internet.
|
||||
|
||||
:ref:`forward-zone:<unbound.conf.forward>`
|
||||
Configuration for a zone that forwards to specific DNS resolvers.
|
||||
|
||||
:ref:`auth-zone:<unbound.conf.auth>`
|
||||
Configuration for local authoritative zones.
|
||||
|
||||
:ref:`view:<unbound.conf.view>`
|
||||
Overriding a small subset of configuration for incoming requests.
|
||||
Requests are mapped to views with
|
||||
:ref:`access-control-view<unbound.conf.access-control-view>` and
|
||||
:ref:`interface-view<unbound.conf.interface-view>`.
|
||||
|
||||
:ref:`python:<unbound.conf.python>`
|
||||
Configuration for the optional ``python`` script module.
|
||||
|
||||
:ref:`dynlib:<unbound.conf.dynlib>`
|
||||
Configuration for the optional ``dynlib`` module that loads dynamic
|
||||
libraries into Unbound.
|
||||
|
||||
:ref:`dnscrypt:<unbound.conf.dnscrypt>`
|
||||
Configuration for the optional DNSCrypt feature.
|
||||
|
||||
:ref:`cachedb:<unbound.conf.cachedb>`
|
||||
Configuration for the optional ``cachedb`` module that can interface
|
||||
with second level caches, currently Redis or Redis-complatible
|
||||
databases.
|
||||
|
||||
:ref:`dnstap:<unbound.conf.dnstap>`
|
||||
Configuration of the optional dnstap logging feature; a flexible,
|
||||
structured binary log format for DNS software.
|
||||
|
||||
:ref:`rpz:<unbound.conf.rpz>`
|
||||
Configuration for Response Policy Zones that allows for DNS filtering.
|
||||
Requires the ``respip`` module.
|
||||
|
||||
Section clauses can be repeated throughout the file (or included files) to
|
||||
logically group options in one visually cohesive group.
|
||||
This may be particularly useful for the ``server:`` clause with its myriad of
|
||||
options.
|
||||
|
||||
.. _unbound.conf.include:
|
||||
|
||||
Files can be included using the **include:** directive.
|
||||
Including Files
|
||||
---------------
|
||||
|
||||
Files can be included using the ``include:`` directive.
|
||||
It can appear anywhere, it accepts a single file name as argument.
|
||||
Processing continues as if the text from the included file was copied into the
|
||||
config file at that point.
|
||||
@@ -122,17 +181,17 @@ Wildcards can be used to include multiple files, see *glob(7)*.
|
||||
|
||||
.. _unbound.conf.include-toplevel:
|
||||
|
||||
For a more structural include option, the **include-toplevel:** directive can
|
||||
For a more structural include option, the ``include-toplevel:`` directive can
|
||||
be used.
|
||||
This closes whatever clause is currently active (if any) and forces the use of
|
||||
clauses in the included files and right after this directive.
|
||||
This closes whatever section clause is currently active (if any) and forces the
|
||||
use of section clauses in the included files and right after this directive.
|
||||
|
||||
.. _unbound.conf.server:
|
||||
|
||||
Server Options
|
||||
^^^^^^^^^^^^^^
|
||||
--------------
|
||||
|
||||
These options are part of the **server:** clause.
|
||||
These options are part of the ``server:`` section.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@verbosity@@: *<number>*
|
||||
@@ -496,6 +555,9 @@ These options are part of the **server:** clause.
|
||||
The wait time in msec where recursion requests are dropped.
|
||||
This is to stop a large number of replies from accumulating.
|
||||
They receive no reply, the work item continues to recurse.
|
||||
For UDP the replies are dropped, for stream connections the reply
|
||||
is not dropped if the stream connection is still open ready to receive
|
||||
answers.
|
||||
It is nice to be a bit larger than
|
||||
:ref:`serve-expired-client-timeout<unbound.conf.serve-expired-client-timeout>`
|
||||
if that is enabled.
|
||||
@@ -510,7 +572,7 @@ These options are part of the **server:** clause.
|
||||
This makes a ratelimit per IP address of waiting replies for recursion.
|
||||
It stops very large amounts of queries waiting to be returned to one
|
||||
destination.
|
||||
The value ``0`` disables wait limits.
|
||||
The value ``0`` disables all wait limits.
|
||||
|
||||
Default: 1000
|
||||
|
||||
@@ -518,7 +580,11 @@ These options are part of the **server:** clause.
|
||||
@@UAHL@unbound.conf@wait-limit-cookie@@: *<number>*
|
||||
The number of replies that can wait for recursion, for an IP address
|
||||
that sent the query with a valid DNS Cookie.
|
||||
Since the cookie validates the client address, this limit can be higher.
|
||||
Since the cookie already validates the client address, this option allows
|
||||
to override a configured
|
||||
:ref:`wait-limit<unbound.conf.wait-limit>` value usually with a higher one
|
||||
for cookie validated queries.
|
||||
The value ``0`` disables wait limits for cookie validated queries.
|
||||
|
||||
Default: 10000
|
||||
|
||||
@@ -1049,8 +1115,8 @@ These options are part of the **server:** clause.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@tls-system-cert@@: *<yes or no>*
|
||||
This the same attribute as the
|
||||
:ref:`tls-win-cert<unbound.conf.tls-win-cert>` attribute, under a
|
||||
This the same as the
|
||||
:ref:`tls-win-cert<unbound.conf.tls-win-cert>` option, under a
|
||||
different name.
|
||||
Because it is not windows specific.
|
||||
|
||||
@@ -1103,6 +1169,30 @@ These options are part of the **server:** clause.
|
||||
Default: ""
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@tls-use-sni@@: *<yes or no>*
|
||||
Enable or disable sending the SNI extension on TLS connections.
|
||||
|
||||
.. note:: Changing the value requires a reload.
|
||||
|
||||
Default: yes
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@tls-use-system-policy-versions@@: *<yes or no>*
|
||||
Enable or disable general-puspose version-flexible TLS server configuration
|
||||
when serving TLS.
|
||||
This will allow the whole list of available TLS versions provided by the
|
||||
crypto library, which may have been further restricted by the system's
|
||||
crypto policy.
|
||||
|
||||
By default Unbound only uses the latest available TLS version.
|
||||
|
||||
.. caution:: Use only if you want to support legacy TLS client connections.
|
||||
|
||||
.. note:: Changing the value requires a reload.
|
||||
|
||||
Default: no
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@pad-responses@@: *<yes or no>*
|
||||
If enabled, TLS serviced queries that contained an EDNS Padding option will
|
||||
cause responses padded to the closest multiple of the size specified in
|
||||
@@ -1132,14 +1222,6 @@ These options are part of the **server:** clause.
|
||||
Default: 128
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@tls-use-sni@@: *<yes or no>*
|
||||
Enable or disable sending the SNI extension on TLS connections.
|
||||
|
||||
.. note:: Changing the value requires a reload.
|
||||
|
||||
Default: yes
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@https-port@@: *<number>*
|
||||
The port number on which to provide DNS-over-HTTPS service.
|
||||
Only interfaces configured with that port number as @number get the HTTPS
|
||||
@@ -1224,6 +1306,9 @@ These options are part of the **server:** clause.
|
||||
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.
|
||||
If it is set to 0, the server does not init QUIC code, and QUIC is
|
||||
disabled.
|
||||
This is similar to if QUIC is not in use, but then explicitly.
|
||||
|
||||
Default: 853
|
||||
|
||||
@@ -1421,8 +1506,8 @@ These options are part of the **server:** clause.
|
||||
.. note::
|
||||
The interface needs to be already specified with
|
||||
:ref:`interface<unbound.conf.interface>` and that any
|
||||
**access-control\*:** attribute overrides all **interface-\*:**
|
||||
attributes for targeted clients.
|
||||
**access-control\*:** option overrides all **interface-\*:**
|
||||
options for targeted clients.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@interface-tag@@: *<ip address or interface name [@port]> <"list of tags">*
|
||||
@@ -1432,8 +1517,8 @@ These options are part of the **server:** clause.
|
||||
.. note::
|
||||
The interface needs to be already specified with
|
||||
:ref:`interface<unbound.conf.interface>` and that any
|
||||
**access-control\*:** attribute overrides all **interface-\*:**
|
||||
attributes for targeted clients.
|
||||
**access-control\*:** option overrides all **interface-\*:**
|
||||
options for targeted clients.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@interface-tag-action@@: *<ip address or interface name [@port]> <tag> <action>*
|
||||
@@ -1444,8 +1529,8 @@ These options are part of the **server:** clause.
|
||||
.. note::
|
||||
The interface needs to be already specified with
|
||||
:ref:`interface<unbound.conf.interface>` and that any
|
||||
**access-control\*:** attribute overrides all **interface-\*:**
|
||||
attributes for targeted clients.
|
||||
**access-control\*:** option overrides all **interface-\*:**
|
||||
options for targeted clients.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@interface-tag-data@@: *<ip address or interface name [@port]> <tag> <"resource record string">*
|
||||
@@ -1456,8 +1541,8 @@ These options are part of the **server:** clause.
|
||||
.. note::
|
||||
The interface needs to be already specified with
|
||||
:ref:`interface<unbound.conf.interface>` and that any
|
||||
**access-control\*:** attribute overrides all **interface-\*:**
|
||||
attributes for targeted clients.
|
||||
**access-control\*:** option overrides all **interface-\*:**
|
||||
options for targeted clients.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@interface-view@@: *<ip address or interface name [@port]> <view name>*
|
||||
@@ -1467,8 +1552,8 @@ These options are part of the **server:** clause.
|
||||
.. note::
|
||||
The interface needs to be already specified with
|
||||
:ref:`interface<unbound.conf.interface>` and that any
|
||||
**access-control\*:** attribute overrides all **interface-\*:**
|
||||
attributes for targeted clients.
|
||||
**access-control\*:** option overrides all **interface-\*:**
|
||||
options for targeted clients.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@chroot@@: *<directory>*
|
||||
@@ -1533,7 +1618,7 @@ These options are part of the **server:** clause.
|
||||
[seconds since 1970] unbound[pid:tid]: type: message.
|
||||
|
||||
If this option is given, the :ref:`use-syslog<unbound.conf.use-syslog>`
|
||||
attribute is internally set to ``no``.
|
||||
option is internally set to ``no``.
|
||||
|
||||
The logfile is reopened (for append) when the config file is reread, on
|
||||
SIGHUP.
|
||||
@@ -1632,6 +1717,15 @@ These options are part of the **server:** clause.
|
||||
Default: no
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@log-thread-id@@: *<yes or no>*
|
||||
(Only on Linux and only when threads are available)
|
||||
Logs the system-wide Linux thread ID instead of Unbound's internal thread
|
||||
counter.
|
||||
Can be useful when debugging with system tools.
|
||||
|
||||
Default: no
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@pidfile@@: *<filename>*
|
||||
The process id is written to the file.
|
||||
Default is :file:`"@UNBOUND_PIDFILE@"`.
|
||||
@@ -1657,8 +1751,8 @@ These options are part of the **server:** clause.
|
||||
Default is nothing, using builtin hints for the IN class.
|
||||
The file has the format of zone files, with root nameserver names and
|
||||
addresses only.
|
||||
The default may become outdated, when servers change, therefore it is good
|
||||
practice to use a root hints file.
|
||||
The default may become outdated, when servers change, and then it is
|
||||
possible to use a root hints file with specific servers.
|
||||
|
||||
Default: ""
|
||||
|
||||
@@ -1744,7 +1838,7 @@ These options are part of the **server:** clause.
|
||||
@@UAHL@unbound.conf@harden-short-bufsize@@: *<yes or no>*
|
||||
Very small EDNS buffer sizes from queries are ignored.
|
||||
|
||||
Default: yes (as described in the standard)
|
||||
Default: yes (per :rfc:`6891`)
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@harden-large-queries@@: *<yes or no>*
|
||||
@@ -2306,6 +2400,12 @@ These options are part of the **server:** clause.
|
||||
:ref:`serve-expired-client-timeout<unbound.conf.serve-expired-client-timeout>`
|
||||
is also used then it is RECOMMENDED to use 30 as the value (:rfc:`8767`).
|
||||
|
||||
This value is capped by the original TTL of the record.
|
||||
This means that records with higher original TTL than this value will use
|
||||
this value for expired replies.
|
||||
Records with lower original TTL than this value will use their original TTL
|
||||
for expired replies.
|
||||
|
||||
Default: 30
|
||||
|
||||
|
||||
@@ -2808,7 +2908,7 @@ These options are part of the **server:** clause.
|
||||
Configure local data shorthand for a PTR record with the reversed IPv4 or
|
||||
IPv6 address and the host name.
|
||||
For example ``"192.0.2.4 www.example.com"``.
|
||||
TTL can be inserted like this: ``"2001:DB8::4 7200 www.example.com"``
|
||||
TTL can be inserted like this: ``"2001:db8::4 7200 www.example.com"``
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@local-zone-tag@@: *<zone> <"list of tags">*
|
||||
@@ -2861,7 +2961,7 @@ These options are part of the **server:** clause.
|
||||
:ref:`response-ip<unbound.conf.response-ip>` with action being to redirect
|
||||
as specified by *<"resource record string">*.
|
||||
*<"Resource record string">* is similar to that of
|
||||
:ref:`access-control-tag-action<unbound.conf.access-control-tag-action>`,
|
||||
:ref:`access-control-tag-data<unbound.conf.access-control-tag-data>`,
|
||||
but it must be of either AAAA, A or CNAME types.
|
||||
If the *<IP-netblock>* is an IPv6/IPv4 prefix, the record must be AAAA/A
|
||||
respectively, unless it is a CNAME (which can be used for both versions of
|
||||
@@ -3290,17 +3390,18 @@ These options are part of the **server:** clause.
|
||||
.. _unbound.conf.remote:
|
||||
|
||||
Remote Control Options
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
----------------------
|
||||
|
||||
These options are part of the ``remote-control:`` section and are the
|
||||
declarations for the remote control facility.
|
||||
|
||||
In the **remote-control:** clause are the declarations for the remote control
|
||||
facility.
|
||||
If this is enabled, the :doc:`unbound-control(8)</manpages/unbound-control>`
|
||||
utility can be used to send commands to the running Unbound server.
|
||||
The server uses these clauses to setup TLSv1 security for the connection.
|
||||
The :doc:`unbound-control(8)</manpages/unbound-control>` utility also reads the
|
||||
**remote-control:** section for options.
|
||||
The server uses these options to setup TLS security for the connection.
|
||||
The :doc:`unbound-control(8)</manpages/unbound-control>` utility also reads
|
||||
this ``remote-control:`` section for options.
|
||||
To setup the correct self-signed certificates use the
|
||||
*unbound-control-setup(8)* utility.
|
||||
``unbound-control-setup(8)`` utility.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.remote@control-enable@@: *<yes or no>*
|
||||
@@ -3392,9 +3493,11 @@ To setup the correct self-signed certificates use the
|
||||
.. _unbound.conf.stub:
|
||||
|
||||
Stub Zone Options
|
||||
^^^^^^^^^^^^^^^^^
|
||||
-----------------
|
||||
|
||||
There may be multiple **stub-zone:** clauses.
|
||||
These options are part of the ``stub-zone:`` section.
|
||||
|
||||
There may be multiple ``stub-zone:`` sections.
|
||||
Each with a :ref:`name<unbound.conf.stub.name>` and zero or more hostnames or
|
||||
IP addresses.
|
||||
For the stub zone this list of nameservers is used.
|
||||
@@ -3427,9 +3530,10 @@ Consider adding :ref:`server<unbound.conf.server>` statements for
|
||||
:ref:`domain-insecure<unbound.conf.domain-insecure>` and for
|
||||
:ref:`local-zone: \<name\> nodefault<unbound.conf.local-zone.type.nodefault>`
|
||||
for the zone if it is a locally served zone.
|
||||
The insecure clause stops DNSSEC from invalidating the zone.
|
||||
The :ref:`domain-insecure<unbound.conf.domain-insecure>` option stops DNSSEC
|
||||
from invalidating the zone.
|
||||
The :ref:`local-zone: nodefault<unbound.conf.local-zone.type.nodefault>` (or
|
||||
:ref:`transparent<unbound.conf.local-zone.type.transparent>`) clause makes the
|
||||
:ref:`transparent<unbound.conf.local-zone.type.transparent>`) option makes the
|
||||
(reverse-) zone bypass Unbound's filtering of :rfc:`1918` zones.
|
||||
|
||||
|
||||
@@ -3442,6 +3546,19 @@ The :ref:`local-zone: nodefault<unbound.conf.local-zone.type.nodefault>` (or
|
||||
Name of stub zone nameserver.
|
||||
Is itself resolved before it is used.
|
||||
|
||||
.. caution::
|
||||
If the domain (or a subdomain) from this zone is used as the host, it
|
||||
will unavoidably introduce a circular dependency on retrieving the IP
|
||||
addresses of the name server.
|
||||
In that case, it is suggested to use
|
||||
:ref:`stub-addr<unbound.conf.stub.stub-addr>` instead.
|
||||
Alternatively,
|
||||
:ref:`stub-first: yes<unbound.conf.stub.stub-first>` can also work
|
||||
around the circular dependency by trying resolution outside of this
|
||||
zone.
|
||||
However this has the caveat that it would allow escaping this zone when
|
||||
any resolution attempt fails within this zone.
|
||||
|
||||
To use a non-default port for DNS communication append ``'@'`` with the
|
||||
port number.
|
||||
|
||||
@@ -3479,9 +3596,12 @@ The :ref:`local-zone: nodefault<unbound.conf.local-zone.type.nodefault>` (or
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.stub@stub-first@@: *<yes or no>*
|
||||
If enabled, a query is attempted without the stub clause if it fails.
|
||||
If enabled, a query is attempted without this stub section if it fails.
|
||||
The data could not be retrieved and would have caused SERVFAIL because the
|
||||
servers are unreachable, instead it is tried without this clause.
|
||||
servers are unreachable, instead it is tried without this stub section.
|
||||
This can lead to using less specific configured forward/stub/auth zones if
|
||||
any, or end up to otherwise normal recursive resolution for that particular
|
||||
query.
|
||||
|
||||
Default: no
|
||||
|
||||
@@ -3513,9 +3633,11 @@ The :ref:`local-zone: nodefault<unbound.conf.local-zone.type.nodefault>` (or
|
||||
.. _unbound.conf.forward:
|
||||
|
||||
Forward Zone Options
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
--------------------
|
||||
|
||||
There may be multiple **forward-zone:** clauses.
|
||||
These options are part of the ``forward-zone:`` section.
|
||||
|
||||
There may be multiple ``forward-zone:`` sections.
|
||||
Each with a :ref:`name<unbound.conf.forward.name>` and zero or more hostnames
|
||||
or IP addresses.
|
||||
For the forward zone this list of nameservers is used to forward the queries
|
||||
@@ -3545,6 +3667,19 @@ cache).
|
||||
Name of server to forward to.
|
||||
Is itself resolved before it is used.
|
||||
|
||||
.. caution::
|
||||
If the domain (or a subdomain) from this zone is used as the host, it
|
||||
will unavoidably introduce a circular dependency on retrieving the IP
|
||||
addresses of the name server.
|
||||
In that case, it is suggested to use
|
||||
:ref:`forward-addr<unbound.conf.forward.forward-addr>` instead.
|
||||
Alternatively,
|
||||
:ref:`forward-first: yes<unbound.conf.forward.forward-first>` can also
|
||||
work around the circular dependency by trying resolution outside of
|
||||
this zone.
|
||||
However this has the caveat that it would allow escaping this zone when
|
||||
any resolution attempt fails within this zone.
|
||||
|
||||
To use a non-default port for DNS communication append ``'@'`` with the
|
||||
port number.
|
||||
|
||||
@@ -3579,9 +3714,11 @@ cache).
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.forward@forward-first@@: *<yes or no>*
|
||||
If a forwarded query is met with a SERVFAIL error, and this option is
|
||||
enabled, Unbound will fall back to normal recursive resolution for this
|
||||
query as if no query forwarding had been specified.
|
||||
If a forwarded query is met with a SERVFAIL error and this option is
|
||||
enabled Unbound will fall back to less specific resolution.
|
||||
This can lead to using less specific configured forward/stub/auth zones if
|
||||
any, or end up to otherwise normal recursive resolution for that particular
|
||||
query.
|
||||
|
||||
Default: no
|
||||
|
||||
@@ -3618,12 +3755,14 @@ cache).
|
||||
.. _unbound.conf.auth:
|
||||
|
||||
Authority Zone Options
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
----------------------
|
||||
|
||||
Authority zones are configured with **auth-zone:**, and each one must have a
|
||||
These options are part of the ``auth-zone:`` section.
|
||||
|
||||
Authority zones are configured with ``auth-zone:``, and each one must have a
|
||||
:ref:`name<unbound.conf.auth.name>`.
|
||||
There can be multiple ones, by listing multiple auth-zone clauses, each with a
|
||||
different name, pertaining to that part of the namespace.
|
||||
There can be multiple ones, by listing multiple ``auth-zone`` section clauses,
|
||||
each with a different name, pertaining to that part of the namespace.
|
||||
The authority zone with the name closest to the name looked up is used.
|
||||
Authority zones can be processed on two distinct, non-exclusive, configurable
|
||||
stages.
|
||||
@@ -3654,7 +3793,7 @@ consult the local zone data while resolving.
|
||||
In this case, the aforementioned CNAME example will result in a thoroughly
|
||||
resolved answer.
|
||||
|
||||
Authority zones can be read from zonefile.
|
||||
Authority zones can be read from a zonefile.
|
||||
And can be kept updated via AXFR and IXFR.
|
||||
After update the zonefile is rewritten.
|
||||
The update mechanism uses the SOA timer values and performs SOA UDP queries to
|
||||
@@ -3690,9 +3829,11 @@ fallback activates to fetch from the upstream instead of the SERVFAIL.
|
||||
:ref:`url<unbound.conf.auth.url>` to download the zonefile as a text file
|
||||
from a webserver that would work.
|
||||
|
||||
If you specify the hostname, you cannot use the domain from the zonefile,
|
||||
because it may not have that when retrieving that data, instead use a plain
|
||||
IP address to avoid a circular dependency on retrieving that IP address.
|
||||
.. caution::
|
||||
If you specify the hostname, you cannot use the domain from the
|
||||
zonefile, because it may not have that when retrieving that data,
|
||||
instead use a plain IP address to avoid a circular dependency on
|
||||
retrieving that IP address.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.auth@master@@: *<IP address or host name>*
|
||||
@@ -3823,18 +3964,20 @@ fallback activates to fetch from the upstream instead of the SERVFAIL.
|
||||
.. _unbound.conf.view:
|
||||
|
||||
View Options
|
||||
^^^^^^^^^^^^
|
||||
------------
|
||||
|
||||
There may be multiple **view:** clauses.
|
||||
These options are part of the ``view:`` section.
|
||||
|
||||
There may be multiple ``view:`` sections.
|
||||
Each with a :ref:`name<unbound.conf.view.name>` and zero or more
|
||||
:ref:`local-zone<unbound.conf.view.local-zone>` and
|
||||
:ref:`local-data<unbound.conf.view.local-data>` attributes.
|
||||
:ref:`local-data<unbound.conf.view.local-data>` options.
|
||||
Views can also contain :ref:`view-first<unbound.conf.view.view-first>`,
|
||||
:ref:`response-ip<unbound.conf.response-ip>`,
|
||||
:ref:`response-ip-data<unbound.conf.response-ip-data>` and
|
||||
:ref:`local-data-ptr<unbound.conf.view.local-data-ptr>` attributes.
|
||||
:ref:`local-data-ptr<unbound.conf.view.local-data-ptr>` options.
|
||||
View can be mapped to requests by specifying the view name in an
|
||||
:ref:`access-control-view<unbound.conf.access-control-view>` attribute.
|
||||
:ref:`access-control-view<unbound.conf.access-control-view>` option.
|
||||
Options from matching views will override global options.
|
||||
Global options will be used if no matching view is found, or when the matching
|
||||
view does not have the option specified.
|
||||
@@ -3844,7 +3987,7 @@ view does not have the option specified.
|
||||
Name of the view.
|
||||
Must be unique.
|
||||
This name is used in the
|
||||
:ref:`access-control-view<unbound.conf.access-control-view>` attribute.
|
||||
:ref:`access-control-view<unbound.conf.access-control-view>` option.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.view@local-zone@@: *<zone> <type>*
|
||||
@@ -3873,6 +4016,20 @@ view does not have the option specified.
|
||||
:ref:`local-data-ptr<unbound.conf.local-data-ptr>` elements.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.view@response-ip@@: *<IP-netblock> <action>*
|
||||
This requires use of the ``respip`` module.
|
||||
|
||||
Similar to :ref:`response-ip<unbound.conf.response-ip>` but
|
||||
only applies to this view.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.view@response-ip-data@@: *<IP-netblock> <"resource record string">*
|
||||
This requires use of the ``respip`` module.
|
||||
|
||||
Similar to :ref:`response-ip-data<unbound.conf.response-ip-data>` but
|
||||
only applies to this view.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.view@view-first@@: *<yes or no>*
|
||||
If enabled, it attempts to use the global
|
||||
:ref:`local-zone<unbound.conf.local-zone>` and
|
||||
@@ -3881,10 +4038,14 @@ view does not have the option specified.
|
||||
|
||||
Default: no
|
||||
|
||||
Python Module Options
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
.. _unbound.conf.python:
|
||||
|
||||
The **python:** clause gives the settings for the *python(1)* script module.
|
||||
Python Module Options
|
||||
---------------------
|
||||
|
||||
These options are part of the ``python:`` section.
|
||||
|
||||
The ``python:`` section gives the settings for the *python(1)* script module.
|
||||
This module acts like the iterator and validator modules do, on queries and
|
||||
answers.
|
||||
To enable the script module it has to be compiled into the daemon, and the word
|
||||
@@ -3907,15 +4068,19 @@ path to the working directory.
|
||||
Repeat this option for every python module instance added to the
|
||||
:ref:`module-config<unbound.conf.module-config>` option.
|
||||
|
||||
Dynamic Library Module Options
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
.. _unbound.conf.dynlib:
|
||||
|
||||
The **dynlib:** clause gives the settings for the ``dynlib`` module.
|
||||
Dynamic Library Module Options
|
||||
------------------------------
|
||||
|
||||
These options are part of the ``dynlib:`` section.
|
||||
|
||||
The ``dynlib:`` section gives the settings for the ``dynlib`` module.
|
||||
This module is only a very small wrapper that allows dynamic modules to be
|
||||
loaded on runtime instead of being compiled into the application.
|
||||
To enable the dynlib module it has to be compiled into the daemon, and the word
|
||||
``dynlib`` has to be put in the
|
||||
:ref:`module-config<unbound.conf.module-config>` attribute.
|
||||
:ref:`module-config<unbound.conf.module-config>` option.
|
||||
Multiple instances of dynamic libraries are supported by adding the word
|
||||
``dynlib`` more than once.
|
||||
|
||||
@@ -3931,7 +4096,9 @@ directory.
|
||||
:ref:`module-config<unbound.conf.module-config>` option.
|
||||
|
||||
DNS64 Module Options
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
--------------------
|
||||
|
||||
These options are part of the ``server:`` section.
|
||||
|
||||
The ``dns64`` module must be configured in the
|
||||
:ref:`module-config<unbound.conf.module-config>` directive, e.g.:
|
||||
@@ -3943,7 +4110,11 @@ The ``dns64`` module must be configured in the
|
||||
and be compiled into the daemon to be enabled.
|
||||
|
||||
.. note::
|
||||
These settings go in the :ref:`server:<unbound.conf.server>` section.
|
||||
If combining the ``respip`` and ``dns64`` modules, the ``respip`` module
|
||||
needs to appear before the ``dns64`` module in the
|
||||
:ref:`module-config<unbound.conf.module-config>`
|
||||
configuration option so that response IP and/or RPZ feeds can properly
|
||||
filter responses regardless of DNS64 synthesis.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.dns64@dns64-prefix@@: *<IPv6 prefix>*
|
||||
@@ -3969,13 +4140,13 @@ and be compiled into the daemon to be enabled.
|
||||
per line.
|
||||
Applies also to names underneath the name given.
|
||||
|
||||
NAT64 Operation
|
||||
^^^^^^^^^^^^^^^
|
||||
NAT64 Options
|
||||
-------------
|
||||
|
||||
These options are part of the ``server:`` section.
|
||||
|
||||
NAT64 operation allows using a NAT64 prefix for outbound requests to IPv4-only
|
||||
servers.
|
||||
It is controlled by two options in the
|
||||
:ref:`server:<unbound.conf.server>` section:
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.nat64@do-nat64@@: *<yes or no>*
|
||||
@@ -3992,10 +4163,14 @@ It is controlled by two options in the
|
||||
|
||||
Default: 64:ff9b::/96 (same as :ref:`dns64-prefix<unbound.conf.dns64.dns64-prefix>`)
|
||||
|
||||
DNSCrypt Options
|
||||
^^^^^^^^^^^^^^^^
|
||||
.. _unbound.conf.dnscrypt:
|
||||
|
||||
The **dnscrypt:** clause gives the settings of the dnscrypt channel.
|
||||
DNSCrypt Options
|
||||
----------------
|
||||
|
||||
These options are part of the ``dnscrypt:`` section.
|
||||
|
||||
The ``dnscrypt:`` section gives the settings of the dnscrypt channel.
|
||||
While those options are available, they are only meaningful if Unbound was
|
||||
compiled with ``--enable-dnscrypt``.
|
||||
Currently certificate and secret/public keys cannot be generated by Unbound.
|
||||
@@ -4102,7 +4277,9 @@ https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage
|
||||
Default: (unconfigured)
|
||||
|
||||
EDNS Client Subnet Module Options
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
---------------------------------
|
||||
|
||||
These options are part of the ``server:`` section.
|
||||
|
||||
The ECS module must be configured in the
|
||||
:ref:`module-config<unbound.conf.module-config>` directive, e.g.:
|
||||
@@ -4113,9 +4290,6 @@ The ECS module must be configured in the
|
||||
|
||||
and be compiled into the daemon to be enabled.
|
||||
|
||||
.. note::
|
||||
These settings go in the :ref:`server:<unbound.conf.server>` section.
|
||||
|
||||
If the destination address is allowed in the configuration Unbound will add the
|
||||
EDNS0 option to the query containing the relevant part of the client's address.
|
||||
When an answer contains the ECS option the response and the option are placed
|
||||
@@ -4230,7 +4404,9 @@ This module does not interact with the
|
||||
Default: 100
|
||||
|
||||
Opportunistic IPsec Support Module Options
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
------------------------------------------
|
||||
|
||||
These options are part of the ``server:`` section.
|
||||
|
||||
The IPsec module must be configured in the
|
||||
:ref:`module-config<unbound.conf.module-config>` directive, e.g.:
|
||||
@@ -4241,9 +4417,6 @@ The IPsec module must be configured in the
|
||||
|
||||
and be compiled into Unbound by using ``--enable-ipsecmod`` to be enabled.
|
||||
|
||||
.. note::
|
||||
These settings go in the :ref:`server:<unbound.conf.server>` section.
|
||||
|
||||
When Unbound receives an A/AAAA query that is not in the cache and finds a
|
||||
valid answer, it will withhold returning the answer and instead will generate
|
||||
an IPSECKEY subquery for the same domain name.
|
||||
@@ -4333,8 +4506,12 @@ answer given from cache is still relevant for opportunistic IPsec.
|
||||
@@UAHL@unbound.conf@ipsecmod-whitelist@@: *<domain>*
|
||||
Alternate syntax for :ref:`ipsecmod-allow<unbound.conf.ipsecmod-allow>`.
|
||||
|
||||
.. _unbound.conf.cachedb:
|
||||
|
||||
Cache DB Module Options
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
-----------------------
|
||||
|
||||
These options are part of the ``cachedb:`` section.
|
||||
|
||||
The Cache DB module must be configured in the
|
||||
:ref:`module-config<unbound.conf.module-config>` directive, e.g.:
|
||||
@@ -4386,7 +4563,7 @@ If connection close or timeout happens too often, Unbound will be effectively
|
||||
unusable with this backend.
|
||||
It's the administrator's responsibility to make the assumption hold.
|
||||
|
||||
The **cachedb:** clause gives custom settings of the cache DB module.
|
||||
The ``cachedb:`` section gives custom settings of the cache DB module.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.cachedb@backend@@: *<backend name>*
|
||||
@@ -4434,7 +4611,7 @@ The **cachedb:** clause gives custom settings of the cache DB module.
|
||||
|
||||
Default: yes
|
||||
|
||||
The following **cachedb:** options are specific to the ``redis`` backend.
|
||||
The following ``cachedb:`` options are specific to the ``redis`` backend.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.cachedb@redis-server-host@@: *<server address or name>*
|
||||
@@ -4593,11 +4770,14 @@ The following **cachedb:** options are specific to the ``redis`` backend.
|
||||
|
||||
.. _unbound.conf.dnstap:
|
||||
|
||||
DNSTAP Logging Options
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
DNSTAP Options
|
||||
--------------
|
||||
|
||||
DNSTAP support, when compiled in by using ``--enable-dnstap``, is enabled in
|
||||
the **dnstap:** section.
|
||||
These options are part of the ``dnstap:`` section.
|
||||
|
||||
DNSTAP is a flexible, structured binary log format for DNS software.
|
||||
When compiled in by using ``--enable-dnstap``, it can be enabled in the
|
||||
``dnstap:`` section.
|
||||
This starts an extra thread (when compiled with threading) that writes the log
|
||||
information to the destination.
|
||||
If Unbound is compiled without threading it does not spawn a thread, but
|
||||
@@ -4747,15 +4927,18 @@ connects per-process to the destination.
|
||||
.. _unbound.conf.rpz:
|
||||
|
||||
Response Policy Zone Options
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
----------------------------
|
||||
|
||||
Response Policy Zones are configured with **rpz:**, and each one must have a
|
||||
:ref:`name<unbound.conf.rpz.name>` attribute.
|
||||
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.
|
||||
These options are part of the ``rpz:`` section.
|
||||
|
||||
Response Policy Zones are configured with ``rpz:`` section clauses, and each
|
||||
one must have a :ref:`name<unbound.conf.rpz.name>` option.
|
||||
There can be multiple ones, by listing multiple ``rpz:`` section clauses, each
|
||||
with a different name.
|
||||
RPZ sections 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 respip module needs to be added to the
|
||||
:ref:`module-config<unbound.conf.module-config>`, e.g.:
|
||||
|
||||
@@ -4763,6 +4946,13 @@ The respip module needs to be added to the
|
||||
|
||||
module-config: "respip validator iterator"
|
||||
|
||||
.. note::
|
||||
If combining the ``respip`` and ``dns64`` modules, the ``respip`` module
|
||||
needs to appear before the ``dns64`` module in the
|
||||
:ref:`module-config<unbound.conf.module-config>`
|
||||
configuration option so that response IP and/or RPZ feeds can properly
|
||||
filter responses regardless of DNS64 synthesis.
|
||||
|
||||
QNAME, Response IP Address, nsdname, nsip and clientip triggers are supported.
|
||||
Supported actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp-only
|
||||
and drop.
|
||||
@@ -4814,9 +5004,6 @@ The actions are specified with the record on the right
|
||||
Other records like AAAA, TXT and other CNAMEs (not rpz-..) can also be used to
|
||||
answer queries with that content.
|
||||
|
||||
The RPZ zones can be configured in the config file with these settings in the
|
||||
**rpz:** block.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.rpz@name@@: *<zone name>*
|
||||
Name of the authority zone.
|
||||
@@ -4932,7 +5119,7 @@ The RPZ zones can be configured in the config file with these settings in the
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.rpz@tags@@: *"<list of tags>"*
|
||||
Limit the policies from this RPZ clause to clients with a matching tag.
|
||||
Limit the policies from this RPZ section to clients with a matching tag.
|
||||
|
||||
Tags need to be defined in :ref:`define-tag<unbound.conf.define-tag>` and
|
||||
can be assigned to client addresses using
|
||||
@@ -4940,7 +5127,7 @@ The RPZ zones can be configured in the config file with these settings in the
|
||||
:ref:`interface-tag<unbound.conf.interface-tag>`.
|
||||
Enclose list of tags in quotes (``""``) and put spaces between tags.
|
||||
|
||||
If no tags are specified the policies from this clause will be applied for
|
||||
If no tags are specified the policies from this section will be applied for
|
||||
all clients.
|
||||
|
||||
Memory Control Example
|
||||
|
||||
@@ -1007,6 +1007,7 @@ EXCLUDE = ./build \
|
||||
libunbound/python/doc \
|
||||
libunbound/python/examples \
|
||||
./ldns-src \
|
||||
./simdzone \
|
||||
README.md \
|
||||
doc/control_proto_spec.txt \
|
||||
doc/requirements.txt
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ unbound(8)
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
**unbound** [``-hdpv``] [``-c <cfgfile>``]
|
||||
**unbound** [``-hdpVv``] [``-c <cfgfile>``]
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
+12
-4
@@ -162,8 +162,15 @@ int ecs_whitelist_check(struct query_info* qinfo,
|
||||
if(!ecs_is_whitelisted(sn_env->whitelist,
|
||||
addr, addrlen, qinfo->qname, qinfo->qname_len,
|
||||
qinfo->qclass)) {
|
||||
verbose(VERB_ALGO, "subnet store subquery global, name and addr have no subnet treatment.");
|
||||
qstate->no_cache_store = 0;
|
||||
/* The stub or forward can have no_cache set.*/
|
||||
if(iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0)) {
|
||||
verbose(VERB_ALGO, "subnet subquery is not stored globally, stuborfwd is no_cache");
|
||||
} else {
|
||||
verbose(VERB_ALGO, "subnet store subquery global, name and addr have no subnet treatment.%s",
|
||||
(sq->started_no_cache_store?
|
||||
" But the subnet module was started with no_cache_store for the super query, and that is still applied to this query":""));
|
||||
qstate->no_cache_store = sq->started_no_cache_store;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@@ -567,8 +574,8 @@ generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate*
|
||||
}
|
||||
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec,
|
||||
&subq)) {
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinf, qstate->client_info,
|
||||
qflags, prime, valrec, &subq)) {
|
||||
return 0;
|
||||
}
|
||||
if(subq) {
|
||||
@@ -580,6 +587,7 @@ generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate*
|
||||
}
|
||||
subsq = (struct subnet_qstate*)subq->minfo[id];
|
||||
subsq->is_subquery_nonsubnet = 1;
|
||||
subsq->started_no_cache_store = sq->started_no_cache_store;
|
||||
|
||||
/* When the client asks 0.0.0.0/0 and the name is not treated
|
||||
* as subnet, it is to be stored in the global cache.
|
||||
|
||||
-501
@@ -1,501 +0,0 @@
|
||||
#!/usr/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2013-12-25.23; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# 'make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
tab=' '
|
||||
nl='
|
||||
'
|
||||
IFS=" $tab$nl"
|
||||
|
||||
# Set DOITPROG to "echo" to test this script.
|
||||
|
||||
doit=${DOITPROG-}
|
||||
doit_exec=${doit:-exec}
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
is_target_a_directory=possibly
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t)
|
||||
is_target_a_directory=always
|
||||
dst_arg=$2
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-T) is_target_a_directory=never;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# We allow the use of options -d and -T together, by making -d
|
||||
# take the precedence; this is for compatibility with GNU install.
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
if test -n "$dst_arg"; then
|
||||
echo "$0: target directory not allowed when installing a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call 'install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
if test $# -gt 1 || test "$is_target_a_directory" = always; then
|
||||
if test ! -d "$dst_arg"; then
|
||||
echo "$0: $dst_arg: Is not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $src in
|
||||
-* | [=\(\)!]) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst_arg
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test "$is_target_a_directory" = never; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dst=$dstdir/`basename "$src"`
|
||||
dstdir_status=0
|
||||
else
|
||||
dstdir=`dirname "$dst"`
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
if (umask $mkdir_umask &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/d" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
[-=\(\)!]*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test X"$d" = X && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
set +f &&
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
+1
-1
@@ -163,7 +163,7 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name,
|
||||
}
|
||||
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
if(!(*qstate->env->attach_sub)(qstate, &ask,
|
||||
if(!(*qstate->env->attach_sub)(qstate, &ask, NULL,
|
||||
(uint16_t)(BIT_RD|flags), 0, 0, &newq)){
|
||||
log_err("Could not generate request: out of memory");
|
||||
return 0;
|
||||
|
||||
@@ -228,6 +228,11 @@ read_fwds_host(struct config_stub* s, struct delegpt* dp)
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(dname_subdomain_c(dname, dp->name)) {
|
||||
log_warn("forward-host '%s' may have a circular "
|
||||
"dependency on forward-zone '%s'",
|
||||
p->str, s->name);
|
||||
}
|
||||
#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
|
||||
if(tls_auth_name)
|
||||
log_err("no name verification functionality in "
|
||||
|
||||
@@ -231,6 +231,11 @@ read_stubs_host(struct config_stub* s, struct delegpt* dp)
|
||||
s->name, p->str);
|
||||
return 0;
|
||||
}
|
||||
if(dname_subdomain_c(dname, dp->name)) {
|
||||
log_warn("stub-host '%s' may have a circular "
|
||||
"dependency on stub-zone '%s'",
|
||||
p->str, s->name);
|
||||
}
|
||||
#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
|
||||
if(tls_auth_name)
|
||||
log_err("no name verification functionality in "
|
||||
|
||||
+17
-1
@@ -253,7 +253,9 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** filter out unsuitable targets
|
||||
/** filter out unsuitable targets.
|
||||
* Applies NAT64 if needed as well by replacing the IPv4 with the synthesized
|
||||
* IPv6 address.
|
||||
* @param iter_env: iterator environment with ipv6-support flag.
|
||||
* @param env: module environment with infra cache.
|
||||
* @param name: zone name
|
||||
@@ -317,6 +319,20 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
!addr_is_ip6(&a->addr, a->addrlen)) {
|
||||
return -1; /* there is no ip4 available */
|
||||
}
|
||||
if(iter_env->nat64.use_nat64 && !addr_is_ip6(&a->addr, a->addrlen)) {
|
||||
struct sockaddr_storage real_addr;
|
||||
socklen_t real_addrlen;
|
||||
addr_to_nat64(&a->addr, &iter_env->nat64.nat64_prefix_addr,
|
||||
iter_env->nat64.nat64_prefix_addrlen,
|
||||
iter_env->nat64.nat64_prefix_net,
|
||||
&real_addr, &real_addrlen);
|
||||
log_name_addr(VERB_QUERY, "NAT64 apply: from: ",
|
||||
name, &a->addr, a->addrlen);
|
||||
log_name_addr(VERB_QUERY, "NAT64 apply: to: ",
|
||||
name, &real_addr, real_addrlen);
|
||||
a->addr = real_addr;
|
||||
a->addrlen = real_addrlen;
|
||||
}
|
||||
/* check lameness - need zone , class info */
|
||||
if(infra_get_lame_rtt(env->infra_cache, &a->addr, a->addrlen,
|
||||
name, namelen, qtype, &lame, &dnsseclame, &reclame,
|
||||
|
||||
@@ -84,6 +84,7 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
|
||||
/**
|
||||
* Select a valid, nice target to send query to.
|
||||
* Sorting and removing unsuitable targets is combined.
|
||||
* Adds records to the infra cache if not already there.
|
||||
*
|
||||
* @param iter_env: iterator module global state, with ip6 enabled and
|
||||
* do-not-query-addresses.
|
||||
|
||||
+7
-20
@@ -829,7 +829,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
struct mesh_state* sub = NULL;
|
||||
fptr_ok(fptr_whitelist_modenv_add_sub(
|
||||
qstate->env->add_sub));
|
||||
if(!(*qstate->env->add_sub)(qstate, &qinf,
|
||||
if(!(*qstate->env->add_sub)(qstate, &qinf, NULL,
|
||||
qflags, prime, valrec, &subq, &sub)){
|
||||
return 0;
|
||||
}
|
||||
@@ -838,8 +838,8 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
/* attach subquery, lookup existing or make a new one */
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(
|
||||
qstate->env->attach_sub));
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime,
|
||||
valrec, &subq)) {
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinf, NULL, qflags,
|
||||
prime, valrec, &subq)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -2436,8 +2436,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
int tf_policy;
|
||||
struct delegpt_addr* target;
|
||||
struct outbound_entry* outq;
|
||||
struct sockaddr_storage real_addr;
|
||||
socklen_t real_addrlen;
|
||||
int auth_fallback = 0;
|
||||
uint8_t* qout_orig = NULL;
|
||||
size_t qout_orig_len = 0;
|
||||
@@ -3060,17 +3058,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->dnssec_lame_query?" but lame_query anyway": "");
|
||||
}
|
||||
|
||||
real_addr = target->addr;
|
||||
real_addrlen = target->addrlen;
|
||||
|
||||
if(ie->nat64.use_nat64 && target->addr.ss_family == AF_INET) {
|
||||
addr_to_nat64(&target->addr, &ie->nat64.nat64_prefix_addr,
|
||||
ie->nat64.nat64_prefix_addrlen, ie->nat64.nat64_prefix_net,
|
||||
&real_addr, &real_addrlen);
|
||||
log_name_addr(VERB_QUERY, "applied NAT64:",
|
||||
iq->dp->name, &real_addr, real_addrlen);
|
||||
}
|
||||
|
||||
fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
|
||||
outq = (*qstate->env->send_query)(&iq->qinfo_out,
|
||||
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0),
|
||||
@@ -3082,7 +3069,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
!qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env,
|
||||
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
|
||||
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
|
||||
ie, iq), sq_check_ratelimit, &real_addr, real_addrlen,
|
||||
ie, iq), sq_check_ratelimit, &target->addr, target->addrlen,
|
||||
iq->dp->name, iq->dp->namelen,
|
||||
(iq->dp->tcp_upstream || qstate->env->cfg->tcp_upstream),
|
||||
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
|
||||
@@ -3099,7 +3086,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
log_addr(VERB_QUERY, "error sending query to auth server",
|
||||
&real_addr, real_addrlen);
|
||||
&target->addr, target->addrlen);
|
||||
if(qstate->env->cfg->qname_minimisation)
|
||||
iq->minimisation_state = SKIP_MINIMISE_STATE;
|
||||
return next_state(iq, QUERYTARGETS_STATE);
|
||||
@@ -3616,7 +3603,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return next_state(iq, INIT_REQUEST_STATE);
|
||||
} else if(type == RESPONSE_TYPE_LAME) {
|
||||
/* Cache the LAMEness. */
|
||||
verbose(VERB_DETAIL, "query response was %sLAME",
|
||||
verbose(VERB_DETAIL, "query response was categorized as %sLAME",
|
||||
dnsseclame?"DNSSEC ":"");
|
||||
if(!dname_subdomain_c(iq->qchase.qname, iq->dp->name)) {
|
||||
log_err("mark lame: mismatch in qname and dpname");
|
||||
@@ -3655,7 +3642,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* In this case, the event is just sent directly back to
|
||||
* the QUERYTARGETS_STATE without resetting anything,
|
||||
* because, clearly, the next target must be tried. */
|
||||
verbose(VERB_DETAIL, "query response was THROWAWAY");
|
||||
verbose(VERB_DETAIL, "query response was categorized as THROWAWAY");
|
||||
} else {
|
||||
log_warn("A query response came back with an unknown type: %d",
|
||||
(int)type);
|
||||
|
||||
@@ -1385,7 +1385,7 @@ int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name,
|
||||
return UB_NOERROR;
|
||||
}
|
||||
if(!local_zones_add_zone(ctx->local_zones, nm, nmlen, nmlabs,
|
||||
LDNS_RR_CLASS_IN, t)) {
|
||||
LDNS_RR_CLASS_IN, t, NULL)) {
|
||||
lock_rw_unlock(&ctx->local_zones->lock);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
|
||||
@@ -853,7 +853,7 @@ Result: ['74.125.43.147', '74.125.43.99', '74.125.43.103', '74.125.43.104']
|
||||
%{
|
||||
//printf("resolve_start(%lX)\n",(long unsigned int)arg1);
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
$function
|
||||
$action
|
||||
Py_END_ALLOW_THREADS
|
||||
//printf("resolve_stop()\n");
|
||||
%}
|
||||
|
||||
@@ -853,6 +853,8 @@ struct ub_server_stats {
|
||||
long long qquic;
|
||||
/** number of queries removed due to discard-timeout */
|
||||
long long num_queries_discard_timeout;
|
||||
/** number of queries removed due to replyaddr limit */
|
||||
long long num_queries_replyaddr_limit;
|
||||
/** number of queries removed due to wait-limit */
|
||||
long long num_queries_wait_limit;
|
||||
/** number of dns error reports generated */
|
||||
@@ -872,6 +874,8 @@ struct ub_stats_info {
|
||||
long long mesh_num_states;
|
||||
/** mesh stats: current number of reply (user) states */
|
||||
long long mesh_num_reply_states;
|
||||
/** mesh stats: current number of reply entries */
|
||||
long long mesh_num_reply_addrs;
|
||||
/** mesh stats: number of reply states overwritten with a new one */
|
||||
long long mesh_jostled;
|
||||
/** mesh stats: number of incoming queries dropped */
|
||||
|
||||
+35
-10
@@ -142,7 +142,7 @@ check_git_repo () {
|
||||
create_temp_dir () {
|
||||
# Creating temp directory
|
||||
info "Creating temporary working directory"
|
||||
temp_dir=`mktemp -d unbound-dist-XXXXXX`
|
||||
temp_dir=`mktemp -t -d unbound-dist-XXXXXX`
|
||||
info "Directory '$temp_dir' created."
|
||||
cd $temp_dir
|
||||
}
|
||||
@@ -409,7 +409,14 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
info "git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound"
|
||||
git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound || error_cleanup "git clone failed"
|
||||
cd unbound || error_cleanup "Unbound not exported correctly from git"
|
||||
rm -rf .git .travis.yml .gitattributes .github .gitignore || error_cleanup "Failed to remove .git tracking and ci information"
|
||||
git submodule update --init || error_cleanup "Could not fetch submodule"
|
||||
rm -rf .git .travis.yml .gitattributes .gitmodules .github .gitignore || error_cleanup "Failed to remove .git tracking and ci information"
|
||||
rm -rf simdzone/.git simdzone/.github simdzone/.gitignore \
|
||||
simdzone/configure~ simdzone/config.h.in~ simdzone/autom4te.cache \
|
||||
simdzone/cmake simdzone/CMakeLists.txt simdzone/simdzoneConfig.cmake.in \
|
||||
simdzone/conanfile.txt simdzone/tests simdzone/.readthedocs.yaml \
|
||||
simdzone/doc simdzone/scripts || \
|
||||
error_cleanup "Failed to remove simdzone .git tracking and ci information"
|
||||
|
||||
# on a re-configure the cache may no longer be valid...
|
||||
if test -f mingw32-config.cache; then rm mingw32-config.cache; fi
|
||||
@@ -436,10 +443,14 @@ if [ "$DOWIN" = "yes" ]; then
|
||||
replace_version "configure.ac" "$version" "$version2"
|
||||
version="$version2"
|
||||
info "Rebuilding configure script (autoconf) snapshot."
|
||||
autoconf -f || error_cleanup "Autoconf failed."
|
||||
autoreconf -fi || error_cleanup "Autoconf failed."
|
||||
autoheader -f || error_cleanup "Autoheader failed."
|
||||
rm -r autom4te* || echo "ignored"
|
||||
rm -f config.h.in~ || echo "ignore absence of config.h.in~ file."
|
||||
rm -f configure~ || echo "ignore absence of configure~ file."
|
||||
rm -r simdzone/autom4te* || echo "ignored"
|
||||
rm -f simdzone/config.h.in~ || echo "ignore absence of simdzone/config.h.in~ file."
|
||||
rm -f simdzone/configure~ || echo "ignore absence of simdzone/configure~ file."
|
||||
fi
|
||||
|
||||
if test "`uname`" = "Linux"; then
|
||||
@@ -597,7 +608,15 @@ info "git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound"
|
||||
git clone --depth=1 --no-tags -b $GITBRANCH $GITREPO unbound || error_cleanup "git clone failed"
|
||||
|
||||
cd unbound || error_cleanup "Unbound not exported correctly from git"
|
||||
rm -rf .git .travis.yml .gitattributes .github .gitignore || error_cleanup "Failed to remove .git tracking and ci information"
|
||||
git submodule update --init || error_cleanup "Could not fetch submodule"
|
||||
rm -rf .git .travis.yml .gitattributes .gitmodules .github .gitignore || error_cleanup "Failed to remove .git tracking and ci information"
|
||||
rm -rf simdzone/.git simdzone/.github simdzone/.gitignore \
|
||||
simdzone/configure~ simdzone/config.h.in~ simdzone/autom4te.cache \
|
||||
simdzone/cmake simdzone/CMakeLists.txt simdzone/simdzoneConfig.cmake.in \
|
||||
simdzone/conanfile.txt simdzone/tests simdzone/.readthedocs.yaml \
|
||||
simdzone/doc simdzone/scripts || \
|
||||
error_cleanup "Failed to remove simdzone .git tracking and ci information"
|
||||
|
||||
|
||||
info "Adding libtool utils (libtoolize)."
|
||||
libtoolize -c --install || libtoolize -c || error_cleanup "Libtoolize failed."
|
||||
@@ -617,10 +636,14 @@ if [ `uname -s | grep -i -c darwin` -ne 0 ]; then
|
||||
fi
|
||||
|
||||
info "Building configure script (autoreconf)."
|
||||
autoreconf -f || error_cleanup "Autoconf failed."
|
||||
autoreconf -fi || error_cleanup "Autoconf failed."
|
||||
|
||||
rm -r autom4te* || error_cleanup "Failed to remove autoconf cache directory."
|
||||
rm -f config.h.in~ || echo "ignore absence of config.h.in~ file."
|
||||
rm -f configure~ || echo "ignore absence of configure~ file."
|
||||
rm -r simdzone/autom4te* || echo "ignored"
|
||||
rm -f simdzone/config.h.in~ || echo "ignore absence of simdzone/config.h.in~ file."
|
||||
rm -f simdzone/configure~ || echo "ignore absence of simdzone/configure~ file."
|
||||
|
||||
info "Building lexer and parser."
|
||||
echo "#include \"config.h\"" > util/configlexer.c || error_cleanup "Failed to create configlexer"
|
||||
@@ -663,9 +686,13 @@ fi
|
||||
|
||||
if [ "$RECONFIGURE" = "yes" ]; then
|
||||
info "Rebuilding configure script (autoconf) snapshot."
|
||||
autoreconf -f || error_cleanup "Autoconf failed."
|
||||
autoreconf -fi || error_cleanup "Autoconf failed."
|
||||
rm -r autom4te* || error_cleanup "Failed to remove autoconf cache directory."
|
||||
rm -f config.h.in~ || echo "ignore absence of config.h.in~ file."
|
||||
rm -f configure~ || echo "ignore absence of configure~ file."
|
||||
rm -r simdzone/autom4te* || echo "ignored"
|
||||
rm -f simdzone/config.h.in~ || echo "ignore absence of simdzone/config.h.in~ file."
|
||||
rm -f simdzone/configure~ || echo "ignore absence of simdzone/configure~ file."
|
||||
fi
|
||||
|
||||
replace_all doc/README
|
||||
@@ -682,7 +709,7 @@ info "Renaming Unbound directory to unbound-$version."
|
||||
cd ..
|
||||
mv unbound unbound-$version || error_cleanup "Failed to rename unbound directory."
|
||||
|
||||
tarfile="../unbound-$version.tar.gz"
|
||||
tarfile="$cwd/unbound-$version.tar.gz"
|
||||
|
||||
if [ -f $tarfile ]; then
|
||||
(question "The file $tarfile already exists. Overwrite?" \
|
||||
@@ -690,14 +717,12 @@ if [ -f $tarfile ]; then
|
||||
fi
|
||||
|
||||
info "Creating tar unbound-$version.tar.gz"
|
||||
tar czf ../unbound-$version.tar.gz unbound-$version || error_cleanup "Failed to create tar file."
|
||||
tar czf $tarfile unbound-$version || error_cleanup "Failed to create tar file."
|
||||
|
||||
cleanup
|
||||
|
||||
storehash unbound-$version.tar.gz
|
||||
echo "create unbound-$version.tar.gz.asc with:"
|
||||
echo " gpg --armor --detach-sign --digest-algo SHA256 unbound-$version.tar.gz"
|
||||
echo " gpg --armor --detach-sign --digest-algo SHA256 unbound-$version.zip"
|
||||
echo " gpg --armor --detach-sign --digest-algo SHA256 unbound_setup_$version.exe"
|
||||
|
||||
info "Unbound distribution created successfully."
|
||||
|
||||
@@ -732,8 +732,8 @@ struct module_env {
|
||||
char* tls_auth_name, struct module_qstate* q, int* was_ratelimited);
|
||||
void (*detach_subs)(struct module_qstate* qstate);
|
||||
int (*attach_sub)(struct module_qstate* qstate,
|
||||
struct query_info* qinfo, uint16_t qflags, int prime,
|
||||
int valrec, struct module_qstate** newq);
|
||||
struct query_info* qinfo, struct respip_client_info* cinfo,
|
||||
uint16_t qflags, int prime, int valrec, struct module_qstate** newq);
|
||||
void (*kill_sub)(struct module_qstate* newq);
|
||||
int (*detect_cycle)(struct module_qstate* qstate,
|
||||
struct query_info* qinfo, uint16_t flags, int prime,
|
||||
|
||||
+15
-32
@@ -454,7 +454,7 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
if(PyDict_SetItemString(pe->data, "script", fname) < 0) {
|
||||
log_err("pythonmod: could not add item to dictionary");
|
||||
Py_XDECREF(fname);
|
||||
goto python_init_fail;
|
||||
goto fail_close_file;
|
||||
}
|
||||
Py_XDECREF(fname);
|
||||
Py_XINCREF(pe->data); /* reference will be stolen below */
|
||||
@@ -462,7 +462,7 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
log_err("pythonmod: could not add mod_env object");
|
||||
Py_XDECREF(pe->data); /* 2 times, here and on python_init_fail; */
|
||||
/* on failure the reference is not stolen */
|
||||
goto python_init_fail;
|
||||
goto fail_close_file;
|
||||
}
|
||||
|
||||
if (PyRun_SimpleFile(script_py, pe->fname) < 0) {
|
||||
@@ -493,31 +493,15 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
flen = (size_t)ftell(script_py);
|
||||
fstr = malloc(flen+1);
|
||||
if(!fstr) {
|
||||
log_err("malloc failure to print parse error");
|
||||
|
||||
/* close the file */
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
Py_XDECREF(PyFileObject);
|
||||
#else
|
||||
fclose(script_py);
|
||||
#endif
|
||||
|
||||
goto python_init_fail;
|
||||
log_err("malloc failure to print parse error");
|
||||
goto fail_close_file;
|
||||
}
|
||||
fseek(script_py, 0, SEEK_SET);
|
||||
if(fread(fstr, flen, 1, script_py) < 1) {
|
||||
log_err("file read failed to print parse error: %s: %s",
|
||||
log_err("file read failed to print parse error: %s: %s",
|
||||
pe->fname, strerror(errno));
|
||||
free(fstr);
|
||||
|
||||
/* close the file */
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
Py_XDECREF(PyFileObject);
|
||||
#else
|
||||
fclose(script_py);
|
||||
#endif
|
||||
|
||||
goto python_init_fail;
|
||||
free(fstr);
|
||||
goto fail_close_file;
|
||||
}
|
||||
fstr[flen] = 0;
|
||||
/* we compile the string, but do not run it, to stop side-effects */
|
||||
@@ -527,21 +511,13 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
#endif
|
||||
|
||||
log_py_err();
|
||||
|
||||
/* close the file */
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
Py_XDECREF(PyFileObject);
|
||||
#else
|
||||
fclose(script_py);
|
||||
#endif
|
||||
|
||||
#if PY_MAJOR_VERSION <= 2 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9)
|
||||
/* no cleanup needed for python before 3.9 */
|
||||
#else
|
||||
/* cleanup for python 3.9 and newer */
|
||||
free(fstr);
|
||||
#endif
|
||||
goto python_init_fail;
|
||||
goto fail_close_file;
|
||||
}
|
||||
|
||||
/* close the file */
|
||||
@@ -602,6 +578,13 @@ int pythonmod_init(struct module_env* env, int id)
|
||||
PyGILState_Release(gil);
|
||||
return 1;
|
||||
|
||||
fail_close_file:
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
Py_XDECREF(PyFileObject);
|
||||
#else
|
||||
fclose(script_py);
|
||||
#endif
|
||||
|
||||
python_init_fail:
|
||||
Py_XDECREF(pe->module);
|
||||
Py_XDECREF(pe->dict);
|
||||
|
||||
+53
-6
@@ -102,7 +102,7 @@ respip_set_get_tree(struct respip_set* set)
|
||||
|
||||
struct resp_addr*
|
||||
respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int net, int create, const char* ipstr)
|
||||
socklen_t addrlen, int net, int create)
|
||||
{
|
||||
struct resp_addr* node;
|
||||
log_assert(set);
|
||||
@@ -119,7 +119,10 @@ respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage*
|
||||
addrlen, net)) {
|
||||
/* We know we didn't find it, so this should be
|
||||
* impossible. */
|
||||
log_warn("unexpected: duplicate address: %s", ipstr);
|
||||
char a[128];
|
||||
addr_to_str(addr, addrlen, a, sizeof(a));
|
||||
log_warn("unexpected: duplicate address: %s/%d",
|
||||
a, net);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
@@ -154,8 +157,7 @@ respip_find_or_create(struct respip_set* set, const char* ipstr, int create)
|
||||
log_err("cannot parse netblock: '%s'", ipstr);
|
||||
return NULL;
|
||||
}
|
||||
return respip_sockaddr_find_or_create(set, &addr, addrlen, net, create,
|
||||
ipstr);
|
||||
return respip_sockaddr_find_or_create(set, &addr, addrlen, net, create);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -291,6 +293,49 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
|
||||
return rrset_insert_rr(region, pd, rdata, rdata_len, ttl, rrstr);
|
||||
}
|
||||
|
||||
int
|
||||
respip_enter_rr_wol(struct regional* region, struct resp_addr* raddr,
|
||||
uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata_wol,
|
||||
size_t rdata_len, const char* netblockstr)
|
||||
{
|
||||
struct packed_rrset_data* pd;
|
||||
struct sockaddr* sa;
|
||||
sa = (struct sockaddr*)&raddr->node.addr;
|
||||
if (rrtype == LDNS_RR_TYPE_CNAME && raddr->data) {
|
||||
char* rrstr = dname_rdata_to_str(NULL, 0, rrtype,
|
||||
rrclass, ttl, rdata_wol, rdata_len);
|
||||
log_err("CNAME response-ip data (%s) can not co-exist with other "
|
||||
"response-ip data for netblock %s", (rrstr?rrstr:"<out of memory>"), netblockstr);
|
||||
free(rrstr);
|
||||
return 0;
|
||||
} else if (raddr->data &&
|
||||
raddr->data->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
|
||||
char* rrstr = dname_rdata_to_str(NULL, 0, rrtype,
|
||||
rrclass, ttl, rdata_wol, rdata_len);
|
||||
log_err("response-ip data (%s) can not be added; CNAME response-ip "
|
||||
"data already in place for netblock %s", (rrstr?rrstr:"<out of memory>"), netblockstr);
|
||||
free(rrstr);
|
||||
return 0;
|
||||
} else if((rrtype != LDNS_RR_TYPE_CNAME) &&
|
||||
((sa->sa_family == AF_INET && rrtype != LDNS_RR_TYPE_A) ||
|
||||
(sa->sa_family == AF_INET6 && rrtype != LDNS_RR_TYPE_AAAA))) {
|
||||
char* rrstr = dname_rdata_to_str(NULL, 0, rrtype,
|
||||
rrclass, ttl, rdata_wol, rdata_len);
|
||||
log_err("response-ip data %s record type does not correspond "
|
||||
"to netblock %s address family", (rrstr?rrstr:"<out of memory>"), netblockstr);
|
||||
free(rrstr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!raddr->data) {
|
||||
raddr->data = new_rrset(region, rrtype, rrclass);
|
||||
if(!raddr->data)
|
||||
return 0;
|
||||
}
|
||||
pd = raddr->data->entry.data;
|
||||
return rrset_insert_rr_wol(region, pd, rdata_wol, rdata_len, ttl);
|
||||
}
|
||||
|
||||
static int
|
||||
respip_enter_rrstr(struct regional* region, struct resp_addr* raddr,
|
||||
const char* rrstr, const char* netblock)
|
||||
@@ -1074,7 +1119,8 @@ generate_cname_request(struct module_qstate* qstate,
|
||||
subqi.qtype = qstate->qinfo.qtype;
|
||||
subqi.qclass = qstate->qinfo.qclass;
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
return (*qstate->env->attach_sub)(qstate, &subqi, BIT_RD, 0, 0, &subq);
|
||||
return (*qstate->env->attach_sub)(qstate, &subqi,
|
||||
qstate->client_info, BIT_RD, 0, 0, &subq);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1233,7 +1279,8 @@ respip_inform_super(struct module_qstate* qstate, int id,
|
||||
struct respip_qstate* rq = (struct respip_qstate*)super->minfo[id];
|
||||
struct reply_info* new_rep = NULL;
|
||||
|
||||
rq->state = RESPIP_SUBQUERY_FINISHED;
|
||||
if(rq)
|
||||
rq->state = RESPIP_SUBQUERY_FINISHED;
|
||||
|
||||
/* respip subquery should have always been created with a valid reply
|
||||
* in super. */
|
||||
|
||||
+17
-2
@@ -276,12 +276,11 @@ void respip_inform_print(struct respip_action_info* respip_actinfo,
|
||||
* @param addrlen: length of addr.
|
||||
* @param net: netblock to lookup.
|
||||
* @param create: create node if it does not exist when 1.
|
||||
* @param ipstr: human readable ip string, for logging.
|
||||
* @return newly created of found node, not holding lock.
|
||||
*/
|
||||
struct resp_addr*
|
||||
respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int net, int create, const char* ipstr);
|
||||
socklen_t addrlen, int net, int create);
|
||||
|
||||
/**
|
||||
* Add RR to resp_addr's RRset. Create RRset if not existing.
|
||||
@@ -301,6 +300,22 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr,
|
||||
uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
|
||||
size_t rdata_len, const char* rrstr, const char* netblockstr);
|
||||
|
||||
/**
|
||||
* Add RR to resp_addr's RRset. Create RRset if not existing.
|
||||
* @param region: region to alloc RR(set).
|
||||
* @param raddr: resp_addr containing RRset. Must hold write lock.
|
||||
* @param rrtype: RR type.
|
||||
* @param rrclass: RR class.
|
||||
* @param ttl: TTL.
|
||||
* @param rdata: RDATA. Without prefix len.
|
||||
* @param rdata_len: length of rdata.
|
||||
* @param netblockstr: netblock as string, for logging
|
||||
* @return 0 on error
|
||||
*/
|
||||
int respip_enter_rr_wol(struct regional* region, struct resp_addr* raddr,
|
||||
uint16_t rrtype, uint16_t rrclass, time_t ttl, uint8_t* rdata,
|
||||
size_t rdata_len, const char* netblockstr);
|
||||
|
||||
/**
|
||||
* Delete resp_addr node from tree.
|
||||
* @param set: struct containing tree. Must hold write lock.
|
||||
|
||||
+526
-139
@@ -72,7 +72,11 @@
|
||||
#include "validator/val_sigcrypt.h"
|
||||
#include "validator/val_anchor.h"
|
||||
#include "validator/val_utils.h"
|
||||
#include "zone.h"
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
/** bytes to use for NSEC3 hash buffer. 20 for sha1 */
|
||||
#define N3HASHBUFLEN 32
|
||||
@@ -171,7 +175,7 @@ get_rrset_ttl(struct ub_packed_rrset_key* k)
|
||||
/** Copy rrset into region from domain-datanode and packet rrset */
|
||||
static struct ub_packed_rrset_key*
|
||||
auth_packed_rrset_copy_region(struct auth_zone* z, struct auth_data* node,
|
||||
struct auth_rrset* rrset, struct regional* region, time_t adjust)
|
||||
struct auth_rrset* rrset, struct regional* region)
|
||||
{
|
||||
struct ub_packed_rrset_key key;
|
||||
memset(&key, 0, sizeof(key));
|
||||
@@ -182,7 +186,7 @@ auth_packed_rrset_copy_region(struct auth_zone* z, struct auth_data* node,
|
||||
key.rk.type = htons(rrset->type);
|
||||
key.rk.rrset_class = htons(z->dclass);
|
||||
key.entry.hash = rrset_key_hash(&key.rk);
|
||||
return packed_rrset_copy_region(&key, region, adjust);
|
||||
return packed_rrset_copy_region(&key, region, 0);
|
||||
}
|
||||
|
||||
/** fix up msg->rep TTL and prefetch ttl */
|
||||
@@ -236,7 +240,7 @@ msg_add_rrset_an(struct auth_zone* z, struct regional* region,
|
||||
return 0;
|
||||
/* copy it */
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region)))
|
||||
return 0;
|
||||
msg->rep->rrset_count++;
|
||||
msg->rep->an_numrrsets++;
|
||||
@@ -260,7 +264,7 @@ msg_add_rrset_ns(struct auth_zone* z, struct regional* region,
|
||||
return 0;
|
||||
/* copy it */
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region)))
|
||||
return 0;
|
||||
msg->rep->rrset_count++;
|
||||
msg->rep->ns_numrrsets++;
|
||||
@@ -283,7 +287,7 @@ msg_add_rrset_ar(struct auth_zone* z, struct regional* region,
|
||||
return 0;
|
||||
/* copy it */
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count] =
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region, 0)))
|
||||
auth_packed_rrset_copy_region(z, node, rrset, region)))
|
||||
return 0;
|
||||
msg->rep->rrset_count++;
|
||||
msg->rep->ar_numrrsets++;
|
||||
@@ -702,13 +706,15 @@ az_rrset_find_rrsig(struct packed_rrset_data* d, uint8_t* rdata, size_t len,
|
||||
|
||||
/** see if rdata is duplicate */
|
||||
static int
|
||||
rdata_duplicate(struct packed_rrset_data* d, uint8_t* rdata, size_t len)
|
||||
rdata_duplicate(struct packed_rrset_data* d, uint8_t* rdata_wol, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
size_t i, rdatawl_len = len+2;
|
||||
uint16_t len16 = htons(len);
|
||||
for(i=0; i<d->count + d->rrsig_count; i++) {
|
||||
if(d->rr_len[i] != len)
|
||||
if(d->rr_len[i] != rdatawl_len)
|
||||
continue;
|
||||
if(memcmp(d->rr_data[i], rdata, len) == 0)
|
||||
if(memcmp(d->rr_data[i], &len16, 2) == 0 &&
|
||||
memcmp(d->rr_data[i]+2, rdata_wol, len) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -727,6 +733,19 @@ rrsig_rdata_get_type_covered(uint8_t* rdata, size_t rdatalen)
|
||||
return sldns_read_uint16(rdata+2);
|
||||
}
|
||||
|
||||
/** get rrsig type covered from rdata.
|
||||
* @param rdata_wol: rdata in wireformat, without the prefix rdlength.
|
||||
* @param rdatalen: length of rdata buffer.
|
||||
* @return type covered (or 0).
|
||||
*/
|
||||
static uint16_t
|
||||
rrsig_rdata_get_type_covered_wol(uint8_t* rdata_wol, size_t rdatalen)
|
||||
{
|
||||
if(rdatalen < 2)
|
||||
return 0;
|
||||
return sldns_read_uint16(rdata_wol);
|
||||
}
|
||||
|
||||
/** remove RR from existing RRset. Also sig, if it is a signature.
|
||||
* reallocates the packed rrset for a new one, false on alloc failure */
|
||||
static int
|
||||
@@ -792,7 +811,7 @@ rrset_remove_rr(struct auth_rrset* rrset, size_t index)
|
||||
/** add RR to existing RRset. If insert_sig is true, add to rrsigs.
|
||||
* This reallocates the packed rrset for a new one */
|
||||
static int
|
||||
rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
|
||||
rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata_wol,
|
||||
size_t rdatalen, int insert_sig)
|
||||
{
|
||||
struct packed_rrset_data* d, *old = rrset->data;
|
||||
@@ -800,7 +819,7 @@ rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
|
||||
|
||||
d = (struct packed_rrset_data*)calloc(1, packed_rrset_sizeof(old)
|
||||
+ sizeof(size_t) + sizeof(uint8_t*) + sizeof(time_t)
|
||||
+ rdatalen);
|
||||
+ 2 /* rdlen */ + rdatalen);
|
||||
if(!d) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
@@ -823,8 +842,8 @@ rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
|
||||
memmove(d->rr_len+d->count, old->rr_len+old->count,
|
||||
old->rrsig_count*sizeof(size_t));
|
||||
if(!insert_sig)
|
||||
d->rr_len[d->count-1] = rdatalen;
|
||||
else d->rr_len[total-1] = rdatalen;
|
||||
d->rr_len[d->count-1] = rdatalen + 2;
|
||||
else d->rr_len[total-1] = rdatalen + 2;
|
||||
packed_rrset_ptr_fixup(d);
|
||||
if((time_t)rr_ttl < d->ttl)
|
||||
d->ttl = rr_ttl;
|
||||
@@ -849,10 +868,12 @@ rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
|
||||
/* insert new value */
|
||||
if(!insert_sig) {
|
||||
d->rr_ttl[d->count-1] = rr_ttl;
|
||||
memmove(d->rr_data[d->count-1], rdata, rdatalen);
|
||||
sldns_write_uint16(d->rr_data[d->count-1], rdatalen);
|
||||
memmove(d->rr_data[d->count-1]+2, rdata_wol, rdatalen);
|
||||
} else {
|
||||
d->rr_ttl[total-1] = rr_ttl;
|
||||
memmove(d->rr_data[total-1], rdata, rdatalen);
|
||||
sldns_write_uint16(d->rr_data[total-1], rdatalen);
|
||||
memmove(d->rr_data[total-1]+2, rdata_wol, rdatalen);
|
||||
}
|
||||
|
||||
rrset->data = d;
|
||||
@@ -860,10 +881,11 @@ rrset_add_rr(struct auth_rrset* rrset, uint32_t rr_ttl, uint8_t* rdata,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Create new rrset for node with packed rrset with one RR element */
|
||||
/** Create new rrset for node with packed rrset with one RR element.
|
||||
* rdata_wol is the rdata without prefixed rdlength. */
|
||||
static struct auth_rrset*
|
||||
rrset_create(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
|
||||
uint8_t* rdata, size_t rdatalen)
|
||||
uint8_t* rdata_wol, size_t rdatalen)
|
||||
{
|
||||
struct auth_rrset* rrset = (struct auth_rrset*)calloc(1,
|
||||
sizeof(*rrset));
|
||||
@@ -878,7 +900,7 @@ rrset_create(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
|
||||
/* the rrset data structure, with one RR */
|
||||
d = (struct packed_rrset_data*)calloc(1,
|
||||
sizeof(struct packed_rrset_data) + sizeof(size_t) +
|
||||
sizeof(uint8_t*) + sizeof(time_t) + rdatalen);
|
||||
sizeof(uint8_t*) + sizeof(time_t) + 2 /* rdlen*/ + rdatalen);
|
||||
if(!d) {
|
||||
free(rrset);
|
||||
log_err("out of memory");
|
||||
@@ -893,9 +915,10 @@ rrset_create(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
|
||||
d->rr_data[0] = (uint8_t*)&(d->rr_ttl[1]);
|
||||
|
||||
/* insert the RR */
|
||||
d->rr_len[0] = rdatalen;
|
||||
d->rr_len[0] = rdatalen + 2;
|
||||
d->rr_ttl[0] = rr_ttl;
|
||||
memmove(d->rr_data[0], rdata, rdatalen);
|
||||
sldns_write_uint16(d->rr_data[0], rdatalen);
|
||||
memmove(d->rr_data[0]+2, rdata_wol, rdatalen);
|
||||
d->count++;
|
||||
|
||||
/* insert rrset into linked list for domain */
|
||||
@@ -1079,14 +1102,14 @@ rrsigs_copy_from_rrset_to_rrsigset(struct auth_rrset* rrset,
|
||||
* duplicates are ignored */
|
||||
for(i=rrset->data->count;
|
||||
i<rrset->data->count+rrset->data->rrsig_count; i++) {
|
||||
uint8_t* rdata = rrset->data->rr_data[i];
|
||||
size_t rdatalen = rrset->data->rr_len[i];
|
||||
uint8_t* rdata_wol = rrset->data->rr_data[i]+2;
|
||||
size_t rdatalen = rrset->data->rr_len[i]-2;
|
||||
time_t rr_ttl = rrset->data->rr_ttl[i];
|
||||
|
||||
if(rdata_duplicate(rrsigset->data, rdata, rdatalen)) {
|
||||
if(rdata_duplicate(rrsigset->data, rdata_wol, rdatalen)) {
|
||||
continue;
|
||||
}
|
||||
if(!rrset_add_rr(rrsigset, rr_ttl, rdata, rdatalen, 0))
|
||||
if(!rrset_add_rr(rrsigset, rr_ttl, rdata_wol, rdatalen, 0))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -1096,32 +1119,35 @@ rrsigs_copy_from_rrset_to_rrsigset(struct auth_rrset* rrset,
|
||||
* rdata points to buffer with rdatalen octets, starts with 2bytelength. */
|
||||
static int
|
||||
az_domain_add_rr(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
|
||||
uint8_t* rdata, size_t rdatalen, int* duplicate)
|
||||
uint8_t* rdata_wol, size_t rdatalen, int* duplicate)
|
||||
{
|
||||
struct auth_rrset* rrset;
|
||||
/* packed rrsets have their rrsigs along with them, sort them out */
|
||||
if(rr_type == LDNS_RR_TYPE_RRSIG) {
|
||||
uint16_t ctype = rrsig_rdata_get_type_covered(rdata, rdatalen);
|
||||
uint16_t ctype = rrsig_rdata_get_type_covered_wol(rdata_wol,
|
||||
rdatalen);
|
||||
if((rrset=az_domain_rrset(node, ctype))!= NULL) {
|
||||
/* a node of the correct type exists, add the RRSIG
|
||||
* to the rrset of the covered data type */
|
||||
if(rdata_duplicate(rrset->data, rdata, rdatalen)) {
|
||||
if(rdata_duplicate(rrset->data, rdata_wol, rdatalen)) {
|
||||
if(duplicate) *duplicate = 1;
|
||||
return 1;
|
||||
}
|
||||
if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 1))
|
||||
if(!rrset_add_rr(rrset, rr_ttl, rdata_wol, rdatalen,
|
||||
1))
|
||||
return 0;
|
||||
} else if((rrset=az_domain_rrset(node, rr_type))!= NULL) {
|
||||
/* add RRSIG to rrset of type RRSIG */
|
||||
if(rdata_duplicate(rrset->data, rdata, rdatalen)) {
|
||||
if(rdata_duplicate(rrset->data, rdata_wol, rdatalen)) {
|
||||
if(duplicate) *duplicate = 1;
|
||||
return 1;
|
||||
}
|
||||
if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 0))
|
||||
if(!rrset_add_rr(rrset, rr_ttl, rdata_wol, rdatalen,
|
||||
0))
|
||||
return 0;
|
||||
} else {
|
||||
/* create rrset of type RRSIG */
|
||||
if(!rrset_create(node, rr_type, rr_ttl, rdata,
|
||||
if(!rrset_create(node, rr_type, rr_ttl, rdata_wol,
|
||||
rdatalen))
|
||||
return 0;
|
||||
}
|
||||
@@ -1129,17 +1155,18 @@ az_domain_add_rr(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
|
||||
/* normal RR type */
|
||||
if((rrset=az_domain_rrset(node, rr_type))!= NULL) {
|
||||
/* add data to existing node with data type */
|
||||
if(rdata_duplicate(rrset->data, rdata, rdatalen)) {
|
||||
if(rdata_duplicate(rrset->data, rdata_wol, rdatalen)) {
|
||||
if(duplicate) *duplicate = 1;
|
||||
return 1;
|
||||
}
|
||||
if(!rrset_add_rr(rrset, rr_ttl, rdata, rdatalen, 0))
|
||||
if(!rrset_add_rr(rrset, rr_ttl, rdata_wol, rdatalen,
|
||||
0))
|
||||
return 0;
|
||||
} else {
|
||||
struct auth_rrset* rrsig;
|
||||
/* create new node with data type */
|
||||
if(!(rrset=rrset_create(node, rr_type, rr_ttl, rdata,
|
||||
rdatalen)))
|
||||
if(!(rrset=rrset_create(node, rr_type, rr_ttl,
|
||||
rdata_wol, rdatalen)))
|
||||
return 0;
|
||||
|
||||
/* see if node of type RRSIG has signatures that
|
||||
@@ -1156,21 +1183,15 @@ az_domain_add_rr(struct auth_data* node, uint16_t rr_type, uint32_t rr_ttl,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** insert RR into zone, ignore duplicates */
|
||||
/** insert RR as name,rdata into zone, ignore duplicates.
|
||||
* The rdata_wol is the rdata without the prefix rdlength, because simdzone
|
||||
* returns that as the parsed rdata byte string. */
|
||||
static int
|
||||
az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
|
||||
size_t dname_len, int* duplicate)
|
||||
az_insert_rr_as_rdata(struct auth_zone* z, uint8_t* dname, size_t dname_len,
|
||||
uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
|
||||
uint8_t* rdata_wol, size_t rdatalen, int* duplicate)
|
||||
{
|
||||
struct auth_data* node;
|
||||
uint8_t* dname = rr;
|
||||
uint16_t rr_type = sldns_wirerr_get_type(rr, rr_len, dname_len);
|
||||
uint16_t rr_class = sldns_wirerr_get_class(rr, rr_len, dname_len);
|
||||
uint32_t rr_ttl = sldns_wirerr_get_ttl(rr, rr_len, dname_len);
|
||||
size_t rdatalen = ((size_t)sldns_wirerr_get_rdatalen(rr, rr_len,
|
||||
dname_len))+2;
|
||||
/* rdata points to rdata prefixed with uint16 rdatalength */
|
||||
uint8_t* rdata = sldns_wirerr_get_rdatawl(rr, rr_len, dname_len);
|
||||
|
||||
if(rr_class != z->dclass) {
|
||||
log_err("wrong class for RR");
|
||||
return 0;
|
||||
@@ -1179,20 +1200,38 @@ az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
|
||||
log_err("cannot create domain");
|
||||
return 0;
|
||||
}
|
||||
if(!az_domain_add_rr(node, rr_type, rr_ttl, rdata, rdatalen,
|
||||
if(!az_domain_add_rr(node, rr_type, rr_ttl, rdata_wol, rdatalen,
|
||||
duplicate)) {
|
||||
log_err("cannot add RR to domain");
|
||||
return 0;
|
||||
}
|
||||
if(z->rpz) {
|
||||
if(!(rpz_insert_rr(z->rpz, z->name, z->namelen, dname,
|
||||
dname_len, rr_type, rr_class, rr_ttl, rdata, rdatalen,
|
||||
rr, rr_len)))
|
||||
dname_len, rr_type, rr_class, rr_ttl, rdata_wol,
|
||||
rdatalen)))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** insert RR into zone, ignore duplicates */
|
||||
static int
|
||||
az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
|
||||
size_t dname_len, int* duplicate)
|
||||
{
|
||||
uint8_t* dname = rr;
|
||||
uint16_t rr_type = sldns_wirerr_get_type(rr, rr_len, dname_len);
|
||||
uint16_t rr_class = sldns_wirerr_get_class(rr, rr_len, dname_len);
|
||||
uint32_t rr_ttl = sldns_wirerr_get_ttl(rr, rr_len, dname_len);
|
||||
size_t rdatalen = ((size_t)sldns_wirerr_get_rdatalen(rr, rr_len,
|
||||
dname_len));
|
||||
/* rdata points to rdata without prefix rdlength. */
|
||||
uint8_t* rdata_wol = sldns_wirerr_get_rdata(rr, rr_len, dname_len);
|
||||
|
||||
return az_insert_rr_as_rdata(z, dname, dname_len, rr_type, rr_class,
|
||||
rr_ttl, rdata_wol, rdatalen, duplicate);
|
||||
}
|
||||
|
||||
/** Remove rr from node, ignores nonexisting RRs,
|
||||
* rdata points to buffer with rdatalen octets, starts with 2bytelength. */
|
||||
static int
|
||||
@@ -1563,13 +1602,157 @@ az_parse_file(struct auth_zone* z, FILE* in, uint8_t* rr, size_t rrbuflen,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Structure for simdzone parse state */
|
||||
struct az_parse_state {
|
||||
/** The zone that is processed. */
|
||||
struct auth_zone* z;
|
||||
/** number of errors, if 0 it was read successfully. */
|
||||
int errors;
|
||||
/** for http parse, chunk iterator. */
|
||||
struct auth_chunk* chunk;
|
||||
/** for http parse, position in chunk. */
|
||||
size_t chunk_pos;
|
||||
};
|
||||
|
||||
/** Callback for simdzone parse, log an error */
|
||||
static void
|
||||
az_parse_log(zone_parser_t *parser, uint32_t category,
|
||||
const char *file, size_t line, const char *message, void *user_data)
|
||||
{
|
||||
struct az_parse_state* state = (struct az_parse_state*)user_data;
|
||||
(void)parser;
|
||||
|
||||
switch (category) {
|
||||
case ZONE_INFO:
|
||||
if (file)
|
||||
log_info("%s:%d: %s", file, (int)line, message);
|
||||
else
|
||||
log_info("%s", message);
|
||||
break;
|
||||
case ZONE_WARNING:
|
||||
if (file)
|
||||
log_warn("%s:%d: %s", file, (int)line, message);
|
||||
else
|
||||
log_warn("%s", message);
|
||||
break;
|
||||
default:
|
||||
if (file)
|
||||
log_err("%s:%d: %s", file, (int)line, message);
|
||||
else
|
||||
log_err("%s", message);
|
||||
state->errors++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Callback for simdzone parse, accept an RR that has been read in. */
|
||||
int32_t
|
||||
az_parse_accept(zone_parser_t *parser, const zone_name_t *owner,
|
||||
uint16_t type, uint16_t dclass, uint32_t ttl, uint16_t rdlength,
|
||||
const uint8_t *rdata, void *user_data)
|
||||
{
|
||||
struct az_parse_state* state = (struct az_parse_state*)user_data;
|
||||
if(verbosity >= 7) {
|
||||
char dname[LDNS_MAX_DOMAINLEN], t[16], c[16];
|
||||
dname_str((uint8_t*)owner->octets, dname);
|
||||
sldns_wire2str_type_buf(type, t, sizeof(t));
|
||||
sldns_wire2str_class_buf(dclass, c, sizeof(c));
|
||||
verbose(7, "zone parse record %s %s %s", dname, c, t);
|
||||
}
|
||||
|
||||
/* Duplicates can be ignored, do not insert them twice. */
|
||||
if(!az_insert_rr_as_rdata(state->z, (uint8_t*)owner->octets,
|
||||
owner->length, type, dclass, ttl, (uint8_t*)rdata, rdlength,
|
||||
NULL)) {
|
||||
char dname[LDNS_MAX_DOMAINLEN], t[16], c[16];
|
||||
dname_str((uint8_t*)owner->octets, dname);
|
||||
sldns_wire2str_type_buf(type, t, sizeof(t));
|
||||
sldns_wire2str_class_buf(dclass, c, sizeof(c));
|
||||
log_err("record insert allocation failed, %s %s %s",
|
||||
dname, c, t);
|
||||
return ZONE_OUT_OF_MEMORY;
|
||||
}
|
||||
(void)parser;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for simdzone parse, include a zone file.
|
||||
* It is called for every $INCLUDE entry. It could be used to save
|
||||
* the file names, so that it can track if the files have changed, later.
|
||||
*/
|
||||
static int32_t
|
||||
az_parse_include(zone_parser_t *parser, const char *file,
|
||||
const char *path, void *user_data)
|
||||
{
|
||||
struct az_parse_state* state = (struct az_parse_state*)user_data;
|
||||
(void)parser;
|
||||
if(state->z->zone_is_slave) {
|
||||
/* A $INCLUDE is not expected for a secondary zone. */
|
||||
log_err("$INCLUDE not allowed for secondary zone");
|
||||
return ZONE_SEMANTIC_ERROR;
|
||||
}
|
||||
verbose(6, "zone parse descended into include file %s (full path %s)",
|
||||
file, path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse file with simdzone.
|
||||
*/
|
||||
static int
|
||||
az_parse_file_simdzone(struct auth_zone* z, char* zfilename,
|
||||
struct config_file* cfg)
|
||||
{
|
||||
zone_parser_t parser;
|
||||
zone_options_t options;
|
||||
zone_name_buffer_t name_buffer;
|
||||
zone_rdata_buffer_t rdata_buffer;
|
||||
zone_buffers_t buffers = { 1, &name_buffer, &rdata_buffer };
|
||||
struct az_parse_state state;
|
||||
|
||||
memset(&options, 0, sizeof(options));
|
||||
options.origin.octets = z->name;
|
||||
options.origin.length = z->namelen;
|
||||
options.default_ttl = 3600;
|
||||
options.default_class = LDNS_RR_CLASS_IN;
|
||||
options.secondary = z->zone_is_slave;
|
||||
options.pretty_ttls = true; /* non-standard, for backwards compatibility */
|
||||
if(cfg->chrootdir && cfg->chrootdir[0])
|
||||
options.chrootdir = cfg->chrootdir;
|
||||
else options.chrootdir = NULL;
|
||||
options.log.callback = &az_parse_log;
|
||||
options.accept.callback = &az_parse_accept;
|
||||
options.include.callback = &az_parse_include;
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
state.z = z;
|
||||
|
||||
/* Parse and process all RRs. */
|
||||
if (zone_parse(&parser, &options, &buffers, zfilename, &state) != 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** See if the file can be accessed, or if it does not exist. Look at errno. */
|
||||
static int
|
||||
file_exists(char* filename)
|
||||
{
|
||||
struct stat buf;
|
||||
if(stat(filename, &buf) < 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg)
|
||||
{
|
||||
int use_simdzone = 1;
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
struct sldns_file_parse_state state;
|
||||
char* zfilename;
|
||||
FILE* in;
|
||||
if(!z || !z->zonefile || z->zonefile[0]==0)
|
||||
return 1; /* no file, or "", nothing to read */
|
||||
|
||||
@@ -1582,8 +1765,7 @@ auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg)
|
||||
dname_str(z->name, nm);
|
||||
verbose(VERB_ALGO, "read zonefile %s for %s", zfilename, nm);
|
||||
}
|
||||
in = fopen(zfilename, "r");
|
||||
if(!in) {
|
||||
if(!file_exists(zfilename)) {
|
||||
char* n = sldns_wire2str_dname(z->name, z->namelen);
|
||||
if(z->zone_is_slave && errno == ENOENT) {
|
||||
/* we fetch the zone contents later, no file yet */
|
||||
@@ -1614,15 +1796,36 @@ auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg)
|
||||
state.origin_len = z->namelen;
|
||||
}
|
||||
/* parse the (toplevel) file */
|
||||
if(!az_parse_file(z, in, rr, sizeof(rr), &state, zfilename, 0, cfg)) {
|
||||
char* n = sldns_wire2str_dname(z->name, z->namelen);
|
||||
log_err("error parsing zonefile %s for %s",
|
||||
zfilename, n?n:"error");
|
||||
free(n);
|
||||
if(use_simdzone) {
|
||||
/* Use simdzone. */
|
||||
if(!az_parse_file_simdzone(z, zfilename, cfg)) {
|
||||
char* n = sldns_wire2str_dname(z->name, z->namelen);
|
||||
log_err("error parsing zonefile %s for %s",
|
||||
zfilename, n?n:"error");
|
||||
free(n);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* Read with sldns_str2wire functions. */
|
||||
FILE* in;
|
||||
in = fopen(zfilename, "r");
|
||||
if(!in) {
|
||||
char* n = sldns_wire2str_dname(z->name, z->namelen);
|
||||
log_err("cannot open zonefile %s for %s: %s",
|
||||
zfilename, n?n:"error", strerror(errno));
|
||||
free(n);
|
||||
return 0;
|
||||
}
|
||||
if(!az_parse_file(z, in, rr, sizeof(rr), &state, zfilename, 0, cfg)) {
|
||||
char* n = sldns_wire2str_dname(z->name, z->namelen);
|
||||
log_err("error parsing zonefile %s for %s",
|
||||
zfilename, n?n:"error");
|
||||
free(n);
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
||||
fclose(in);
|
||||
return 0;
|
||||
}
|
||||
fclose(in);
|
||||
|
||||
if(z->rpz)
|
||||
rpz_finish_config(z->rpz);
|
||||
@@ -3990,6 +4193,22 @@ auth_master_copy(struct auth_master* o)
|
||||
return m;
|
||||
}
|
||||
|
||||
/** append the master to the copied list. */
|
||||
static int
|
||||
auth_master_copy_and_append(struct auth_master* p, struct auth_master** list,
|
||||
struct auth_master** last)
|
||||
{
|
||||
struct auth_master* m = auth_master_copy(p);
|
||||
if(!m) {
|
||||
return 0;
|
||||
}
|
||||
m->next = NULL;
|
||||
if(*last) (*last)->next = m;
|
||||
if(!*list) *list = m;
|
||||
*last = m;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** copy the master addresses from the task_probe lookups to the allow_notify
|
||||
* list of masters */
|
||||
static void
|
||||
@@ -3998,17 +4217,27 @@ probe_copy_masters_for_allow_notify(struct auth_xfer* xfr)
|
||||
struct auth_master* list = NULL, *last = NULL;
|
||||
struct auth_master* p;
|
||||
/* build up new list with copies */
|
||||
for(p = xfr->task_transfer->masters; p; p=p->next) {
|
||||
struct auth_master* m = auth_master_copy(p);
|
||||
if(!m) {
|
||||
/* The list in task probe has been looked up before the list in
|
||||
* task transfer. */
|
||||
for(p = xfr->task_probe->masters; p; p=p->next) {
|
||||
if(!auth_master_copy_and_append(p, &list, &last)) {
|
||||
auth_free_masters(list);
|
||||
/* failed because of malloc failure, use old list */
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* The list in task transfer also contains the http entries. */
|
||||
for(p = xfr->task_transfer->masters; p; p=p->next) {
|
||||
/* Copy the http entries from this lookup. The allow_notify
|
||||
* entries are not looked up from this list. The other
|
||||
* ones are already in from the probe lookups. */
|
||||
if(!p->http)
|
||||
continue;
|
||||
if(!auth_master_copy_and_append(p, &list, &last)) {
|
||||
auth_free_masters(list);
|
||||
/* failed because of malloc failure, use old list */
|
||||
return;
|
||||
}
|
||||
m->next = NULL;
|
||||
if(last) last->next = m;
|
||||
if(!list) list = m;
|
||||
last = m;
|
||||
}
|
||||
/* success, replace list */
|
||||
auth_free_masters(xfr->allow_notify_list);
|
||||
@@ -4556,6 +4785,23 @@ http_parse_ttl(sldns_buffer* buf, struct sldns_file_parse_state* pstate)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** remove newlines from collated line */
|
||||
static void
|
||||
chunkline_newline_removal(sldns_buffer* buf)
|
||||
{
|
||||
size_t i, end=sldns_buffer_limit(buf);
|
||||
for(i=0; i<end; i++) {
|
||||
char c = (char)sldns_buffer_read_u8_at(buf, i);
|
||||
if(c == '\n' && i==end-1) {
|
||||
sldns_buffer_write_u8_at(buf, i, 0);
|
||||
sldns_buffer_set_limit(buf, end-1);
|
||||
return;
|
||||
}
|
||||
if(c == '\n')
|
||||
sldns_buffer_write_u8_at(buf, i, (uint8_t)' ');
|
||||
}
|
||||
}
|
||||
|
||||
/** find noncomment RR line in chunks, collates lines if ( ) format */
|
||||
static int
|
||||
chunkline_non_comment_RR(struct auth_chunk** chunk, size_t* chunk_pos,
|
||||
@@ -4563,6 +4809,7 @@ chunkline_non_comment_RR(struct auth_chunk** chunk, size_t* chunk_pos,
|
||||
{
|
||||
int ret;
|
||||
while(chunkline_get_line_collated(chunk, chunk_pos, buf)) {
|
||||
chunkline_newline_removal(buf);
|
||||
if(chunkline_is_comment_line_or_empty(buf)) {
|
||||
/* a comment, go to next line */
|
||||
continue;
|
||||
@@ -4638,23 +4885,6 @@ chunklist_sum(struct auth_chunk* list)
|
||||
return s;
|
||||
}
|
||||
|
||||
/** remove newlines from collated line */
|
||||
static void
|
||||
chunkline_newline_removal(sldns_buffer* buf)
|
||||
{
|
||||
size_t i, end=sldns_buffer_limit(buf);
|
||||
for(i=0; i<end; i++) {
|
||||
char c = (char)sldns_buffer_read_u8_at(buf, i);
|
||||
if(c == '\n' && i==end-1) {
|
||||
sldns_buffer_write_u8_at(buf, i, 0);
|
||||
sldns_buffer_set_limit(buf, end-1);
|
||||
return;
|
||||
}
|
||||
if(c == '\n')
|
||||
sldns_buffer_write_u8_at(buf, i, (uint8_t)' ');
|
||||
}
|
||||
}
|
||||
|
||||
/** for http download, parse and add RR to zone */
|
||||
static int
|
||||
http_parse_add_rr(struct auth_xfer* xfr, struct auth_zone* z,
|
||||
@@ -5070,14 +5300,11 @@ apply_axfr(struct auth_xfer* xfr, struct auth_zone* z,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** apply HTTP to zone in memory. z is locked. false on failure(mallocfail) */
|
||||
/** parse http zone with sldns. */
|
||||
static int
|
||||
apply_http(struct auth_xfer* xfr, struct auth_zone* z,
|
||||
parse_http_sldns(struct auth_xfer* xfr, struct auth_zone* z,
|
||||
struct sldns_buffer* scratch_buffer)
|
||||
{
|
||||
/* parse data in chunks */
|
||||
/* parse RR's and read into memory. ignore $INCLUDE from the
|
||||
* downloaded file*/
|
||||
struct sldns_file_parse_state pstate;
|
||||
struct auth_chunk* chunk;
|
||||
size_t chunk_pos;
|
||||
@@ -5089,6 +5316,184 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
|
||||
memmove(pstate.origin, xfr->name, xfr->namelen);
|
||||
}
|
||||
|
||||
chunk = xfr->task_transfer->chunks_first;
|
||||
chunk_pos = 0;
|
||||
pstate.lineno = 0;
|
||||
while(chunkline_get_line_collated(&chunk, &chunk_pos, scratch_buffer)) {
|
||||
/* process this line */
|
||||
pstate.lineno++;
|
||||
chunkline_newline_removal(scratch_buffer);
|
||||
if(chunkline_is_comment_line_or_empty(scratch_buffer)) {
|
||||
continue;
|
||||
}
|
||||
/* parse line and add RR */
|
||||
if((ret=http_parse_origin(scratch_buffer, &pstate))!=0) {
|
||||
if(ret == 2) {
|
||||
verbose(VERB_ALGO, "error parsing ORIGIN on line [%s:%d] %s",
|
||||
xfr->task_transfer->master->file,
|
||||
pstate.lineno,
|
||||
sldns_buffer_begin(scratch_buffer));
|
||||
return 0;
|
||||
}
|
||||
continue; /* $ORIGIN has been handled */
|
||||
}
|
||||
if((ret=http_parse_ttl(scratch_buffer, &pstate))!=0) {
|
||||
if(ret == 2) {
|
||||
verbose(VERB_ALGO, "error parsing TTL on line [%s:%d] %s",
|
||||
xfr->task_transfer->master->file,
|
||||
pstate.lineno,
|
||||
sldns_buffer_begin(scratch_buffer));
|
||||
return 0;
|
||||
}
|
||||
continue; /* $TTL has been handled */
|
||||
}
|
||||
if(!http_parse_add_rr(xfr, z, scratch_buffer, &pstate)) {
|
||||
verbose(VERB_ALGO, "error parsing line [%s:%d] %s",
|
||||
xfr->task_transfer->master->file,
|
||||
pstate.lineno,
|
||||
sldns_buffer_begin(scratch_buffer));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for simdzone parse of http, include a zone file.
|
||||
* It is called for every $INCLUDE entry.
|
||||
*/
|
||||
static int32_t
|
||||
az_http_parse_include(zone_parser_t *parser, const char *file,
|
||||
const char *path, void *user_data)
|
||||
{
|
||||
struct az_parse_state* state = (struct az_parse_state*)user_data;
|
||||
char dname[LDNS_MAX_DOMAINLEN];
|
||||
(void)parser;
|
||||
verbose(6, "zone parse has include file %s (full path %s)",
|
||||
file, path);
|
||||
dname_str(state->z->name, dname);
|
||||
verbose(1, "zone parse for zonefile of %s has $INCLUDE %s, but $INCLUDE not followed",
|
||||
dname, file);
|
||||
/* Not expecting a secondary zone file with includes. */
|
||||
return ZONE_SEMANTIC_ERROR;
|
||||
}
|
||||
|
||||
int32_t az_http_read_data(zone_parser_t* parser, char* data, size_t len,
|
||||
size_t* outlen, void* user_data)
|
||||
{
|
||||
struct az_parse_state* state = (struct az_parse_state*)user_data;
|
||||
size_t written = 0;
|
||||
(void)parser;
|
||||
|
||||
if(state->chunk == NULL) {
|
||||
/* End of the chunk list */
|
||||
*outlen = 0;
|
||||
return 0;
|
||||
}
|
||||
if(state->chunk_pos == state->chunk->len) {
|
||||
/* The end of the chunk list is reached, with 0 data. */
|
||||
state->chunk = NULL;
|
||||
*outlen = 0;
|
||||
return 0;
|
||||
}
|
||||
if(len == 0) {
|
||||
*outlen = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fill up the data buffer with the requested amount. */
|
||||
while(written < len) {
|
||||
/* The amount that is wanted. */
|
||||
size_t wanted = len - written;
|
||||
/* That amount that is in this chunk. */
|
||||
size_t avail = state->chunk->len - state->chunk_pos;
|
||||
|
||||
if(wanted < avail) {
|
||||
/* Write a piece of this chunk. */
|
||||
memmove(data+written,
|
||||
state->chunk->data+state->chunk_pos, wanted);
|
||||
state->chunk_pos += wanted;
|
||||
*outlen = len;
|
||||
return 0;
|
||||
}
|
||||
/* Write the entire chunk and continue on. */
|
||||
if(avail > 0)
|
||||
memmove(data+written,
|
||||
state->chunk->data+state->chunk_pos, avail);
|
||||
written += avail;
|
||||
|
||||
/* move to next chunk */
|
||||
state->chunk = state->chunk->next;
|
||||
state->chunk_pos = 0;
|
||||
|
||||
/* Is this the exact amount requested. */
|
||||
if(written == len) {
|
||||
/* continue later. */
|
||||
*outlen = len;
|
||||
return 0;
|
||||
}
|
||||
/* Is there no more data. */
|
||||
if(state->chunk == NULL) {
|
||||
/* End of data. */
|
||||
*outlen = written;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*outlen = written;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** parse http zone with simdzone. */
|
||||
static int
|
||||
parse_http_simdzone(struct auth_xfer* xfr, struct auth_zone* z)
|
||||
{
|
||||
zone_parser_t parser;
|
||||
zone_options_t options;
|
||||
zone_name_buffer_t name_buffer;
|
||||
zone_rdata_buffer_t rdata_buffer;
|
||||
zone_buffers_t buffers = { 1, &name_buffer, &rdata_buffer };
|
||||
struct az_parse_state state;
|
||||
|
||||
memset(&options, 0, sizeof(options));
|
||||
options.origin.octets = z->name;
|
||||
options.origin.length = z->namelen;
|
||||
options.default_ttl = 3600;
|
||||
options.default_class = LDNS_RR_CLASS_IN;
|
||||
options.secondary = z->zone_is_slave;
|
||||
options.pretty_ttls = true; /* non-standard, for backwards compatibility */
|
||||
options.no_includes = true; /* the secondary zone file transferred over https is not expected to have $INCLUDE files. */
|
||||
/* The log callback for file read prints the error and can be used
|
||||
* here too. */
|
||||
options.log.callback = &az_parse_log;
|
||||
/* The parse accept callback for file inserts the RR, and can be
|
||||
* used here too. */
|
||||
options.accept.callback = &az_parse_accept;
|
||||
options.include.callback = &az_http_parse_include;
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
state.z = z;
|
||||
state.chunk = xfr->task_transfer->chunks_first;
|
||||
state.chunk_pos = 0;
|
||||
|
||||
/* Parse and process all RRs. */
|
||||
if (zone_parse_from_callback(&parser, &options, &buffers,
|
||||
az_http_read_data, &state) != 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** apply HTTP to zone in memory. z is locked. false on failure(mallocfail) */
|
||||
static int
|
||||
apply_http(struct auth_xfer* xfr, struct auth_zone* z,
|
||||
struct sldns_buffer* scratch_buffer)
|
||||
{
|
||||
int use_simdzone = 1;
|
||||
|
||||
/* parse data in chunks */
|
||||
/* parse RR's and read into memory. ignore $INCLUDE from the
|
||||
* downloaded file*/
|
||||
|
||||
if(verbosity >= VERB_ALGO)
|
||||
verbose(VERB_ALGO, "http download %s of size %d",
|
||||
xfr->task_transfer->master->file,
|
||||
@@ -5128,44 +5533,14 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
|
||||
xfr->serial = 0;
|
||||
xfr->soa_zone_acquired = 0;
|
||||
|
||||
chunk = xfr->task_transfer->chunks_first;
|
||||
chunk_pos = 0;
|
||||
pstate.lineno = 0;
|
||||
while(chunkline_get_line_collated(&chunk, &chunk_pos, scratch_buffer)) {
|
||||
/* process this line */
|
||||
pstate.lineno++;
|
||||
chunkline_newline_removal(scratch_buffer);
|
||||
if(chunkline_is_comment_line_or_empty(scratch_buffer)) {
|
||||
continue;
|
||||
}
|
||||
/* parse line and add RR */
|
||||
if((ret=http_parse_origin(scratch_buffer, &pstate))!=0) {
|
||||
if(ret == 2) {
|
||||
verbose(VERB_ALGO, "error parsing ORIGIN on line [%s:%d] %s",
|
||||
xfr->task_transfer->master->file,
|
||||
pstate.lineno,
|
||||
sldns_buffer_begin(scratch_buffer));
|
||||
return 0;
|
||||
}
|
||||
continue; /* $ORIGIN has been handled */
|
||||
}
|
||||
if((ret=http_parse_ttl(scratch_buffer, &pstate))!=0) {
|
||||
if(ret == 2) {
|
||||
verbose(VERB_ALGO, "error parsing TTL on line [%s:%d] %s",
|
||||
xfr->task_transfer->master->file,
|
||||
pstate.lineno,
|
||||
sldns_buffer_begin(scratch_buffer));
|
||||
return 0;
|
||||
}
|
||||
continue; /* $TTL has been handled */
|
||||
}
|
||||
if(!http_parse_add_rr(xfr, z, scratch_buffer, &pstate)) {
|
||||
verbose(VERB_ALGO, "error parsing line [%s:%d] %s",
|
||||
xfr->task_transfer->master->file,
|
||||
pstate.lineno,
|
||||
sldns_buffer_begin(scratch_buffer));
|
||||
if(use_simdzone) {
|
||||
/* Use simdzone for parse. */
|
||||
if(!parse_http_simdzone(xfr, z))
|
||||
return 0;
|
||||
} else {
|
||||
/* Parse with sldns. */
|
||||
if(!parse_http_sldns(xfr, z, scratch_buffer))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -6668,6 +7043,18 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** return true if there are probe (SOA UDP query) targets in the master list*/
|
||||
static int
|
||||
have_probe_targets(struct auth_master* list)
|
||||
{
|
||||
struct auth_master* p;
|
||||
for(p=list; p; p = p->next) {
|
||||
if(!p->allow_notify && p->host)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** move to sending the probe packets, next if fails. task_probe */
|
||||
static void
|
||||
xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
@@ -6707,6 +7094,16 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
verbose(VERB_ALGO, "auth zone %s probe: finished only_lookup", zname);
|
||||
}
|
||||
xfr_probe_disown(xfr);
|
||||
if(!have_probe_targets(xfr->task_probe->masters)) {
|
||||
/* If there are no masters to probe, go to transfer. */
|
||||
if(xfr->task_transfer->worker == NULL) {
|
||||
xfr_start_transfer(xfr, env, NULL);
|
||||
return;
|
||||
}
|
||||
/* The transfer is already in progress. */
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return;
|
||||
}
|
||||
if(xfr->task_nextprobe->worker == NULL)
|
||||
xfr_set_timeout(xfr, env, 0, 0);
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
@@ -6863,18 +7260,6 @@ auth_xfer_timer(void* arg)
|
||||
}
|
||||
}
|
||||
|
||||
/** return true if there are probe (SOA UDP query) targets in the master list*/
|
||||
static int
|
||||
have_probe_targets(struct auth_master* list)
|
||||
{
|
||||
struct auth_master* p;
|
||||
for(p=list; p; p = p->next) {
|
||||
if(!p->allow_notify && p->host)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** start task_probe if possible, if no masters for probe start task_transfer
|
||||
* returns true if task has been started, and false if the task is already
|
||||
* in progress. */
|
||||
@@ -6886,7 +7271,9 @@ xfr_start_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
* progress (due to notify)) */
|
||||
if(xfr->task_probe->worker == NULL) {
|
||||
if(!have_probe_targets(xfr->task_probe->masters) &&
|
||||
!(xfr->task_probe->only_lookup &&
|
||||
xfr->task_probe->masters != NULL)
|
||||
xfr->task_probe->only_lookup = 1;
|
||||
if(!(xfr->task_probe->only_lookup &&
|
||||
xfr->task_probe->masters != NULL)) {
|
||||
/* useless to pick up task_probe, no masters to
|
||||
* probe. Instead attempt to pick up task transfer */
|
||||
|
||||
Vendored
+59
-27
@@ -60,10 +60,10 @@
|
||||
* @param rep: contains list of rrsets to store.
|
||||
* @param now: current time.
|
||||
* @param leeway: during prefetch how much leeway to update TTLs.
|
||||
* This makes rrsets (other than type NS) timeout sooner so they get
|
||||
* updated with a new full TTL.
|
||||
* Type NS does not get this, because it must not be refreshed from the
|
||||
* child domain, but keep counting down properly.
|
||||
* This makes rrsets expire sooner so they get updated with a new full
|
||||
* TTL.
|
||||
* Child side type NS does get this but TTL checks are done using the time
|
||||
* the query was created rather than the time the answer was received.
|
||||
* @param pside: if from parentside discovered NS, so that its NS is okay
|
||||
* in a prefetch situation to be updated (without becoming sticky).
|
||||
* @param qrep: update rrsets here if cache is better
|
||||
@@ -100,11 +100,20 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
||||
rep->ref[i].id != rep->ref[i].key->id)
|
||||
ck = NULL;
|
||||
else ck = packed_rrset_copy_region(
|
||||
rep->ref[i].key, region, now);
|
||||
rep->ref[i].key, region,
|
||||
((ntohs(rep->ref[i].key->rk.type)==
|
||||
LDNS_RR_TYPE_NS && !pside)?qstarttime:now));
|
||||
lock_rw_unlock(&rep->ref[i].key->entry.lock);
|
||||
if(ck) {
|
||||
/* use cached copy if memory allows */
|
||||
qrep->rrsets[i] = ck;
|
||||
ttl = ((struct packed_rrset_data*)
|
||||
ck->entry.data)->ttl;
|
||||
if(ttl < qrep->ttl) {
|
||||
qrep->ttl = ttl;
|
||||
qrep->prefetch_ttl = PREFETCH_TTL_CALC(qrep->ttl);
|
||||
qrep->serve_expired_ttl = qrep->ttl + SERVE_EXPIRED_TTL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* no break: also copy key item */
|
||||
@@ -169,10 +178,12 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
|
||||
|
||||
/* there was a reply_info_sortref(rep) here but it seems to be
|
||||
* unnecessary, because the cache gets locked per rrset. */
|
||||
reply_info_set_ttls(rep, *env->now);
|
||||
if((flags & DNSCACHE_STORE_EXPIRED_MSG_CACHEDB)) {
|
||||
reply_info_absolute_ttls(rep, *env->now, *env->now - ttl);
|
||||
} else reply_info_set_ttls(rep, *env->now);
|
||||
store_rrsets(env, rep, *env->now, leeway, pside, qrep, region,
|
||||
qstarttime);
|
||||
if(ttl == 0 && !(flags & DNSCACHE_STORE_ZEROTTL)) {
|
||||
if(ttl == 0) {
|
||||
/* we do not store the message, but we did store the RRs,
|
||||
* which could be useful for delegation information */
|
||||
verbose(VERB_ALGO, "TTL 0: dropped msg from cache");
|
||||
@@ -272,8 +283,10 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
{
|
||||
if((msg->rep->rrsets[msg->rep->rrset_count] =
|
||||
packed_rrset_copy_region(rrset, region, now))) {
|
||||
struct packed_rrset_data* d = rrset->entry.data;
|
||||
msg->rep->ar_numrrsets++;
|
||||
msg->rep->rrset_count++;
|
||||
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,8 +469,10 @@ find_add_ds(struct module_env* env, struct regional* region,
|
||||
/* add it to auth section. This is the second rrset. */
|
||||
if((msg->rep->rrsets[msg->rep->rrset_count] =
|
||||
packed_rrset_copy_region(rrset, region, now))) {
|
||||
struct packed_rrset_data* d = rrset->entry.data;
|
||||
msg->rep->ns_numrrsets++;
|
||||
msg->rep->rrset_count++;
|
||||
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
|
||||
}
|
||||
lock_rw_unlock(&rrset->entry.lock);
|
||||
}
|
||||
@@ -487,6 +502,8 @@ dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
return NULL; /* integer overflow protection */
|
||||
msg->rep->flags = BIT_QR; /* with QR, no AA */
|
||||
msg->rep->qdcount = 1;
|
||||
msg->rep->ttl = MAX_TTL; /* will be updated (brought down) while we add
|
||||
* rrsets to the message */
|
||||
msg->rep->reason_bogus = LDNS_EDE_NONE;
|
||||
msg->rep->rrsets = (struct ub_packed_rrset_key**)
|
||||
regional_alloc(region,
|
||||
@@ -497,24 +514,28 @@ dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
}
|
||||
|
||||
int
|
||||
dns_msg_authadd(struct dns_msg* msg, struct regional* region,
|
||||
dns_msg_authadd(struct dns_msg* msg, struct regional* region,
|
||||
struct ub_packed_rrset_key* rrset, time_t now)
|
||||
{
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
|
||||
struct packed_rrset_data* d = rrset->entry.data;
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
|
||||
packed_rrset_copy_region(rrset, region, now)))
|
||||
return 0;
|
||||
msg->rep->ns_numrrsets++;
|
||||
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
|
||||
dns_msg_ansadd(struct dns_msg* msg, struct regional* region,
|
||||
struct ub_packed_rrset_key* rrset, time_t now)
|
||||
{
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
|
||||
struct packed_rrset_data* d = rrset->entry.data;
|
||||
if(!(msg->rep->rrsets[msg->rep->rrset_count++] =
|
||||
packed_rrset_copy_region(rrset, region, now)))
|
||||
return 0;
|
||||
msg->rep->an_numrrsets++;
|
||||
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -585,6 +606,7 @@ gen_dns_msg(struct regional* region, struct query_info* q, size_t num)
|
||||
sizeof(struct reply_info) - sizeof(struct rrset_ref));
|
||||
if(!msg->rep)
|
||||
return NULL;
|
||||
msg->rep->ttl = MAX_TTL;
|
||||
msg->rep->reason_bogus = LDNS_EDE_NONE;
|
||||
msg->rep->reason_bogus_str = NULL;
|
||||
if(num > RR_COUNT_MAX)
|
||||
@@ -606,13 +628,13 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
||||
size_t i;
|
||||
int is_expired = 0;
|
||||
time_t now_control = now;
|
||||
if(now > r->ttl) {
|
||||
if(TTL_IS_EXPIRED(r->ttl, now)) {
|
||||
/* Check if we are allowed to serve expired */
|
||||
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;
|
||||
/* Change the current time so we can pass the below TTL checks
|
||||
* when serving expired data. */
|
||||
now_control = 0;
|
||||
is_expired = 1;
|
||||
}
|
||||
|
||||
@@ -620,15 +642,6 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
||||
if(!msg) return NULL;
|
||||
msg->rep->flags = r->flags;
|
||||
msg->rep->qdcount = r->qdcount;
|
||||
msg->rep->ttl = is_expired
|
||||
?SERVE_EXPIRED_REPLY_TTL
|
||||
:r->ttl - now;
|
||||
if(r->prefetch_ttl > now)
|
||||
msg->rep->prefetch_ttl = r->prefetch_ttl - now;
|
||||
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;
|
||||
@@ -656,13 +669,30 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
|
||||
return NULL;
|
||||
}
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
struct packed_rrset_data* d;
|
||||
msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i],
|
||||
region, now);
|
||||
if(!msg->rep->rrsets[i]) {
|
||||
rrset_array_unlock(r->ref, r->rrset_count);
|
||||
return NULL;
|
||||
}
|
||||
d = msg->rep->rrsets[i]->entry.data;
|
||||
UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl);
|
||||
}
|
||||
if(msg->rep->rrset_count < 1) {
|
||||
msg->rep->ttl = is_expired
|
||||
?SERVE_EXPIRED_REPLY_TTL
|
||||
:r->ttl - now;
|
||||
if(r->prefetch_ttl > now)
|
||||
msg->rep->prefetch_ttl = r->prefetch_ttl - now;
|
||||
else
|
||||
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
} else {
|
||||
/* msg->rep->ttl has been updated through the RRSets above */
|
||||
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;
|
||||
if(env)
|
||||
rrset_array_unlock_touch(env->rrset_cache, scratch, r->ref,
|
||||
r->rrset_count);
|
||||
@@ -701,7 +731,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
struct dns_msg* msg;
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)
|
||||
rrset->entry.data;
|
||||
if(now > d->ttl)
|
||||
if(TTL_IS_EXPIRED(d->ttl, now))
|
||||
return NULL;
|
||||
msg = gen_dns_msg(region, q, 1); /* only the CNAME (or other) RRset */
|
||||
if(!msg)
|
||||
@@ -736,7 +766,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
rrset->entry.data;
|
||||
uint8_t* newname, *dtarg = NULL;
|
||||
size_t newlen, dtarglen;
|
||||
if(now > d->ttl)
|
||||
if(TTL_IS_EXPIRED(d->ttl, now))
|
||||
return NULL;
|
||||
/* only allow validated (with DNSSEC) DNAMEs used from cache
|
||||
* for insecure DNAMEs, query again. */
|
||||
@@ -844,6 +874,8 @@ fill_any(struct module_env* env,
|
||||
/* set NOTIMPL for RFC 8482 */
|
||||
msg->rep->flags |= LDNS_RCODE_NOTIMPL;
|
||||
msg->rep->security = sec_status_indeterminate;
|
||||
msg->rep->ttl = 1; /* empty NOTIMPL response will never be
|
||||
* updated with rrsets, set TTL to 1 */
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -1069,7 +1101,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
msgqinf->qclass, flags, 0, 1);
|
||||
if(e) {
|
||||
struct reply_info* cached = e->entry.data;
|
||||
if(cached->ttl < *env->now
|
||||
if(TTL_IS_EXPIRED(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.
|
||||
|
||||
Vendored
+1
-1
@@ -53,7 +53,7 @@ struct delegpt;
|
||||
* Must be an unsigned 32-bit value larger than 0xffff */
|
||||
|
||||
/** Allow caching a DNS message with a zero TTL. */
|
||||
#define DNSCACHE_STORE_ZEROTTL 0x100000
|
||||
#define DNSCACHE_STORE_EXPIRED_MSG_CACHEDB 0x100000
|
||||
|
||||
/**
|
||||
* Region allocated message reply
|
||||
|
||||
Vendored
+2
-1
@@ -1269,7 +1269,8 @@ int infra_wait_limit_allowed(struct infra_cache* infra, struct comm_reply* rep,
|
||||
int cookie_valid, struct config_file* cfg)
|
||||
{
|
||||
struct lruhash_entry* entry;
|
||||
if(cfg->wait_limit == 0)
|
||||
if(cfg->wait_limit == 0 ||
|
||||
(cookie_valid && cfg->wait_limit_cookie == 0))
|
||||
return 1;
|
||||
|
||||
entry = infra_find_ip_ratedata(infra, &rep->client_addr,
|
||||
|
||||
Vendored
+10
-9
@@ -131,7 +131,7 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
|
||||
struct packed_rrset_data* newd = (struct packed_rrset_data*)nd;
|
||||
struct packed_rrset_data* cached = (struct packed_rrset_data*)cd;
|
||||
/* o if new data is expired, cached data is better */
|
||||
if( newd->ttl < timenow && timenow <= cached->ttl)
|
||||
if( TTL_IS_EXPIRED(newd->ttl, timenow) && !TTL_IS_EXPIRED(cached->ttl, timenow))
|
||||
return 0;
|
||||
/* o store if rrset has been validated
|
||||
* everything better than bogus data
|
||||
@@ -146,13 +146,13 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
|
||||
if( newd->trust > cached->trust ) {
|
||||
/* if the cached rrset is bogus, and new is equal,
|
||||
* do not update the TTL - let it expire. */
|
||||
if(equal && cached->ttl >= timenow &&
|
||||
if(equal && !TTL_IS_EXPIRED(cached->ttl, timenow) &&
|
||||
cached->security == sec_status_bogus)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
/* o item in cache has expired */
|
||||
if( cached->ttl < timenow )
|
||||
if( TTL_IS_EXPIRED(cached->ttl, timenow) )
|
||||
return 1;
|
||||
/* o same trust, but different in data - insert it */
|
||||
if( newd->trust == cached->trust && !equal ) {
|
||||
@@ -300,7 +300,7 @@ rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
|
||||
/* check TTL */
|
||||
struct packed_rrset_data* data =
|
||||
(struct packed_rrset_data*)e->data;
|
||||
if(timenow > data->ttl) {
|
||||
if(TTL_IS_EXPIRED(data->ttl, timenow)) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
return NULL;
|
||||
}
|
||||
@@ -310,17 +310,18 @@ rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
rrset_array_lock(struct rrset_ref* ref, size_t count, time_t timenow)
|
||||
{
|
||||
size_t i;
|
||||
struct packed_rrset_data* d;
|
||||
for(i=0; i<count; i++) {
|
||||
if(i>0 && ref[i].key == ref[i-1].key)
|
||||
continue; /* only lock items once */
|
||||
lock_rw_rdlock(&ref[i].key->entry.lock);
|
||||
if(ref[i].id != ref[i].key->id || timenow >
|
||||
((struct packed_rrset_data*)(ref[i].key->entry.data))
|
||||
->ttl) {
|
||||
d = ref[i].key->entry.data;
|
||||
if(ref[i].id != ref[i].key->id ||
|
||||
TTL_IS_EXPIRED(d->ttl, timenow)) {
|
||||
/* failure! rollback our readlocks */
|
||||
rrset_array_unlock(ref, i+1);
|
||||
return 0;
|
||||
@@ -511,7 +512,7 @@ rrset_cache_expired_above(struct rrset_cache* r, uint8_t** qname, size_t*
|
||||
*qnamelen, searchtype, qclass, 0, 0, 0))) {
|
||||
struct packed_rrset_data* data =
|
||||
(struct packed_rrset_data*)rrset->entry.data;
|
||||
if(now > data->ttl) {
|
||||
if(TTL_IS_EXPIRED(data->ttl, now)) {
|
||||
/* it is expired, this is not wanted */
|
||||
lock_rw_unlock(&rrset->entry.lock);
|
||||
log_nametypeclass(VERB_ALGO, "this rrset is expired", *qname, searchtype, qclass);
|
||||
|
||||
@@ -1564,7 +1564,7 @@ listen_create(struct comm_base* base, struct listen_port* ports,
|
||||
cp = comm_point_create_udp(base, ports->fd,
|
||||
front->udp_buff, ports->pp2_enabled, cb,
|
||||
cb_arg, ports->socket);
|
||||
} else if(ports->ftype == listen_type_doq) {
|
||||
} else if(ports->ftype == listen_type_doq && doq_table) {
|
||||
#ifndef HAVE_NGTCP2
|
||||
log_warn("Unbound is not compiled with "
|
||||
"ngtcp2. This is required to use DNS "
|
||||
@@ -2884,6 +2884,7 @@ submit_http_error:
|
||||
sldns_buffer_flip(h2_stream->qbuffer);
|
||||
h2_session->postpone_drop = 1;
|
||||
query_read_done = http2_query_read_done(h2_session, h2_stream);
|
||||
h2_session->postpone_drop = 0;
|
||||
if(query_read_done < 0)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
else if(!query_read_done) {
|
||||
@@ -2893,11 +2894,9 @@ submit_http_error:
|
||||
* failure will result in reclaiming (and closing)
|
||||
* of comm point. */
|
||||
verbose(VERB_QUERY, "http2 query dropped in worker cb");
|
||||
h2_session->postpone_drop = 0;
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
/* nothing to submit right now, query added to mesh. */
|
||||
h2_session->postpone_drop = 0;
|
||||
return 0;
|
||||
}
|
||||
if(!http2_submit_dns_response(h2_session)) {
|
||||
@@ -3275,14 +3274,18 @@ nghttp2_session_callbacks* http2_req_callbacks_create(void)
|
||||
struct doq_table*
|
||||
doq_table_create(struct config_file* cfg, struct ub_randstate* rnd)
|
||||
{
|
||||
struct doq_table* table = calloc(1, sizeof(*table));
|
||||
struct doq_table* table;
|
||||
|
||||
if (!cfg->quic_port)
|
||||
return NULL;
|
||||
table = calloc(1, sizeof(*table));
|
||||
if(!table)
|
||||
return NULL;
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
/* Initialize the ossl crypto, it is harmless to call twice,
|
||||
* and this is before use of doq connections. */
|
||||
if(ngtcp2_crypto_ossl_init() != 0) {
|
||||
log_err("ngtcp2_crypto_oss_init failed");
|
||||
log_err("ngtcp2_crypto_ossl_init failed");
|
||||
free(table);
|
||||
return NULL;
|
||||
}
|
||||
@@ -3354,7 +3357,7 @@ conn_tree_del(rbnode_type* node, void* arg)
|
||||
{
|
||||
struct doq_table* table = (struct doq_table*)arg;
|
||||
struct doq_conn* conn;
|
||||
if(!node)
|
||||
if(!node || !table)
|
||||
return;
|
||||
conn = (struct doq_conn*)node->key;
|
||||
if(conn->timer.timer_in_list) {
|
||||
@@ -3413,6 +3416,7 @@ doq_timer_find_time(struct doq_table* table, struct timeval* tv)
|
||||
{
|
||||
struct doq_timer key;
|
||||
struct rbnode_type* node;
|
||||
log_assert(table != NULL);
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.time.tv_sec = tv->tv_sec;
|
||||
key.time.tv_usec = tv->tv_usec;
|
||||
@@ -4922,6 +4926,7 @@ doq_conid_find(struct doq_table* table, const uint8_t* data, size_t datalen)
|
||||
key.node.key = &key;
|
||||
key.cid = (void*)data;
|
||||
key.cidlen = datalen;
|
||||
log_assert(table != NULL);
|
||||
node = rbtree_search(table->conid_tree, &key);
|
||||
if(node)
|
||||
return (struct doq_conid*)node->key;
|
||||
@@ -5662,6 +5667,8 @@ doq_table_quic_size_available(struct doq_table* table,
|
||||
struct config_file* cfg, size_t mem)
|
||||
{
|
||||
size_t cur;
|
||||
if (!table)
|
||||
return 0;
|
||||
lock_basic_lock(&table->size_lock);
|
||||
cur = table->current_size;
|
||||
lock_basic_unlock(&table->size_lock);
|
||||
|
||||
+202
-3
@@ -41,6 +41,7 @@
|
||||
#include "config.h"
|
||||
#include "services/localzone.h"
|
||||
#include "sldns/str2wire.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/data/dname.h"
|
||||
@@ -356,6 +357,22 @@ rr_is_duplicate(struct packed_rrset_data* pd, uint8_t* rdata, size_t rdata_len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** see if rdata is duplicate */
|
||||
static int
|
||||
rr_is_duplicate_wol(struct packed_rrset_data* d, uint8_t* rdata_wol, size_t len)
|
||||
{
|
||||
size_t i, rdatawl_len = len+2;
|
||||
uint16_t len16 = htons(len);
|
||||
for(i=0; i<d->count + d->rrsig_count; i++) {
|
||||
if(d->rr_len[i] != rdatawl_len)
|
||||
continue;
|
||||
if(memcmp(d->rr_data[i], &len16, 2) == 0 &&
|
||||
memcmp(d->rr_data[i]+2, rdata_wol, len) == 0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** new local_rrset */
|
||||
static struct local_rrset*
|
||||
new_local_rrset(struct regional* region, struct local_data* node,
|
||||
@@ -393,6 +410,49 @@ new_local_rrset(struct regional* region, struct local_data* node,
|
||||
return rrset;
|
||||
}
|
||||
|
||||
/** insert RR into RRset data structure; Wastes a couple of bytes */
|
||||
int
|
||||
rrset_insert_rr_wol(struct regional* region, struct packed_rrset_data* pd,
|
||||
uint8_t* rdata_wol, size_t rdata_len, time_t ttl)
|
||||
{
|
||||
size_t* oldlen = pd->rr_len;
|
||||
time_t* oldttl = pd->rr_ttl;
|
||||
uint8_t** olddata = pd->rr_data;
|
||||
|
||||
/* add RR to rrset */
|
||||
if(pd->count > LOCALZONE_RRSET_COUNT_MAX) {
|
||||
log_warn("RRset has more than %d records, record ignored",
|
||||
LOCALZONE_RRSET_COUNT_MAX);
|
||||
return 1;
|
||||
}
|
||||
pd->count++;
|
||||
pd->rr_len = regional_alloc(region, sizeof(*pd->rr_len)*pd->count);
|
||||
pd->rr_ttl = regional_alloc(region, sizeof(*pd->rr_ttl)*pd->count);
|
||||
pd->rr_data = regional_alloc(region, sizeof(*pd->rr_data)*pd->count);
|
||||
if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
if(pd->count > 1) {
|
||||
memcpy(pd->rr_len+1, oldlen,
|
||||
sizeof(*pd->rr_len)*(pd->count-1));
|
||||
memcpy(pd->rr_ttl+1, oldttl,
|
||||
sizeof(*pd->rr_ttl)*(pd->count-1));
|
||||
memcpy(pd->rr_data+1, olddata,
|
||||
sizeof(*pd->rr_data)*(pd->count-1));
|
||||
}
|
||||
pd->rr_len[0] = rdata_len+2;
|
||||
pd->rr_ttl[0] = ttl;
|
||||
pd->rr_data[0] = regional_alloc(region, rdata_len+2);
|
||||
if(!pd->rr_data[0]) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
sldns_write_uint16(pd->rr_data[0], rdata_len);
|
||||
memmove(pd->rr_data[0]+2, rdata_wol, rdata_len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** insert RR into RRset data structure; Wastes a couple of bytes */
|
||||
int
|
||||
rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd,
|
||||
@@ -503,6 +563,48 @@ lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Mark the SOA record for the zone. This only marks the SOA rrset; the data
|
||||
* for the RR is entered later on local_zone_enter_rr() as with the other
|
||||
* records. An artificial soa_negative record with a modified TTL (minimum of
|
||||
* the TTL and the SOA.MINIMUM) is also created and marked for usage with
|
||||
* negative answers and to avoid allocations during those answers. */
|
||||
static int
|
||||
lz_mark_soa_for_zone_wol(struct local_zone* z, struct ub_packed_rrset_key* soa_rrset,
|
||||
uint8_t* rdata_wol, size_t rdata_len, time_t ttl)
|
||||
{
|
||||
struct packed_rrset_data* pd = (struct packed_rrset_data*)
|
||||
regional_alloc_zero(z->region, sizeof(*pd));
|
||||
struct ub_packed_rrset_key* rrset_negative = (struct ub_packed_rrset_key*)
|
||||
regional_alloc_zero(z->region, sizeof(*rrset_negative));
|
||||
time_t minimum;
|
||||
if(!rrset_negative||!pd) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
/* Mark the original SOA record and then continue with the negative one. */
|
||||
z->soa = soa_rrset;
|
||||
rrset_negative->entry.key = rrset_negative;
|
||||
pd->trust = rrset_trust_prim_noglue;
|
||||
pd->security = sec_status_insecure;
|
||||
rrset_negative->entry.data = pd;
|
||||
rrset_negative->rk.dname = soa_rrset->rk.dname;
|
||||
rrset_negative->rk.dname_len = soa_rrset->rk.dname_len;
|
||||
rrset_negative->rk.type = soa_rrset->rk.type;
|
||||
rrset_negative->rk.rrset_class = soa_rrset->rk.rrset_class;
|
||||
if(!rrset_insert_rr_wol(z->region, pd, rdata_wol, rdata_len, ttl))
|
||||
return 0;
|
||||
/* last 4 bytes are minimum ttl in network format */
|
||||
if(pd->count == 0 || pd->rr_len[0] < 2+4)
|
||||
return 0;
|
||||
minimum = (time_t)sldns_read_uint32(pd->rr_data[0]+(pd->rr_len[0]-4));
|
||||
minimum = ttl<minimum?ttl:minimum;
|
||||
pd->ttl = minimum;
|
||||
pd->rr_ttl[0] = minimum;
|
||||
|
||||
z->soa_negative = rrset_negative;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Mark the SOA record for the zone. This only marks the SOA rrset; the data
|
||||
* for the RR is entered later on local_zone_enter_rr() as with the other
|
||||
* records. An artificial soa_negative record with a modified TTL (minimum of
|
||||
@@ -545,6 +647,96 @@ lz_mark_soa_for_zone(struct local_zone* z, struct ub_packed_rrset_key* soa_rrset
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert dname, type, class, ttl, rdata to an rr string.
|
||||
* rdata without prefixed length. returned string is malloced.
|
||||
*/
|
||||
char* dname_rdata_to_str(uint8_t* dname, size_t dnamelen, uint16_t rrtype,
|
||||
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
char buf[65536], t[32], c[32], d[1024], result[65536+32+32+1024+1024];
|
||||
buf[0]=0; buf[sizeof(buf)-1]=0;
|
||||
d[0]=0; d[sizeof(d)-1]=0;
|
||||
(void)sldns_wire2str_rdata_buf(rdata, rdata_len, buf, sizeof(buf),
|
||||
rrtype);
|
||||
(void)sldns_wire2str_type_buf(rrtype, t, sizeof(t));
|
||||
(void)sldns_wire2str_class_buf(rrclass, c, sizeof(c));
|
||||
if(dname)
|
||||
(void)sldns_wire2str_dname_buf(dname, dnamelen, d, sizeof(d));
|
||||
snprintf(result, sizeof(result), "%s%s%u %s %s %s",
|
||||
dname, (dname?" ":""), (unsigned)ttl, c, t, d);
|
||||
return strdup(result);
|
||||
}
|
||||
|
||||
int
|
||||
local_zone_enter_rr_wol(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
|
||||
uint8_t* rdata_wol, size_t rdata_len)
|
||||
{
|
||||
struct local_data* node;
|
||||
struct local_rrset* rrset;
|
||||
struct packed_rrset_data* pd;
|
||||
|
||||
if(!lz_find_create_node(z, nm, nmlen, nmlabs, &node)) {
|
||||
return 0;
|
||||
}
|
||||
log_assert(node);
|
||||
|
||||
/* Reject it if we would end up having CNAME and other data (including
|
||||
* another CNAME) for a redirect zone. */
|
||||
if((z->type == local_zone_redirect ||
|
||||
z->type == local_zone_inform_redirect) && node->rrsets) {
|
||||
const char* othertype = NULL;
|
||||
if (rrtype == LDNS_RR_TYPE_CNAME)
|
||||
othertype = "other";
|
||||
else if (node->rrsets->rrset->rk.type ==
|
||||
htons(LDNS_RR_TYPE_CNAME)) {
|
||||
othertype = "CNAME";
|
||||
}
|
||||
if(othertype) {
|
||||
char* rrstr = dname_rdata_to_str(nm, nmlen, rrtype,
|
||||
rrclass, ttl, rdata_wol, rdata_len);
|
||||
log_err("local-data '%s' in redirect zone must not "
|
||||
"coexist with %s local-data", (rrstr?rrstr:"<out of memory>"), othertype);
|
||||
free(rrstr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
rrset = local_data_find_type(node, rrtype, 0);
|
||||
if(!rrset) {
|
||||
rrset = new_local_rrset(z->region, node, rrtype, rrclass);
|
||||
if(!rrset)
|
||||
return 0;
|
||||
if(query_dname_compare(node->name, z->name) == 0) {
|
||||
if(rrtype == LDNS_RR_TYPE_NSEC)
|
||||
rrset->rrset->rk.flags = PACKED_RRSET_NSEC_AT_APEX;
|
||||
if(rrtype == LDNS_RR_TYPE_SOA &&
|
||||
!lz_mark_soa_for_zone_wol(z, rrset->rrset, rdata_wol, rdata_len, ttl))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
pd = (struct packed_rrset_data*)rrset->rrset->entry.data;
|
||||
log_assert(rrset && pd);
|
||||
|
||||
/* check for duplicate RR */
|
||||
if(rr_is_duplicate_wol(pd, rdata_wol, rdata_len)) {
|
||||
char* rrstr = dname_rdata_to_str(nm, nmlen, rrtype,
|
||||
rrclass, ttl, rdata_wol, rdata_len);
|
||||
verbose(VERB_ALGO, "ignoring duplicate RR: %s", (rrstr?rrstr:"<out of memory>"));
|
||||
free(rrstr);
|
||||
return 1;
|
||||
}
|
||||
if(pd->count > LOCALZONE_RRSET_COUNT_MAX) {
|
||||
char* rrstr = dname_rdata_to_str(nm, nmlen, rrtype,
|
||||
rrclass, ttl, rdata_wol, rdata_len);
|
||||
log_warn("RRset %s has more than %d records, record ignored",
|
||||
(rrstr?rrstr:"<out of memory>"), LOCALZONE_RRSET_COUNT_MAX);
|
||||
free(rrstr);
|
||||
return 1;
|
||||
}
|
||||
return rrset_insert_rr_wol(z->region, pd, rdata_wol, rdata_len, ttl);
|
||||
}
|
||||
|
||||
int
|
||||
local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
|
||||
@@ -2039,7 +2231,7 @@ set_kiddo_parents(struct local_zone* z, struct local_zone* match,
|
||||
|
||||
struct local_zone* local_zones_add_zone(struct local_zones* zones,
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass,
|
||||
enum localzone_type tp)
|
||||
enum localzone_type tp, int* duplicate)
|
||||
{
|
||||
int exact;
|
||||
/* create */
|
||||
@@ -2047,6 +2239,7 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones,
|
||||
struct local_zone* z = local_zone_create(name, len, labs, tp, dclass);
|
||||
if(!z) {
|
||||
free(name);
|
||||
if(duplicate) *duplicate = 0;
|
||||
return NULL;
|
||||
}
|
||||
lock_rw_wrlock(&z->lock);
|
||||
@@ -2060,8 +2253,14 @@ struct local_zone* local_zones_add_zone(struct local_zones* zones,
|
||||
if(exact||!rbtree_insert(&zones->ztree, &z->node)) {
|
||||
/* duplicate entry! */
|
||||
lock_rw_unlock(&z->lock);
|
||||
if(duplicate) {
|
||||
*duplicate = 1;
|
||||
z->name = NULL; /* Do not delete the name in
|
||||
local_zone_delete. */
|
||||
}
|
||||
local_zone_delete(z);
|
||||
log_err("internal: duplicate entry in local_zones_add_zone");
|
||||
if(duplicate == NULL)
|
||||
log_err("internal: duplicate entry in local_zones_add_zone");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2105,7 +2304,7 @@ local_zones_add_RR(struct local_zones* zones, const char* rr)
|
||||
z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type);
|
||||
if(!z) {
|
||||
z = local_zones_add_zone(zones, rr_name, len, labs, rr_class,
|
||||
local_zone_transparent);
|
||||
local_zone_transparent, NULL);
|
||||
if(!z) {
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return 0;
|
||||
|
||||
+45
-1
@@ -403,11 +403,17 @@ local_zones_find_le(struct local_zones* zones,
|
||||
* @param labs: labelcount of name.
|
||||
* @param dclass: class to add.
|
||||
* @param tp: type.
|
||||
* @param duplicate: Allows to check if a NULL return from the function is a
|
||||
* memory error, or a duplicate entry. Pass NULL to have it not returned,
|
||||
* the name is freed on errors, and for a duplicate a log message is
|
||||
* printed. Pass not NULL, and when the error is a duplicate, the function
|
||||
* returns NULL, and the variable is set true. The name is not freed
|
||||
* when there is a duplicate, no error is printed by this function.
|
||||
* @return local_zone or NULL on error, caller must printout memory error.
|
||||
*/
|
||||
struct local_zone* local_zones_add_zone(struct local_zones* zones,
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass,
|
||||
enum localzone_type tp);
|
||||
enum localzone_type tp, int* duplicate);
|
||||
|
||||
/**
|
||||
* Delete a zone. Caller must hold the zones lock.
|
||||
@@ -526,6 +532,18 @@ int rrstr_get_rr_content(const char* str, uint8_t** nm, uint16_t* type,
|
||||
int rrset_insert_rr(struct regional* region, struct packed_rrset_data* pd,
|
||||
uint8_t* rdata, size_t rdata_len, time_t ttl, const char* rrstr);
|
||||
|
||||
/**
|
||||
* Insert specified rdata into the specified resource record.
|
||||
* @param region: allocator
|
||||
* @param pd: data portion of the destination resource record
|
||||
* @param rdata_wol: source rdata, without prefix len.
|
||||
* @param rdata_len: source rdata length
|
||||
* @param ttl: time to live
|
||||
* @return 1 on success; 0 otherwise.
|
||||
*/
|
||||
int rrset_insert_rr_wol(struct regional* region, struct packed_rrset_data* pd,
|
||||
uint8_t* rdata_wol, size_t rdata_len, time_t ttl);
|
||||
|
||||
/**
|
||||
* Remove RR from rrset that is created using localzone's rrset_insert_rr.
|
||||
* @param pd: the RRset containing the RR to remove
|
||||
@@ -631,6 +649,24 @@ local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, const char* rrstr);
|
||||
|
||||
/**
|
||||
* Add RR to local zone. Without prefix length on rdata.
|
||||
* @param z: local zone to add RR to
|
||||
* @param nm: dname of RR
|
||||
* @param nmlen: length of nm
|
||||
* @param nmlabs: number of labels of nm
|
||||
* @param rrtype: RR type
|
||||
* @param rrclass: RR class
|
||||
* @param ttl: TTL of RR to add
|
||||
* @param rdata_wol: RDATA of RR to add, without prefix length.
|
||||
* @param rdata_len: length of rdata, without prefix length.
|
||||
* @return: 1 on success
|
||||
*/
|
||||
int
|
||||
local_zone_enter_rr_wol(struct local_zone* z, uint8_t* nm, size_t nmlen,
|
||||
int nmlabs, uint16_t rrtype, uint16_t rrclass, time_t ttl,
|
||||
uint8_t* rdata_wol, size_t rdata_len);
|
||||
|
||||
/**
|
||||
* Find a data node by exact name for a local zone
|
||||
* @param z: local_zone containing data tree
|
||||
@@ -674,4 +710,12 @@ lz_enter_zone(struct local_zones* zones, const char* name, const char* type,
|
||||
*/
|
||||
void
|
||||
lz_init_parents(struct local_zones* zones);
|
||||
|
||||
/**
|
||||
* Convert dname, type, class, ttl, rdata to an rr string.
|
||||
* rdata without prefixed length. returned string is malloced.
|
||||
*/
|
||||
char* dname_rdata_to_str(uint8_t* dname, size_t dnamelen, uint16_t rrtype,
|
||||
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len);
|
||||
|
||||
#endif /* SERVICES_LOCALZONE_H */
|
||||
|
||||
+72
-43
@@ -231,6 +231,7 @@ mesh_create(struct module_stack* stack, struct module_env* env)
|
||||
mesh->ans_expired = 0;
|
||||
mesh->ans_cachedb = 0;
|
||||
mesh->num_queries_discard_timeout = 0;
|
||||
mesh->num_queries_replyaddr_limit = 0;
|
||||
mesh->num_queries_wait_limit = 0;
|
||||
mesh->num_dns_error_reports = 0;
|
||||
mesh->max_reply_states = env->cfg->num_queries_per_thread;
|
||||
@@ -348,7 +349,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;
|
||||
if(TTL_IS_EXPIRED(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)
|
||||
@@ -441,9 +442,18 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
if(!infra_wait_limit_allowed(mesh->env->infra_cache, rep,
|
||||
edns->cookie_valid, mesh->env->cfg)) {
|
||||
verbose(VERB_ALGO, "Too many queries waiting from the IP. "
|
||||
"dropping incoming query.");
|
||||
comm_point_drop_reply(rep);
|
||||
"servfail incoming query.");
|
||||
mesh->num_queries_wait_limit++;
|
||||
edns_opt_list_append_ede(&edns->opt_list_out,
|
||||
mesh->env->scratch, LDNS_EDE_OTHER,
|
||||
"Too many queries queued up and waiting from the IP");
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
|
||||
LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, mesh->env->now_tv))
|
||||
edns->opt_list_inplace_cb_out = NULL;
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
regional_free_all(mesh->env->scratch);
|
||||
comm_point_send_reply(rep);
|
||||
return;
|
||||
}
|
||||
if(!unique)
|
||||
@@ -453,6 +463,8 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
if(!mesh_make_new_space(mesh, rep->c->buffer)) {
|
||||
verbose(VERB_ALGO, "Too many queries. dropping "
|
||||
"incoming query.");
|
||||
if(rep->c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->c->h2_stream);
|
||||
comm_point_drop_reply(rep);
|
||||
mesh->stats_dropped++;
|
||||
return;
|
||||
@@ -464,8 +476,10 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
if(mesh->num_reply_addrs > mesh->max_reply_states*16) {
|
||||
verbose(VERB_ALGO, "Too many requests queued. "
|
||||
"dropping incoming query.");
|
||||
if(rep->c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->c->h2_stream);
|
||||
comm_point_drop_reply(rep);
|
||||
mesh->stats_dropped++;
|
||||
mesh->num_queries_replyaddr_limit++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1152,8 +1166,7 @@ mesh_detect_cycle_found(struct module_qstate* qstate, struct mesh_state* dep_m)
|
||||
{
|
||||
struct mesh_state* cyc_m = qstate->mesh_info;
|
||||
size_t counter = 0;
|
||||
if(!dep_m)
|
||||
return 0;
|
||||
log_assert(dep_m);
|
||||
if(dep_m == cyc_m || find_in_subsub(dep_m, cyc_m, &counter)) {
|
||||
if(counter > MESH_MAX_SUBSUB)
|
||||
return 2;
|
||||
@@ -1190,24 +1203,19 @@ void mesh_detach_subs(struct module_qstate* qstate)
|
||||
}
|
||||
|
||||
int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
uint16_t qflags, int prime, int valrec, struct module_qstate** newq,
|
||||
struct mesh_state** sub)
|
||||
struct respip_client_info* cinfo, uint16_t qflags, int prime,
|
||||
int valrec, struct module_qstate** newq, struct mesh_state** sub)
|
||||
{
|
||||
/* find it, if not, create it */
|
||||
struct mesh_area* mesh = qstate->env->mesh;
|
||||
*sub = mesh_area_find(mesh, NULL, qinfo, qflags,
|
||||
prime, valrec);
|
||||
if(mesh_detect_cycle_found(qstate, *sub)) {
|
||||
verbose(VERB_ALGO, "attach failed, cycle detected");
|
||||
return 0;
|
||||
}
|
||||
*sub = mesh_area_find(mesh, cinfo, qinfo, qflags, prime, valrec);
|
||||
if(!*sub) {
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
/* create a new one */
|
||||
*sub = mesh_state_create(qstate->env, qinfo, NULL, qflags, prime,
|
||||
valrec);
|
||||
*sub = mesh_state_create(qstate->env, qinfo, cinfo, qflags,
|
||||
prime, valrec);
|
||||
if(!*sub) {
|
||||
log_err("mesh_attach_sub: out of memory");
|
||||
return 0;
|
||||
@@ -1230,18 +1238,25 @@ int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
rbtree_insert(&mesh->run, &(*sub)->run_node);
|
||||
log_assert(n != NULL);
|
||||
*newq = &(*sub)->s;
|
||||
} else
|
||||
} else {
|
||||
*newq = NULL;
|
||||
if(mesh_detect_cycle_found(qstate, *sub)) {
|
||||
verbose(VERB_ALGO, "attach failed, cycle detected");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
uint16_t qflags, int prime, int valrec, struct module_qstate** newq)
|
||||
struct respip_client_info* cinfo, uint16_t qflags, int prime,
|
||||
int valrec, struct module_qstate** newq)
|
||||
{
|
||||
struct mesh_area* mesh = qstate->env->mesh;
|
||||
struct mesh_state* sub = NULL;
|
||||
int was_detached;
|
||||
if(!mesh_add_sub(qstate, qinfo, qflags, prime, valrec, newq, &sub))
|
||||
if(!mesh_add_sub(qstate, qinfo, cinfo, qflags, prime, valrec, newq,
|
||||
&sub))
|
||||
return 0;
|
||||
was_detached = (sub->super_set.count == 0);
|
||||
if(!mesh_state_attachment(qstate->mesh_info, sub))
|
||||
@@ -1684,7 +1699,7 @@ static void dns_error_reporting(struct module_qstate* qstate,
|
||||
|
||||
log_query_info(VERB_ALGO, "DNS Error Reporting: generating report "
|
||||
"query for", &qinfo);
|
||||
if(mesh_add_sub(qstate, &qinfo, BIT_RD, 0, 0, &newq, &sub)) {
|
||||
if(mesh_add_sub(qstate, &qinfo, NULL, BIT_RD, 0, 0, &newq, &sub)) {
|
||||
qstate->env->mesh->num_dns_error_reports++;
|
||||
}
|
||||
return;
|
||||
@@ -1727,28 +1742,39 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
dns_error_reporting(&mstate->s, rep);
|
||||
|
||||
for(r = mstate->reply_list; r; r = r->next) {
|
||||
struct timeval old;
|
||||
timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time);
|
||||
if(mstate->s.env->cfg->discard_timeout != 0 &&
|
||||
((int)old.tv_sec)*1000+((int)old.tv_usec)/1000 >
|
||||
mstate->s.env->cfg->discard_timeout) {
|
||||
/* Drop the reply, it is too old */
|
||||
/* briefly set the reply_list to NULL, so that the
|
||||
* tcp req info cleanup routine that calls the mesh
|
||||
* to deregister the meshstate for it is not done
|
||||
* because the list is NULL and also accounting is not
|
||||
* done there, but instead we do that here. */
|
||||
struct mesh_reply* reply_list = mstate->reply_list;
|
||||
verbose(VERB_ALGO, "drop reply, it is older than discard-timeout");
|
||||
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->num_queries_discard_timeout++;
|
||||
continue;
|
||||
if(mesh_is_udp(r)) {
|
||||
/* For UDP queries, the old replies are discarded.
|
||||
* This stops a large volume of old replies from
|
||||
* building up.
|
||||
* The stream replies, are not discarded. The
|
||||
* stream is open, the other side is waiting.
|
||||
* Some answer is needed, even if servfail, but the
|
||||
* real reply is ready to go, so that is given. */
|
||||
struct timeval old;
|
||||
timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time);
|
||||
if(mstate->s.env->cfg->discard_timeout != 0 &&
|
||||
((int)old.tv_sec)*1000+((int)old.tv_usec)/1000 >
|
||||
mstate->s.env->cfg->discard_timeout) {
|
||||
/* Drop the reply, it is too old */
|
||||
/* briefly set the reply_list to NULL, so that the
|
||||
* tcp req info cleanup routine that calls the mesh
|
||||
* to deregister the meshstate for it is not done
|
||||
* because the list is NULL and also accounting is not
|
||||
* done there, but instead we do that here. */
|
||||
struct mesh_reply* reply_list = mstate->reply_list;
|
||||
verbose(VERB_ALGO, "drop reply, it is older than discard-timeout");
|
||||
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;
|
||||
log_assert(mstate->s.env->mesh->num_reply_addrs > 0);
|
||||
mstate->s.env->mesh->num_reply_addrs--;
|
||||
mstate->s.env->mesh->num_queries_discard_timeout++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
@@ -1782,6 +1808,8 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
}
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
log_assert(mstate->s.env->mesh->num_reply_addrs > 0);
|
||||
mstate->s.env->mesh->num_reply_addrs--;
|
||||
} else {
|
||||
struct sldns_buffer* r_buffer = r->query_reply.c->buffer;
|
||||
if(r->query_reply.c->tcp_req_info) {
|
||||
@@ -2272,6 +2300,7 @@ mesh_stats_clear(struct mesh_area* mesh)
|
||||
memset(&mesh->rpz_action[0], 0, sizeof(size_t)*UB_STATS_RPZ_ACTION_NUM);
|
||||
mesh->ans_nodata = 0;
|
||||
mesh->num_queries_discard_timeout = 0;
|
||||
mesh->num_queries_replyaddr_limit = 0;
|
||||
mesh->num_queries_wait_limit = 0;
|
||||
mesh->num_dns_error_reports = 0;
|
||||
}
|
||||
@@ -2297,7 +2326,7 @@ mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
struct mesh_area* mesh = qstate->env->mesh;
|
||||
struct mesh_state* dep_m = NULL;
|
||||
dep_m = mesh_area_find(mesh, NULL, qinfo, flags, prime, valrec);
|
||||
return mesh_detect_cycle_found(qstate, dep_m);
|
||||
return dep_m?mesh_detect_cycle_found(qstate, dep_m):0;
|
||||
}
|
||||
|
||||
void mesh_list_insert(struct mesh_state* m, struct mesh_state** fp,
|
||||
|
||||
+10
-3
@@ -141,6 +141,8 @@ struct mesh_area {
|
||||
size_t rpz_action[UB_STATS_RPZ_ACTION_NUM];
|
||||
/** stats, number of queries removed due to discard-timeout */
|
||||
size_t num_queries_discard_timeout;
|
||||
/** stats, number of queries removed due to replyaddr limit */
|
||||
size_t num_queries_replyaddr_limit;
|
||||
/** stats, number of queries removed due to wait-limit */
|
||||
size_t num_queries_wait_limit;
|
||||
/** stats, number of dns error reports generated */
|
||||
@@ -399,6 +401,8 @@ void mesh_detach_subs(struct module_qstate* qstate);
|
||||
* @param qstate: the state to find mesh state, and that wants to receive
|
||||
* the results from the new subquery.
|
||||
* @param qinfo: what to query for (copied).
|
||||
* @param cinfo: if non-NULL client specific info that may affect IP-based
|
||||
* actions that apply to the query result. It is copied.
|
||||
* @param qflags: what flags to use (RD / CD flag or not).
|
||||
* @param prime: if it is a (stub) priming query.
|
||||
* @param valrec: if it is a validation recursion query (lookup of key, DS).
|
||||
@@ -407,7 +411,8 @@ void mesh_detach_subs(struct module_qstate* qstate);
|
||||
* @return: false on error, true if success (and init may be needed).
|
||||
*/
|
||||
int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
uint16_t qflags, int prime, int valrec, struct module_qstate** newq);
|
||||
struct respip_client_info* cinfo, uint16_t qflags, int prime,
|
||||
int valrec, struct module_qstate** newq);
|
||||
|
||||
/**
|
||||
* Add detached query.
|
||||
@@ -426,6 +431,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
* @param qstate: the state to find mesh state, and that wants to receive
|
||||
* the results from the new subquery.
|
||||
* @param qinfo: what to query for (copied).
|
||||
* @param cinfo: if non-NULL client specific info that may affect IP-based
|
||||
* actions that apply to the query result. It is copied.
|
||||
* @param qflags: what flags to use (RD / CD flag or not).
|
||||
* @param prime: if it is a (stub) priming query.
|
||||
* @param valrec: if it is a validation recursion query (lookup of key, DS).
|
||||
@@ -435,8 +442,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
* @return: false on error, true if success (and init may be needed).
|
||||
*/
|
||||
int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo,
|
||||
uint16_t qflags, int prime, int valrec, struct module_qstate** newq,
|
||||
struct mesh_state** sub);
|
||||
struct respip_client_info* cinfo, uint16_t qflags, int prime,
|
||||
int valrec, struct module_qstate** newq, struct mesh_state** sub);
|
||||
|
||||
/**
|
||||
* Query state is done, send messages to reply entries.
|
||||
|
||||
+5
-2
@@ -262,6 +262,7 @@ int
|
||||
modstack_call_init(struct module_stack* stack, const char* module_conf,
|
||||
struct module_env* env)
|
||||
{
|
||||
const char* orig_module_conf = module_conf;
|
||||
int i, changed = 0;
|
||||
env->need_to_validate = 0; /* set by module init below */
|
||||
for(i=0; i<stack->num; i++) {
|
||||
@@ -276,11 +277,13 @@ modstack_call_init(struct module_stack* stack, const char* module_conf,
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
module_conf += strlen(stack->mod[i]->name);
|
||||
/* Skip this module name in module_conf. */
|
||||
while(*module_conf && !isspace((unsigned char)*module_conf))
|
||||
module_conf++;
|
||||
}
|
||||
if(changed) {
|
||||
modstack_free(stack);
|
||||
if(!modstack_config(stack, module_conf)) {
|
||||
if(!modstack_config(stack, orig_module_conf)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,10 @@
|
||||
#include "util/regional.h"
|
||||
#include "util/netevent.h"
|
||||
#include "dnstap/dnstap_config.h"
|
||||
#ifdef __QNX__
|
||||
/* For struct timeval */
|
||||
#include <sys/time.h>
|
||||
#endif /* __QNX__ */
|
||||
struct pending;
|
||||
struct pending_timeout;
|
||||
struct ub_randstate;
|
||||
|
||||
+86
-82
@@ -170,15 +170,14 @@ rpz_type_ignored(uint16_t rr_type)
|
||||
/**
|
||||
* Classify RPZ action for RR type/rdata
|
||||
* @param rr_type: the RR type
|
||||
* @param rdatawl: RDATA with 2 bytes length
|
||||
* @param rdatalen: the length of rdatawl (including its 2 bytes length)
|
||||
* @param rdata: RDATA without 2 bytes length
|
||||
* @param rdatalen: the length of rdatawl (not including its 2 bytes length)
|
||||
* @return: the RPZ action
|
||||
*/
|
||||
static enum rpz_action
|
||||
rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
||||
rpz_rr_to_action_wol(uint16_t rr_type, uint8_t* rdata, size_t rdatalen)
|
||||
{
|
||||
char* endptr;
|
||||
uint8_t* rdata;
|
||||
int rdatalabs;
|
||||
uint8_t* tldlab = NULL;
|
||||
|
||||
@@ -202,11 +201,10 @@ rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
||||
|
||||
/* use CNAME target to determine RPZ action */
|
||||
log_assert(rr_type == LDNS_RR_TYPE_CNAME);
|
||||
if(rdatalen < 3)
|
||||
if(rdatalen < 1)
|
||||
return RPZ_INVALID_ACTION;
|
||||
|
||||
rdata = rdatawl + 2; /* 2 bytes of rdata length */
|
||||
if(dname_valid(rdata, rdatalen-2) != rdatalen-2)
|
||||
if(dname_valid(rdata, rdatalen) != rdatalen)
|
||||
return RPZ_INVALID_ACTION;
|
||||
|
||||
rdatalabs = dname_count_labels(rdata);
|
||||
@@ -226,7 +224,7 @@ rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
||||
}
|
||||
|
||||
/* all other TLDs starting with "rpz-" are invalid */
|
||||
tldlab = get_tld_label(rdata, rdatalen-2);
|
||||
tldlab = get_tld_label(rdata, rdatalen);
|
||||
if(tldlab && dname_lab_startswith(tldlab, "rpz-", &endptr))
|
||||
return RPZ_INVALID_ACTION;
|
||||
|
||||
@@ -234,6 +232,21 @@ rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
||||
return RPZ_LOCAL_DATA_ACTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Classify RPZ action for RR type/rdata
|
||||
* @param rr_type: the RR type
|
||||
* @param rdatawl: RDATA with 2 bytes length
|
||||
* @param rdatalen: the length of rdatawl (including its 2 bytes length)
|
||||
* @return: the RPZ action
|
||||
*/
|
||||
static enum rpz_action
|
||||
rpz_rr_to_action(uint16_t rr_type, uint8_t* rdatawl, size_t rdatalen)
|
||||
{
|
||||
if(rdatalen < 2)
|
||||
return RPZ_INVALID_ACTION;
|
||||
return rpz_rr_to_action_wol(rr_type, rdatawl+2, rdatalen-2);
|
||||
}
|
||||
|
||||
static enum localzone_type
|
||||
rpz_action_to_localzone_type(enum rpz_action a)
|
||||
{
|
||||
@@ -658,7 +671,7 @@ strip_dname_origin(uint8_t* dname, size_t dnamelen, size_t originlen,
|
||||
static void
|
||||
rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
|
||||
size_t dnamelen, enum rpz_action a, uint16_t rrtype, uint16_t rrclass,
|
||||
uint32_t ttl, uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
|
||||
uint32_t ttl, uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
struct local_zone* z;
|
||||
enum localzone_type tp = local_zone_always_transparent;
|
||||
@@ -685,20 +698,41 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
|
||||
return;
|
||||
}
|
||||
|
||||
/* For not a local-data action.
|
||||
* Insert the zone, then detect a duplicate, instead of find it first,
|
||||
* for speed of searching the tree once. */
|
||||
if(a != RPZ_LOCAL_DATA_ACTION) {
|
||||
int duplicate = 0;
|
||||
lock_rw_wrlock(&lz->lock);
|
||||
tp = rpz_action_to_localzone_type(a);
|
||||
z = local_zones_add_zone(lz, dname, dnamelen,
|
||||
dnamelabs, rrclass, tp, &duplicate);
|
||||
if(z == NULL) {
|
||||
if(duplicate) {
|
||||
char* rrstr = dname_rdata_to_str(dname, dnamelen, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len);
|
||||
verbose(VERB_ALGO, "rpz: skipping duplicate record: %s", (rrstr?rrstr:"<out of memory>"));
|
||||
free(rrstr);
|
||||
free(dname);
|
||||
lock_rw_unlock(&lz->lock);
|
||||
return;
|
||||
}
|
||||
log_warn("rpz: create failed, out of memory");
|
||||
lock_rw_unlock(&lz->lock);
|
||||
/* dname will be free'd in failed local_zone_create() */
|
||||
return;
|
||||
}
|
||||
lock_rw_unlock(&lz->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
lock_rw_wrlock(&lz->lock);
|
||||
/* exact match */
|
||||
z = local_zones_find(lz, dname, dnamelen, dnamelabs, LDNS_RR_CLASS_IN);
|
||||
if(z != NULL && a != RPZ_LOCAL_DATA_ACTION) {
|
||||
char* rrstr = sldns_wire2str_rr(rr, rr_len);
|
||||
if(rrstr == NULL) {
|
||||
log_err("malloc error while inserting rpz nsdname trigger");
|
||||
free(dname);
|
||||
lock_rw_unlock(&lz->lock);
|
||||
return;
|
||||
}
|
||||
if(rrstr[0])
|
||||
rrstr[strlen(rrstr)-1]=0; /* remove newline */
|
||||
verbose(VERB_ALGO, "rpz: skipping duplicate record: '%s'", rrstr);
|
||||
char* rrstr = dname_rdata_to_str(dname, dnamelen, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len);
|
||||
verbose(VERB_ALGO, "rpz: skipping duplicate record: %s", (rrstr?rrstr:"<out of memory>"));
|
||||
free(rrstr);
|
||||
free(dname);
|
||||
lock_rw_unlock(&lz->lock);
|
||||
@@ -707,7 +741,7 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
|
||||
if(z == NULL) {
|
||||
tp = rpz_action_to_localzone_type(a);
|
||||
z = local_zones_add_zone(lz, dname, dnamelen,
|
||||
dnamelabs, rrclass, tp);
|
||||
dnamelabs, rrclass, tp, NULL);
|
||||
if(z == NULL) {
|
||||
log_warn("rpz: create failed");
|
||||
lock_rw_unlock(&lz->lock);
|
||||
@@ -717,18 +751,10 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
|
||||
newzone = 1;
|
||||
}
|
||||
if(a == RPZ_LOCAL_DATA_ACTION) {
|
||||
char* rrstr = sldns_wire2str_rr(rr, rr_len);
|
||||
if(rrstr == NULL) {
|
||||
log_err("malloc error while inserting rpz nsdname trigger");
|
||||
free(dname);
|
||||
lock_rw_unlock(&lz->lock);
|
||||
return;
|
||||
}
|
||||
lock_rw_wrlock(&z->lock);
|
||||
local_zone_enter_rr(z, dname, dnamelen, dnamelabs, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len, rrstr);
|
||||
local_zone_enter_rr_wol(z, dname, dnamelen, dnamelabs, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len);
|
||||
lock_rw_unlock(&z->lock);
|
||||
free(rrstr);
|
||||
}
|
||||
if(!newzone) {
|
||||
free(dname);
|
||||
@@ -748,7 +774,7 @@ rpz_log_dname(char const* msg, uint8_t* dname, size_t dname_len)
|
||||
static void
|
||||
rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
|
||||
uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
if(a == RPZ_INVALID_ACTION) {
|
||||
verbose(VERB_ALGO, "rpz: skipping invalid action");
|
||||
@@ -757,7 +783,7 @@ rpz_insert_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
}
|
||||
|
||||
rpz_insert_local_zones_trigger(r->local_zones, dname, dnamelen, a, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len, rr, rr_len);
|
||||
rrclass, ttl, rdata, rdata_len);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -799,7 +825,7 @@ rpz_strip_nsdname_suffix(uint8_t* dname, size_t maxdnamelen,
|
||||
static void
|
||||
rpz_insert_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
|
||||
uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
uint8_t* dname_stripped = NULL;
|
||||
size_t dnamelen_stripped = 0;
|
||||
@@ -814,32 +840,22 @@ rpz_insert_nsdname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
|
||||
/* dname_stripped is consumed or freed by the insert routine */
|
||||
rpz_insert_local_zones_trigger(r->nsdname_zones, dname_stripped,
|
||||
dnamelen_stripped, a, rrtype, rrclass, ttl, rdata, rdata_len,
|
||||
rr, rr_len);
|
||||
dnamelen_stripped, a, rrtype, rrclass, ttl, rdata, rdata_len);
|
||||
}
|
||||
|
||||
static int
|
||||
rpz_insert_ipaddr_based_trigger(struct respip_set* set, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype,
|
||||
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len,
|
||||
uint8_t* rr, size_t rr_len)
|
||||
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
struct resp_addr* node;
|
||||
char* rrstr;
|
||||
enum respip_action respa = rpz_action_to_respip_action(a);
|
||||
|
||||
lock_rw_wrlock(&set->lock);
|
||||
rrstr = sldns_wire2str_rr(rr, rr_len);
|
||||
if(rrstr == NULL) {
|
||||
log_err("malloc error while inserting rpz ipaddr based trigger");
|
||||
lock_rw_unlock(&set->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
node = respip_sockaddr_find_or_create(set, addr, addrlen, net, 1, rrstr);
|
||||
node = respip_sockaddr_find_or_create(set, addr, addrlen, net, 1);
|
||||
if(node == NULL) {
|
||||
lock_rw_unlock(&set->lock);
|
||||
free(rrstr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -849,12 +865,11 @@ rpz_insert_ipaddr_based_trigger(struct respip_set* set, struct sockaddr_storage*
|
||||
node->action = respa;
|
||||
|
||||
if(a == RPZ_LOCAL_DATA_ACTION) {
|
||||
respip_enter_rr(set->region, node, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len, rrstr, "");
|
||||
respip_enter_rr_wol(set->region, node, rrtype,
|
||||
rrclass, ttl, rdata, rdata_len, "");
|
||||
}
|
||||
|
||||
lock_rw_unlock(&node->lock);
|
||||
free(rrstr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -890,17 +905,6 @@ rpz_clientip_ensure_entry(struct clientip_synthesized_rrset* set,
|
||||
return node;
|
||||
}
|
||||
|
||||
static void
|
||||
rpz_report_rrset_error(const char* msg, uint8_t* rr, size_t rr_len) {
|
||||
char* rrstr = sldns_wire2str_rr(rr, rr_len);
|
||||
if(rrstr == NULL) {
|
||||
log_err("malloc error while inserting rpz clientip based record");
|
||||
return;
|
||||
}
|
||||
log_err("rpz: unexpected: unable to insert %s: %s", msg, rrstr);
|
||||
free(rrstr);
|
||||
}
|
||||
|
||||
/* from localzone.c; difference is we don't have a dname */
|
||||
static struct local_rrset*
|
||||
rpz_clientip_new_rrset(struct regional* region,
|
||||
@@ -958,14 +962,13 @@ rpz_clientip_enter_rr(struct regional* region, struct clientip_synthesized_rr* r
|
||||
return 0;
|
||||
}
|
||||
|
||||
return rrset_insert_rr(region, rrset->rrset->entry.data, rdata, rdata_len, ttl, "");
|
||||
return rrset_insert_rr_wol(region, rrset->rrset->entry.data, rdata, rdata_len, ttl);
|
||||
}
|
||||
|
||||
static int
|
||||
rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int net, enum rpz_action a, uint16_t rrtype,
|
||||
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len,
|
||||
uint8_t* rr, size_t rr_len)
|
||||
uint16_t rrclass, uint32_t ttl, uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
struct clientip_synthesized_rr* node;
|
||||
|
||||
@@ -973,8 +976,14 @@ rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct so
|
||||
|
||||
node = rpz_clientip_ensure_entry(set, addr, addrlen, net);
|
||||
if(node == NULL) {
|
||||
char as[64], *rrstr;
|
||||
lock_rw_unlock(&set->lock);
|
||||
rpz_report_rrset_error("client ip address", rr, rr_len);
|
||||
addr_to_str(addr, addrlen, as, sizeof(as));
|
||||
rrstr = dname_rdata_to_str(NULL, 0, rrtype, rrclass, ttl,
|
||||
rdata, rdata_len);
|
||||
log_err("rpz: unexpected: unable to insert %s: %s/%d %s",
|
||||
"client ip address", as, net, (rrstr?rrstr:"<out of memory>"));
|
||||
free(rrstr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1000,7 +1009,7 @@ rpz_clientip_insert_trigger_rr(struct clientip_synthesized_rrset* set, struct so
|
||||
static int
|
||||
rpz_insert_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
|
||||
uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
@@ -1016,13 +1025,13 @@ rpz_insert_clientip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
}
|
||||
|
||||
return rpz_clientip_insert_trigger_rr(r->client_set, &addr, addrlen, net,
|
||||
a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
|
||||
a, rrtype, rrclass, ttl, rdata, rdata_len);
|
||||
}
|
||||
|
||||
static int
|
||||
rpz_insert_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
|
||||
uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
@@ -1038,14 +1047,14 @@ rpz_insert_nsip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
}
|
||||
|
||||
return rpz_clientip_insert_trigger_rr(r->ns_set, &addr, addrlen, net,
|
||||
a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
|
||||
a, rrtype, rrclass, ttl, rdata, rdata_len);
|
||||
}
|
||||
|
||||
/** Insert RR into RPZ's respip_set */
|
||||
static int
|
||||
rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
enum rpz_action a, uint16_t rrtype, uint16_t rrclass, uint32_t ttl,
|
||||
uint8_t* rdata, size_t rdata_len, uint8_t* rr, size_t rr_len)
|
||||
uint8_t* rdata, size_t rdata_len)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
@@ -1070,13 +1079,13 @@ rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
|
||||
}
|
||||
|
||||
return rpz_insert_ipaddr_based_trigger(r->respip_set, &addr, addrlen, net,
|
||||
a, rrtype, rrclass, ttl, rdata, rdata_len, rr, rr_len);
|
||||
a, rrtype, rrclass, ttl, rdata, rdata_len);
|
||||
}
|
||||
|
||||
int
|
||||
rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
|
||||
size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
|
||||
uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len)
|
||||
uint8_t* rdatawol, size_t rdatalen)
|
||||
{
|
||||
size_t policydnamelen;
|
||||
/* name is free'd in local_zone delete */
|
||||
@@ -1110,7 +1119,7 @@ rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
|
||||
return 0;
|
||||
}
|
||||
|
||||
a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
|
||||
a = rpz_rr_to_action_wol(rr_type, rdatawol, rdatalen);
|
||||
if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
|
||||
policydname, (dnamelen-aznamelen)+1))) {
|
||||
free(policydname);
|
||||
@@ -1125,27 +1134,22 @@ rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
|
||||
if(t == RPZ_QNAME_TRIGGER) {
|
||||
/* policydname will be consumed, no free */
|
||||
rpz_insert_qname_trigger(r, policydname, policydnamelen,
|
||||
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
|
||||
rr_len);
|
||||
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
|
||||
} else if(t == RPZ_RESPONSE_IP_TRIGGER) {
|
||||
rpz_insert_response_ip_trigger(r, policydname, policydnamelen,
|
||||
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
|
||||
rr_len);
|
||||
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
|
||||
free(policydname);
|
||||
} else if(t == RPZ_CLIENT_IP_TRIGGER) {
|
||||
rpz_insert_clientip_trigger(r, policydname, policydnamelen,
|
||||
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
|
||||
rr_len);
|
||||
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
|
||||
free(policydname);
|
||||
} else if(t == RPZ_NSIP_TRIGGER) {
|
||||
rpz_insert_nsip_trigger(r, policydname, policydnamelen,
|
||||
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
|
||||
rr_len);
|
||||
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
|
||||
free(policydname);
|
||||
} else if(t == RPZ_NSDNAME_TRIGGER) {
|
||||
rpz_insert_nsdname_trigger(r, policydname, policydnamelen,
|
||||
a, rr_type, rr_class, rr_ttl, rdatawl, rdatalen, rr,
|
||||
rr_len);
|
||||
a, rr_type, rr_class, rr_ttl, rdatawol, rdatalen);
|
||||
free(policydname);
|
||||
} else {
|
||||
free(policydname);
|
||||
|
||||
+3
-5
@@ -136,15 +136,13 @@ struct rpz {
|
||||
* @param rr_type: RR type of the RR
|
||||
* @param rr_class: RR class of the RR
|
||||
* @param rr_ttl: TTL of the RR
|
||||
* @param rdatawl: rdata of the RR, prepended with the rdata size
|
||||
* @param rdatalen: length if the RR, including the prepended rdata size
|
||||
* @param rr: the complete RR, for logging purposes
|
||||
* @param rr_len: the length of the complete RR
|
||||
* @param rdatawol: rdata of the RR, not prepended with the rdata size
|
||||
* @param rdatalen: length if the RR, not including the prepended rdata size
|
||||
* @return: 0 on error
|
||||
*/
|
||||
int rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
|
||||
size_t dnamelen, uint16_t rr_type, uint16_t rr_class, uint32_t rr_ttl,
|
||||
uint8_t* rdatawl, size_t rdatalen, uint8_t* rr, size_t rr_len);
|
||||
uint8_t* rdatawol, size_t rdatalen);
|
||||
|
||||
/**
|
||||
* Delete policy matching RR, used for IXFR.
|
||||
|
||||
Submodule
+1
Submodule simdzone added at eca67807d0
+3
-1
@@ -480,11 +480,13 @@ enum sldns_enum_ede_code
|
||||
LDNS_EDE_TOO_EARLY = 26,
|
||||
LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS = 27,
|
||||
LDNS_EDE_BADPROXYPOLICY = 28,
|
||||
LDNS_EDE_SYNTHESIZED = 29
|
||||
LDNS_EDE_SYNTHESIZED = 29,
|
||||
LDNS_EDE_INVALID_QUERY_TYPE = 30
|
||||
};
|
||||
typedef enum sldns_enum_ede_code sldns_ede_code;
|
||||
|
||||
#define LDNS_EDNS_MASK_DO_BIT 0x8000
|
||||
#define LDNS_EDNS_MASK_CO_BIT 0x4000
|
||||
|
||||
/** TSIG and TKEY extended rcodes (16bit), 0-15 are the normal rcodes. */
|
||||
#define LDNS_TSIG_ERROR_NOERROR 0
|
||||
|
||||
@@ -233,6 +233,7 @@ static sldns_lookup_table sldns_edns_ede_codes_data[] = {
|
||||
{ LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS, "Unsupported NSEC3 Iterations Value" },
|
||||
{ LDNS_EDE_BADPROXYPOLICY, "Unable to Conform to Policy" },
|
||||
{ LDNS_EDE_SYNTHESIZED, "Synthesized Answer" },
|
||||
{ LDNS_EDE_INVALID_QUERY_TYPE, "Invalid Query Type" },
|
||||
{ 0, NULL}
|
||||
};
|
||||
sldns_lookup_table* sldns_edns_ede_codes = sldns_edns_ede_codes_data;
|
||||
@@ -2485,6 +2486,8 @@ int sldns_wire2str_edns_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
w += sldns_str_print(str, str_len, " flags:");
|
||||
if((edns_bits & LDNS_EDNS_MASK_DO_BIT))
|
||||
w += sldns_str_print(str, str_len, " do");
|
||||
if((edns_bits & LDNS_EDNS_MASK_CO_BIT))
|
||||
w += sldns_str_print(str, str_len, " co");
|
||||
/* the extended rcode is the value set, shifted four bits,
|
||||
* and or'd with the original rcode */
|
||||
if(ext_rcode) {
|
||||
|
||||
@@ -783,7 +783,6 @@ morechecks(struct config_file* cfg)
|
||||
/* check that the modules listed in module_conf exist */
|
||||
check_modules_exist(cfg->module_conf);
|
||||
|
||||
/* Respip is known to *not* work with dns64. */
|
||||
if(strcmp(cfg->module_conf, "iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 validator iterator") != 0
|
||||
@@ -869,6 +868,7 @@ morechecks(struct config_file* cfg)
|
||||
&& strcmp(cfg->module_conf, "respip cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip dns64 validator cachedb iterator") != 0
|
||||
#endif
|
||||
#if defined(WITH_PYTHONMODULE) && defined(USE_CACHEDB)
|
||||
&& strcmp(cfg->module_conf, "python dns64 cachedb iterator") != 0
|
||||
|
||||
@@ -236,6 +236,8 @@ static void pr_stats(const char* nm, struct ub_stats_info* s)
|
||||
s->svr.num_queries_cookie_invalid);
|
||||
PR_UL_NM("num.queries_discard_timeout",
|
||||
s->svr.num_queries_discard_timeout);
|
||||
PR_UL_NM("num.queries_replyaddr_limit",
|
||||
s->svr.num_queries_replyaddr_limit);
|
||||
PR_UL_NM("num.queries_wait_limit", s->svr.num_queries_wait_limit);
|
||||
PR_UL_NM("num.cachehits",
|
||||
s->svr.num_queries - s->svr.num_queries_missed_cache);
|
||||
@@ -263,6 +265,7 @@ static void pr_stats(const char* nm, struct ub_stats_info* s)
|
||||
PR_UL_NM("requestlist.exceeded", s->mesh_dropped);
|
||||
PR_UL_NM("requestlist.current.all", s->mesh_num_states);
|
||||
PR_UL_NM("requestlist.current.user", s->mesh_num_reply_states);
|
||||
PR_UL_NM("requestlist.current.replies", s->mesh_num_reply_addrs);
|
||||
#ifndef S_SPLINT_S
|
||||
sumwait.tv_sec = s->mesh_replies_sum_wait_sec;
|
||||
sumwait.tv_usec = s->mesh_replies_sum_wait_usec;
|
||||
|
||||
@@ -2255,7 +2255,7 @@ create_doq_client_data(const char* svr, int port, struct ub_event_base* base,
|
||||
/* Initialize the ossl crypto, it is harmless to call twice,
|
||||
* and this is before use of doq connections. */
|
||||
if(ngtcp2_crypto_ossl_init() != 0)
|
||||
fatal_exit("ngtcp2_crypto_oss_init failed");
|
||||
fatal_exit("ngtcp2_crypto_ossl_init failed");
|
||||
#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_INIT)
|
||||
if(ngtcp2_crypto_quictls_init() != 0)
|
||||
fatal_exit("ngtcp2_crypto_quictls_init failed");
|
||||
|
||||
+4
-2
@@ -222,7 +222,8 @@ read_http_headers(SSL* ssl, char* file, size_t flen, char* host, size_t hlen,
|
||||
if(verb>=2) printf("read: %s\n", buf);
|
||||
if(buf[0] == 0) {
|
||||
int e = ERR_peek_error();
|
||||
printf("error string: %s\n", ERR_reason_error_string(e));
|
||||
if(e)
|
||||
printf("error string: %s\n", ERR_reason_error_string(e));
|
||||
return 1;
|
||||
}
|
||||
if(!process_one_header(buf, file, flen, host, hlen, vs))
|
||||
@@ -246,7 +247,8 @@ setup_ctx(char* key, char* cert)
|
||||
#endif
|
||||
if(!SSL_CTX_use_certificate_chain_file(ctx, cert)) {
|
||||
int e = ERR_peek_error();
|
||||
printf("error string: %s\n", ERR_reason_error_string(e));
|
||||
if(e)
|
||||
printf("error string: %s\n", ERR_reason_error_string(e));
|
||||
print_exit("cannot read cert");
|
||||
}
|
||||
if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM))
|
||||
|
||||
@@ -142,6 +142,10 @@
|
||||
#include "util/netevent.h"
|
||||
#include "testcode/testpkts.h"
|
||||
#include "util/rbtree.h"
|
||||
#ifdef __QNX__
|
||||
/* For struct timeval */
|
||||
#include <sys/time.h>
|
||||
#endif /* __QNX__ */
|
||||
struct replay_answer;
|
||||
struct replay_moment;
|
||||
struct replay_range;
|
||||
|
||||
+37
-8
@@ -135,6 +135,8 @@ static void matchline(char* line, struct entry* e)
|
||||
e->match_ttl = 1;
|
||||
} else if(str_keyword(&parse, "DO")) {
|
||||
e->match_do = 1;
|
||||
} else if(str_keyword(&parse, "CO")) {
|
||||
e->match_co = 1;
|
||||
} else if(str_keyword(&parse, "noedns")) {
|
||||
e->match_noedns = 1;
|
||||
} else if(str_keyword(&parse, "ednsdata")) {
|
||||
@@ -178,7 +180,7 @@ static void matchline(char* line, struct entry* e)
|
||||
|
||||
/** parse REPLY line */
|
||||
static void replyline(char* line, uint8_t* reply, size_t reply_len,
|
||||
int* do_flag)
|
||||
int* do_flag, int* co_flag)
|
||||
{
|
||||
char* parse = line;
|
||||
if(reply_len < LDNS_HEADER_SIZE) error("packet too short for header");
|
||||
@@ -236,6 +238,8 @@ static void replyline(char* line, uint8_t* reply, size_t reply_len,
|
||||
LDNS_AD_SET(reply);
|
||||
} else if(str_keyword(&parse, "DO")) {
|
||||
*do_flag = 1;
|
||||
} else if(str_keyword(&parse, "CO")) {
|
||||
*co_flag = 1;
|
||||
} else {
|
||||
error("could not parse REPLY: '%s'", parse);
|
||||
}
|
||||
@@ -289,6 +293,7 @@ static struct entry* new_entry(void)
|
||||
e->match_all_noedns = 0;
|
||||
e->match_ttl = 0;
|
||||
e->match_do = 0;
|
||||
e->match_co = 0;
|
||||
e->match_noedns = 0;
|
||||
e->match_serial = 0;
|
||||
e->ixfr_soa_serial = 0;
|
||||
@@ -521,15 +526,17 @@ static void add_rr(char* rrstr, uint8_t* pktbuf, size_t pktsize,
|
||||
|
||||
/* add EDNS 4096 opt record */
|
||||
static void
|
||||
add_edns(uint8_t* pktbuf, size_t pktsize, int do_flag, uint8_t *ednsdata,
|
||||
uint16_t ednslen, size_t* pktlen)
|
||||
add_edns(uint8_t* pktbuf, size_t pktsize, int do_flag, int co_flag,
|
||||
uint8_t *ednsdata, uint16_t ednslen, size_t* pktlen)
|
||||
{
|
||||
uint8_t edns[] = {0x00, /* root label */
|
||||
0x00, LDNS_RR_TYPE_OPT, /* type */
|
||||
0x04, 0xD0, /* class is UDPSIZE 1232 */
|
||||
0x00, /* TTL[0] is ext rcode */
|
||||
0x00, /* TTL[1] is edns version */
|
||||
(uint8_t)(do_flag?0x80:0x00), 0x00, /* TTL[2-3] is edns flags, DO */
|
||||
(uint8_t)(do_flag?0x80:0x00)
|
||||
| (uint8_t)(co_flag?0x40:0x00)
|
||||
, 0x00, /* TTL[2-3] is edns flags, DO */
|
||||
(uint8_t)((ednslen >> 8) & 0xff),
|
||||
(uint8_t)(ednslen & 0xff), /* rdatalength */
|
||||
};
|
||||
@@ -561,6 +568,7 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
|
||||
uint8_t pktbuf[MAX_PACKETLEN];
|
||||
size_t pktlen = LDNS_HEADER_SIZE;
|
||||
int do_flag = 0; /* DO flag in EDNS */
|
||||
int co_flag = 0; /* CO flag in EDNS */
|
||||
memset(pktbuf, 0, pktlen); /* ID = 0, FLAGS="", and rr counts 0 */
|
||||
|
||||
while(fgets(line, (int)sizeof(line), in) != NULL) {
|
||||
@@ -598,7 +606,7 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
|
||||
if(str_keyword(&parse, "MATCH")) {
|
||||
matchline(parse, current);
|
||||
} else if(str_keyword(&parse, "REPLY")) {
|
||||
replyline(parse, pktbuf, pktlen, &do_flag);
|
||||
replyline(parse, pktbuf, pktlen, &do_flag, &co_flag);
|
||||
} else if(str_keyword(&parse, "ADJUST")) {
|
||||
adjustline(parse, current, cur_reply);
|
||||
} else if(str_keyword(&parse, "EXTRA_PACKET")) {
|
||||
@@ -654,15 +662,16 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
|
||||
if(hex_ednsdata_buffer)
|
||||
sldns_buffer_free(hex_ednsdata_buffer);
|
||||
if(pktlen != 0) {
|
||||
if(do_flag || cur_reply->raw_ednsdata) {
|
||||
if(do_flag || co_flag
|
||||
|| cur_reply->raw_ednsdata) {
|
||||
if(cur_reply->raw_ednsdata &&
|
||||
sldns_buffer_limit(cur_reply->raw_ednsdata))
|
||||
add_edns(pktbuf, sizeof(pktbuf), do_flag,
|
||||
add_edns(pktbuf, sizeof(pktbuf), do_flag, co_flag,
|
||||
sldns_buffer_begin(cur_reply->raw_ednsdata),
|
||||
(uint16_t)sldns_buffer_limit(cur_reply->raw_ednsdata),
|
||||
&pktlen);
|
||||
else
|
||||
add_edns(pktbuf, sizeof(pktbuf), do_flag,
|
||||
add_edns(pktbuf, sizeof(pktbuf), do_flag, co_flag,
|
||||
NULL, 0, &pktlen);
|
||||
}
|
||||
cur_reply->reply_pkt = memdup(pktbuf, pktlen);
|
||||
@@ -909,6 +918,22 @@ get_do_flag(uint8_t* pkt, size_t len)
|
||||
return (int)(edns_bits&LDNS_EDNS_MASK_DO_BIT);
|
||||
}
|
||||
|
||||
/** return true if the CO flag is set */
|
||||
static int
|
||||
get_co_flag(uint8_t* pkt, size_t len)
|
||||
{
|
||||
uint16_t edns_bits;
|
||||
uint8_t* walk = pkt;
|
||||
size_t walk_len = len;
|
||||
if(!pkt_find_edns_opt(&walk, &walk_len)) {
|
||||
return 0;
|
||||
}
|
||||
if(walk_len < 6)
|
||||
return 0; /* malformed */
|
||||
edns_bits = sldns_read_uint16(walk+4);
|
||||
return (int)(edns_bits&LDNS_EDNS_MASK_CO_BIT);
|
||||
}
|
||||
|
||||
/** Snips the specified EDNS option out of the OPT record and puts it in the
|
||||
* provided buffer. The buffer should be able to hold any opt data ie 65535.
|
||||
* Returns the length of the option written,
|
||||
@@ -1654,6 +1679,10 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
|
||||
verbose(3, "no DO bit set\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_co && !get_co_flag(query_pkt, len)) {
|
||||
verbose(3, "no CO bit set\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_noedns && get_has_edns(query_pkt, len)) {
|
||||
verbose(3, "bad; EDNS OPT present\n");
|
||||
continue;
|
||||
|
||||
@@ -218,6 +218,8 @@ struct entry {
|
||||
uint8_t match_ttl;
|
||||
/** match DO bit */
|
||||
uint8_t match_do;
|
||||
/** match CO bit */
|
||||
uint8_t match_co;
|
||||
/** match absence of EDNS OPT record in query */
|
||||
uint8_t match_noedns;
|
||||
/** match edns data field given in hex */
|
||||
|
||||
@@ -207,7 +207,11 @@ rr_test_file(const char* input, const char* check)
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
#ifndef __QNX__
|
||||
#define SRCDIRSTR xstr(SRCDIR)
|
||||
#else /* !__QNX__ */
|
||||
#define SRCDIRSTR "."
|
||||
#endif /* __QNX__ */
|
||||
|
||||
/** read rrs to and from string, to and from wireformat */
|
||||
static void
|
||||
|
||||
+2
-2
@@ -283,7 +283,7 @@ net_test(void)
|
||||
unit_assert(strcmp(astr, "1.2.3.0") == 0);
|
||||
unit_assert(ntohs(((struct sockaddr_in*)&a)->sin_port)==53);
|
||||
|
||||
res = netblockstrtoaddr("2001:DB8:33:44::/64", 53,
|
||||
res = netblockstrtoaddr("2001:db8:33:44::/64", 53,
|
||||
&a, &alen, &net);
|
||||
unit_assert(res!=0 && net == 64);
|
||||
addr_to_str(&a, alen, astr, sizeof(astr));
|
||||
@@ -1265,7 +1265,7 @@ static void localzone_parents_test(void)
|
||||
nmlabs = dname_count_size_labels(nm, &nmlen);
|
||||
lock_rw_wrlock(&z2->lock);
|
||||
local_zones_add_zone(z2, nm, nmlen, nmlabs, LDNS_RR_CLASS_IN,
|
||||
local_zone_always_nxdomain);
|
||||
local_zone_always_nxdomain, NULL);
|
||||
lock_rw_unlock(&z2->lock);
|
||||
}
|
||||
/* The trees should be the same, iterate and check the nodes */
|
||||
|
||||
@@ -498,7 +498,11 @@ testfromdrillfile(sldns_buffer* pkt, struct alloc_cache* alloc,
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
#ifndef __QNX__
|
||||
#define SRCDIRSTR xstr(SRCDIR)
|
||||
#else /* !__QNX__ */
|
||||
#define SRCDIRSTR "."
|
||||
#endif /* __QNX__ */
|
||||
|
||||
void msgparse_test(void)
|
||||
{
|
||||
|
||||
+34
-13
@@ -513,8 +513,11 @@ nsec3_hash_test(const char* fname)
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
#ifndef __QNX__
|
||||
#define SRCDIRSTR xstr(SRCDIR)
|
||||
|
||||
#else /* !__QNX__ */
|
||||
#define SRCDIRSTR "."
|
||||
#endif /* __QNX__ */
|
||||
#if defined(HAVE_SSL) && defined(USE_SHA1)
|
||||
/* Detect if openssl is configured to disable RSASHA1 signatures,
|
||||
* with the rh-allow-sha1-signatures disabled. */
|
||||
@@ -631,6 +634,7 @@ rh_allow_sha1_signatures_disabled(void)
|
||||
void
|
||||
verify_test(void)
|
||||
{
|
||||
int do_sha1 = 1;
|
||||
unit_show_feature("signature verify");
|
||||
|
||||
#if defined(HAVE_SSL) && defined(USE_SHA1)
|
||||
@@ -643,27 +647,40 @@ verify_test(void)
|
||||
#else
|
||||
_putenv("OPENSSL_ENABLE_SHA1_SIGNATURES=1");
|
||||
#endif
|
||||
do_sha1 = 1;
|
||||
}
|
||||
#ifdef HAVE_EVP_DEFAULT_PROPERTIES_IS_FIPS_ENABLED
|
||||
if (EVP_default_properties_is_fips_enabled(NULL))
|
||||
do_sha1 = 0;
|
||||
#endif
|
||||
#endif /* HAVE_SSL and USE_SHA1 */
|
||||
|
||||
#ifdef USE_SHA1
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.1", "20070818005004");
|
||||
if(do_sha1) {
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.1", "20070818005004");
|
||||
}
|
||||
#endif
|
||||
#if defined(USE_DSA) && defined(USE_SHA1)
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.2", "20080414005004");
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.3", "20080416005004");
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.4", "20080416005004");
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.5", "20080416005004");
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.6", "20080416005004");
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.7", "20070829144150");
|
||||
if(do_sha1) {
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.2", "20080414005004");
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.3", "20080416005004");
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.4", "20080416005004");
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.5", "20080416005004");
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.6", "20080416005004");
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.7", "20070829144150");
|
||||
}
|
||||
#endif /* USE_DSA */
|
||||
#ifdef USE_SHA1
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.8", "20070829144150");
|
||||
if(do_sha1) {
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.8", "20070829144150");
|
||||
}
|
||||
#endif
|
||||
#if (defined(HAVE_EVP_SHA256) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2)
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_sigs.rsasha256", "20070829144150");
|
||||
# ifdef USE_SHA1
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_sigs.sha1_and_256", "20070829144150");
|
||||
if(do_sha1) {
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_sigs.sha1_and_256", "20070829144150");
|
||||
}
|
||||
# endif
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_sigs.rsasha256_draft", "20090101000000");
|
||||
#endif
|
||||
@@ -672,8 +689,10 @@ verify_test(void)
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_signatures.9", "20171215000000");
|
||||
#endif
|
||||
#ifdef USE_SHA1
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_sigs.hinfo", "20090107100022");
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_sigs.revoked", "20080414005004");
|
||||
if(do_sha1) {
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_sigs.hinfo", "20090107100022");
|
||||
verifytest_file(SRCDIRSTR "/testdata/test_sigs.revoked", "20080414005004");
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_GOST
|
||||
if(sldns_key_EVP_load_gost_id())
|
||||
@@ -699,7 +718,9 @@ verify_test(void)
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_SHA1
|
||||
dstest_file(SRCDIRSTR "/testdata/test_ds.sha1");
|
||||
if(do_sha1) {
|
||||
dstest_file(SRCDIRSTR "/testdata/test_ds.sha1");
|
||||
}
|
||||
#endif
|
||||
nsectest();
|
||||
nsec3_hash_test(SRCDIRSTR "/testdata/test_nsec3_hash.1");
|
||||
|
||||
@@ -50,7 +50,11 @@
|
||||
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
#ifndef __QNX__
|
||||
#define SRCDIRSTR xstr(SRCDIR)
|
||||
#else /* !__QNX__ */
|
||||
#define SRCDIRSTR "."
|
||||
#endif /* __QNX__ */
|
||||
|
||||
/** Add zone from file for testing */
|
||||
struct auth_zone* authtest_addzone(struct auth_zones* az, const char* name,
|
||||
|
||||
Vendored
+2
@@ -40,6 +40,8 @@ grep -F -v -e "dnstap" hlist > ilist; mv ilist hlist
|
||||
grep -F -v -e "util/siphash.c" hlist > ilist; mv ilist hlist
|
||||
# filter out compat
|
||||
grep -F -v -e "compat/" hlist > ilist; mv ilist hlist
|
||||
# filter out simdzone
|
||||
grep -F -v -e "simdzone/" hlist > ilist; mv ilist hlist
|
||||
for h in `cat hlist`; do
|
||||
if grep -F "`basename $h`" $PRE/doc/html/files.html >/dev/null; then
|
||||
: # ok
|
||||
|
||||
Vendored
+1
-1
@@ -24,7 +24,7 @@ server:
|
||||
# specify every interface on a new 'interface:' labelled line.
|
||||
interface: 192.0.2.153
|
||||
interface: 192.0.2.154
|
||||
interface: 2001:DB8::5
|
||||
interface: 2001:db8::5
|
||||
|
||||
# port to answer queries from
|
||||
port: 53
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ server:
|
||||
# specify every interface on a new 'interface:' labelled line.
|
||||
interface: 192.0.2.153
|
||||
interface: 192.0.2.154
|
||||
interface: 2001:DB8::5
|
||||
interface: 2001:db8::5
|
||||
interface: 0.0.0.0@5353
|
||||
|
||||
# config
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
$ORIGIN .
|
||||
$TTL 7200
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
|
||||
example.com. IN NS ns.example.net.
|
||||
www.example.com. IN A 1.2.3.4
|
||||
@@ -0,0 +1,17 @@
|
||||
server:
|
||||
verbosity: 7
|
||||
# num-threads: 1
|
||||
interface: 127.0.0.1
|
||||
port: @PORT@
|
||||
use-syslog: no
|
||||
directory: ""
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
auth-zone:
|
||||
name: "example.com"
|
||||
for-upstream: yes
|
||||
for-downstream: yes
|
||||
url: "https://127.0.0.1:@TOPORT@/example.com.zone"
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
BaseName: auth_https_origin
|
||||
Version: 1.0
|
||||
Description: Perform https for authority zone with $ORIGIN
|
||||
CreationDate: Mon 29 September 14:35:40 CEST 2025
|
||||
Maintainer: dr. W.C.A. Wijngaards
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: auth_https_origin.pre
|
||||
Post: auth_https_origin.post
|
||||
Test: auth_https_origin.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user