Vendor import of Unbound 1.11.0.

This commit is contained in:
Cy Schubert 2020-08-21 22:56:05 +00:00
parent 6a53c00e64
commit 7973006f41
302 changed files with 21848 additions and 8853 deletions

12
.github/FUNDING.yml vendored
View File

@ -1,12 +1,2 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
github: [NLnetLabs]
custom: ['https://nlnetlabs.nl/funding/']

1
.gitignore vendored
View File

@ -37,6 +37,7 @@
/petal
/pktview
/streamtcp
/unbound-dnstap-socket
/testbound
/unittest
/contrib/libunbound.pc

View File

@ -1,7 +1,8 @@
sudo: false
language: c
compiler:
- gcc
git:
depth: 5
addons:
apt:
packages:
@ -9,8 +10,335 @@ addons:
- libevent-dev
- libexpat-dev
- clang
homebrew:
packages:
- openssl
- libevent
- expat
update: true
jobs:
include:
- os: linux
name: GCC on Linux, Amd64
compiler: gcc
arch: amd64
env:
- CONFIG_OPTS="--enable-debug --disable-flto"
- os: linux
name: Clang on Linux, Amd64
compiler: clang
arch: amd64
env:
- CONFIG_OPTS="--enable-debug --disable-flto"
- os: osx
name: Clang on OS X, Amd64
compiler: clang
arch: amd64
env:
- TEST_OSX=yes
- CONFIG_OPTS="--enable-debug --disable-flto --with-ssl=/usr/local/opt/openssl/"
- os: linux
name: Libevent, GCC on Linux, Amd64
compiler: gcc
arch: amd64
env:
- TEST_LIBEVENT=yes
- CONFIG_OPTS="--with-libevent"
- os: linux
name: Libevent, Clang on Linux, Amd64
compiler: clang
arch: amd64
env:
- TEST_LIBEVENT=yes
- CONFIG_OPTS="--with-libevent"
- os: osx
name: Libevent, Clang on OS X, Amd64
compiler: clang
arch: amd64
env:
- TEST_OSX=yes
- TEST_LIBEVENT=yes
- CONFIG_OPTS="--with-ssl=/usr/local/opt/openssl/ --with-libevent=/usr/local/opt/libevent/"
- os: linux
name: UBsan, GCC on Linux, Amd64
compiler: gcc
arch: amd64
dist: bionic
env:
- TEST_UBSAN=yes
- os: linux
name: UBsan, Clang on Linux, Amd64
compiler: clang
arch: amd64
dist: bionic
env:
- TEST_UBSAN=yes
- os: linux
name: Asan, GCC on Linux, Amd64
compiler: gcc
arch: amd64
dist: bionic
env:
- TEST_ASAN=yes
- os: linux
name: Asan, Clang on Linux, Amd64
compiler: clang
arch: amd64
dist: bionic
env:
- TEST_ASAN=yes
- os: linux
name: GCC on Linux, Aarch64
compiler: gcc
arch: arm64
dist: bionic
env:
- CONFIG_OPTS="--enable-debug --disable-flto"
- os: linux
name: Clang on Linux, Aarch64
compiler: clang
arch: arm64
dist: bionic
env:
- CONFIG_OPTS="--enable-debug --disable-flto"
- os: linux
name: GCC on Linux, PowerPC64
compiler: gcc
arch: ppc64le
dist: bionic
env:
- CONFIG_OPTS="--enable-debug --disable-flto"
- os: linux
name: Clang on Linux, PowerPC64
compiler: clang
arch: ppc64le
dist: bionic
env:
- CONFIG_OPTS="--enable-debug --disable-flto"
- os: linux
name: GCC on Linux, s390x
compiler: gcc
arch: s390x
dist: bionic
env:
- CONFIG_OPTS="--enable-debug --disable-flto"
- os: linux
name: Clang on Linux, s390x
compiler: clang
arch: s390x
dist: bionic
env:
- CONFIG_OPTS="--enable-debug --disable-flto"
- os: osx
osx_image: xcode10
name: Apple iPhone on iOS, armv7
compiler: clang
env:
- TEST_IOS=yes
- AUTOTOOLS_HOST=armv7-apple-ios
- OPENSSL_HOST=ios-cross
- IOS_SDK=iPhoneOS
- IOS_CPU=armv7s
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
- os: osx
osx_image: xcode10
name: Apple iPhone on iOS, arm64
compiler: clang
env:
- TEST_IOS=yes
- AUTOTOOLS_HOST=aarch64-apple-ios
- OPENSSL_HOST=ios64-cross
- IOS_SDK=iPhoneOS
- IOS_CPU=arm64
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
- os: osx
osx_image: xcode10
name: Apple TV on iOS, arm64
compiler: clang
env:
- TEST_IOS=yes
- AUTOTOOLS_HOST=aarch64-apple-ios
- OPENSSL_HOST=ios64-cross
- IOS_SDK=AppleTVOS
- IOS_CPU=arm64
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
- os: osx
osx_image: xcode10
name: Apple Watch on iOS, armv7
compiler: clang
env:
- TEST_IOS=yes
- AUTOTOOLS_HOST=armv7-apple-ios
- OPENSSL_HOST=ios-cross
- IOS_SDK=WatchOS
- IOS_CPU=armv7k
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
- os: osx
osx_image: xcode10
name: iPhoneSimulator on OS X, i386
env:
- TEST_IOS=yes
- AUTOTOOLS_HOST=i386-apple-ios
- OPENSSL_HOST=iphoneos-cross
- IOS_CPU=i386
- IOS_SDK=iPhoneSimulator
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
- os: osx
osx_image: xcode10
name: iPhoneSimulator on OS X, x86_64
env:
- TEST_IOS=yes
- AUTOTOOLS_HOST=x86_64-apple-ios
- OPENSSL_HOST=iphoneos-cross
- IOS_CPU=x86_64
- IOS_SDK=iPhoneSimulator
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
- os: osx
osx_image: xcode10
name: AppleTVSimulator on OS X, x86_64
env:
- TEST_IOS=yes
- AUTOTOOLS_HOST=x86_64-apple-ios
- OPENSSL_HOST=iphoneos-cross
- IOS_CPU=x86_64
- IOS_SDK=AppleTVSimulator
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
- os: osx
osx_image: xcode10
name: WatchSimulator on OS X, i386
env:
- TEST_IOS=yes
- AUTOTOOLS_HOST=i386-apple-ios
- OPENSSL_HOST=iphoneos-cross
- IOS_CPU=i386
- IOS_SDK=WatchSimulator
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
- os: linux
name: Android armv7a, Linux, Amd64
compiler: clang
arch: amd64
dist: bionic
env:
- TEST_ANDROID=yes
- AUTOTOOLS_HOST=armv7a-linux-androideabi
- OPENSSL_HOST=android-arm
- ANDROID_CPU=armv7a
- ANDROID_API=23
- ANDROID_PREFIX="$HOME/android$ANDROID_API-$ANDROID_CPU"
- ANDROID_SDK_ROOT="$HOME/android-sdk"
- ANDROID_NDK_ROOT="$HOME/android-ndk"
- os: linux
name: Android aarch64, Linux, Amd64
compiler: clang
arch: amd64
dist: bionic
env:
- TEST_ANDROID=yes
- AUTOTOOLS_HOST=aarch64-linux-android
- OPENSSL_HOST=android-arm64
- ANDROID_CPU=aarch64
- ANDROID_API=23
- ANDROID_PREFIX="$HOME/android$ANDROID_API-$ANDROID_CPU"
- ANDROID_SDK_ROOT="$HOME/android-sdk"
- ANDROID_NDK_ROOT="$HOME/android-ndk"
- os: linux
name: Android x86, Linux, Amd64
compiler: clang
arch: amd64
dist: bionic
env:
- TEST_ANDROID=yes
- AUTOTOOLS_HOST=i686-linux-android
- OPENSSL_HOST=android-x86
- ANDROID_CPU=x86
- ANDROID_API=23
- ANDROID_PREFIX="$HOME/android$ANDROID_API-$ANDROID_CPU"
- ANDROID_SDK_ROOT="$HOME/android-sdk"
- ANDROID_NDK_ROOT="$HOME/android-ndk"
- os: linux
name: Android x86_64, Linux, Amd64
compiler: clang
arch: amd64
dist: bionic
env:
- TEST_ANDROID=yes
- AUTOTOOLS_HOST=x86_64-linux-android
- OPENSSL_HOST=android-x86_64
- ANDROID_CPU=x86_64
- ANDROID_API=23
- ANDROID_PREFIX="$HOME/android$ANDROID_API-$ANDROID_CPU"
- ANDROID_SDK_ROOT="$HOME/android-sdk"
- ANDROID_NDK_ROOT="$HOME/android-ndk"
allow_failures:
- os: linux
name: Android armv7a, Linux, Amd64
- os: linux
name: Android aarch64, Linux, Amd64
- os: linux
name: Android x86, Linux, Amd64
- os: linux
name: Android x86_64, Linux, Amd64
before_script:
- |
if [ "$TEST_ANDROID" = "yes" ]; then
./contrib/android/install_tools.sh
elif [ "$TEST_IOS" = "yes" ]; then
./contrib/ios/install_tools.sh
fi
# The Travis docs say to avoid calling exit in the script. It leads to
# some code duplication to avoid failures in cross-compiles. Also see
# https://docs.travis-ci.com/user/job-lifecycle/ in the Travis docs.
script:
- ./configure --enable-debug --disable-flto
- make
- make test
- (cd testdata/clang-analysis.tdir; bash clang-analysis.test)
- |
if [ "$TEST_UBSAN" = "yes" ]; then
export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=undefined -fno-sanitize-recover"
./configure
make -j 2
make test
elif [ "$TEST_ASAN" = "yes" ]; then
export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=address"
./configure
make -j 2
make test
elif [ "$TEST_IOS" = "yes" ]; then
export AUTOTOOLS_BUILD="$(./config.guess)"
export PKG_CONFIG_PATH="$IOS_PREFIX/lib/pkgconfig"
source ./contrib/ios/setenv_ios.sh
./contrib/ios/install_openssl.sh
./contrib/ios/install_expat.sh
./configure \
--build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \
--prefix="$IOS_PREFIX" \
--with-ssl="$IOS_PREFIX" --disable-gost \
--with-libexpat="$IOS_PREFIX";
make -j 2
make install
elif [ "$TEST_ANDROID" = "yes" ]; then
export AUTOTOOLS_BUILD="$(./config.guess)"
export PKG_CONFIG_PATH="$ANDROID_PREFIX/lib/pkgconfig"
./contrib/android/install_ndk.sh
source ./contrib/android/setenv_android.sh
./contrib/android/install_openssl.sh
./contrib/android/install_expat.sh
./configure \
--build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \
--prefix="$ANDROID_PREFIX" \
--with-ssl="$ANDROID_PREFIX" --disable-gost \
--with-libexpat="$ANDROID_PREFIX";
make -j 2
make install
elif [ "$TEST_OSX" = "yes" ]; then
./configure --enable-debug --disable-flto --with-ssl=/usr/local/opt/openssl/
make -j 2
make test
(cd testdata/clang-analysis.tdir; bash clang-analysis.test)
else
./configure ${CONFIG_OPTS}
make -j 2
make test
(cd testdata/clang-analysis.tdir; bash clang-analysis.test)
fi

View File

@ -25,6 +25,7 @@ DNSTAP_SRC=@DNSTAP_SRC@
DNSTAP_OBJ=@DNSTAP_OBJ@
DNSCRYPT_SRC=@DNSCRYPT_SRC@
DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
WITH_DYNLIBMODULE=@WITH_DYNLIBMODULE@
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
WITH_PYUNBOUND=@WITH_PYUNBOUND@
PY_MAJOR_VERSION=@PY_MAJOR_VERSION@
@ -77,7 +78,7 @@ LINT=splint
LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 -D__gnuc_va_list=va_list -formatcode
#-Dglob64=glob -Dglobfree64=globfree
# compat with openssl linux edition.
LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t -DRC4_INT=unsigned -fixedformalarray -D"ENGINE=unsigned" -D"RSA=unsigned" -D"DSA=unsigned" -D"EVP_PKEY=unsigned" -D"EVP_MD=unsigned" -D"SSL=unsigned" -D"SSL_CTX=unsigned" -D"X509=unsigned" -D"RC4_KEY=unsigned" -D"EVP_MD_CTX=unsigned" -D"ECDSA_SIG=DSA_SIG" -Dfstrm_res=int
LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t -DRC4_INT=unsigned -fixedformalarray -D"ENGINE=unsigned" -D"RSA=unsigned" -D"DSA=unsigned" -D"EVP_PKEY=unsigned" -D"EVP_MD=unsigned" -D"SSL=unsigned" -D"SSL_CTX=unsigned" -D"X509=unsigned" -D"RC4_KEY=unsigned" -D"EVP_MD_CTX=unsigned" -D"ECDSA_SIG=DSA_SIG"
# compat with NetBSD
LINTFLAGS+=@NETBSD_LINTFLAGS@
# compat with OpenBSD
@ -87,6 +88,12 @@ LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=i
INSTALL=$(SHELL) $(srcdir)/install-sh
DYNLIBMOD_SRC=dynlibmod/dynlibmod.c
DYNLIBMOD_OBJ=@DYNLIBMOD_OBJ@
DYNLIBMOD_HEADER=@DYNLIBMOD_HEADER@
DYNLIBMOD_EXTRALIBS=@DYNLIBMOD_EXTRALIBS@
#pythonmod.c is not here, it is mentioned by itself in its own rules,
#makedepend fails on missing interface.h otherwise.
PYTHONMOD_SRC=pythonmod/pythonmod_utils.c
@ -140,7 +147,7 @@ autotrust.lo val_anchor.lo rpz.lo \
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
$(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
outside_network.lo
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
@ -219,7 +226,7 @@ MEMSTATS_OBJ_LINK=$(MEMSTATS_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
$(SLDNS_OBJ)
ASYNCLOOK_SRC=testcode/asynclook.c
ASYNCLOOK_OBJ=asynclook.lo
ASYNCLOOK_OBJ_LINK=$(ASYNCLOOK_OBJ) log.lo locks.lo $(COMPAT_OBJ) @ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ@
ASYNCLOOK_OBJ_LINK=$(ASYNCLOOK_OBJ) log.lo locks.lo $(CHECKLOCK_OBJ) $(COMPAT_OBJ) @ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ@
STREAMTCP_SRC=testcode/streamtcp.c
STREAMTCP_OBJ=streamtcp.lo
STREAMTCP_OBJ_LINK=$(STREAMTCP_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
@ -233,6 +240,10 @@ DELAYER_OBJ_LINK=$(DELAYER_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
$(SLDNS_OBJ)
IPSET_SRC=@IPSET_SRC@
IPSET_OBJ=@IPSET_OBJ@
DNSTAP_SOCKET_SRC=dnstap/unbound-dnstap-socket.c
DNSTAP_SOCKET_OBJ=unbound-dnstap-socket.lo
DNSTAP_SOCKET_OBJ_LINK=$(DNSTAP_SOCKET_OBJ) $(COMMON_OBJ) \
$(COMPAT_OBJ) $(SLDNS_OBJ)
LIBUNBOUND_SRC=libunbound/context.c libunbound/libunbound.c \
libunbound/libworker.c
LIBUNBOUND_OBJ=context.lo libunbound.lo libworker.lo ub_event_pluggable.lo
@ -259,7 +270,7 @@ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
$(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) \
$(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \
$(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \
$(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC) \
$(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC) $(DNSTAP_SOCKET_SRC)\
$(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC) \
$(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC)
@ -267,7 +278,7 @@ ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
$(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \
$(MEMSTATS_OBJ) $(CHECKCONF_OBJ) $(LIBUNBOUND_OBJ) $(HOST_OBJ) \
$(ASYNCLOOK_OBJ) $(STREAMTCP_OBJ) $(PERF_OBJ) $(DELAYER_OBJ) \
$(CONTROL_OBJ) $(UBANCHOR_OBJ) $(PETAL_OBJ) \
$(CONTROL_OBJ) $(UBANCHOR_OBJ) $(PETAL_OBJ) $(DNSTAP_SOCKET_OBJ)\
$(COMPAT_OBJ) $(PYUNBOUND_OBJ) \
$(SVCINST_OBJ) $(SVCUNINST_OBJ) $(ANCHORUPD_OBJ) $(SLDNS_OBJ)
@ -306,6 +317,7 @@ rsrc_unbound_checkconf.o: $(srcdir)/winrc/rsrc_unbound_checkconf.rc config.h
TEST_BIN=asynclook$(EXEEXT) delayer$(EXEEXT) \
lock-verify$(EXEEXT) memstats$(EXEEXT) perf$(EXEEXT) \
petal$(EXEEXT) pktview$(EXEEXT) streamtcp$(EXEEXT) \
unbound-dnstap-socket$(EXEEXT) \
testbound$(EXEEXT) unittest$(EXEEXT)
tests: all $(TEST_BIN)
@ -315,7 +327,7 @@ longcheck: longtest
test: unittest$(EXEEXT) testbound$(EXEEXT)
./unittest$(EXEEXT)
./testbound$(EXEEXT) -s
for x in $(srcdir)/testdata/*.rpl; do echo -n "$$x "; if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then echo OK; else echo failed; exit 1; fi done
for x in $(srcdir)/testdata/*.rpl; do printf "%s" "$$x "; if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then echo OK; else echo failed; exit 1; fi done
@echo test OK
longtest: tests
@ -328,13 +340,13 @@ libunbound.la: $(LIBUNBOUND_OBJ_LINK)
$(LINK_LIB) $(UBSYMS) -o $@ $(LIBUNBOUND_OBJ_LINK) -rpath $(libdir) $(SSLLIB) $(LIBS)
unbound$(EXEEXT): $(DAEMON_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(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) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
unbound-control$(EXEEXT): $(CONTROL_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(CONTROL_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(CONTROL_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
unbound-host$(EXEEXT): $(HOST_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(HOST_OBJ_LINK) -L. -L.libs -lunbound $(SSLLIB) $(LIBS)
@ -352,34 +364,34 @@ anchor-update$(EXEEXT): $(ANCHORUPD_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(ANCHORUPD_OBJ_LINK) -L. -L.libs -lunbound $(LIBS)
unittest$(EXEEXT): $(UNITTEST_OBJ_LINK)
$(LINK) -o $@ $(UNITTEST_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(UNITTEST_OBJ_LINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
testbound$(EXEEXT): $(TESTBOUND_OBJ_LINK)
$(LINK) -o $@ $(TESTBOUND_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(TESTBOUND_OBJ_LINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
lock-verify$(EXEEXT): $(LOCKVERIFY_OBJ_LINK)
$(LINK) -o $@ $(LOCKVERIFY_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(LOCKVERIFY_OBJ_LINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
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) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
memstats$(EXEEXT): $(MEMSTATS_OBJ_LINK)
$(LINK) -o $@ $(MEMSTATS_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(MEMSTATS_OBJ_LINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
asynclook$(EXEEXT): $(ASYNCLOOK_OBJ_LINK) libunbound.la
$(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) -L. -L.libs -lunbound $(SSLLIB) $(LIBS)
streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK)
$(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
perf$(EXEEXT): $(PERF_OBJ_LINK)
$(LINK) -o $@ $(PERF_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(PERF_OBJ_LINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
delayer$(EXEEXT): $(DELAYER_OBJ_LINK)
$(LINK) -o $@ $(DELAYER_OBJ_LINK) $(SSLLIB) $(LIBS)
$(LINK) -o $@ $(DELAYER_OBJ_LINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
signit$(EXEEXT): testcode/signit.c
$(CC) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@ -o $@ testcode/signit.c $(LDFLAGS) -lldns $(SSLLIB) $(LIBS)
@ -401,7 +413,13 @@ dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h: $(srcdir)/dnstap/dnstap.proto
@-if test ! -d dnstap; then $(INSTALL) -d dnstap; fi
$(PROTOC_C) --c_out=. --proto_path=$(srcdir) $(srcdir)/dnstap/dnstap.proto
unbound-dnstap-socket$(EXEEXT): $(DNSTAP_SOCKET_OBJ_LINK)
$(LINK) -o $@ $(DNSTAP_SOCKET_OBJ_LINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
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
dnstap_fstrm.lo dnstap_fstrm.o: $(srcdir)/dnstap/dnstap_fstrm.c config.h $(srcdir)/dnstap/dnstap_fstrm.h
unbound-dnstap-socket.lo unbound-dnstap-socket.o: $(srcdir)/dnstap/unbound-dnstap-socket.c config.h $(srcdir)/dnstap/dtstream.h
# dnscrypt
dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
@ -455,6 +473,7 @@ clean:
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)
rm -f _unbound.la libunbound/python/libunbound_wrap.c libunbound/python/unbound.py pythonmod/interface.h pythonmod/unboundmodule.py
rm -f libunbound.a
rm -rf autom4te.cache .libs build doc/html doc/xml
distclean: clean
@ -629,6 +648,7 @@ depend:
-e 's?$$(srcdir)/pythonmod/pythonmod.h?$$(PYTHONMOD_HEADER)?g' \
-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!\(.*\)\.o[ :]*!\1.lo \1.o: !g' \
> $(DEPEND_TMP)
cp $(DEPEND_TARGET) $(DEPEND_TMP2)
@ -796,12 +816,13 @@ modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/service
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \
$(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
$(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/dns64/dns64.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h \
$(srcdir)/validator/val_utils.h $(srcdir)/respip/respip.h $(srcdir)/services/localzone.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(PYTHONMOD_HEADER) $(srcdir)/ipsecmod/ipsecmod.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h \
$(srcdir)/ipset/ipset.h $(srcdir)/dynlibmod/dynlibmod.h
view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
@ -886,21 +907,23 @@ authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/service
$(srcdir)/validator/val_secalgo.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)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/services/outside_network.h $(srcdir)/services/cache/infra.h \
$(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \
$(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
$(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h \
$(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h \
$(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \
$(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound-event.h \
$(srcdir)/libunbound/worker.h
$(srcdir)/dnscrypt/cert.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h \
$(srcdir)/services/outside_network.h $(srcdir)/services/localzone.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/authzone.h \
$(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \
$(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/validator/validator.h \
$(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_nsec3.h \
$(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_neg.h \
$(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h $(srcdir)/libunbound/context.h \
$(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/respip/respip.h \
$(PYTHONMOD_HEADER) $(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/edns-subnet/subnetmod.h $(srcdir)/util/net_help.h \
$(srcdir)/edns-subnet/addrtree.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/ipset/ipset.h \
$(srcdir)/dynlibmod/dynlibmod.h
locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
@ -1108,7 +1131,32 @@ respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localz
$(srcdir)/util/regional.h
checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/testcode/checklocks.h
dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
$(srcdir)/util/locks.h $(srcdir)/dnstap/dnstap.h \
dnstap/dnstap.pb-c.h
dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h \
dynlibmod.lo dynlibmod.o: $(srcdir)/dynlibmod/dynlibmod.c config.h $(srcdir)/dynlibmod/dynlibmod.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/rbtree.h\
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/tube.h \
$(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
$(srcdir)/util/config_file.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/wire2str.h
dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h $(srcdir)/sldns/sbuffer.h \
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
$(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
$(srcdir)/util/locks.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/storage/lookup3.h
ipsecmod.lo ipsecmod.o: $(srcdir)/ipsecmod/ipsecmod.c config.h
ipset.lo ipset.o: $(srcdir)/ipset/ipset.c config.h $(srcdir)/ipset/ipset.h $(srcdir)/util/module.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/services/cache/dns.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h
ipsecmod-whitelist.lo ipsecmod-whitelist.o: $(srcdir)/ipsecmod/ipsecmod-whitelist.c config.h
unitanchor.lo unitanchor.o: $(srcdir)/testcode/unitanchor.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/unitmain.h \

278
README-Travis.md Normal file
View File

@ -0,0 +1,278 @@
# Travis Testing
Unbound 1.10 and above leverage Travis CI to increase coverage of compilers and platforms. Compilers include Clang and GCC; while platforms include Android, iOS, Linux, and OS X on AMD64, Aarch64, PowerPC and s390x hardware.
Android is tested on armv7a, aarch64, x86 and x86_64. The Android recipes build and install OpenSSL and Expat, and then builds Unbound. The testing is tailored for Android NDK-r19 and above, and includes NDK-r20 and NDK-r21. Mips and Mips64 are not tested because they are no longer supported under current NDKs.
iOS is tested for iPhoneOS, WatchOS, AppleTVOS, iPhoneSimulator, AppleTVSimulator and WatchSimulator. The testing uses Xcode 10 on OS X 10.13.
The Unbound Travis configuration file `.travis.yml` does not use top-level keys like `os:` and `compiler:` so there is no matrix expansion. Instead Unbound specifies the exact job to run under the `jobs:` and `include:` keys.
## Typical recipe
A typical recipe tests Clang and GCC on various hardware. The hardware includes AMD64, Aarch64, PowerPC and s390x. PowerPC is a little-endian platform, and s390x is a big-endian platform. There are pairs of recipes that are similar to the following.
```
- os: linux
name: GCC on Linux, Aarch64
compiler: gcc
arch: arm64
dist: bionic
- os: linux
name: Clang on Linux, Aarch64
compiler: clang
arch: arm64
dist: bionic
```
OS X provides a single recipe to test Clang. GCC is not tested because GCC is an alias for Clang.
## Sanitizer builds
Two sanitizer builds are tested using Clang and GCC, for a total of four builds. The first sanitizer is Undefined Behavior sanitizer (UBsan), and the second is Address sanitizer (Asan). The sanitizers are only run on AMD64 hardware. Note the environment includes `TEST_UBSAN=yes` or `TEST_ASAN=yes` for the sanitizer builds.
The recipes are similar to the following.
```
- os: linux
name: UBsan, GCC on Linux, Amd64
compiler: gcc
arch: amd64
dist: bionic
env: TEST_UBSAN=yes
- os: linux
name: UBsan, Clang on Linux, Amd64
compiler: clang
arch: amd64
dist: bionic
env: TEST_UBSAN=yes
```
When the Travis script encounters a sanitizer it uses different `CFLAGS` and configuration string.
```
if [ "$TEST_UBSAN" = "yes" ]; then
export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=undefined -fno-sanitize-recover"
./configure
make -j 2
make test
elif [ "$TEST_ASAN" = "yes" ]; then
export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=address"
./configure
make -j 2
make test
...
```
## Android builds
Travis tests Android builds for the armv7a, aarch64, x86 and x86_64 architectures. The builds are trickier than other builds for several reasons. The testing requires installation of the Android NDK and SDK, it requires a cross-compile, and requires OpenSSL and Expat prerequisites. The Android cross-compiles also require care to set the Autotools triplet, the OpenSSL triplet, the toolchain path, the tool variables, and the sysroot. The discussion below detail the steps of the Android recipes.
### Android job
The first step sets environmental variables for the cross-compile using the Travis job. A typical job with variables is shown below.
```
- os: linux
name: Android armv7a, Linux, Amd64
compiler: clang
arch: amd64
dist: bionic
env:
- TEST_ANDROID=yes
- AUTOTOOLS_HOST=armv7a-linux-androideabi
- OPENSSL_HOST=android-arm
- ANDROID_CPU=armv7a
- ANDROID_API=23
- ANDROID_PREFIX="$HOME/android$ANDROID_API-$ANDROID_CPU"
- ANDROID_SDK_ROOT="$HOME/android-sdk"
- ANDROID_NDK_ROOT="$HOME/android-ndk"
```
### ANDROID_NDK_ROOT
The second step for Android is to set the environmental variables `ANDROID_NDK_ROOT` and `ANDROID_SDK_ROOT`. This is an important step because the NDK and SDK use the variables internally to locate their own tools. Also see [Recommended NDK Directory?](https://groups.google.com/forum/#!topic/android-ndk/qZjhOaynHXc) on the android-ndk mailing list. (Many folks miss this step, or use incorrect variables like `ANDROID_NDK_HOME` or `ANDROID_SDK_HOME`).
If you are working from a developer machine you probably already have the necessary tools installed. You should ensure `ANDROID_NDK_ROOT` and `ANDROID_SDK_ROOT` are set properly.
### Tool installation
The second step installs tools needed for OpenSSL, Expat and Unbound. This step is handled in by the script `contrib/android/install_tools.sh`. The tools include curl, tar, zip, unzip and java.
```
before_script:
- |
if [ "$TEST_ANDROID" = "yes" ]; then
./contrib/android/install_tools.sh
elif [ "$TEST_IOS" = "yes" ]; then
./contrib/ios/install_tools.sh
fi
```
### NDK installation
The third step installs the NDK and SDK. This step is handled in by the script `contrib/android/install_ndk.sh`. The script uses `ANDROID_NDK_ROOT` and `ANDROID_SDK_ROOT` to place the NDK and SDK in the `$HOME` directory.
If you are working from a developer machine you probably already have a NDK and SDK installed.
### Android environment
The fourth step sets the Android cross-compile environment using the script `contrib/android/setenv_android.sh`. The script is `sourced` so the variables in the script are available to the calling shell. The script sets variables like `CC`, `CXX`, `AS` and `AR`; sets `CFLAGS` and `CXXFLAGS`; sets a `sysroot` so Android headers and libraries are found; and adds the path to the toolchain to `PATH`.
`contrib/android/setenv_android.sh` knows which toolchain and architecture to select by inspecting environmental variables set by Travis for the job. In particular, the variables `ANDROID_CPU` and `ANDROID_API` tell `contrib/android/setenv_android.sh` which tools and libraries to select.
The `contrib/android/setenv_android.sh` script specifies the tools in a `case` statement like the following. There is a case for each of the architectures armv7a, aarch64, x86 and x86_64.
```
armv8a|aarch64|arm64|arm64-v8a)
CC="aarch64-linux-android$ANDROID_API-clang"
CXX="aarch64-linux-android$ANDROID_API-clang++"
LD="aarch64-linux-android-ld"
AS="aarch64-linux-android-as"
AR="aarch64-linux-android-ar"
RANLIB="aarch64-linux-android-ranlib"
STRIP="aarch64-linux-android-strip"
CFLAGS="-funwind-tables -fexceptions"
CXXFLAGS="-funwind-tables -fexceptions -frtti"
```
### OpenSSL and Expat
The fifth step builds OpenSSL and Expat. OpenSSL and Expat are built for Android using the scripts `contrib/android/install_openssl.sh` and `contrib/android/install_expat.sh`. The scripts download, configure and install the latest release version of the libraries. The libraries are configured with `--prefix="$ANDROID_PREFIX"` so the headers are placed in `$ANDROID_PREFIX/include` directory, and the libraries are placed in the `$ANDROID_PREFIX/lib` directory.
`ANDROID_PREFIX` is the value `$HOME/android$ANDROID_API-$ANDROID_CPU`. The libraries will be installed in `$HOME/android23-armv7a`, `$HOME/android23-aarch64`, etc. For Autotools projects, the appropriate `PKG_CONFIG_PATH` is exported. `PKG_CONFIG_PATH` is the userland equivalent to sysroot, and allows Autotools to find non-system headers and libraries for an architecture. Typical `PKG_CONFIG_PATH` are `$HOME/android23-armv7a/lib/pkgconfig` and `$HOME/android23-aarch64/lib/pkgconfig`.
OpenSSL also uses a custom configuration file called `15-android.conf`. It is a copy of the OpenSSL's project file and located at `contrib/android/15-android.conf`. The Unbound version is copied to the OpenSSL source files after unpacking the OpenSSL distribution. The Unbound version has legacy NDK support removed and some other fixes, like `ANDROID_NDK_ROOT` awareness. The changes mean Unbound's `15-android.conf` will only work with Unbound, with NDK-r19 and above, and a properly set environment.
OpenSSL is configured with `no-engine`. If you want to include OpenSSL engines then edit `contrib/android/install_openssl.sh` and remove the config option.
### Android build
Finally, once OpenSSL and Expat are built, then the Travis script configures and builds Unbound. The recipe looks as follows.
```
elif [ "$TEST_ANDROID" = "yes" ]; then
export AUTOTOOLS_BUILD="$(./config.guess)"
export PKG_CONFIG_PATH="$ANDROID_PREFIX/lib/pkgconfig"
./contrib/android/install_ndk.sh
source ./contrib/android/setenv_android.sh
./contrib/android/install_openssl.sh
./contrib/android/install_expat.sh
./configure \
--build="$AUTOTOOLS_BUILD" \
--host="$AUTOTOOLS_HOST" \
--prefix="$ANDROID_PREFIX" \
--with-ssl="$ANDROID_PREFIX" \
--with-libexpat="$ANDROID_PREFIX" \
--disable-gost;
make -j 2
make install
```
Travis only smoke tests an Android build using a compile, link and install. The self tests are not run. TODO: figure out how to fire up an emulator, push the tests to the device and run them.
### Android flags
`contrib/android/setenv_android.sh` uses specific flags for `CFLAGS` and `CXXFLAGS`. They are taken from `ndk-build`, so we consider them the official flag set. It is important to use the same flags across projects to avoid subtle problems due to mixing and matching different flags.
`CXXFLAGS` includes `-fexceptions` and `-frtti` because exceptions and runtime type info are disabled by default. `CFLAGS` include `-funwind-tables` and `-fexceptions` to ensure C++ exceptions pass through C code, if needed. Also see `docs/CPLUSPLUS-SUPPORT.html` in the NDK docs.
To inspect the flags used by `ndk-build` for a platform clone ASOP's [ndk-samples](https://github.com/android/ndk-samples/tree/master/hello-jni) and build the `hello-jni` project. Use the `V=1` flag to see the full compiler output from `ndk-build`.
## iOS builds
Travis tests iOS builds for the armv7a, armv7s and aarch64 architectures for iPhoneOS, AppleTVOS and WatchOS. iPhoneOS is tested using both 32-bit builds (iPhones) and 64-bit builds (iPads). Travis also tests compiles against the simulators. The builds are trickier than other builds for several reasons. The testing requires a cross-compile, and requires OpenSSL and Expat prerequisites. The iOS cross-compiles also require care to set the Autotools triplet, the OpenSSL triplet, the toolchain path, the tool variables, and the sysroot. The discussion below detail the steps of the iOS recipes.
### iOS job
The first step sets environmental variables for the cross-compile using the Travis job. A typical job with variables is shown below.
```
- os: osx
osx_image: xcode10
name: Apple iPhone on iOS, armv7
compiler: clang
env:
- TEST_IOS=yes
- AUTOTOOLS_HOST=armv7-apple-ios
- OPENSSL_HOST=ios-cross
- IOS_SDK=iPhoneOS
- IOS_CPU=armv7s
- IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
```
### Tool installation
The second step installs tools needed for OpenSSL, Expat and Unbound. This step is handled in by the script `contrib/ios/install_tools.sh`. The tools include autotools, curl and perl. The installation happens at the `before_script:` stage of Travis.
```
before_script:
- |
if [ "$TEST_ANDROID" = "yes" ]; then
./contrib/android/install_tools.sh
elif [ "$TEST_IOS" = "yes" ]; then
./contrib/ios/install_tools.sh
fi
```
### iOS environment
The third step sets the iOS cross-compile environment using the script `contrib/ios/setenv_ios.sh`. The script is `sourced` so the variables in the script are available to the calling shell. The script sets variables like `CC`, `CXX`, `AS` and `AR`; sets `CFLAGS` and `CXXFLAGS`; sets a `sysroot` so iOS headers and libraries are found; and adds the path to the toolchain to `PATH`.
`contrib/ios/setenv_ios.sh` knows which toolchain and architecture to select by inspecting environmental variables set by Travis for the job. In particular, the variables `IOS_SDK` and `IOS_CPU` tell `contrib/ios/setenv_ios.sh` which tools and libraries to select.
The `contrib/ios/setenv_ios.sh` script specifies the tools to use during the cross-compile. For Apple SDKs, the tool names are the same as a desktop. There are no special prefixes for the mobile tools.
```
CPP=cpp
CC=clang
CXX=clang++
LD=ld
AS=as
AR=ar
RANLIB=ranlib
STRIP=strip
```
If you are working from a developer machine you probably already have the necessary tools installed.
### OpenSSL and Expat
The fourth step builds OpenSSL and Expat. OpenSSL and Expat are built for iOS using the scripts `contrib/ios/install_openssl.sh` and `contrib/ios/install_expat.sh`. The scripts download, configure and install the latest release version of the libraries. The libraries are configured with `--prefix="$IOS_PREFIX"` so the headers are placed in `$IOS_PREFIX/include` directory, and the libraries are placed in the `$IOS_PREFIX/lib` directory.
`IOS_PREFIX` is the value `$HOME/$IOS_SDK-$IOS_CPU`. The scheme handles both iOS SDKs and cpu architectures so the pair recieves a unique installation directory. The libraries will be installed in `$HOME/iPhoneOS-armv7s`, `$HOME/iPhoneOS-arm64`, `$HOME/iPhoneSimulator-i386`, etc. For Autotools projects, the appropriate `PKG_CONFIG_PATH` is exported.
`PKG_CONFIG_PATH` is an important variable. It is the userland equivalent to sysroot, and allows Autotools to find non-system headers and libraries for an architecture. Typical `PKG_CONFIG_PATH` are `$HOME/iPhoneOS-armv7s/lib/pkgconfig` and `$HOME/iPhoneOS-arm64/lib/pkgconfig`.
OpenSSL also uses a custom configuration file called `15-ios.conf`. It is a copy of the OpenSSL's project file and located at `contrib/ios/15-ios.conf`. The Unbound version is copied to the OpenSSL source files after unpacking the OpenSSL distribution. The changes mean Unbound's `15-ios.conf` will only work with Unbound and a properly set environment.
OpenSSL is configured with `no-engine`. Engines require dynamic loading so engines are disabled permanently in `15-ios.conf`.
### iOS build
Finally, once OpenSSL and Expat are built, then the Travis script configures and builds Unbound. The full recipe looks as follows.
```
elif [ "$TEST_IOS" = "yes" ]; then
export AUTOTOOLS_BUILD="$(./config.guess)"
export PKG_CONFIG_PATH="$IOS_PREFIX/lib/pkgconfig"
source ./contrib/ios/setenv_ios.sh
./contrib/ios/install_openssl.sh
./contrib/ios/install_expat.sh
./configure \
--build="$AUTOTOOLS_BUILD" \
--host="$AUTOTOOLS_HOST" \
--prefix="$IOS_PREFIX" \
--with-ssl="$IOS_PREFIX" \
--with-libexpat="$IOS_PREFIX" \
--disable-gost;
make -j 2
make install
```
Travis only smoke tests an iOS build using a compile, link and install. The self tests are not run. TODO: figure out how to fire up an simulator, push the tests to the device and run them.
### iOS flags
`contrib/ios/setenv_ios.sh` uses specific flags for `CFLAGS` and `CXXFLAGS`. They are taken from Xcode, so we consider them the official flag set. It is important to use the same flags across projects to avoid subtle problems due to mixing and matching different flags.

View File

@ -58,6 +58,11 @@ $ac_distutils_result])
AC_MSG_RESULT([$PYTHON_LDFLAGS])
AC_SUBST([PYTHON_LDFLAGS])
if test -z "$PYTHON_LIBDIR"; then
PYTHON_LIBDIR=`$PYTHON -c "from distutils.sysconfig import *; \
print(get_config_var('LIBDIR'));"`
fi
#
# Check for site packages
#

View File

@ -160,7 +160,7 @@ testframe_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
static void
testframe_store(struct module_env* env, struct cachedb_env* cachedb_env,
char* key, uint8_t* data, size_t data_len)
char* key, uint8_t* data, size_t data_len, time_t ATTR_UNUSED(ttl))
{
struct testframe_moddata* d = (struct testframe_moddata*)
cachedb_env->backend_data;
@ -606,7 +606,8 @@ cachedb_extcache_store(struct module_qstate* qstate, struct cachedb_env* ie)
/* call backend */
(*ie->backend->store)(qstate->env, ie, key,
sldns_buffer_begin(qstate->env->scratch_buffer),
sldns_buffer_limit(qstate->env->scratch_buffer));
sldns_buffer_limit(qstate->env->scratch_buffer),
qstate->return_msg->rep->ttl);
}
/**

View File

@ -84,7 +84,7 @@ struct cachedb_backend {
/** Store (env, cachedb_env, key, data, data_len) */
void (*store)(struct module_env*, struct cachedb_env*, char*,
uint8_t*, size_t);
uint8_t*, size_t, time_t);
};
#define CACHEDB_HASHSIZE 256 /* bit hash */

View File

@ -59,6 +59,9 @@ struct redis_moddata {
struct timeval timeout; /* timeout for connection setup and commands */
};
static redisReply* redis_command(struct module_env*, struct cachedb_env*,
const char*, const uint8_t*, size_t);
static redisContext*
redis_connect(const struct redis_moddata* moddata)
{
@ -114,6 +117,33 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
for(i = 0; i < moddata->numctxs; i++)
moddata->ctxs[i] = redis_connect(moddata);
cachedb_env->backend_data = moddata;
if(env->cfg->redis_expire_records) {
redisReply* rep = NULL;
int redis_reply_type = 0;
/** check if setex command is supported */
rep = redis_command(env, cachedb_env,
"SETEX __UNBOUND_REDIS_CHECK__ 1 none", NULL, 0);
if(!rep) {
/** init failed, no response from redis server*/
log_err("redis_init: failed to init redis, the "
"redis-expire-records option requires the SETEX command "
"(redis >= 2.0.0)");
return 0;
}
redis_reply_type = rep->type;
freeReplyObject(rep);
switch(redis_reply_type) {
case REDIS_REPLY_STATUS:
break;
default:
/** init failed, setex command not supported */
log_err("redis_init: failed to init redis, the "
"redis-expire-records option requires the SETEX command "
"(redis >= 2.0.0)");
return 0;
}
}
return 1;
}
@ -219,7 +249,7 @@ redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0);
if(!rep)
return 0;
switch (rep->type) {
switch(rep->type) {
case REDIS_REPLY_NIL:
verbose(VERB_ALGO, "redis_lookup: no data cached");
break;
@ -249,16 +279,33 @@ redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
static void
redis_store(struct module_env* env, struct cachedb_env* cachedb_env,
char* key, uint8_t* data, size_t data_len)
char* key, uint8_t* data, size_t data_len, time_t ttl)
{
redisReply* rep;
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+3+1]; /* "SET " + key + " %b" */
int n;
int set_ttl = (env->cfg->redis_expire_records &&
(!env->cfg->serve_expired || env->cfg->serve_expired_ttl > 0));
/* Supported commands:
* - "SET " + key + " %b"
* - "SETEX " + key + " " + ttl + " %b"
*/
char cmdbuf[6+(CACHEDB_HASHSIZE/8)*2+11+3+1];
if (!set_ttl) {
verbose(VERB_ALGO, "redis_store %s (%d bytes)", key, (int)data_len);
/* build command to set to a binary safe string */
n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b", key);
} else {
/* add expired ttl time to redis ttl to avoid premature eviction of key */
ttl += env->cfg->serve_expired_ttl;
verbose(VERB_ALGO, "redis_store %s (%d bytes) with ttl %u",
key, (int)data_len, (uint32_t)ttl);
/* build command to set to a binary safe string */
n = snprintf(cmdbuf, sizeof(cmdbuf), "SETEX %s %u %%b", key,
(uint32_t)ttl);
}
verbose(VERB_ALGO, "redis_store %s (%d bytes)", key, (int)data_len);
/* build command to set to a binary safe string */
n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b", key);
if(n < 0 || n >= (int)sizeof(cmdbuf)) {
log_err("redis_store: unexpected failure to build command");
return;

895
config.guess vendored

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,9 @@
/* Whether daemon is deprecated */
#undef DEPRECATED_DAEMON
/* Define this to enable kernel based UDP source port randomization. */
#undef DISABLE_EXPLICIT_PORT_RANDOMISATION
/* default dnstap socket path */
#undef DNSTAP_SOCKET_PATH
@ -176,6 +179,9 @@
/* Define to 1 if you have the `endservent' function. */
#undef HAVE_ENDSERVENT
/* Define to 1 if you have the `ENGINE_cleanup' function. */
#undef HAVE_ENGINE_CLEANUP
/* Define to 1 if you have the `ERR_free_strings' function. */
#undef HAVE_ERR_FREE_STRINGS
@ -380,6 +386,9 @@
/* Define to 1 if you have the <openssl/conf.h> header file. */
#undef HAVE_OPENSSL_CONF_H
/* Define to 1 if you have the <openssl/core_names.h> header file. */
#undef HAVE_OPENSSL_CORE_NAMES_H
/* Define to 1 if you have the <openssl/dh.h> header file. */
#undef HAVE_OPENSSL_DH_H
@ -494,8 +503,9 @@
/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_cb' function. */
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_CB
/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_evp_cb'
function. */
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
/* Define to 1 if you have the `SSL_get0_peername' function. */
#undef HAVE_SSL_GET0_PEERNAME
@ -590,6 +600,9 @@
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if you have the <TargetConditionals.h> header file. */
#undef HAVE_TARGETCONDITIONALS_H
/* Define to 1 if you have the <time.h> header file. */
#undef HAVE_TIME_H
@ -805,6 +818,9 @@
/* Define to 1 to use ipset support */
#undef USE_IPSET
/* Define if you enable libevent */
#undef USE_LIBEVENT
/* Define if you want to use internal select based events */
#undef USE_MINI_EVENT
@ -854,6 +870,9 @@
/* the version of the windows API enabled */
#undef WINVER
/* Define if you want dynlib module. */
#undef WITH_DYNLIBMODULE
/* Define if you want Python module. */
#undef WITH_PYTHONMODULE

2874
config.sub vendored

File diff suppressed because it is too large Load Diff

224
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for unbound 1.10.1.
# Generated by GNU Autoconf 2.69 for unbound 1.11.0.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
#
@ -591,8 +591,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
PACKAGE_VERSION='1.10.1'
PACKAGE_STRING='unbound 1.10.1'
PACKAGE_VERSION='1.11.0'
PACKAGE_STRING='unbound 1.11.0'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
PACKAGE_URL=''
@ -649,6 +649,7 @@ ENABLE_DNSCRYPT
ENABLE_DNSCRYPT_XCHACHA20
DNSTAP_OBJ
DNSTAP_SRC
DNSTAP_SOCKET_PATH
opt_dnstap_socket_path
ENABLE_DNSTAP
PROTOC_C
@ -699,6 +700,10 @@ PYTHON_LDFLAGS
PYTHON_CPPFLAGS
PYTHON
PYTHON_VERSION
DYNLIBMOD_EXTRALIBS
DYNLIBMOD_HEADER
DYNLIBMOD_OBJ
WITH_DYNLIBMODULE
PTHREAD_CFLAGS_ONLY
PTHREAD_CFLAGS
PTHREAD_LIBS
@ -855,6 +860,7 @@ enable_alloc_nonregional
with_pthreads
with_solaris_threads
with_syslog_facility
with_dynlibmodule
with_pyunbound
with_pythonmodule
enable_swig_version_check
@ -883,13 +889,13 @@ enable_allsymbols
enable_dnstap
with_dnstap_socket_path
with_protobuf_c
with_libfstrm
enable_dnscrypt
with_libsodium
enable_cachedb
enable_ipsecmod
enable_ipset
with_libmnl
enable_explicit_port_randomisation
with_libunbound_only
'
ac_precious_vars='build_alias
@ -1452,7 +1458,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures unbound 1.10.1 to adapt to many kinds of systems.
\`configure' configures unbound 1.11.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1517,7 +1523,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of unbound 1.10.1:";;
short | recursive ) echo "Configuration of unbound 1.11.0:";;
esac
cat <<\_ACEOF
@ -1572,13 +1578,16 @@ Optional Features:
--enable-allsymbols export all symbols from libunbound and link binaries
to it, smaller install size but libunbound export
table is polluted by internal symbols
--enable-dnstap Enable dnstap support (requires fstrm, protobuf-c)
--enable-dnstap Enable dnstap support (requires protobuf-c)
--enable-dnscrypt Enable dnscrypt support (requires libsodium)
--enable-cachedb enable cachedb module that can use external cache
storage
--enable-ipsecmod Enable ipsecmod module that facilitates
opportunistic IPsec
--enable-ipset enable ipset module
--disable-explicit-port-randomisation
disable explicit source port randomisation and rely
on the kernel to provide random source ports
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@ -1614,6 +1623,8 @@ Optional Packages:
--with-solaris-threads use solaris native thread library.
--with-syslog-facility=LOCAL0 - LOCAL7
set SYSLOG_FACILITY, default DAEMON
--with-dynlibmodule build dynamic library module, or
--without-dynlibmodule to disable it. (default=no)
--with-pyunbound build PyUnbound, or --without-pyunbound to skip it.
(default=no)
--with-pythonmodule build Python module, or --without-pythonmodule to
@ -1634,7 +1645,6 @@ Optional Packages:
--with-dnstap-socket-path=pathname
set default dnstap socket path
--with-protobuf-c=path Path where protobuf-c is installed, for dnstap
--with-libfstrm=path Path where libfstrm is installed, for dnstap
--with-libsodium=path Path where libsodium is installed, for dnscrypt
--with-libmnl=path specify explicit path for libmnl.
--with-libunbound-only do not build daemon and tool programs
@ -1740,7 +1750,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
unbound configure 1.10.1
unbound configure 1.11.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -2449,7 +2459,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by unbound $as_me 1.10.1, which was
It was created by unbound $as_me 1.11.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@ -2799,13 +2809,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=10
UNBOUND_VERSION_MINOR=11
UNBOUND_VERSION_MICRO=1
UNBOUND_VERSION_MICRO=0
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=8
LIBUNBOUND_REVISION=9
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@ -2881,6 +2891,7 @@ LIBUNBOUND_AGE=1
# 1.9.6 had 9:6:1
# 1.10.0 had 9:7:1
# 1.10.1 had 9:8:1
# 1.11.0 had 9:9:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@ -14729,6 +14740,20 @@ fi
done
# Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH
for ac_header in TargetConditionals.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "TargetConditionals.h" "ac_cv_header_TargetConditionals_h" "$ac_includes_default"
if test "x$ac_cv_header_TargetConditionals_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_TARGETCONDITIONALS_H 1
_ACEOF
fi
done
# check for types.
# Using own tests for int64* because autoconf builtin only give 32bit.
ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default"
@ -17171,6 +17196,34 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
# Check for dynamic library module
# Check whether --with-dynlibmodule was given.
if test "${with_dynlibmodule+set}" = set; then :
withval=$with_dynlibmodule;
else
withval="no"
fi
if test x_$withval != x_no; then
$as_echo "#define WITH_DYNLIBMODULE 1" >>confdefs.h
WITH_DYNLIBMODULE=yes
DYNLIBMOD_OBJ="dynlibmod.lo"
DYNLIBMOD_HEADER='$(srcdir)/dynlibmod/dynlibmod.h'
if test $on_mingw = "no"; then
DYNLIBMOD_EXTRALIBS="-ldl -export-dynamic"
else
DYNLIBMOD_EXTRALIBS="-Wl,--export-all-symbols,--out-implib,libunbound.a"
fi
fi
# Check for PyUnbound
# Check whether --with-pyunbound was given.
@ -17312,6 +17365,11 @@ $as_echo_n "checking for Python library path... " >&6; }
$as_echo "$PYTHON_LDFLAGS" >&6; }
if test -z "$PYTHON_LIBDIR"; then
PYTHON_LIBDIR=`$PYTHON -c "from distutils.sysconfig import *; \
print(get_config_var('LIBDIR'));"`
fi
#
# Check for site packages
#
@ -17417,6 +17475,15 @@ $as_echo "#define HAVE_PYTHON 1" >>confdefs.h
else
CPPFLAGS="$PYTHON_CPPFLAGS"
fi
if test "$PYTHON_LIBDIR" != "/usr/lib" -a "$PYTHON_LIBDIR" != "" -a "$PYTHON_LIBDIR" != "/usr/lib64"; then
if test "x$enable_rpath" = xyes; then
if echo "$PYTHON_LIBDIR" | grep "^/" >/dev/null; then
RUNTIME_PATH="$RUNTIME_PATH -R$PYTHON_LIBDIR"
fi
fi
fi
ub_have_python=yes
if test -n "$PKG_CONFIG" && \
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\"python\${PY_MAJOR_VERSION}\"\""; } >&5
@ -18259,7 +18326,7 @@ else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
for ac_header in openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h
for ac_header in openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
@ -18273,7 +18340,7 @@ fi
done
for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback
for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -18289,7 +18356,7 @@ done
# these check_funcs need -lssl
BAKLIBS="$LIBS"
LIBS="-lssl $LIBS"
for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites
for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -19107,31 +19174,34 @@ esac
if test "${with_libevent+set}" = set; then :
withval=$with_libevent;
else
withval="no"
with_libevent="no"
fi
if test x_$withval = x_yes -o x_$withval != x_no; then
if test "x_$with_libevent" != x_no; then
$as_echo "#define USE_LIBEVENT 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libevent" >&5
$as_echo_n "checking for libevent... " >&6; }
if test x_$withval = x_ -o x_$withval = x_yes; then
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
if test "x_$with_libevent" = x_ -o "x_$with_libevent" = x_yes; then
with_libevent="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
for dir in $withval; do
for dir in $with_libevent; do
thedir="$dir"
if test -f "$dir/include/event.h" -o -f "$dir/include/event2/event.h"; then
found_libevent="yes"
if test "$thedir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$thedir/include"
fi
break;
fi
if test "$thedir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$thedir/include"
fi
break;
fi
done
if test x_$found_libevent != x_yes; then
if test -f "$dir/event.h" -a \( -f "$dir/libevent.la" -o -f "$dir/libev.la" \) ; then
# libevent source directory
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $thedir" >&5
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $thedir" >&5
$as_echo "found in $thedir" >&6; }
CPPFLAGS="$CPPFLAGS -I$thedir -I$thedir/include"
CPPFLAGS="$CPPFLAGS -I$thedir -I$thedir/include"
BAK_LDFLAGS_SET="1"
BAK_LDFLAGS="$LDFLAGS"
# remove evdns from linking
@ -19144,10 +19214,10 @@ $as_echo "found in $thedir" >&6; }
cp $ev_files_o build/libevent
cp $ev_files_lo build/libevent
cp $ev_files_libso build/libevent/.libs
LATE_LDFLAGS="build/libevent/*.lo -lm"
LATE_LDFLAGS="build/libevent/*.lo -lm"
LDFLAGS="build/libevent/*.o $LDFLAGS -lm"
else
as_fn_error $? "Cannot find the libevent library in $withval
as_fn_error $? "Cannot find the libevent library in $with_libevent
You can restart ./configure --with-libevent=no to use a builtin alternative.
Please note that this alternative is not as capable as libevent when using
large outgoing port ranges. " "$LINENO" 5
@ -20968,73 +21038,6 @@ else
fi
# Check whether --with-libfstrm was given.
if test "${with_libfstrm+set}" = set; then :
withval=$with_libfstrm;
CFLAGS="$CFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval/lib"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fstrm_iothr_init" >&5
$as_echo_n "checking for library containing fstrm_iothr_init... " >&6; }
if ${ac_cv_search_fstrm_iothr_init+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char fstrm_iothr_init ();
int
main ()
{
return fstrm_iothr_init ();
;
return 0;
}
_ACEOF
for ac_lib in '' fstrm; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_fstrm_iothr_init=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_fstrm_iothr_init+:} false; then :
break
fi
done
if ${ac_cv_search_fstrm_iothr_init+:} false; then :
else
ac_cv_search_fstrm_iothr_init=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fstrm_iothr_init" >&5
$as_echo "$ac_cv_search_fstrm_iothr_init" >&6; }
ac_res=$ac_cv_search_fstrm_iothr_init
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
else
as_fn_error $? "The fstrm library was not found. Please install fstrm!" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing protobuf_c_message_pack" >&5
$as_echo_n "checking for library containing protobuf_c_message_pack... " >&6; }
if ${ac_cv_search_protobuf_c_message_pack+:} false; then :
@ -21108,10 +21111,12 @@ cat >>confdefs.h <<_ACEOF
#define DNSTAP_SOCKET_PATH "$hdr_dnstap_socket_path"
_ACEOF
DNSTAP_SOCKET_PATH="$hdr_dnstap_socket_path"
DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c"
DNSTAP_OBJ="dnstap.lo dnstap.pb-c.lo"
DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c"
DNSTAP_OBJ="dnstap.lo dnstap.pb-c.lo dnstap_fstrm.lo dtstream.lo"
else
@ -21443,6 +21448,21 @@ $as_echo "found in $dir" >&6; }
# nothing
;;
esac
# Check whether --enable-explicit-port-randomisation was given.
if test "${enable_explicit_port_randomisation+set}" = set; then :
enableval=$enable_explicit_port_randomisation;
fi
case "$enable_explicit_port_randomisation" in
no)
$as_echo "#define DISABLE_EXPLICIT_PORT_RANDOMISATION 1" >>confdefs.h
;;
yes|*)
;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${MAKE:-make} supports $< with implicit rule in scope" >&5
$as_echo_n "checking if ${MAKE:-make} supports $< with implicit rule in scope... " >&6; }
@ -21599,7 +21619,7 @@ _ACEOF
version=1.10.1
version=1.11.0
date=`date +'%b %e, %Y'`
@ -22118,7 +22138,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by unbound $as_me 1.10.1, which was
This file was extended by unbound $as_me 1.11.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -22184,7 +22204,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
unbound config.status 1.10.1
unbound config.status 1.11.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@ -10,15 +10,15 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[10])
m4_define([VERSION_MICRO],[1])
m4_define([VERSION_MINOR],[11])
m4_define([VERSION_MICRO],[0])
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues, unbound)
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=8
LIBUNBOUND_REVISION=9
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@ -94,6 +94,7 @@ LIBUNBOUND_AGE=1
# 1.9.6 had 9:6:1
# 1.10.0 had 9:7:1
# 1.10.1 had 9:8:1
# 1.11.0 had 9:9:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@ -399,6 +400,9 @@ PKG_PROG_PKG_CONFIG
# Checks for header files.
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
# Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH
AC_CHECK_HEADERS([TargetConditionals.h])
# check for types.
# Using own tests for int64* because autoconf builtin only give 32bit.
AC_CHECK_TYPE(int8_t, signed char)
@ -624,6 +628,28 @@ case "${UNBOUND_SYSLOG_FACILITY}" in
esac
AC_DEFINE_UNQUOTED(UB_SYSLOG_FACILITY,${UNBOUND_SYSLOG_FACILITY},[the SYSLOG_FACILITY to use, default LOG_DAEMON])
# Check for dynamic library module
AC_ARG_WITH(dynlibmodule,
AC_HELP_STRING([--with-dynlibmodule],
[build dynamic library module, or --without-dynlibmodule to disable it. (default=no)]),
[], [ withval="no" ])
if test x_$withval != x_no; then
AC_DEFINE(WITH_DYNLIBMODULE, 1, [Define if you want dynlib module.])
WITH_DYNLIBMODULE=yes
AC_SUBST(WITH_DYNLIBMODULE)
DYNLIBMOD_OBJ="dynlibmod.lo"
AC_SUBST(DYNLIBMOD_OBJ)
DYNLIBMOD_HEADER='$(srcdir)/dynlibmod/dynlibmod.h'
AC_SUBST(DYNLIBMOD_HEADER)
if test $on_mingw = "no"; then
DYNLIBMOD_EXTRALIBS="-ldl -export-dynamic"
else
DYNLIBMOD_EXTRALIBS="-Wl,--export-all-symbols,--out-implib,libunbound.a"
fi
AC_SUBST(DYNLIBMOD_EXTRALIBS)
fi
# Check for PyUnbound
AC_ARG_WITH(pyunbound,
AC_HELP_STRING([--with-pyunbound],
@ -675,6 +701,9 @@ if test x_$ub_test_python != x_no; then
else
CPPFLAGS="$PYTHON_CPPFLAGS"
fi
if test "$PYTHON_LIBDIR" != "/usr/lib" -a "$PYTHON_LIBDIR" != "" -a "$PYTHON_LIBDIR" != "/usr/lib64"; then
ACX_RUNTIME_PATH_ADD([$PYTHON_LIBDIR])
fi
ub_have_python=yes
PKG_CHECK_EXISTS(["python${PY_MAJOR_VERSION}"],
[PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"],
@ -821,13 +850,13 @@ if grep VERSION_TEXT $ssldir/include/openssl/opensslv.h | grep "LibreSSL" >/dev/
else
AC_MSG_RESULT([no])
fi
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback])
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback])
# these check_funcs need -lssl
BAKLIBS="$LIBS"
LIBS="-lssl $LIBS"
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites])
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb])
LIBS="$BAKLIBS"
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
@ -1215,28 +1244,29 @@ esac
# check for libevent
AC_ARG_WITH(libevent, AC_HELP_STRING([--with-libevent=pathname],
[use libevent (will check /usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr or you can specify an explicit path). Slower, but allows use of large outgoing port ranges.]),
[ ],[ withval="no" ])
if test x_$withval = x_yes -o x_$withval != x_no; then
[ ],[ with_libevent="no" ])
if test "x_$with_libevent" != x_no; then
AC_DEFINE([USE_LIBEVENT], [1], [Define if you enable libevent])
AC_MSG_CHECKING(for libevent)
if test x_$withval = x_ -o x_$withval = x_yes; then
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
if test "x_$with_libevent" = x_ -o "x_$with_libevent" = x_yes; then
with_libevent="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
for dir in $withval; do
for dir in $with_libevent; do
thedir="$dir"
if test -f "$dir/include/event.h" -o -f "$dir/include/event2/event.h"; then
found_libevent="yes"
dnl assume /usr is in default path.
if test "$thedir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$thedir/include"
fi
break;
fi
dnl assume /usr is in default path.
if test "$thedir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$thedir/include"
fi
break;
fi
done
if test x_$found_libevent != x_yes; then
if test -f "$dir/event.h" -a \( -f "$dir/libevent.la" -o -f "$dir/libev.la" \) ; then
# libevent source directory
AC_MSG_RESULT(found in $thedir)
CPPFLAGS="$CPPFLAGS -I$thedir -I$thedir/include"
AC_MSG_RESULT(found in $thedir)
CPPFLAGS="$CPPFLAGS -I$thedir -I$thedir/include"
BAK_LDFLAGS_SET="1"
BAK_LDFLAGS="$LDFLAGS"
# remove evdns from linking
@ -1249,10 +1279,10 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
cp $ev_files_o build/libevent
cp $ev_files_lo build/libevent
cp $ev_files_libso build/libevent/.libs
LATE_LDFLAGS="build/libevent/*.lo -lm"
LATE_LDFLAGS="build/libevent/*.lo -lm"
LDFLAGS="build/libevent/*.o $LDFLAGS -lm"
else
AC_MSG_ERROR([Cannot find the libevent library in $withval
AC_MSG_ERROR([Cannot find the libevent library in $with_libevent
You can restart ./configure --with-libevent=no to use a builtin alternative.
Please note that this alternative is not as capable as libevent when using
large outgoing port ranges. ])
@ -1688,9 +1718,10 @@ dt_DNSTAP([$UNBOUND_RUN_DIR/dnstap.sock],
ACX_ESCAPE_BACKSLASH($opt_dnstap_socket_path, hdr_dnstap_socket_path)
AC_DEFINE_UNQUOTED(DNSTAP_SOCKET_PATH,
["$hdr_dnstap_socket_path"], [default dnstap socket path])
AC_SUBST(DNSTAP_SOCKET_PATH,["$hdr_dnstap_socket_path"])
AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c"])
AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo"])
AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c"])
AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo dnstap_fstrm.lo dtstream.lo"])
],
[
AC_SUBST([ENABLE_DNSTAP], [0])
@ -1778,6 +1809,15 @@ case "$enable_ipset" in
# nothing
;;
esac
AC_ARG_ENABLE(explicit-port-randomisation, AC_HELP_STRING([--disable-explicit-port-randomisation], [disable explicit source port randomisation and rely on the kernel to provide random source ports]))
case "$enable_explicit_port_randomisation" in
no)
AC_DEFINE([DISABLE_EXPLICIT_PORT_RANDOMISATION], [1], [Define this to enable kernel based UDP source port randomization.])
;;
yes|*)
;;
esac
AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
# on openBSD, the implicit rule make $< work.

View File

@ -13,9 +13,9 @@ Index: trunk/doc/unbound.conf.5.in
+This also causes an additional A query to be sent for each AAAA query.
+This breaks DNSSEC!
+.TP
.B private\-address: \fI<IP address or subnet>
Give IPv4 of IPv6 addresses or classless subnets. These are addresses
on your private network, and are not allowed to be returned for
.B aggressive\-nsec: \fI<yes or no>
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
and other denials, using information from previous NXDOMAINs answers.
Index: trunk/iterator/iter_scrub.c
===================================================================
--- trunk/iterator/iter_scrub.c (revision 4357)
@ -125,7 +125,7 @@ Index: trunk/iterator/iterator.c
+ * ASN: This event state was added as an intermediary step between
+ * QUERYTARGETS_STATE and the next step, in order to cast a subquery for the
+ * purpose of caching A records for the queried name.
+ *
+ *
+ * @param qstate: query state.
+ * @param iq: iterator query state.
+ * @param ie: iterator shared global environment.
@ -147,9 +147,9 @@ Index: trunk/iterator/iterator.c
+
+ /* re-throw same query, but with a different type */
+ if(!generate_sub_request(iq->qchase.qname,
+ iq->qchase.qname_len, LDNS_RR_TYPE_A,
+ iq->qchase.qname_len, LDNS_RR_TYPE_A,
+ iq->qchase.qclass, qstate, id, iq,
+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: failed "
+ "preloading of A record for",
+ iq->qchase.qname, LDNS_RR_TYPE_A,
@ -188,7 +188,7 @@ Index: trunk/iterator/iterator.c
return 0;
}
+/**
+/**
+ * ASN: Do final processing on responses to A queries originated from AAAA
+ * queries. Events reach this state after the iterative resolution algorithm
+ * terminates.

View File

@ -0,0 +1,37 @@
#### Android...
#
# Heavily hacked 15-android.conf based on OpenSSL's config file of the same name.
# This 15-android.conf avoids compiler errors using NDK-r20. This 15-android.conf
# requires an environment set (sourced) using setenv-android.sh.
my %targets = (
"android" => {
inherit_from => [ "linux-generic32" ],
template => 1,
bin_cflags => add("-fPIE"),
bin_lflags => add("-pie"),
enable => [ ],
},
"android-arm" => {
inherit_from => [ "android", asm("armv4_asm") ],
bn_ops => [ "BN_LLONG", "RC4_CHAR" ],
},
"android-arm64" => {
inherit_from => [ "android", asm("aarch64_asm") ],
bn_ops => [ "SIXTY_FOUR_BIT_LONG", "RC4_CHAR" ],
perlasm_scheme => "linux64",
},
"android-x86" => {
inherit_from => [ "android", asm("x86_asm") ],
cflags => add(picker(release => "-fomit-frame-pointer")),
bn_ops => [ "BN_LLONG", "RC4_INT" ],
perlasm_scheme => "android",
},
"android-x86_64" => {
inherit_from => [ "android", asm("x86_64_asm") ],
bn_ops => [ "SIXTY_FOUR_BIT_LONG", "RC4_INT" ],
perlasm_scheme => "elf",
},
);

View File

@ -0,0 +1,51 @@
#!/usr/bin/env bash
echo "Downloading Expat"
if ! curl -L -k -s -o expat-2.2.9.tar.gz https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.gz;
then
echo "Failed to download Expat"
exit 1
fi
echo "Unpacking Expat"
rm -rf ./expat-2.2.9
if ! tar -xf expat-2.2.9.tar.gz;
then
echo "Failed to unpack Expat"
exit 1
fi
cd expat-2.2.9 || exit 1
echo "Configuring Expat"
if ! ./configure --build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" --prefix="$ANDROID_PREFIX"; then
echo "Error: Failed to configure Expat"
exit 1
fi
# Cleanup warnings, https://github.com/libexpat/libexpat/issues/383
echo "Fixing Makefiles"
(IFS="" find "$PWD" -name 'Makefile' -print | while read -r file
do
cp -p "$file" "$file.fixed"
sed 's|-Wduplicated-cond ||g; s|-Wduplicated-branches ||g; s|-Wlogical-op ||g' "$file" > "$file.fixed"
mv "$file.fixed" "$file"
cp -p "$file" "$file.fixed"
sed 's|-Wrestrict ||g; s|-Wjump-misses-init ||g; s|-Wmisleading-indentation ||g' "$file" > "$file.fixed"
mv "$file.fixed" "$file"
done)
echo "Building Expat"
if ! make; then
echo "Failed to build Expat"
exit 1
fi
echo "Installing Expat"
if ! make install; then
echo "Failed to install Expat"
exit 1
fi
exit 0

60
contrib/android/install_ndk.sh Executable file
View File

@ -0,0 +1,60 @@
#!/usr/bin/env bash
if [ -z "$ANDROID_SDK_ROOT" ]; then
echo "ERROR: ANDROID_SDK_ROOT is not a valid path. Please set it."
echo "SDK root is $ANDROID_SDK_ROOT"
exit 1
fi
if [ -z "$ANDROID_NDK_ROOT" ]; then
echo "ERROR: ANDROID_NDK_ROOT is not a valid path. Please set it."
echo "NDK root is $ANDROID_NDK_ROOT"
exit 1
fi
echo "Using ANDROID_SDK_ROOT: $ANDROID_SDK_ROOT"
echo "Using ANDROID_NDK_ROOT: $ANDROID_NDK_ROOT"
echo "Downloading SDK"
if ! curl -L -k -s -o "$HOME/android-sdk.zip" https://dl.google.com/android/repository/commandlinetools-linux-6200805_latest.zip;
then
echo "Failed to download SDK"
exit 1
fi
echo "Downloading NDK"
if ! curl -L -k -s -o "$HOME/android-ndk.zip" https://dl.google.com/android/repository/android-ndk-r20b-linux-x86_64.zip;
then
echo "Failed to download NDK"
exit 1
fi
echo "Unpacking SDK to $ANDROID_SDK_ROOT"
if ! unzip -qq "$HOME/android-sdk.zip" -d "$ANDROID_SDK_ROOT";
then
echo "Failed to unpack SDK"
exit 1
fi
echo "Unpacking NDK to $ANDROID_NDK_ROOT"
if ! unzip -qq "$HOME/android-ndk.zip" -d "$HOME";
then
echo "Failed to unpack NDK"
exit 1
fi
if ! mv "$HOME/android-ndk-r20b" "$ANDROID_NDK_ROOT";
then
echo "Failed to move $HOME/android-ndk-r20b to $ANDROID_NDK_ROOT"
exit 1
fi
rm -f "$HOME/android-sdk.zip"
rm -f "$HOME/android-ndk.zip"
# https://stackoverflow.com/a/47028911/608639
touch "$ANDROID_SDK_ROOT/repositories.cfg"
echo "Finished installing SDK and NDK"
exit 0

View File

@ -0,0 +1,44 @@
#!/usr/bin/env bash
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;
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;
then
echo "Failed to unpack OpenSSL"
exit 1
fi
cd openssl-1.1.1d || exit 1
if ! cp ../contrib/android/15-android.conf Configurations/; then
echo "Failed to copy OpenSSL Android config"
exit 1
fi
echo "Configuring OpenSSL"
if ! ./Configure "$OPENSSL_HOST" no-comp no-asm no-hw no-engine shared \
--prefix="$ANDROID_PREFIX" --openssldir="$ANDROID_PREFIX"; then
echo "Failed to configure OpenSSL"
exit 1
fi
echo "Building OpenSSL"
if ! make; then
echo "Failed to build OpenSSL"
exit 1
fi
echo "Installing OpenSSL"
if ! make install_sw; then
echo "Failed to install OpenSSL"
exit 1
fi
exit 0

View File

@ -0,0 +1,6 @@
#!/usr/bin/env bash
# This step should install tools needed for all packages - OpenSSL, Expat and Unbound
echo "Updating tools"
sudo apt-get -qq update
sudo apt-get -qq install --no-install-recommends curl tar zip unzip perl openjdk-8-jdk autoconf automake libtool pkg-config

203
contrib/android/setenv_android.sh Executable file
View File

@ -0,0 +1,203 @@
#!/usr/bin/env bash
# ====================================================================
# Sets the cross compile environment for Android
#
# Based upon OpenSSL's setenv-android.sh by TH, JW, and SM.
# Heavily modified by JWW for Crypto++.
# Updated by Skycoder42 for current recommendations for Android.
# Modified by JWW for Unbound.
# ====================================================================
#########################################
##### Some validation #####
#########################################
if [ -z "$ANDROID_API" ]; then
echo "ANDROID_API is not set. Please set it"
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
if [ -z "$ANDROID_CPU" ]; then
echo "ANDROID_CPU is not set. Please set it"
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
if [ ! -d "$ANDROID_NDK_ROOT" ]; then
echo "ERROR: ANDROID_NDK_ROOT is not a valid path. Please set it."
echo "NDK root is $ANDROID_NDK_ROOT"
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# cryptest-android.sh may run this script without sourcing.
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
echo "setenv-android.sh is usually sourced, but not this time."
fi
#####################################################################
# Need to set THIS_HOST to darwin-x86_64, linux-x86_64,
# windows, or windows-x86_64
if [[ "$(uname -s | grep -i -c darwin)" -ne 0 ]]; then
THIS_HOST=darwin-x86_64
elif [[ "$(uname -s | grep -i -c linux)" -ne 0 ]]; then
THIS_HOST=linux-x86_64
else
echo "ERROR: Unknown host"
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
ANDROID_TOOLCHAIN="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$THIS_HOST/bin"
ANDROID_SYSROOT="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$THIS_HOST/sysroot"
# Error checking
if [ ! -d "$ANDROID_TOOLCHAIN" ]; then
echo "ERROR: ANDROID_TOOLCHAIN is not a valid path. Please set it."
echo "Path is $ANDROID_TOOLCHAIN"
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -d "$ANDROID_SYSROOT" ]; then
echo "ERROR: ANDROID_SYSROOT is not a valid path. Please set it."
echo "Path is $ANDROID_SYSROOT"
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
#####################################################################
THE_ARCH=$(tr '[:upper:]' '[:lower:]' <<< "$ANDROID_CPU")
# https://developer.android.com/ndk/guides/abis.html
case "$THE_ARCH" in
armv7*|armeabi*)
CC="armv7a-linux-androideabi$ANDROID_API-clang"
CXX="armv7a-linux-androideabi$ANDROID_API-clang++"
LD="arm-linux-androideabi-ld"
AS="arm-linux-androideabi-as"
AR="arm-linux-androideabi-ar"
RANLIB="arm-linux-androideabi-ranlib"
STRIP="arm-linux-androideabi-strip"
CFLAGS="-march=armv7-a -mthumb -mfloat-abi=softfp -funwind-tables -fexceptions"
CXXFLAGS="-march=armv7-a -mthumb -mfloat-abi=softfp -funwind-tables -fexceptions -frtti"
;;
armv8*|aarch64|arm64*)
CC="aarch64-linux-android$ANDROID_API-clang"
CXX="aarch64-linux-android$ANDROID_API-clang++"
LD="aarch64-linux-android-ld"
AS="aarch64-linux-android-as"
AR="aarch64-linux-android-ar"
RANLIB="aarch64-linux-android-ranlib"
STRIP="aarch64-linux-android-strip"
CFLAGS="-funwind-tables -fexceptions"
CXXFLAGS="-funwind-tables -fexceptions -frtti"
;;
x86)
CC="i686-linux-android$ANDROID_API-clang"
CXX="i686-linux-android$ANDROID_API-clang++"
LD="i686-linux-android-ld"
AS="i686-linux-android-as"
AR="i686-linux-android-ar"
RANLIB="i686-linux-android-ranlib"
STRIP="i686-linux-android-strip"
CFLAGS="-mtune=intel -mssse3 -mfpmath=sse -funwind-tables -fexceptions"
CXXFLAGS="-mtune=intel -mssse3 -mfpmath=sse -funwind-tables -fexceptions -frtti"
;;
x86_64|x64)
CC="x86_64-linux-android$ANDROID_API-clang"
CXX="x86_64-linux-android$ANDROID_API-clang++"
LD="x86_64-linux-android-ld"
AS="x86_64-linux-android-as"
AR="x86_64-linux-android-ar"
RANLIB="x86_64-linux-android-ranlib"
STRIP="x86_64-linux-android-strip"
CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -mtune=intel -funwind-tables -fexceptions"
CXXFLAGS="-march=x86-64 -msse4.2 -mpopcnt -mtune=intel -funwind-tables -fexceptions -frtti"
;;
*)
echo "ERROR: Unknown architecture $ANDROID_CPU"
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
;;
esac
#####################################################################
# Error checking
if [ ! -e "$ANDROID_TOOLCHAIN/$CC" ]; then
echo "ERROR: Failed to find Android clang. Please edit this script."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$ANDROID_TOOLCHAIN/$CXX" ]; then
echo "ERROR: Failed to find Android clang++. Please edit this script."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$ANDROID_TOOLCHAIN/$RANLIB" ]; then
echo "ERROR: Failed to find Android ranlib. Please edit this script."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$ANDROID_TOOLCHAIN/$AR" ]; then
echo "ERROR: Failed to find Android ar. Please edit this script."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$ANDROID_TOOLCHAIN/$AS" ]; then
echo "ERROR: Failed to find Android as. Please edit this script."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$ANDROID_TOOLCHAIN/$LD" ]; then
echo "ERROR: Failed to find Android ld. Please edit this script."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
#####################################################################
LENGTH=${#ANDROID_TOOLCHAIN}
SUBSTR=${PATH:0:$LENGTH}
if [ "$SUBSTR" != "$ANDROID_TOOLCHAIN" ]; then
export PATH="$ANDROID_TOOLCHAIN:$PATH"
fi
#####################################################################
export CPP CC CXX LD AS AR RANLIB STRIP
export ANDROID_SYSROOT="$AOSP_SYSROOT"
export CPPFLAGS="-D__ANDROID_API__=$ANDROID_API"
export CFLAGS="$CFLAGS --sysroot=$AOSP_SYSROOT"
export CXXFLAGS="$CXXFLAGS -stdlib=libc++ --sysroot=$AOSP_SYSROOT"
#####################################################################
echo "ANDROID_TOOLCHAIN: $ANDROID_TOOLCHAIN"
echo "CPP: $(command -v "$CPP")"
echo "CC: $(command -v "$CC")"
echo "CXX: $(command -v "$CXX")"
echo "LD: $(command -v "$LD")"
echo "AS: $(command -v "$AS")"
echo "AR: $(command -v "$AR")"
echo "ANDROID_SYSROOT: $ANDROID_SYSROOT"
echo "CPPFLAGS: $CPPFLAGS"
echo "CFLAGS: $CFLAGS"
echo "CXXFLAGS: $CXXFLAGS"
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0

View File

@ -2,7 +2,7 @@ Description: based on the included patch contrib/fastrpz.patch
Author: fastrpz@farsightsecurity.com
---
diff --git a/Makefile.in b/Makefile.in
index a20058cc..495779cc 100644
index bac212df..4824927f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c
@ -13,8 +13,8 @@ index a20058cc..495779cc 100644
+FASTRPZ_OBJ=@FASTRPZ_OBJ@
DNSCRYPT_SRC=@DNSCRYPT_SRC@
DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
@@ -127,7 +129,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
WITH_DYNLIBMODULE=@WITH_DYNLIBMODULE@
@@ -134,7 +136,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
@ -23,16 +23,16 @@ index a20058cc..495779cc 100644
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
@@ -140,7 +142,7 @@ autotrust.lo val_anchor.lo rpz.lo \
@@ -147,7 +149,7 @@ autotrust.lo val_anchor.lo rpz.lo \
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
-$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
-$(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
outside_network.lo
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
@@ -410,6 +412,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
@@ -428,6 +430,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
$(srcdir)/util/config_file.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h
@ -45,10 +45,10 @@ index a20058cc..495779cc 100644
pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
pythonmod/interface.h \
diff --git a/config.h.in b/config.h.in
index 78d47fed..e33073e4 100644
index f7a4095e..d5a4fa01 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1345,4 +1345,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
@@ -1364,4 +1364,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
/** the version of unbound-control that this software implements */
#define UNBOUND_CONTROL_VERSION 1
@ -62,7 +62,7 @@ index 78d47fed..e33073e4 100644
+/** turn on fastrpz response policy zones */
+#undef ENABLE_FASTRPZ
diff --git a/configure.ac b/configure.ac
index 2b91dd3c..e6063d17 100644
index 5c373d9d..e45abd89 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,6 +6,7 @@ sinclude(ax_pthread.m4)
@ -73,10 +73,10 @@ index 2b91dd3c..e6063d17 100644
sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
@@ -1778,6 +1779,9 @@ case "$enable_ipset" in
;;
@@ -1819,6 +1820,9 @@ case "$enable_explicit_port_randomisation" in
esac
+# check for Fastrpz with fastrpz/rpz.m4
+ck_FASTRPZ
+
@ -84,7 +84,7 @@ index 2b91dd3c..e6063d17 100644
# on openBSD, the implicit rule make $< work.
# on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
diff --git a/daemon/daemon.c b/daemon/daemon.c
index 8b0fc348..7ffb9221 100644
index 5d427925..f89f1437 100644
--- a/daemon/daemon.c
+++ b/daemon/daemon.c
@@ -91,6 +91,9 @@
@ -97,8 +97,8 @@ index 8b0fc348..7ffb9221 100644
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
@@ -458,6 +461,14 @@ daemon_create_workers(struct daemon* daemon)
dt_apply_cfg(daemon->dtenv, daemon->cfg);
@@ -456,6 +459,14 @@ daemon_create_workers(struct daemon* daemon)
fatal_exit("dt_create failed");
#else
fatal_exit("dnstap enabled in config but not built with dnstap support");
+#endif
@ -112,7 +112,7 @@ index 8b0fc348..7ffb9221 100644
#endif
}
for(i=0; i<daemon->num; i++) {
@@ -731,6 +742,9 @@ daemon_cleanup(struct daemon* daemon)
@@ -729,6 +740,9 @@ daemon_cleanup(struct daemon* daemon)
#ifdef USE_DNSCRYPT
dnsc_delete(daemon->dnscenv);
daemon->dnscenv = NULL;
@ -139,7 +139,7 @@ index 3effbafb..4d4c34da 100644
/**
diff --git a/daemon/worker.c b/daemon/worker.c
index eb7fdf2f..1982228d 100644
index 23e3244c..b63d49b7 100644
--- a/daemon/worker.c
+++ b/daemon/worker.c
@@ -76,6 +76,9 @@
@ -152,7 +152,7 @@ index eb7fdf2f..1982228d 100644
#include "sldns/wire2str.h"
#include "util/shm_side/shm_main.h"
#include "dnscrypt/dnscrypt.h"
@@ -534,8 +537,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
@@ -535,8 +538,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
/* not secure */
secure = 0;
break;
@ -180,7 +180,7 @@ index eb7fdf2f..1982228d 100644
/* return this delegation from the cache */
edns_bak = *edns;
edns->edns_version = EDNS_ADVERTISED_VERSION;
@@ -710,6 +732,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
@@ -711,6 +733,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
*is_secure_answer = 0;
}
} else *is_secure_answer = 0;
@ -204,7 +204,7 @@ index eb7fdf2f..1982228d 100644
edns_bak = *edns;
edns->edns_version = EDNS_ADVERTISED_VERSION;
@@ -1435,6 +1474,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
@@ -1436,6 +1475,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
&repinfo->addr, repinfo->addrlen);
goto send_reply;
@ -220,7 +220,7 @@ index eb7fdf2f..1982228d 100644
}
/* If we've found a local alias, replace the qname with the alias
@@ -1485,12 +1533,21 @@ lookup_cache:
@@ -1486,12 +1534,21 @@ lookup_cache:
h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
/* answer from cache - we have acquired a readlock on it */
@ -244,7 +244,7 @@ index eb7fdf2f..1982228d 100644
/* prefetch it if the prefetch TTL expired.
* Note that if there is more than one pass
* its qname must be that used for cache
@@ -1547,11 +1604,19 @@ lookup_cache:
@@ -1548,11 +1605,19 @@ lookup_cache:
lock_rw_unlock(&e->lock);
}
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
@ -267,10 +267,10 @@ index eb7fdf2f..1982228d 100644
}
verbose(VERB_ALGO, "answer norec from cache -- "
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
index 38c2d298..3b07f392 100644
index cd43f04e..b92a1af8 100644
--- a/doc/unbound.conf.5.in
+++ b/doc/unbound.conf.5.in
@@ -1828,6 +1828,81 @@ List domain for which the AAAA records are ignored and the A record is
@@ -1878,6 +1878,81 @@ List domain for which the AAAA records are ignored and the A record is
used by dns64 processing instead. Can be entered multiple times, list a
new domain for which it applies, one per line. Applies also to names
underneath the name given.
@ -2888,7 +2888,7 @@ index 00000000..21235355
+ fi
+])
diff --git a/iterator/iterator.c b/iterator/iterator.c
index 1e0113a8..2fcbf547 100644
index 23b07ea9..c3d31a33 100644
--- a/iterator/iterator.c
+++ b/iterator/iterator.c
@@ -68,6 +68,9 @@
@ -2901,7 +2901,7 @@ index 1e0113a8..2fcbf547 100644
/* in msec */
int UNKNOWN_SERVER_NICENESS = 376;
@@ -555,6 +558,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -563,6 +566,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
if(ntohs(r->rk.type) == LDNS_RR_TYPE_CNAME &&
query_dname_compare(*mname, r->rk.dname) == 0 &&
!iter_find_rrset_in_prepend_answer(iq, r)) {
@ -2925,7 +2925,7 @@ index 1e0113a8..2fcbf547 100644
/* Add this relevant CNAME rrset to the prepend list.*/
if(!iter_add_prepend_answer(qstate, iq, r))
return 0;
@@ -563,6 +583,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -571,6 +591,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
/* Other rrsets in the section are ignored. */
}
@ -2935,7 +2935,7 @@ index 1e0113a8..2fcbf547 100644
/* add authority rrsets to authority prepend, for wildcarded CNAMEs */
for(i=msg->rep->an_numrrsets; i<msg->rep->an_numrrsets +
msg->rep->ns_numrrsets; i++) {
@@ -1199,6 +1222,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -1231,6 +1254,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
uint8_t* delname;
size_t delnamelen;
struct dns_msg* msg = NULL;
@ -2943,7 +2943,7 @@ index 1e0113a8..2fcbf547 100644
log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
/* check effort */
@@ -1285,8 +1309,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -1317,8 +1341,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
}
if(msg) {
/* handle positive cache response */
@ -2953,7 +2953,7 @@ index 1e0113a8..2fcbf547 100644
if(verbosity >= VERB_ALGO) {
log_dns_msg("msg from cache lookup", &msg->qinfo,
msg->rep);
@@ -1294,7 +1317,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -1326,7 +1349,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
(int)msg->rep->ttl,
(int)msg->rep->prefetch_ttl);
}
@ -2976,7 +2976,7 @@ index 1e0113a8..2fcbf547 100644
if(type == RESPONSE_TYPE_CNAME) {
uint8_t* sname = 0;
size_t slen = 0;
@@ -2718,6 +2756,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -2801,6 +2839,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
sock_list_insert(&qstate->reply_origin,
&qstate->reply->addr, qstate->reply->addrlen,
qstate->region);
@ -3039,7 +3039,7 @@ index 1e0113a8..2fcbf547 100644
if(iq->minimisation_state != DONOT_MINIMISE_STATE
&& !(iq->chase_flags & BIT_RD)) {
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
@@ -3471,12 +3565,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -3563,12 +3657,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
* but only if we did recursion. The nonrecursion referral
* from cache does not need to be stored in the msg cache. */
if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
@ -3085,10 +3085,10 @@ index 1e0113a8..2fcbf547 100644
qstate->return_msg = iq->response;
return 0;
diff --git a/iterator/iterator.h b/iterator/iterator.h
index a2f1b570..e1e4a738 100644
index 342ac207..49b0ecdd 100644
--- a/iterator/iterator.h
+++ b/iterator/iterator.h
@@ -386,6 +386,16 @@ struct iter_qstate {
@@ -396,6 +396,16 @@ struct iter_qstate {
*/
int minimise_count;
@ -3104,12 +3104,12 @@ index a2f1b570..e1e4a738 100644
+
/**
* Count number of time-outs. Used to prevent resolving failures when
* the QNAME minimisation QTYPE is blocked. */
* the QNAME minimisation QTYPE is blocked. Used to determine if
diff --git a/services/cache/dns.c b/services/cache/dns.c
index 2a5bca4a..6de8863a 100644
index 7b6e142c..6d7449f5 100644
--- a/services/cache/dns.c
+++ b/services/cache/dns.c
@@ -967,6 +967,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
@@ -969,6 +969,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
struct regional* region, uint32_t flags)
{
struct reply_info* rep = NULL;
@ -3125,7 +3125,7 @@ index 2a5bca4a..6de8863a 100644
rep = reply_info_copy(msgrep, env->alloc, NULL);
if(!rep)
diff --git a/services/mesh.c b/services/mesh.c
index 9114ef4c..3dc518e5 100644
index 4b0c5db4..eb9cfa5b 100644
--- a/services/mesh.c
+++ b/services/mesh.c
@@ -61,6 +61,9 @@
@ -3138,7 +3138,7 @@ index 9114ef4c..3dc518e5 100644
#include "respip/respip.h"
#include "services/listen_dnsport.h"
@@ -1195,6 +1198,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
@@ -1207,6 +1210,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
else secure = 0;
if(!rep && rcode == LDNS_RCODE_NOERROR)
rcode = LDNS_RCODE_SERVFAIL;
@ -3152,7 +3152,7 @@ index 9114ef4c..3dc518e5 100644
/* send the reply */
/* We don't reuse the encoded answer if either the previous or current
* response has a local alias. We could compare the alias records
@@ -1415,6 +1425,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
@@ -1434,6 +1444,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
key.s.is_valrec = valrec;
key.s.qinfo = *qinfo;
key.s.query_flags = qflags;
@ -3160,7 +3160,7 @@ index 9114ef4c..3dc518e5 100644
/* We are searching for a similar mesh state when we DO want to
* aggregate the state. Thus unique is set to NULL. (default when we
* desire aggregation).*/
@@ -1461,6 +1472,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
@@ -1480,6 +1491,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
if(!r)
return 0;
r->query_reply = *rep;
@ -3172,11 +3172,11 @@ index 9114ef4c..3dc518e5 100644
if(edns->opt_list) {
r->edns.opt_list = edns_opt_copy_region(edns->opt_list,
diff --git a/util/config_file.c b/util/config_file.c
index 52ca5a18..0660248f 100644
index 0e9ee471..a5fd72e0 100644
--- a/util/config_file.c
+++ b/util/config_file.c
@@ -1460,6 +1460,8 @@ config_delete(struct config_file* cfg)
free(cfg->dnstap_socket_path);
@@ -1495,6 +1495,8 @@ config_delete(struct config_file* cfg)
free(cfg->dnstap_tls_client_cert_file);
free(cfg->dnstap_identity);
free(cfg->dnstap_version);
+ if (cfg->rpz_cstr)
@ -3185,10 +3185,10 @@ index 52ca5a18..0660248f 100644
config_deldblstrlist(cfg->ratelimit_below_domain);
config_delstrlist(cfg->python_script);
diff --git a/util/config_file.h b/util/config_file.h
index 8739ca2a..a2dcf215 100644
index 66e5025d..504f4f92 100644
--- a/util/config_file.h
+++ b/util/config_file.h
@@ -499,6 +499,11 @@ struct config_file {
@@ -522,6 +522,11 @@ struct config_file {
/** true to disable DNSSEC lameness check in iterator */
int disable_dnssec_lame_check;
@ -3201,10 +3201,10 @@ index 8739ca2a..a2dcf215 100644
int ip_ratelimit;
/** number of slabs for ip_ratelimit cache */
diff --git a/util/configlexer.lex b/util/configlexer.lex
index deedffa5..301458a3 100644
index 83cea4b9..9a7feea4 100644
--- a/util/configlexer.lex
+++ b/util/configlexer.lex
@@ -446,6 +446,10 @@ dnstap-log-forwarder-query-messages{COLON} {
@@ -467,6 +467,10 @@ dnstap-log-forwarder-query-messages{COLON} {
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
dnstap-log-forwarder-response-messages{COLON} {
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
@ -3216,18 +3216,18 @@ index deedffa5..301458a3 100644
ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) }
diff --git a/util/configparser.y b/util/configparser.y
index d471babe..cb6b1d63 100644
index fe600a99..ce43390f 100644
--- a/util/configparser.y
+++ b/util/configparser.y
@@ -125,6 +125,7 @@ extern struct config_parser_state* cfg_parser;
@@ -128,6 +128,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
+%token VAR_RPZ VAR_RPZ_ENABLE VAR_RPZ_ZONE VAR_RPZ_OPTION
%token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
%token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
%token VAR_DISABLE_DNSSEC_LAME_CHECK
@@ -173,7 +174,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_IP_DSCP
@@ -179,7 +180,7 @@ extern struct config_parser_state* cfg_parser;
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -3236,7 +3236,7 @@ index d471babe..cb6b1d63 100644
forwardstart contents_forward | pythonstart contents_py |
rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
dnscstart contents_dnsc | cachedbstart contents_cachedb |
@@ -2837,6 +2838,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
@@ -2939,6 +2940,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
free($2);
}
;
@ -3384,7 +3384,7 @@ index 729877ba..ccd1a0c2 100644
/**
diff --git a/util/netevent.c b/util/netevent.c
index 9fe5da2d..037e70d1 100644
index 3e7a433e..f20d806f 100644
--- a/util/netevent.c
+++ b/util/netevent.c
@@ -57,6 +57,9 @@
@ -3397,7 +3397,7 @@ index 9fe5da2d..037e70d1 100644
/* -------- Start of local definitions -------- */
/** if CMSG_ALIGN is not defined on this platform, a workaround */
@@ -590,6 +593,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
@@ -596,6 +599,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
struct cmsghdr* cmsg;
#endif /* S_SPLINT_S */
@ -3407,7 +3407,7 @@ index 9fe5da2d..037e70d1 100644
rep.c = (struct comm_point*)arg;
log_assert(rep.c->type == comm_udp);
@@ -679,6 +685,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
@@ -685,6 +691,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
int i;
struct sldns_buffer *buffer;
@ -3417,7 +3417,7 @@ index 9fe5da2d..037e70d1 100644
rep.c = (struct comm_point*)arg;
log_assert(rep.c->type == comm_udp);
@@ -722,6 +731,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
@@ -728,6 +737,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
(void)comm_point_send_udp_msg(rep.c, buffer,
(struct sockaddr*)&rep.addr, rep.addrlen);
}
@ -3427,7 +3427,7 @@ index 9fe5da2d..037e70d1 100644
if(!rep.c || rep.c->fd != fd) /* commpoint closed to -1 or reused for
another UDP port. Note rep.c cannot be reused with TCP fd. */
break;
@@ -3192,6 +3204,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
@@ -3175,6 +3187,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
repinfo->c->tcp_timeout_msec);
}
}
@ -3437,7 +3437,7 @@ index 9fe5da2d..037e70d1 100644
}
void
@@ -3201,6 +3216,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
@@ -3184,6 +3199,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
return;
log_assert(repinfo->c);
log_assert(repinfo->c->type != comm_tcp_accept);
@ -3447,7 +3447,7 @@ index 9fe5da2d..037e70d1 100644
if(repinfo->c->type == comm_udp)
return;
if(repinfo->c->tcp_req_info)
@@ -3222,6 +3240,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
@@ -3205,6 +3223,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
{
verbose(VERB_ALGO, "comm point start listening %d (%d msec)",
c->fd==-1?newfd:c->fd, msec);
@ -3458,7 +3458,7 @@ index 9fe5da2d..037e70d1 100644
/* no use to start listening no free slots. */
return;
diff --git a/util/netevent.h b/util/netevent.h
index d80c72b3..0233292f 100644
index bb2cd1e5..666067e8 100644
--- a/util/netevent.h
+++ b/util/netevent.h
@@ -120,6 +120,10 @@ struct comm_reply {

41
contrib/ios/15-ios.conf Normal file
View File

@ -0,0 +1,41 @@
#### iPhoneOS/iOS
#
# It takes recent enough Xcode to use following two targets. It shouldn't
# be a problem by now, but if they don't work, original targets below
# that depend on manual definition of environment variables should still
# work...
#
my %targets = (
"ios-common" => {
template => 1,
inherit_from => [ "darwin-common" ],
sys_id => "iOS",
disable => [ "engine", "async" ],
},
"ios-xcrun" => {
inherit_from => [ "ios-common", asm("armv4_asm") ],
bn_ops => [ "BN_LLONG", "RC4_CHAR" ],
perlasm_scheme => "ios32",
},
"ios64-xcrun" => {
inherit_from => [ "ios-common", asm("aarch64_asm") ],
bn_ops => [ "SIXTY_FOUR_BIT_LONG", "RC4_CHAR" ],
perlasm_scheme => "ios64",
},
"iossimulator-xcrun" => {
inherit_from => [ "ios-common" ],
},
"iphoneos-cross" => {
inherit_from => [ "ios-common" ],
cflags => add("-Wall -fno-common"),
},
"ios-cross" => {
inherit_from => [ "ios-xcrun" ],
cflags => add("-Wall -fno-common"),
},
"ios64-cross" => {
inherit_from => [ "ios64-xcrun" ],
cflags => add("-Wall -fno-common"),
},
);

56
contrib/ios/install_expat.sh Executable file
View File

@ -0,0 +1,56 @@
#!/usr/bin/env bash
echo "Downloading Expat"
if ! curl -L -k -s -o expat-2.2.9.tar.gz https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.gz;
then
echo "Failed to download Expat"
exit 1
fi
echo "Unpacking Expat"
rm -rf ./expat-2.2.9
if ! tar -xf expat-2.2.9.tar.gz;
then
echo "Failed to unpack Expat"
exit 1
fi
cd expat-2.2.9 || exit 1
export PKG_CONFIG_PATH="$IOS_PREFIX/lib/pkgconfig"
echo "Configuring Expat"
if ! ./configure \
--build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \
--prefix="$IOS_PREFIX" ; then
echo "Error: Failed to configure Expat"
cat config.log
exit 1
fi
# Cleanup warnings, https://github.com/libexpat/libexpat/issues/383
echo "Fixing Makefiles"
(IFS="" find "$PWD" -name 'Makefile' -print | while read -r file
do
cp -p "$file" "$file.fixed"
sed 's|-Wduplicated-cond ||g; s|-Wduplicated-branches ||g; s|-Wlogical-op ||g' "$file" > "$file.fixed"
mv "$file.fixed" "$file"
cp -p "$file" "$file.fixed"
sed 's|-Wrestrict ||g; s|-Wjump-misses-init ||g; s|-Wmisleading-indentation ||g' "$file" > "$file.fixed"
mv "$file.fixed" "$file"
done)
echo "Building Expat"
if ! make; then
echo "Failed to build Expat"
exit 1
fi
echo "Installing Expat"
if ! make install; then
echo "Failed to install Expat"
exit 1
fi
exit 0

52
contrib/ios/install_openssl.sh Executable file
View File

@ -0,0 +1,52 @@
#!/usr/bin/env bash
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;
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;
then
echo "Failed to unpack OpenSSL"
exit 1
fi
cd openssl-1.1.1d || exit 1
if ! cp ../contrib/ios/15-ios.conf Configurations/; then
echo "Failed to copy OpenSSL ios config"
exit 1
fi
# OpenSSL 1.1.1d patch. OK to remove once OpenSSL version is bumped.
# ocsp.c:947:23: error: 'fork' is unavailable: not available on tvOS and watchOS.
# 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
fi
echo "Configuring OpenSSL"
if ! ./Configure "$OPENSSL_HOST" -DNO_FORK no-comp no-asm no-hw no-engine no-tests no-unit-test \
--prefix="$IOS_PREFIX" --openssldir="$IOS_PREFIX"; then
echo "Failed to configure OpenSSL"
exit 1
fi
echo "Building OpenSSL"
if ! make; then
echo "Failed to build OpenSSL"
exit 1
fi
echo "Installing OpenSSL"
if ! make install_sw; then
echo "Failed to install OpenSSL"
exit 1
fi
exit 0

8
contrib/ios/install_tools.sh Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
# This step should install tools needed for all packages - OpenSSL, Expat and Unbound
echo "Updating tools"
brew update 1>/dev/null
echo "Installing tools"
# already installed are: autoconf automake libtool pkg-config
brew install curl perl 1>/dev/null

48
contrib/ios/openssl.patch Normal file
View File

@ -0,0 +1,48 @@
--- apps/speed.c
+++ apps/speed.c
@@ -99,6 +99,13 @@
#endif
#include <openssl/modes.h>
+/* fork() breaks AppleTVOS, WatchOS, AppleTVSimulator and WatchSimulator */
+/* Users should configure with -DNO_FORK */
+#if defined(NO_FORK)
+# undef HAVE_FORK
+# define HAVE_FORK 0
+#endif
+
#ifndef HAVE_FORK
# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_VXWORKS)
# define HAVE_FORK 0
@@ -110,6 +117,7 @@
#if HAVE_FORK
# undef NO_FORK
#else
+# undef NO_FORK
# define NO_FORK
#endif
--- apps/ocsp.c
+++ apps/ocsp.c
@@ -36,6 +36,13 @@
# include <openssl/x509v3.h>
# include <openssl/rand.h>
+/* fork() breaks AppleTVOS, WatchOS, AppleTVSimulator and WatchSimulator */
+/* Users should configure with -DNO_FORK */
+#if defined(NO_FORK)
+# undef HAVE_FORK
+# define HAVE_FORK 0
+#endif
+
#ifndef HAVE_FORK
# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS)
# define HAVE_FORK 0
@@ -47,6 +54,7 @@
#if HAVE_FORK
# undef NO_FORK
#else
+# undef NO_FORK
# define NO_FORK
#endif

274
contrib/ios/setenv_ios.sh Executable file
View File

@ -0,0 +1,274 @@
#!/usr/bin/env bash
# ====================================================================
# Sets the cross compile environment for Xcode/iOS
#
# Based upon OpenSSL's setenv-ios.sh by TH, JW, and SM.
# Heavily modified by JWW for Crypto++.
# Modified by JWW for Unbound.
# ====================================================================
#########################################
##### Some validation #####
#########################################
# In the past we could mostly infer arch or cpu from the SDK (and
# mostly vice-versa). Nowadays we need it set for us because Apple
# platforms can be either 32-bit or 64-bit.
if [ -z "$IOS_SDK" ]; then
echo "IOS_SDK is not set. Please set it"
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
if [ -z "$IOS_CPU" ]; then
echo "IOS_CPU is not set. Please set it"
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
# cryptest-ios.sh may run this script without sourcing.
if [ "$0" = "${BASH_SOURCE[0]}" ]; then
echo "setenv-ios.sh is usually sourced, but not this time."
fi
#########################################
##### Small Fixups, if needed #####
#########################################
if [[ "$IOS_SDK" == "iPhone" ]]; then
IOS_SDK=iPhoneOS
fi
if [[ "$IOS_SDK" == "iPhoneOSSimulator" ]]; then
IOS_SDK=iPhoneSimulator
fi
if [[ "$IOS_SDK" == "TV" || "$IOS_SDK" == "AppleTV" ]]; then
IOS_SDK=AppleTVOS
fi
if [[ "$IOS_SDK" == "Watch" || "$IOS_SDK" == "AppleWatch" ]]; then
IOS_SDK=WatchOS
fi
if [[ "$IOS_CPU" == "aarch64" || "$IOS_CPU" == "armv8"* ]] ; then
IOS_CPU=arm64
fi
########################################
##### Environment #####
########################################
# The flags below were tested with Xcode 8 on Travis. If
# you use downlevel versions of Xcode, then you can push
# xxx-version-min=n lower. For example, Xcode 6 can use
# -miphoneos-version-min=5.
# iPhones can be either 32-bit or 64-bit
if [[ "$IOS_SDK" == "iPhoneOS" && "$IOS_CPU" == "armv7"* ]]; then
MIN_VER=-miphoneos-version-min=6
elif [[ "$IOS_SDK" == "iPhoneOS" && "$IOS_CPU" == "arm64" ]]; then
MIN_VER=-miphoneos-version-min=6
# Fixups for convenience
elif [[ "$IOS_SDK" == "iPhoneOS" && "$IOS_CPU" == "i386" ]]; then
IOS_SDK=iPhoneSimulator
# MIN_VER=-miphoneos-version-min=6
MIN_VER=-miphonesimulator-version-min=6
elif [[ "$IOS_SDK" == "iPhoneOS" && "$IOS_CPU" == "x86_64" ]]; then
IOS_SDK=iPhoneSimulator
# MIN_VER=-miphoneos-version-min=6
MIN_VER=-miphonesimulator-version-min=6
# Simulator builds
elif [[ "$IOS_SDK" == "iPhoneSimulator" && "$IOS_CPU" == "i386" ]]; then
MIN_VER=-miphonesimulator-version-min=6
elif [[ "$IOS_SDK" == "iPhoneSimulator" && "$IOS_CPU" == "x86_64" ]]; then
MIN_VER=-miphonesimulator-version-min=6
# Apple TV can be 32-bit Intel (1st gen), 32-bit ARM (2nd, 3rd gen) or 64-bit ARM (4th gen)
elif [[ "$IOS_SDK" == "AppleTVOS" && "$IOS_CPU" == "i386" ]]; then
MIN_VER=-mappletvos-version-min=6
elif [[ "$IOS_SDK" == "AppleTVOS" && "$IOS_CPU" == "armv7"* ]]; then
MIN_VER=-mappletvos-version-min=6
elif [[ "$IOS_SDK" == "AppleTVOS" && "$IOS_CPU" == "arm64" ]]; then
MIN_VER=-mappletvos-version-min=6
# Simulator builds
elif [[ "$IOS_SDK" == "AppleTVSimulator" && "$IOS_CPU" == "i386" ]]; then
MIN_VER=-mappletvsimulator-version-min=6
elif [[ "$IOS_SDK" == "AppleTVSimulator" && "$IOS_CPU" == "x86_64" ]]; then
MIN_VER=-mappletvsimulator-version-min=6
# Watch can be either 32-bit or 64-bit ARM. TODO: figure out which
# -mwatchos-version-min=n is needed for arm64. 9 is not enough.
elif [[ "$IOS_SDK" == "WatchOS" && "$IOS_CPU" == "armv7"* ]]; then
MIN_VER=-mwatchos-version-min=6
elif [[ "$IOS_SDK" == "WatchOS" && "$IOS_CPU" == "arm64" ]]; then
MIN_VER=-mwatchos-version-min=10
# Simulator builds. TODO: figure out which -watchos-version-min=n
# is needed for arm64. 6 compiles and links, but is it correct?
elif [[ "$IOS_SDK" == "WatchSimulator" && "$IOS_CPU" == "i386" ]]; then
MIN_VER=-mwatchsimulator-version-min=6
elif [[ "$IOS_SDK" == "WatchSimulator" && "$IOS_CPU" == "x86_64" ]]; then
MIN_VER=-mwatchsimulator-version-min=6
# And the final catch-all
else
echo "IOS_SDK and IOS_CPU are not valid. Please fix them"
[[ "$0" = "${BASH_SOURCE[0]}" ]] && exit 1 || return 1
fi
#####################################################################
# Xcode 6 and below cannot handle -miphonesimulator-version-min
# Fix it so the simulator will compile as expected. This trick
# may work on other SDKs, but it was not tested.
if [ -n "$(command -v xcodebuild 2>/dev/null)" ]; then
# Output of xcodebuild is similar to "Xcode 6.2". The first cut gets
# the dotted decimal value. The second cut gets the major version.
XCODE_VERSION=$(xcodebuild -version 2>/dev/null | head -n 1 | cut -f2 -d" " | cut -f1 -d".")
if [ -z "$XCODE_VERSION" ]; then XCODE_VERSION=100; fi
if [ "$XCODE_VERSION" -le 6 ]; then
MIN_VER="${MIN_VER//iphonesimulator/iphoneos}"
fi
fi
#####################################################################
# Allow a user override? I think we should be doing this. The use case is,
# move /Applications/Xcode somewhere else for a side-by-side installation.
if [ -z "${XCODE_DEVELOPER-}" ]; then
XCODE_DEVELOPER=$(xcode-select -print-path 2>/dev/null)
fi
if [ ! -d "$XCODE_DEVELOPER" ]; then
echo "ERROR: unable to find XCODE_DEVELOPER directory."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# XCODE_DEVELOPER_SDK is the SDK location.
XCODE_DEVELOPER_SDK="$XCODE_DEVELOPER/Platforms/$IOS_SDK.platform"
if [ ! -d "$XCODE_DEVELOPER_SDK" ]; then
echo "ERROR: unable to find XCODE_DEVELOPER_SDK directory."
echo " Is the SDK supported by Xcode and installed?"
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# XCODE_TOOLCHAIN is the location of the actual compiler tools.
if [ -d "$XCODE_DEVELOPER/Toolchains/XcodeDefault.xctoolchain/usr/bin/" ]; then
XCODE_TOOLCHAIN="$XCODE_DEVELOPER/Toolchains/XcodeDefault.xctoolchain/usr/bin/"
elif [ -d "$XCODE_DEVELOPER_SDK/Developer/usr/bin/" ]; then
XCODE_TOOLCHAIN="$XCODE_DEVELOPER_SDK/Developer/usr/bin/"
fi
if [ -z "$XCODE_TOOLCHAIN" ] || [ ! -d "$XCODE_TOOLCHAIN" ]; then
echo "ERROR: unable to find Xcode cross-compiler tools."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# XCODE_SDK is the SDK name/version being used - adjust the list as appropriate.
# 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=
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
XCODE_SDK="$IOS_SDK$i.sdk"
break
fi
done
# Error checking
if [ -z "$XCODE_SDK" ]; then
echo "ERROR: unable to find a SDK."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
IOS_SYSROOT="$XCODE_DEVELOPER_SDK/Developer/SDKs/$XCODE_SDK"
if [ -z "$IOS_SYSROOT" ] || [ ! -d "$IOS_SYSROOT" ]; then
echo "ERROR: unable to find IOS_SYSROOT directory."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
#####################################################################
# We want to set AR=libtool and ARFLAGS="-static -o",
# but I am not sure Autotools can handle it.
CPP=cpp; CC=clang; CXX=clang++; LD=ld
AS=as; AR=ar; RANLIB=ranlib; STRIP=strip
# Error checking
if [ ! -e "$XCODE_TOOLCHAIN/$CC" ]; then
echo "ERROR: Failed to find iOS clang. Please edit this script."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$XCODE_TOOLCHAIN/$CXX" ]; then
echo "ERROR: Failed to find iOS clang++. Please edit this script."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$XCODE_TOOLCHAIN/$RANLIB" ]; then
echo "ERROR: Failed to find iOS ranlib. Please edit this script."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$XCODE_TOOLCHAIN/$AR" ]; then
echo "ERROR: Failed to find iOS ar. Please edit this script."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$XCODE_TOOLCHAIN/$AS" ]; then
echo "ERROR: Failed to find iOS as. Please edit this script."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
# Error checking
if [ ! -e "$XCODE_TOOLCHAIN/$LD" ]; then
echo "ERROR: Failed to find iOS ld. Please edit this script."
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
fi
#####################################################################
LENGTH=${#XCODE_TOOLCHAIN}
SUBSTR=${PATH:0:$LENGTH}
if [ "$SUBSTR" != "$XCODE_TOOLCHAIN" ]; then
export PATH="$XCODE_TOOLCHAIN":"$PATH"
fi
#####################################################################
export CPP CC CXX LD AS AR RANLIB STRIP
export IOS_SYSROOT
export CFLAGS="-arch $IOS_CPU $MIN_VER --sysroot=$IOS_SYSROOT"
export CXXFLAGS="-arch $IOS_CPU $MIN_VER -stdlib-libc++ --sysroot=$IOS_SYSROOT"
#####################################################################
echo "XCODE_TOOLCHAIN: $XCODE_TOOLCHAIN"
echo "CPP: $(command -v "$CPP")"
echo "CC: $(command -v "$CC")"
echo "CXX: $(command -v "$CXX")"
echo "LD: $(command -v "$LD")"
echo "AS: $(command -v "$AS")"
echo "AR: $(command -v "$AR")"
echo "IOS_SYSROOT: $IOS_SYSROOT"
echo "CPPFLAGS: $CPPFLAGS"
echo "CFLAGS: $CFLAGS"
echo "CXXFLAGS: $CXXFLAGS"
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0

View File

@ -7,8 +7,7 @@ Name: unbound
Description: Library with validating, recursive, and caching DNS resolver
URL: http://www.unbound.net
Version: @PACKAGE_VERSION@
Requires: @PC_CRYPTO_DEPENDENCY@ @PC_LIBEVENT_DEPENDENCY@
Requires.private: @PC_PY_DEPENDENCY@ @PC_LIBBSD_DEPENDENCY@
Requires.private: @PC_PY_DEPENDENCY@ @PC_LIBBSD_DEPENDENCY@ @PC_CRYPTO_DEPENDENCY@ @PC_LIBEVENT_DEPENDENCY@
Libs: -L${libdir} -lunbound
Libs.private: @SSLLIB@ @LIBS@
Cflags: -I${includedir}

View File

@ -76,7 +76,7 @@ RestrictSUIDSGID=yes
ReadWritePaths=@UNBOUND_RUN_DIR@ @UNBOUND_CHROOT_DIR@
# Below rules are needed when chroot is enabled (usually it's enabled by default).
# If chroot is disabled like chrooot: "" then they may be safely removed.
# If chroot is disabled like chroot: "" then they may be safely removed.
TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/dev:ro
TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/run:ro
BindReadOnlyPaths=-/run/systemd/notify:@UNBOUND_CHROOT_DIR@/run/systemd/notify

View File

@ -273,7 +273,7 @@ check_data(const char* data, const struct config_strlist* head)
if(res == 0)
return 1;
log_err("rr data [char %d] parse error %s",
(int)LDNS_WIREPARSE_OFFSET(res)-13,
(int)LDNS_WIREPARSE_OFFSET(res)-2,
sldns_get_errorstr_parse(res));
return 0;
}

View File

@ -451,11 +451,9 @@ daemon_create_workers(struct daemon* daemon)
fatal_exit("out of memory during daemon init");
if(daemon->cfg->dnstap) {
#ifdef USE_DNSTAP
daemon->dtenv = dt_create(daemon->cfg->dnstap_socket_path,
(unsigned int)daemon->num);
daemon->dtenv = dt_create(daemon->cfg);
if (!daemon->dtenv)
fatal_exit("dt_create failed");
dt_apply_cfg(daemon->dtenv, daemon->cfg);
#else
fatal_exit("dnstap enabled in config but not built with dnstap support");
#endif
@ -783,7 +781,7 @@ daemon_delete(struct daemon* daemon)
# endif
# ifdef HAVE_OPENSSL_CONFIG
EVP_cleanup();
# if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE)
# if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE) && defined(HAVE_ENGINE_CLEANUP)
ENGINE_cleanup();
# endif
CONF_modules_free();

View File

@ -329,7 +329,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
/* open fd */
fd = create_tcp_accept_sock(res, 1, &noproto, 0,
cfg->ip_transparent, 0, cfg->ip_freebind, cfg->use_systemd);
cfg->ip_transparent, 0, cfg->ip_freebind, cfg->use_systemd, cfg->ip_dscp);
freeaddrinfo(res);
}
@ -804,6 +804,9 @@ print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
size_t dnscrypt_shared_secret = 0;
size_t dnscrypt_nonce = 0;
#endif /* USE_DNSCRYPT */
#ifdef WITH_DYNLIBMODULE
size_t dynlib = 0;
#endif /* WITH_DYNLIBMODULE */
msg = slabhash_get_mem(daemon->env->msg_cache);
rrset = slabhash_get_mem(&daemon->env->rrset_cache->table);
val = mod_get_mem(&worker->env, "validator");
@ -822,6 +825,9 @@ print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
dnscrypt_nonce = slabhash_get_mem(daemon->dnscenv->nonces_cache);
}
#endif /* USE_DNSCRYPT */
#ifdef WITH_DYNLIBMODULE
dynlib = mod_get_mem(&worker->env, "dynlib");
#endif /* WITH_DYNLIBMODULE */
if(!print_longnum(ssl, "mem.cache.rrset"SQ, rrset))
return 0;
@ -849,6 +855,10 @@ print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
dnscrypt_nonce))
return 0;
#endif /* USE_DNSCRYPT */
#ifdef WITH_DYNLIBMODULE
if(!print_longnum(ssl, "mem.mod.dynlibmod"SQ, dynlib))
return 0;
#endif /* WITH_DYNLIBMODULE */
if(!print_longnum(ssl, "mem.streamwait"SQ,
(size_t)s->svr.mem_stream_wait))
return 0;
@ -907,7 +917,7 @@ static int
print_ext(RES* ssl, struct ub_stats_info* s)
{
int i;
char nm[16];
char nm[32];
const sldns_rr_descriptor* desc;
const sldns_lookup_table* lt;
/* TYPE */
@ -1124,6 +1134,10 @@ parse_arg_name(RES* ssl, char* str, uint8_t** res, size_t* len, int* labs)
*res = NULL;
*len = 0;
*labs = 0;
if(str[0] == '\0') {
ssl_printf(ssl, "error: this option requires a domain name\n");
return 0;
}
status = sldns_str2wire_dname_buf(str, nm, &nmlen);
if(status != 0) {
ssl_printf(ssl, "error cannot parse name %s at %d: %s\n", str,

View File

@ -88,6 +88,14 @@
# include "nss.h"
#endif
#ifdef HAVE_TARGETCONDITIONALS_H
#include <TargetConditionals.h>
#endif
#if defined(TARGET_OS_TV) || defined(TARGET_OS_WATCH)
#undef HAVE_FORK
#endif
/** print build options. */
static void
print_build_options(void)
@ -526,6 +534,8 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0)
log_warn("unable to setusercontext %s: %s",
cfg->username, strerror(errno));
#else
(void)pwd;
#endif /* HAVE_SETUSERCONTEXT */
}
#endif /* HAVE_GETPWNAM */

View File

@ -79,6 +79,7 @@
#include "sldns/wire2str.h"
#include "util/shm_side/shm_main.h"
#include "dnscrypt/dnscrypt.h"
#include "dnstap/dtstream.h"
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
@ -1807,14 +1808,14 @@ worker_init(struct worker* worker, struct config_file *cfg,
worker->back = outside_network_create(worker->base,
cfg->msg_buffer_size, (size_t)cfg->outgoing_num_ports,
cfg->out_ifs, cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6,
cfg->do_tcp?cfg->outgoing_num_tcp:0,
cfg->do_tcp?cfg->outgoing_num_tcp:0, cfg->ip_dscp,
worker->daemon->env->infra_cache, worker->rndstate,
cfg->use_caps_bits_for_id, worker->ports, worker->numports,
cfg->unwanted_threshold, cfg->outgoing_tcp_mss,
&worker_alloc_cleanup, worker,
cfg->do_udp || cfg->udp_upstream_without_downstream,
worker->daemon->connect_sslctx, cfg->delay_close,
dtenv);
cfg->tls_use_sni, dtenv);
if(!worker->back) {
log_err("could not create outgoing sockets");
worker_delete(worker);
@ -1914,6 +1915,20 @@ worker_init(struct worker* worker, struct config_file *cfg,
) {
auth_xfer_pickup_initial(worker->env.auth_zones, &worker->env);
}
#ifdef USE_DNSTAP
if(worker->daemon->cfg->dnstap
#ifndef THREADS_DISABLED
&& worker->thread_num == 0
#endif
) {
if(!dt_io_thread_start(dtenv->dtio, comm_base_internal(
worker->base), worker->daemon->num)) {
log_err("could not start dnstap io thread");
worker_delete(worker);
return 0;
}
}
#endif /* USE_DNSTAP */
if(!worker->env.mesh || !worker->env.scratch_buffer) {
worker_delete(worker);
return 0;
@ -1961,6 +1976,16 @@ worker_delete(struct worker* worker)
wsvc_desetup_worker(worker);
#endif /* UB_ON_WINDOWS */
}
#ifdef USE_DNSTAP
if(worker->daemon->cfg->dnstap
#ifndef THREADS_DISABLED
&& worker->thread_num == 0
#endif
) {
dt_io_thread_stop(worker->dtenv.dtio);
}
dt_deinit(&worker->dtenv);
#endif /* USE_DNSTAP */
comm_base_delete(worker->base);
ub_randfree(worker->rndstate);
alloc_clear(&worker->alloc);
@ -2099,3 +2124,18 @@ int codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
return 0;
}
#ifdef USE_DNSTAP
void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
#ifdef USE_DNSTAP
void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif

View File

@ -227,7 +227,7 @@ ipv4_to_ptr(uint32_t ipv4, char ptr[], size_t nm_len)
static const char IPV4_PTR_SUFFIX[] = "\07in-addr\04arpa";
int i;
char* c = ptr;
log_assert(nm_len == MAX_PTR_QNAME_IPV4);
log_assert(nm_len == MAX_PTR_QNAME_IPV4); (void)nm_len;
for (i = 0; i < 4; ++i) {
*c = uitoa((unsigned int)(ipv4 % 256), c + 1);

View File

@ -49,13 +49,12 @@
#include "util/netevent.h"
#include "util/log.h"
#include <fstrm.h>
#include <protobuf-c/protobuf-c.h>
#include "dnstap/dnstap.h"
#include "dnstap/dtstream.h"
#include "dnstap/dnstap.pb-c.h"
#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap"
#define DNSTAP_INITIAL_BUF_SIZE 256
struct dt_msg {
@ -90,13 +89,7 @@ dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz)
static void
dt_send(const struct dt_env *env, void *buf, size_t len_buf)
{
fstrm_res res;
if (!buf)
return;
res = fstrm_iothr_submit(env->iothr, env->ioq, buf, len_buf,
fstrm_free_wrapper, NULL);
if (res != fstrm_res_success)
free(buf);
dt_msg_queue_submit(env->msgqueue, buf, len_buf);
}
static void
@ -135,56 +128,33 @@ check_socket_file(const char* socket_path)
}
struct dt_env *
dt_create(const char *socket_path, unsigned num_workers)
dt_create(struct config_file* cfg)
{
#ifdef UNBOUND_DEBUG
fstrm_res res;
#endif
struct dt_env *env;
struct fstrm_iothr_options *fopt;
struct fstrm_unix_writer_options *fuwopt;
struct fstrm_writer *fw;
struct fstrm_writer_options *fwopt;
verbose(VERB_OPS, "attempting to connect to dnstap socket %s",
socket_path);
log_assert(socket_path != NULL);
log_assert(num_workers > 0);
check_socket_file(socket_path);
if(cfg->dnstap && cfg->dnstap_socket_path && cfg->dnstap_socket_path[0] &&
(cfg->dnstap_ip==NULL || cfg->dnstap_ip[0]==0)) {
verbose(VERB_OPS, "attempting to connect to dnstap socket %s",
cfg->dnstap_socket_path);
check_socket_file(cfg->dnstap_socket_path);
}
env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
if (!env)
return NULL;
fwopt = fstrm_writer_options_init();
#ifdef UNBOUND_DEBUG
res =
#else
(void)
#endif
fstrm_writer_options_add_content_type(fwopt,
DNSTAP_CONTENT_TYPE, sizeof(DNSTAP_CONTENT_TYPE) - 1);
log_assert(res == fstrm_res_success);
fuwopt = fstrm_unix_writer_options_init();
fstrm_unix_writer_options_set_socket_path(fuwopt, socket_path);
fw = fstrm_unix_writer_init(fuwopt, fwopt);
log_assert(fw != NULL);
fopt = fstrm_iothr_options_init();
fstrm_iothr_options_set_num_input_queues(fopt, num_workers);
env->iothr = fstrm_iothr_init(fopt, &fw);
if (env->iothr == NULL) {
verbose(VERB_DETAIL, "dt_create: fstrm_iothr_init() failed");
fstrm_writer_destroy(&fw);
env->dtio = dt_io_thread_create();
if(!env->dtio) {
log_err("malloc failure");
free(env);
env = NULL;
return NULL;
}
fstrm_iothr_options_destroy(&fopt);
fstrm_unix_writer_options_destroy(&fuwopt);
fstrm_writer_options_destroy(&fwopt);
if(!dt_io_thread_apply_cfg(env->dtio, cfg)) {
dt_io_thread_delete(env->dtio);
free(env);
return NULL;
}
dt_apply_cfg(env, cfg);
return env;
}
@ -272,19 +242,33 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
int
dt_init(struct dt_env *env)
{
env->ioq = fstrm_iothr_get_input_queue(env->iothr);
if (env->ioq == NULL)
env->msgqueue = dt_msg_queue_create();
if(!env->msgqueue) {
log_err("malloc failure");
return 0;
}
if(!dt_io_thread_register_queue(env->dtio, env->msgqueue)) {
log_err("malloc failure");
dt_msg_queue_delete(env->msgqueue);
env->msgqueue = NULL;
return 0;
}
return 1;
}
void
dt_deinit(struct dt_env* env)
{
dt_io_thread_unregister_queue(env->dtio, env->msgqueue);
dt_msg_queue_delete(env->msgqueue);
}
void
dt_delete(struct dt_env *env)
{
if (!env)
return;
verbose(VERB_OPS, "closing dnstap socket");
fstrm_iothr_destroy(&env->iothr);
dt_io_thread_delete(env->dtio);
free(env->identity);
free(env->version);
free(env);

View File

@ -40,16 +40,16 @@
#ifdef USE_DNSTAP
struct config_file;
struct fstrm_io;
struct fstrm_queue;
struct sldns_buffer;
struct dt_msg_queue;
struct dt_env {
/** dnstap I/O thread */
struct fstrm_iothr *iothr;
/** the io thread (made by the struct daemon) */
struct dt_io_thread* dtio;
/** dnstap I/O thread input queue */
struct fstrm_iothr_queue *ioq;
/** valid in worker struct, not in daemon struct, the per-worker
* message list */
struct dt_msg_queue* msgqueue;
/** dnstap "identity" field, NULL if disabled */
char *identity;
@ -84,12 +84,11 @@ struct dt_env {
* of the structure) to ensure lock-free access to its own per-worker circular
* queue. Duplicate the environment object if more than one worker needs to
* share access to the dnstap I/O socket.
* @param socket_path: path to dnstap logging socket, must be non-NULL.
* @param num_workers: number of worker threads, must be > 0.
* @param cfg: with config settings.
* @return dt_env object, NULL on failure.
*/
struct dt_env *
dt_create(const char *socket_path, unsigned num_workers);
dt_create(struct config_file* cfg);
/**
* Apply config settings.
@ -107,6 +106,11 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg);
int
dt_init(struct dt_env *env);
/**
* Deletes the per-worker state created by dt_init
*/
void dt_deinit(struct dt_env *env);
/**
* Delete dnstap environment object. Closes dnstap I/O socket and deletes all
* per-worker I/O queues.

View File

@ -7,7 +7,7 @@ AC_DEFUN([dt_DNSTAP],
[
AC_ARG_ENABLE([dnstap],
AS_HELP_STRING([--enable-dnstap],
[Enable dnstap support (requires fstrm, protobuf-c)]),
[Enable dnstap support (requires protobuf-c)]),
[opt_dnstap=$enableval], [opt_dnstap=no])
AC_ARG_WITH([dnstap-socket-path],
@ -40,13 +40,6 @@ AC_DEFUN([dt_DNSTAP],
fi
fi
])
AC_ARG_WITH([libfstrm], AC_HELP_STRING([--with-libfstrm=path],
[Path where libfstrm is installed, for dnstap]), [
CFLAGS="$CFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval/lib"
])
AC_SEARCH_LIBS([fstrm_iothr_init], [fstrm], [],
AC_MSG_ERROR([The fstrm library was not found. Please install fstrm!]))
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [],
AC_MSG_ERROR([The protobuf-c library was not found. Please install protobuf-c!]))
$2

236
dnstap/dnstap_fstrm.c Normal file
View File

@ -0,0 +1,236 @@
/*
* dnstap/dnstap_fstrm.c - Frame Streams protocol for dnstap
*
* Copyright (c) 2020, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* \file
*
* Definitions for the Frame Streams data transport protocol for
* dnstap message logs.
*/
#include "config.h"
#include "dnstap/dnstap_fstrm.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
void* fstrm_create_control_frame_start(char* contenttype, size_t* len)
{
uint32_t* control;
size_t n;
/* start framestream message:
* 4byte 0: control indicator.
* 4byte bigendian: length of control frame
* 4byte bigendian: type START
* 4byte bigendian: option: content-type
* 4byte bigendian: length of string
* string of content type (dnstap)
*/
n = 4+4+4+4+4+strlen(contenttype);
control = malloc(n);
if(!control)
return NULL;
control[0] = 0;
control[1] = htonl(4+4+4+strlen(contenttype));
control[2] = htonl(FSTRM_CONTROL_FRAME_START);
control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
control[4] = htonl(strlen(contenttype));
memmove(&control[5], contenttype, strlen(contenttype));
*len = n;
return control;
}
void* fstrm_create_control_frame_stop(size_t* len)
{
uint32_t* control;
size_t n;
/* stop framestream message:
* 4byte 0: control indicator.
* 4byte bigendian: length of control frame
* 4byte bigendian: type STOP
*/
n = 4+4+4;
control = malloc(n);
if(!control)
return NULL;
control[0] = 0;
control[1] = htonl(4);
control[2] = htonl(FSTRM_CONTROL_FRAME_STOP);
*len = n;
return control;
}
void* fstrm_create_control_frame_ready(char* contenttype, size_t* len)
{
uint32_t* control;
size_t n;
/* start bidirectional stream:
* 4 bytes 0 escape
* 4 bytes bigendian length of frame
* 4 bytes bigendian type READY
* 4 bytes bigendian frame option content type
* 4 bytes bigendian length of string
* string of content type.
*/
/* len includes the escape and framelength */
n = 4+4+4+4+4+strlen(contenttype);
control = malloc(n);
if(!control) {
return NULL;
}
control[0] = 0;
control[1] = htonl(4+4+4+strlen(contenttype));
control[2] = htonl(FSTRM_CONTROL_FRAME_READY);
control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
control[4] = htonl(strlen(contenttype));
memmove(&control[5], contenttype, strlen(contenttype));
*len = n;
return control;
}
void* fstrm_create_control_frame_accept(char* contenttype, size_t* len)
{
uint32_t* control;
size_t n;
/* control frame on reply:
* 4 bytes 0 escape
* 4 bytes bigendian length of frame
* 4 bytes bigendian type ACCEPT
* 4 bytes bigendian frame option content type
* 4 bytes bigendian length of string
* string of content type.
*/
/* len includes the escape and framelength */
n = 4+4+4+4+4+strlen(contenttype);
control = malloc(n);
if(!control) {
return NULL;
}
control[0] = 0;
control[1] = htonl(4+4+4+strlen(contenttype));
control[2] = htonl(FSTRM_CONTROL_FRAME_ACCEPT);
control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
control[4] = htonl(strlen(contenttype));
memmove(&control[5], contenttype, strlen(contenttype));
*len = n;
return control;
}
void* fstrm_create_control_frame_finish(size_t* len)
{
uint32_t* control;
size_t n;
/* control frame on reply:
* 4 bytes 0 escape
* 4 bytes bigendian length of frame
* 4 bytes bigendian type FINISH
*/
/* len includes the escape and framelength */
n = 4+4+4;
control = malloc(n);
if(!control) {
return NULL;
}
control[0] = 0;
control[1] = htonl(4);
control[2] = htonl(FSTRM_CONTROL_FRAME_FINISH);
*len = n;
return control;
}
char* fstrm_describe_control(void* pkt, size_t len)
{
uint32_t frametype = 0;
char buf[512];
char* str = buf;
size_t remain, slen = sizeof(buf);
uint8_t* pos;
buf[0]=0;
if(len < 4) {
snprintf(buf, sizeof(buf), "malformed control frame, "
"too short, len=%u", (unsigned int)len);
return strdup(buf);
}
frametype = sldns_read_uint32(pkt);
if(frametype == FSTRM_CONTROL_FRAME_ACCEPT) {
(void)sldns_str_print(&str, &slen, "accept");
} else if(frametype == FSTRM_CONTROL_FRAME_START) {
(void)sldns_str_print(&str, &slen, "start");
} else if(frametype == FSTRM_CONTROL_FRAME_STOP) {
(void)sldns_str_print(&str, &slen, "stop");
} else if(frametype == FSTRM_CONTROL_FRAME_READY) {
(void)sldns_str_print(&str, &slen, "ready");
} else if(frametype == FSTRM_CONTROL_FRAME_FINISH) {
(void)sldns_str_print(&str, &slen, "finish");
} else {
(void)sldns_str_print(&str, &slen, "type%d", (int)frametype);
}
/* show the content type options */
pos = pkt + 4;
remain = len - 4;
while(remain >= 8) {
uint32_t field_type = sldns_read_uint32(pos);
uint32_t field_len = sldns_read_uint32(pos+4);
if(remain < field_len) {
(void)sldns_str_print(&str, &slen, "malformed_field");
break;
}
if(field_type == FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE) {
char tempf[512];
(void)sldns_str_print(&str, &slen, " content-type(");
if(field_len < sizeof(tempf)-1) {
memmove(tempf, pos+8, field_len);
tempf[field_len] = 0;
(void)sldns_str_print(&str, &slen, "%s", tempf);
} else {
(void)sldns_str_print(&str, &slen, "<error-too-long>");
}
(void)sldns_str_print(&str, &slen, ")");
} else {
(void)sldns_str_print(&str, &slen,
" field(type %u, length %u)",
(unsigned int)field_type,
(unsigned int)field_len);
}
pos += 8 + field_len;
remain -= (8 + field_len);
}
if(remain > 0)
(void)sldns_str_print(&str, &slen, " trailing-bytes"
"(length %u)", (unsigned int)remain);
return strdup(buf);
}

194
dnstap/dnstap_fstrm.h Normal file
View File

@ -0,0 +1,194 @@
/*
* dnstap/dnstap_fstrm.h - Frame Streams protocol for dnstap
*
* Copyright (c) 2020, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* \file
*
* Definitions for the Frame Streams data transport protocol for
* dnstap message logs.
*/
#ifndef DNSTAP_FSTRM_H
#define DNSTAP_FSTRM_H
/* Frame Streams data transfer protocol encode for DNSTAP messages.
* The protocol looks to be specified in the libfstrm library.
*
* Quick writeup for DNSTAP usage, from reading fstrm/control.h eloquent
* comments and fstrm/control.c for some bytesize details (the content type
* length).
*
* The Frame Streams can be unidirectional or bi-directional.
* bi-directional streams use control frame types READY, ACCEPT and FINISH.
* uni-directional streams use control frame types START and STOP.
* unknown control frame types should be ignored by the receiver, they
* do not change the data frame encoding.
*
* bi-directional control frames implement a simple handshake protocol
* between sender and receiver.
*
* The uni-directional control frames have one start and one stop frame,
* before and after the data. The start frame can have a content type.
* The start and stop frames are not optional.
*
* data frames are preceded by 4byte length, bigendian.
* zero length data frames are not possible, they are an escape that
* signals the presence of a control frame.
*
* a control frame consists of 0 value in 4byte bigendian, this is really
* the data frame length, with 0 the escape sequence that indicates one
* control frame follows.
* Then, 4byte bigendian, length of the control frame message.
* Then, the control frame payload (of that length). with in it:
* 4byte bigendian, control type (eg. START, STOP, READY, ACCEPT, FINISH).
* perhaps nothing more (STOP, FINISH), but for other types maybe
* control fields
* 4byte bigendian, the control-field-type, currently only content-type.
* 4byte bigendian, length of the string for this option.
* .. bytes of that string.
*
* The START type can have only one field. Field max len 256.
* control frame max frame length 512 (excludes the 0-escape and control
* frame length bytes).
*
* the bidirectional type of transmission is like this:
* client sends READY (with content type included),
* client waits for ACCEPT (with content type included),
* client sends START (with matched content type from ACCEPT)
* .. data frames
* client sends STOP.
* client waits for FINISH frame.
*
*/
/** max length of Frame Streams content type field string */
#define FSTRM_CONTENT_TYPE_LENGTH_MAX 256
/** control frame value to denote the control frame ACCEPT */
#define FSTRM_CONTROL_FRAME_ACCEPT 0x01
/** control frame value to denote the control frame START */
#define FSTRM_CONTROL_FRAME_START 0x02
/** control frame value to denote the control frame STOP */
#define FSTRM_CONTROL_FRAME_STOP 0x03
/** control frame value to denote the control frame READY */
#define FSTRM_CONTROL_FRAME_READY 0x04
/** control frame value to denote the control frame FINISH */
#define FSTRM_CONTROL_FRAME_FINISH 0x05
/** the constant that denotes the control field type that is the
* string for the content type of the stream. */
#define FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE 0x01
/** the content type for DNSTAP frame streams */
#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap"
/**
* This creates an FSTRM control frame of type START.
* @param contenttype: a zero delimited string with the content type.
* eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as
* "protobuf:dnstap.Dnstap", for a dnstap frame stream.
* @param len: if a buffer is returned this is the length of that buffer.
* @return NULL on malloc failure. Returns a malloced buffer with the
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
* a control frame. The buffer should be sent without preceding it with
* the 'len' variable (like data frames are), but straight the content of the
* buffer, because the lengths are included in the buffer. This is so that
* the zero control indicator can be included before the control frame length.
*/
void* fstrm_create_control_frame_start(char* contenttype, size_t* len);
/**
* This creates an FSTRM control frame of type READY.
* @param contenttype: a zero delimited string with the content type.
* eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as
* "protobuf:dnstap.Dnstap", for a dnstap frame stream.
* @param len: if a buffer is returned this is the length of that buffer.
* @return NULL on malloc failure. Returns a malloced buffer with the
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
* a control frame. The buffer should be sent without preceding it with
* the 'len' variable (like data frames are), but straight the content of the
* buffer, because the lengths are included in the buffer. This is so that
* the zero control indicator can be included before the control frame length.
*/
void* fstrm_create_control_frame_ready(char* contenttype, size_t* len);
/**
* This creates an FSTRM control frame of type STOP.
* @param len: if a buffer is returned this is the length of that buffer.
* @return NULL on malloc failure. Returns a malloced buffer with the
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
* a control frame. The buffer should be sent without preceding it with
* the 'len' variable (like data frames are), but straight the content of the
* buffer, because the lengths are included in the buffer. This is so that
* the zero control indicator can be included before the control frame length.
*/
void* fstrm_create_control_frame_stop(size_t* len);
/**
* This creates an FSTRM control frame of type ACCEPT.
* @param contenttype: a zero delimited string with the content type.
* for dnstap streams use DNSTAP_CONTENT_TYPE.
* @param len: if a buffer is returned this is the length of that buffer.
* @return NULL on malloc failure. Returns a malloced buffer with the
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
* a control frame. The buffer should be sent without preceding it with
* the 'len' variable (like data frames are), but straight the content of the
* buffer, because the lengths are included in the buffer. This is so that
* the zero control indicator can be included before the control frame length.
*/
void* fstrm_create_control_frame_accept(char* contenttype, size_t* len);
/**
* This creates an FSTRM control frame of type FINISH.
* @param len: if a buffer is returned this is the length of that buffer.
* @return NULL on malloc failure. Returns a malloced buffer with the
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
* a control frame. The buffer should be sent without preceding it with
* the 'len' variable (like data frames are), but straight the content of the
* buffer, because the lengths are included in the buffer. This is so that
* the zero control indicator can be included before the control frame length.
*/
void* fstrm_create_control_frame_finish(size_t* len);
/**
* Return string that describes a control packet. For debug, logs.
* Like 'start content-type(protobuf:dnstap.Dnstap)' or 'stop'.
* @param pkt: the packet data, that is the data after the 4 zero start
* bytes and 4 length bytes.
* @param len: the length of the control packet data, in pkt. This is the
* ntohl of the 4 bytes length preceding the data.
* @return zero delimited string, malloced. Or NULL on malloc failure.
*/
char* fstrm_describe_control(void* pkt, size_t len);
#endif /* DNSTAP_FSTRM_H */

2128
dnstap/dtstream.c Normal file

File diff suppressed because it is too large Load Diff

341
dnstap/dtstream.h Normal file
View File

@ -0,0 +1,341 @@
/*
* dnstap/dtstream.h - Frame Streams thread for unbound DNSTAP
*
* Copyright (c) 2020, NLnet Labs. All rights reserved.
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the NLNET LABS nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* \file
*
* An implementation of the Frame Streams data transport protocol for
* the Unbound DNSTAP message logging facility.
*/
#ifndef DTSTREAM_H
#define DTSTREAM_H
#include "util/locks.h"
struct dt_msg_entry;
struct dt_io_list_item;
struct dt_io_thread;
struct config_file;
/**
* A message buffer with dnstap messages queued up. It is per-worker.
* It has locks to synchronize. If the buffer is full, a new message
* cannot be added and is discarded. A thread reads the messages and sends
* them.
*/
struct dt_msg_queue {
/** lock of the buffer structure. Hold this lock to add or remove
* entries to the buffer. Release it so that other threads can also
* put messages to log, or a message can be taken out to send away
* by the writer thread.
*/
lock_basic_type lock;
/** the maximum size of the buffer, in bytes */
size_t maxsize;
/** current size of the buffer, in bytes. data bytes of messages.
* If a new message make it more than maxsize, the buffer is full */
size_t cursize;
/** list of messages. The messages are added to the back and taken
* out from the front. */
struct dt_msg_entry* first, *last;
/** reference to the io thread to wakeup */
struct dt_io_thread* dtio;
};
/**
* An entry in the dt_msg_queue. contains one DNSTAP message.
* It is malloced.
*/
struct dt_msg_entry {
/** next in the list. */
struct dt_msg_entry* next;
/** the buffer with the data to send, an encoded DNSTAP message */
void* buf;
/** the length to send. */
size_t len;
};
/**
* Containing buffer and counter for reading DNSTAP frames.
*/
struct dt_frame_read_buf {
/** Buffer containing frame, except length counter(s). */
void* buf;
/** Number of bytes written to buffer. */
size_t buf_count;
/** Capacity of the buffer. */
size_t buf_cap;
/** Frame length field. Will contain the 2nd length field for control
* frames. */
uint32_t frame_len;
/** Number of bytes that have been written to the frame_length field. */
size_t frame_len_done;
/** Set to 1 if this is a control frame, 0 otherwise (ie data frame). */
int control_frame;
};
/**
* IO thread that reads from the queues and writes them.
*/
struct dt_io_thread {
/** the thread number for the dtio thread,
* must be first to cast thread arg to int* in checklock code. */
int threadnum;
/** event base, for event handling */
void* event_base;
/** list of queues that is registered to get written */
struct dt_io_list_item* io_list;
/** iterator point in the io_list, to pick from them in a
* round-robin fashion, instead of only from the first when busy.
* if NULL it means start at the start of the list. */
struct dt_io_list_item* io_list_iter;
/** thread id, of the io thread */
ub_thread_type tid;
/** if the io processing has started */
int started;
/** ssl context for the io thread, for tls connections. type SSL_CTX* */
void* ssl_ctx;
/** if SNI will be used for TLS connections. */
int tls_use_sni;
/** file descriptor that the thread writes to */
int fd;
/** event structure that the thread uses */
void* event;
/** the event is added */
int event_added;
/** event added is a write event */
int event_added_is_write;
/** check for nonblocking connect errors on fd */
int check_nb_connect;
/** ssl for current connection, type SSL* */
void* ssl;
/** true if the handshake for SSL is done, 0 if not */
int ssl_handshake_done;
/** true if briefly the SSL wants a read event, 0 if not.
* This happens during negotiation, we then do not want to write,
* but wait for a read event. */
int ssl_brief_read;
/** true if SSL_read is waiting for a write event. Set back to 0 after
* single write event is handled. */
int ssl_brief_write;
/** the buffer that currently getting written, or NULL if no
* (partial) message written now */
void* cur_msg;
/** length of the current message */
size_t cur_msg_len;
/** number of bytes written for the current message */
size_t cur_msg_done;
/** number of bytes of the length that have been written,
* for the current message length that precedes the frame */
size_t cur_msg_len_done;
/** command pipe that stops the pipe if closed. Used to quit
* the program. [0] is read, [1] is written to. */
int commandpipe[2];
/** the event to listen to the commandpipe */
void* command_event;
/** the io thread wants to exit */
int want_to_exit;
/** in stop flush, this is nonNULL and references the stop_ev */
void* stop_flush_event;
/** the timer event for connection retries */
void* reconnect_timer;
/** if the reconnect timer is added to the event base */
int reconnect_is_added;
/** the current reconnection timeout, it is increased with
* exponential backoff, in msec */
int reconnect_timeout;
/** If the log server is connected to over unix domain sockets,
* eg. a file is named that is created to log onto. */
int upstream_is_unix;
/** if the log server is connected to over TCP. The ip address and
* port are used */
int upstream_is_tcp;
/** if the log server is connected to over TLS. ip address, port,
* and client certificates can be used for authentication. */
int upstream_is_tls;
/** Perform bidirectional Frame Streams handshake before sending
* messages. */
int is_bidirectional;
/** Set if the READY control frame has been sent. */
int ready_frame_sent;
/** Set if valid ACCEPT frame is received. */
int accept_frame_received;
/** (partially) read frame */
struct dt_frame_read_buf read_frame;
/** the file path for unix socket (or NULL) */
char* socket_path;
/** the ip address and port number (or NULL) */
char* ip_str;
/** is the TLS upstream authenticated by name, if nonNULL,
* we use the same cert bundle as used by other TLS streams. */
char* tls_server_name;
/** are client certificates in use */
int use_client_certs;
/** client cert files: the .key file */
char* client_key_file;
/** client cert files: the .pem file */
char* client_cert_file;
};
/**
* IO thread list of queues list item
* lists a worker queue that should be looked at and sent to the log server.
*/
struct dt_io_list_item {
/** next in the list of buffers to inspect */
struct dt_io_list_item* next;
/** buffer of this worker */
struct dt_msg_queue* queue;
};
/**
* Create new (empty) worker message queue. Limit set to default on max.
* @return NULL on malloc failure or a new queue (not locked).
*/
struct dt_msg_queue* dt_msg_queue_create(void);
/**
* Delete a worker message queue. It has to be unlinked from access,
* so it can be deleted without lock worries. The queue is emptied (deleted).
* @param mq: message queue.
*/
void dt_msg_queue_delete(struct dt_msg_queue* mq);
/**
* Submit a message to the queue. The queue is locked by the routine,
* the message is inserted, and then the queue is unlocked so the
* message can be picked up by the writer thread.
* @param mq: message queue.
* @param buf: buffer with message (dnstap contents).
* The buffer must have been malloced by caller. It is linked in
* the queue, and is free()d after use. If the routine fails
* the buffer is freed as well (and nothing happens, the item
* could not be logged).
* @param len: length of buffer.
*/
void dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len);
/**
* Create IO thread.
* @return new io thread object. not yet started. or NULL malloc failure.
*/
struct dt_io_thread* dt_io_thread_create(void);
/**
* Delete the IO thread structure.
* @param dtio: the io thread that is deleted. It must not be running.
*/
void dt_io_thread_delete(struct dt_io_thread* dtio);
/**
* Apply config to the dtio thread
* @param dtio: io thread, not yet started.
* @param cfg: config file struct.
* @return false on malloc failure.
*/
int dt_io_thread_apply_cfg(struct dt_io_thread* dtio,
struct config_file *cfg);
/**
* Register a msg queue to the io thread. It will be polled to see if
* there are messages and those then get removed and sent, when the thread
* is running.
* @param dtio: the io thread.
* @param mq: message queue to register.
* @return false on failure (malloc failure).
*/
int dt_io_thread_register_queue(struct dt_io_thread* dtio,
struct dt_msg_queue* mq);
/**
* Unregister queue from io thread.
* @param dtio: the io thread.
* @param mq: message queue.
*/
void dt_io_thread_unregister_queue(struct dt_io_thread* dtio,
struct dt_msg_queue* mq);
/**
* Start the io thread
* @param dtio: the io thread.
* @param event_base_nothr: the event base to attach the events to, in case
* we are running without threads. With threads, this is ignored
* and a thread is started to process the dnstap log messages.
* @param numworkers: number of worker threads. The dnstap io thread is
* that number +1 as the threadnumber (in logs).
* @return false on failure.
*/
int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr,
int numworkers);
/**
* Stop the io thread
* @param dtio: the io thread.
*/
void dt_io_thread_stop(struct dt_io_thread* dtio);
/** callback for the dnstap reconnect, to start reconnecting to output */
void dtio_reconnect_timeout_cb(int fd, short bits, void* arg);
/** callback for the dnstap events, to write to the output */
void dtio_output_cb(int fd, short bits, void* arg);
/** callback for the dnstap commandpipe, to stop the dnstap IO */
void dtio_cmd_cb(int fd, short bits, void* arg);
/** callback for the timer when the thread stops and wants to finish up */
void dtio_stop_timer_cb(int fd, short bits, void* arg);
/** callback for the output when the thread stops and wants to finish up */
void dtio_stop_ev_cb(int fd, short bits, void* arg);
/** callback for unbound-dnstap-socket */
void dtio_tap_callback(int fd, short bits, void* arg);
/** callback for unbound-dnstap-socket */
void dtio_mainfdcallback(int fd, short bits, void* arg);
#endif /* DTSTREAM_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,330 @@
20 July 2020: Wouter
- Fix streamtcp to print packet data to stdout. This makes the
stdout and stderr not mix together lines, when parsing its output.
- Fix contrib/fastrpz.patch to apply cleanly. It fixes for changes
due to added libdynmod, but it does not compile, it conflicts with
new rpz code.
- branch now named 1.11.0 and 1.11.0rc1 tag.
17 July 2020: Wouter
- Fix libnettle compile for session ticket key callback function
changes.
- Fix lock dependency cycle in rpz zone config setup.
17 July 2020: Ralph
- Merge PR #234 - Ensure proper alignment of cmsg buffers by Jérémie
Courrèges-Anglas.
- Fix PR #234 log_assert sizeof to use union buffer.
16 July 2020: Wouter
- Fix check conf test for referencing installation paths.
- Fix unused variable warning for clang analyzer.
16 July 2020: George
- Introduce 'include-toplevel:' configuration option.
16 July 2020: Ralph
- Add bidirectional frame streams support.
8 July 2020: Wouter
- Fix add missing DSA header, for compilation without deprecated
OpenSSL APIs.
- Fix to use SSL_CTX_set_tlsext_ticket_key_evp_cb in OpenSSL
3.0.0-alpha4.
- Longer keys for the test set, this avoids weak crypto errors.
7 July 2020: Wouter
- Fix #259: Fix unbound-checkconf does not check view existence.
unbound-checkconf checks access-control-view, access-control-tags,
access-control-tag-actions and access-control-tag-datas.
- Fix offset of error printout for access-control-tag-datas.
- Review fixes for checkconf #259 change.
6 July 2020: Wouter
- run_vm cleanup better and removes trailing slash on single argument.
29 June 2020: Wouter
- Move reply list clean for serve expired mesh callback to after
the reply is sent, so that script callbacks have reply_info.
- Also move reply list clean for mesh callbacks to the scrip callback
can see the reply_info.
- Fix for mesh accounting if the reply list already empty to begin
with.
- Fix for mesh accounting when rpz decides to drop a reply with a
tcp stream waiting for it.
- Review fix for number of detached states due to use of variable
after end of loop.
- Fix tcp req info drop due to size call into mesh accounting
removal of mesh state during mesh send reply.
24 June 2020: Wouter
- iana portlist updated.
- doxygen file comments for dynlibmodule.
17 June 2020: Wouter
- Fix default explanation in man page for qname-minimisation-strict.
- Fix display of event loop method with libev.
8 June 2020: Wouter
- Mention tls name possible when tls is enabled for stub-addr in the
man page.
27 May 2020: George
- Merge PR #241 by Robert Edmonds: contrib/libunbound.pc.in: Do not use
"Requires:".
25 May 2020: George
- Update contrib/aaaa-filter-iterator.patch for the recent
generate_sub_request() change and to apply cleanly.
21 May 2020: George
- Fix for integer overflow when printing RDF_TYPE_TIME.
19 May 2020: Wouter
- CVE-2020-12662 Unbound can be tricked into amplifying an incoming
query into a large number of queries directed to a target.
- CVE-2020-12663 Malformed answers from upstream name servers can be
used to make Unbound unresponsive.
- Release 1.10.1 is 1.10.0 with fixes, code repository continues,
including those fixes, towards the next release. Configure has
version 1.10.2 version number in it.
- For PR #93: windows compile warnings removal
- windows compile warnings removal for ip dscp option code.
- For PR #93: unit test for dynlib module.
18 May 2020: Wouter
- For PR #93: dynlibmod can handle reloads and deinit and inits again,
with dlclose and dlopen of the library again. Also for multiple
modules. Fix memory leak by not closing dlopened content. Fix
to allow one dynlibmod instance by unbound-checkconf.
- For PR #93: checkconf allows multiple dynlib in module-config, for
a couple cases.
- For PR #93: checkconf allows python dynlib in module-config, for
a couple cases.
- For PR #93: man page spelling reference fix.
- For PR #93: fix link of other executables for dynlibmod dependency.
15 May 2020: Wouter
- Merge PR #93: Add dynamic library support.
- Fixed conflicts for PR #93 and make configure, yacc, lex.
- For PR #93: Fix warnings for dynlibmodule.
15 May 2020: Ralph
- Cache ECS answers with longest scope of CNAME chain.
22 April 2020: George
- Explicitly use 'rrset-roundrobin: no' for test cases.
21 April 2020: Wouter
- Merge #225 from akhait: KSK-2010 has been revoked. It removes the
KSK-2010 from the default list in unbound-anchor, now that the
revocation period is over. KSK-2017 is the only trust anchor in
the shipped default now.
21 April 2020: George
- Change default value for 'rrset-roundrobin' to yes.
- Fix tests for new rrset-roundrobin default.
20 April 2020: Wouter
- Fix #222: --enable-rpath, fails to rpath python lib.
- Fix for count of reply states in the mesh.
- Remove unneeded was_mesh_reply check.
17 April 2020: George
- Add SNI support on more TLS connections (fixes #193).
- Add SNI support to unbound-anchor.
16 April 2020: George
- Add doxygen documentation for DSCP.
16 April 2020: Wouter
- Fix help return code in unbound-control-setup script.
- Fix for posix shell syntax for trap in nsd-control-setup.
- Fix for posix shell syntax for trap in run_msg.sh test script.
15 April 2020: George
- Fix #220: auth-zone section in config may lead to segfault.
7 April 2020: Wouter
- Merge PR #214 from gearnode: unbound-control-setup recreate
certificates. With the -r option the certificates are created
again, without it, only the files that do not exist are created.
6 April 2020: Ralph
- Keep track of number of timeouts. Use this counter to determine if
capsforid fallback should be started.
6 April 2020: George
- More documentation for redis-expire-records option.
1 April 2020: George
- Merge PR #206: Redis TTL, by Talkabout.
30 March 2020: Wouter
- Merge PR #207: Clarify if-automatic listens on 0.0.0.0 and ::
- Merge PR #208: Fix uncached CLIENT_RESPONSE'es on stateful
transports.
27 March 2020: Wouter
- Merge PR #203 from noloader: Update README-Travis.md with current
procedures.
27 March 2020: Ralph
- Make unbound-control error returned on missing domain name more user
friendly.
26 March 2020: Ralph
- Fix RPZ concurrency issue when using auth_zone_reload.
25 March 2020: George
- Merge PR #201 from noloader: Fix OpenSSL cross-compaile warnings.
- Fix on #201.
24 March 2020: Wouter
- Merge PR #200 from yarikk: add ip-dscp option to specify the DSCP
tag for outgoing packets.
- Fixes on #200.
- Travis fix for ios by omitting tools from install.
23 March 2020: Wouter
- Fix compile on Solaris for unbound-checkconf.
20 March 2020: George
- Merge PR #198 from fobser: Declare lz_enter_rr_into_zone() static, it's
only used in this file.
20 March 2020: Wouter
- Merge PR #197 from fobser: Make log_ident_revert_to_default() a
proper prototype.
19 March 2020: Ralph
- Merge PR#191: Update iOS testing on Travis, by Jeffrey Walton.
- Fix #158: open tls-session-ticket-keys as binary, for Windows. By
Daisuke HIGASHI.
- Merge PR#134, Allow the kernel to provide random source ports. By
Florian Obser.
- Log warning when using outgoing-port-permit and outgoing-port-avoid
while explicit port randomisation is disabled.
- Merge PR#194: Add libevent testing to Travis, by Jeffrey Walton.
- Fix .travis.yml error, missing 'env' option.
16 March 2020: Wouter
- Fix #192: In the unbound-checkconf tool, the module config of
dns64 subnetcache respip validator iterator is whitelisted, it was
reported it seems to work.
12 March 2020: Wouter
- Fix compile of test tools without protobuf.
11 March 2020: Ralph
- Add check to make sure RPZ records are subdomains of configured
zone origin.
11 March 2020: George
- Fix #189: mini_event.h:142:17: error: field 'ev_timeout' has incomplete
type, by noloader.
- Changelog entry for (Fix #189, Merge PR #190).
11 March 2020: Wouter
- Fix #188: unbound-control.c:882:6: error: 'execlp' is
unavailable: not available on tvOS.
6 March 2020: George
- Merge PR #186, fix #183: Fix unrecognized 'echo -n' option on OS X, by
noloader
5 March 2020: Wouter
- Fix PR #182 from noloader: Add iOS testing to Travis.
4 March 2020: Ralph
- Update README-Travis.md (from PR #179), by Jeffrey Walton.
4 March 2020: George
- Merge PR #181 from noloader: Fix OpenSSL -pie warning on Android.
4 March 2020: Wouter
- Merge PR #180 from noloader: Avoid calling exit in Travis script.
3 March 2020: George
- Upgrade config.guess(2020-01-01) and config.sub(2020-01-01).
2 March 2020: Ralph
- Fix #175, Merge PR #176: fix link error when OpenSSL is configured
with no-engine, thanks noloader.
2 March 2020: George
- Fix compiler warning in dns64/dns64.c
- Merge PR #174: Add Android to Travis testing, by noloader.
- Move android build scripts to contrib/ and allow android tests to fail.
2 March 2020: Wouter
- Fix #177: dnstap does not build on macOS.
28 February 2020: Ralph
- Merge PR #172: Add IBM s390x arch for testing, by noloader.
28 February 2020: Wouter
- Merge PR #173: updated makedist.sh for config.guess and
config.sub and sha256 digest for gpg, by noloader.
- Merge PR #164: Framestreams, this branch implements dnstap
unidirectional connectivity in unbound. This has a number of
new features.
The dependency on libfstrm is removed. The fstrm protocol code
resides in dnstap/dnstap_fstrm.h and dnstap/dnstap_fstrm.c. This
contains a brief definition of what unbound needs.
The make unbound-dnstap-socket builds a debug tool,
unbound-dnstap-socket. It can listen, accept multiple DNSTAP
streams and print information. Commandline options control it.
Unbound can reconnect if the unix domain socket file socket is
closed. This uses exponential backoff after which it uses a
one second timer to throttle cpu down. There is also support
to use TCP and TLS for connecting to the log server. There
are new config options to turn them on, in the dnstap section
in the man page and example config file. dnstap-ip with IP
address of server for TCP or TLS use. dnstap-tls to turn
on TLS. And dnstap-tls-server-name, dnstap-tls-cert-bundle,
dnstap-tls-client-key-file and dnstap-tls-client-cert-file
to configure the certificates for server authentication and
client authentication, or leave at "" to not use that.
27 February 2020: George
- Merge PR #171: Add additional compilers and platforms to Travis
testing, by noloader.
27 February 2020: Wouter
- Fix #169: Fix warning for daemon/remote.c output may be truncated
from snprintf.
- Fix #170: Fix gcc undefined sanitizer signed integer overflow
warning in signature expiry RFC1982 serial number arithmetic.
- Fix more undefined sanitizer issues, in respip copy_rrset null
dname, and in the client_info_compare routine for null memcmp.
26 February 2020: Wouter
- iana portlist updated.
25 February 2020: Wouter
- Fix #165: Add prefer-ip4: yesno config option to prefer ipv4 for
using ipv4 filters, because the hosts ip6 netblock /64 is not owned
by one operator, and thus reputation is shared.
24 February 2020: George
- Merge PR #166: Fix typo in unbound.service.in, by glitsj16.
20 February 2020: Wouter
- Updated contrib/unbound_smf23.tar.gz with Solaris SMF service for
Unbound from Yuri Voinov.
- master branch has 1.10.1 version.
18 February 2020: Wouter
- protect X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS with ifdef for
different openssl versions.
17 February 2020: Wouter
- changelog point where the tag for 1.10.0rc2 release is. And with
the unbound_smf23 commit added to it, that is the 1.10.0 release.
17 February 2020: Ralph
- Add respip to supported module-config options in unbound-checkconf.

View File

@ -1,4 +1,4 @@
README for Unbound 1.10.1
README for Unbound 1.11.0
Copyright 2007 NLnet Labs
http://unbound.net

View File

@ -1,13 +1,17 @@
#
# Example configuration file.
#
# See unbound.conf(5) man page, version 1.10.1.
# See unbound.conf(5) man page, version 1.11.0.
#
# this is a comment.
#Use this to include other text into the file.
# Use this anywhere in the file to include other text into this file.
#include: "otherfile.conf"
# Use this anywhere in the file to include other text, that explicitly starts a
# clause, into this file. Text after this directive needs to start a clause.
#include-toplevel: "otherfile.conf"
# The server clause sets the main parameters.
server:
# whitespace is not necessary, but looks cleaner.
@ -70,6 +74,9 @@ server:
# Set this to yes to prefer ipv6 upstream servers over ipv4.
# prefer-ip6: no
# Prefer ipv4 upstream servers, even if ipv6 is available.
# prefer-ip4: no
# number of ports to allocate per thread, determines the size of the
# port range that can be open simultaneously. About double the
# num-queries-per-thread, or, use as many as the OS will allow you.
@ -116,6 +123,11 @@ server:
# Linux only. On Linux you also have ip-transparent that is similar.
# ip-freebind: no
# the value of the Differentiated Services Codepoint (DSCP)
# in the differentiated services field (DS) of the outgoing
# IP packets
# ip-dscp: 0
# EDNS reassembly buffer to advertise to UDP peers (the actual buffer
# is set with msg-buffer-size). 1472 can solve fragmentation (timeouts)
# edns-buffer-size: 4096
@ -465,7 +477,7 @@ server:
# deny-any: no
# if yes, Unbound rotates RRSet order in response.
# rrset-roundrobin: no
# rrset-roundrobin: yes
# if yes, Unbound doesn't insert authority/additional sections
# into response messages when those sections are not required.
@ -738,6 +750,10 @@ server:
# 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"
# Use the SNI extension for TLS connections. Default is yes.
# Changing the value requires a reload.
# tls-use-sni: yes
# 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.
@ -847,6 +863,17 @@ python:
# Script file to load
# python-script: "@UNBOUND_SHARE_DIR@/ubmodule-tst.py"
# Dynamic library config section. To enable:
# o use --with-dynlibmodule to configure before compiling.
# o list dynlib in the module-config string (above) to enable.
# It can be placed anywhere, the dynlib module is only a very thin wrapper
# to load modules dynamically.
# o and give a dynlib-file to run. If more than one dynlib entry is listed in
# the module-config then you need one dynlib-file per instance.
dynlib:
# Script file to load
# dynlib-file: "@UNBOUND_SHARE_DIR@/dynlib.so"
# Remote control config section.
remote-control:
# Enable remote control with unbound-control(8) here.
@ -1005,10 +1032,12 @@ remote-control:
# redis-server-port: 6379
# # timeout (in ms) for communication with the redis server
# redis-timeout: 100
# # set timeout on redis records based on DNS response TTL
# redis-expire-records: no
# IPSet
# Add specify domain into set via ipset.
# Note: To enable ipset needs run unbound as root user.
# Note: To enable ipset unbound needs to run as root user.
# ipset:
# # set name for ip v4 addresses
# name-v4: "list-v4"
@ -1016,6 +1045,40 @@ remote-control:
# name-v6: "list-v6"
#
# Dnstap logging support, if compiled in. To enable, set the dnstap-enable
# to yes and also some of dnstap-log-..-messages to yes. And select an
# upstream log destination, by socket path, TCP or TLS destination.
# dnstap:
# dnstap-enable: no
# # if set to yes frame streams will be used in bidirectional mode
# dnstap-bidirectional: yes
# dnstap-socket-path: "@DNSTAP_SOCKET_PATH@"
# # if "" use the unix socket in dnstap-socket-path, otherwise,
# # set it to "IPaddress[@port]" of the destination.
# dnstap-ip: ""
# # if set to yes if you want to use TLS to dnstap-ip, no for TCP.
# dnstap-tls: yes
# # name for authenticating the upstream server. or "" disabled.
# dnstap-tls-server-name: ""
# # if "", it uses the cert bundle from the main unbound config.
# dnstap-tls-cert-bundle: ""
# # key file for client authentication, or "" disabled.
# dnstap-tls-client-key-file: ""
# # cert file for client authentication, or "" disabled.
# dnstap-tls-client-cert-file: ""
# dnstap-send-identity: no
# dnstap-send-version: no
# # if "" it uses the hostname.
# dnstap-identity: ""
# # if "" it uses the package version.
# dnstap-version: ""
# dnstap-log-resolver-query-messages: no
# dnstap-log-resolver-response-messages: no
# dnstap-log-client-query-messages: no
# dnstap-log-client-response-messages: no
# dnstap-log-forwarder-query-messages: no
# dnstap-log-forwarder-response-messages: no
# Response Policy Zones
# RPZ policies. Applied in order of configuration. QNAME and Response IP
# Address trigger are the only supported triggers. Supported actions are:

View File

@ -1,4 +1,4 @@
.TH "libunbound" "3" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
.TH "libunbound" "3" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.\"
.\" libunbound.3 -- unbound library functions manual
.\"
@ -44,7 +44,7 @@
.B ub_ctx_zone_remove,
.B ub_ctx_data_add,
.B ub_ctx_data_remove
\- Unbound DNS validating resolver 1.10.1 functions.
\- Unbound DNS validating resolver 1.11.0 functions.
.SH "SYNOPSIS"
.B #include <unbound.h>
.LP

View File

@ -1,4 +1,4 @@
.TH "unbound-anchor" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
.TH "unbound-anchor" "8" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.\"
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
.\"
@ -69,6 +69,9 @@ The server name, it connects to https://name. Specify without https:// prefix.
The default is "data.iana.org". It connects to the port specified with \-P.
You can pass an IPv4 address or IPv6 address (no brackets) if you want.
.TP
.B \-S
Do not use SNI for the HTTPS connection. Default is to use SNI.
.TP
.B \-b \fIaddress
The source address to bind to for domain resolution and contacting the server
on https. May be either an IPv4 address or IPv6 address (no brackets).

View File

@ -1,4 +1,4 @@
.TH "unbound-checkconf" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
.TH "unbound-checkconf" "8" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.\"
.\" unbound-checkconf.8 -- unbound configuration checker manual
.\"

View File

@ -1,4 +1,4 @@
.TH "unbound-control" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
.TH "unbound-control" "8" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.\"
.\" unbound-control.8 -- unbound remote control manual
.\"

View File

@ -1,4 +1,4 @@
.TH "unbound\-host" "1" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
.TH "unbound\-host" "1" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.\"
.\" unbound-host.1 -- unbound DNS lookup utility
.\"

View File

@ -1,4 +1,4 @@
.TH "unbound" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
.TH "unbound" "8" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.\"
.\" unbound.8 -- unbound manual
.\"
@ -9,7 +9,7 @@
.\"
.SH "NAME"
.B unbound
\- Unbound DNS validating resolver 1.10.1.
\- Unbound DNS validating resolver 1.11.0.
.SH "SYNOPSIS"
.B unbound
.RB [ \-h ]

View File

@ -1,4 +1,4 @@
.TH "unbound.conf" "5" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
.TH "unbound.conf" "5" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.\"
.\" unbound.conf.5 -- unbound.conf manual
.\"
@ -77,6 +77,12 @@ for the included files works, relative pathnames for the included names work
if the directory where the daemon is started equals its chroot/working
directory or is specified before the include statement with directory: dir.
Wildcards can be used to include multiple files, see \fIglob\fR(7).
.P
For a more structural include option, the
.B 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.
.SS "Server Options"
These options are part of the
.B server:
@ -126,9 +132,12 @@ interface and port number), if not specified the default port (from
Same as interface: (for ease of compatibility with nsd.conf).
.TP
.B interface\-automatic: \fI<yes or no>
Detect source interface on UDP queries and copy them to replies. This
feature is experimental, and needs support in your OS for particular socket
options. Default value is no.
Listen on all addresses on all (current and future) interfaces, detect the
source interface on UDP queries and copy them to replies. This is a lot like
ip\-transparent, but this option services all interfaces whilst with
ip\-transparent you can select which (future) interfaces unbound provides
service on. This feature is experimental, and needs support in your OS for
particular socket options. Default value is no.
.TP
.B outgoing\-interface: \fI<ip address or ip6 netblock>
Interface to use to connect to the network. This interface is used to send
@ -323,6 +332,12 @@ IP addresses that are nonlocal or do not exist, like when the network
interface or IP address is down. Exists only on Linux, where the similar
ip\-transparent option is also available.
.TP
.B ip-dscp: \fI<number>
The value of the Differentiated Services Codepoint (DSCP) in the
differentiated services field (DS) of the outgoing IP packet headers.
The field replaces the outdated IPv4 Type-Of-Service field and the
IPV6 traffic class field.
.TP
.B rrset\-cache\-size: \fI<number>
Number of bytes size of the RRset cache. Default is 4 megabytes.
A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes, megabytes
@ -381,6 +396,13 @@ IPv6 to the internet nameservers. With this option you can disable the
ipv6 transport for sending DNS traffic, it does not impact the contents of
the DNS traffic, which may have ip4 and ip6 addresses in it.
.TP
.B prefer\-ip4: \fI<yes or no>
If enabled, prefer IPv4 transport for sending DNS queries to internet
nameservers. Default is no. Useful if the IPv6 netblock the server has,
the entire /64 of that is not owned by one operator and the reputation of
the netblock /64 is an issue, using IPv4 then uses the IPv4 filters that
the upstream servers have.
.TP
.B prefer\-ip6: \fI<yes or no>
If enabled, prefer IPv6 transport for sending DNS queries to internet
nameservers. Default is no.
@ -530,6 +552,11 @@ and that is the default.
Set the list of ciphersuites to allow when serving TLS. This is for newer
TLS 1.3 connections. Use "" for defaults, and that is the default.
.TP
.B tls\-use\-sni: \fI<yes or no>
Enable or disable sending the SNI extension on TLS connections.
Default is yes.
Changing the value requires a reload.
.TP
.B use\-systemd: \fI<yes or no>
Enable or disable systemd socket activation.
Default is no.
@ -843,7 +870,7 @@ NXDOMAIN from a DNSSEC signed zone. Default is yes.
QNAME minimisation in strict mode. Do not fall-back to sending full QNAME to
potentially broken nameservers. A lot of domains will not be resolvable when
this option in enabled. Only use if you know what you are doing.
This option only has effect when qname-minimisation is enabled. Default is off.
This option only has effect when qname-minimisation is enabled. Default is no.
.TP
.B aggressive\-nsec: \fI<yes or no>
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
@ -911,7 +938,7 @@ are none.
.TP
.B rrset\-roundrobin: \fI<yes or no>
If yes, Unbound rotates RRSet order in response (the random number is taken
from the query ID, for speed and thread safety). Default is no.
from the query ID, for speed and thread safety). Default is yes.
.TP
.B minimal-responses: \fI<yes or no>
If yes, Unbound doesn't insert authority/additional sections into response
@ -942,7 +969,9 @@ EDNS client subnet support the default is "subnetcache validator iterator".
Most modules that need to be listed here have to be listed at the beginning
of the line. The cachedb module has to be listed just before the iterator.
The python module can be listed in different places, it then processes the
output of the module it is just before.
output of the module it is just before. The dynlib module can be listed pretty
much anywhere, it is only a very thin wrapper that allows dynamic libraries to
run in its place.
.TP
.B trust\-anchor\-file: \fI<filename>
File with trusted keys for validation. Both DS and DNSKEY entries can appear
@ -1591,6 +1620,9 @@ Name of stub zone nameserver. Is itself resolved before it is used.
.B stub\-addr: \fI<IP address>
IP address of stub zone nameserver. Can be IP 4 or IP 6.
To use a nondefault port for DNS communication append '@' with the port number.
If tls is enabled, then you can append a '#' and a name, then it'll check
the tls authentication certificates with that name. If you combine
the '@' and '#', the '@' comes first.
.TP
.B stub\-prime: \fI<yes or no>
This option is by default no. If enabled it performs NS set priming,
@ -1809,6 +1841,24 @@ directory.
.B python\-script: \fI<python file>\fR
The script file to load. Repeat this option for every python module instance
added to the \fBmodule\-config:\fR option.
.SS "Dynamic Library Module Options"
.LP
The
.B dynlib:
clause gives the settings for the \fIdynlib\fR 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
\fBmodule\-config:\fR option. Multiple instances of dynamic libraries are
supported by adding the word "dynlib" more than once.
.LP
The \fBdynlib\-file:\fR path should be specified as an absolute path relative
to the new path set by \fBchroot:\fR option, or as a relative path to the
working directory.
.TP
.B dynlib\-file: \fI<dynlib file>\fR
The dynamic library file to load. Repeat this option for every dynlib module
instance added to the \fBmodule\-config:\fR option.
.SS "DNS64 Module Options"
.LP
The dns64 module must be configured in the \fBmodule\-config:\fR "dns64
@ -2060,6 +2110,11 @@ even if some data have expired in terms of DNS TTL or the Redis server has
cached too much data;
if necessary the Redis server must be configured to limit the cache size,
preferably with some kind of least-recently-used eviction policy.
Additionaly, the \fBredis\-expire\-records\fR option can be used in order to
set the relative DNS TTL of the message as timeout to the Redis records; keep
in mind that some additional memory is used per key and that the expire
information is stored as absolute Unix timestamps in Redis (computer time must
be stable).
This backend uses synchronous communication with the Redis server
based on the assumption that the communication is stable and sufficiently
fast.
@ -2114,6 +2169,94 @@ If this timeout expires Unbound closes the connection, treats it as
if the Redis server does not have the requested data, and will try to
re-establish a new connection later.
This option defaults to 100 milliseconds.
.TP
.B redis-expire-records: \fI<yes or no>
If Redis record expiration is enabled. If yes, unbound sets timeout for Redis
records so that Redis can evict keys that have expired automatically. If
unbound is configured with \fBserve-expired\fR and \fBserve-expired-ttl\fR is 0,
this option is internally reverted to "no". Redis SETEX support is required
for this option (Redis >= 2.0.0).
This option defaults to no.
.SS DNSTAP Logging Options
DNSTAP support, when compiled in, is enabled in the \fBdnstap:\fR 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 connects per-process to the
destination.
.TP
.B dnstap-enable: \fI<yes or no>
If dnstap is enabled. Default no. If yes, it connects to the dnstap server
and if any of the dnstap-log-..-messages options is enabled it sends logs
for those messages to the server.
.TP
.B dnstap-bidirectional: \fI<yes or no>
Use frame streams in bidirectional mode to transfer DNSTAP messages. Default is
yes.
.TP
.B dnstap-socket-path: \fI<file name>
Sets the unix socket file name for connecting to the server that is
listening on that socket. Default is "@DNSTAP_SOCKET_PATH@".
.TP
.B dnstap-ip: \fI<IPaddress[@port]>
If "", the unix socket is used, if set with an IP address (IPv4 or IPv6)
that address is used to connect to the server.
.TP
.B dnstap-tls: \fI<yes or no>
Set this to use TLS to connect to the server specified in \fBdnstap-ip\fR.
The default is yes. If set to no, TCP is used to connect to the server.
.TP
.B dnstap-tls-server-name: \fI<name of TLS authentication>
The TLS server name to authenticate the server with. Used when \fBdnstap-tls\fR is enabled. If "" it is ignored, default "".
.TP
.B dnstap-tls-cert-bundle: \fI<file name of cert bundle>
The pem file with certs to verify the TLS server certificate. If "" the
server default cert bundle is used, or the windows cert bundle on windows.
Default is "".
.TP
.B dnstap-tls-client-key-file: \fI<file name>
The client key file for TLS client authentication. If "" client
authentication is not used. Default is "".
.TP
.B dnstap-tls-client-cert-file: \fI<file name>
The client cert file for TLS client authentication. Default is "".
.TP
.B dnstap-send-identity: \fI<yes or no>
If enabled, the server identity is included in the log messages.
Default is no.
.TP
.B dnstap-send-version: \fI<yes or no>
If enabled, the server version if included in the log messages.
Default is no.
.TP
.B dnstap-identity: \fI<string>
The identity to send with messages, if "" the hostname is used.
Default is "".
.TP
.B dnstap-version: \fI<string>
The version to send with messages, if "" the package version is used.
Default is "".
.TP
.B dnstap-log-resolver-query-messages: \fI<yes or no>
Enable to log resolver query messages. Default is no.
These are messages from unbound to upstream servers.
.TP
.B dnstap-log-resolver-response-messages: \fI<yes or no>
Enable to log resolver response messages. Default is no.
These are replies from upstream servers to unbound.
.TP
.B dnstap-log-client-query-messages: \fI<yes or no>
Enable to log client query messages. Default is no.
These are client queries to unbound.
.TP
.B dnstap-log-client-response-messages: \fI<yes or no>
Enable to log client response messages. Default is no.
These are responses from unbound to clients.
.TP
.B dnstap-log-forwarder-query-messages: \fI<yes or no>
Enable to log forwarder query messages. Default is no.
.TP
.B dnstap-log-forwarder-response-messages: \fI<yes or no>
Enable to log forwarder response messages. Default is no.
.SS Response Policy Zone Options
.LP
Response Policy Zones are configured with \fBrpz:\fR, and each one must have a

301
dynlibmod/dynlibmod.c Normal file
View File

@ -0,0 +1,301 @@
/**
* \file
* This file contains the dynamic library module for Unbound.
* This loads a dynamic library (.dll, .so) and calls that for the
* module actions.
*/
#include "config.h"
#include "util/module.h"
#include "util/config_file.h"
#include "dynlibmod/dynlibmod.h"
#if HAVE_WINDOWS_H
#include <windows.h>
#define __DYNMOD HMODULE
#define __DYNSYM FARPROC
#define __LOADSYM GetProcAddress
void log_dlerror() {
DWORD dwLastError = GetLastError();
LPSTR MessageBuffer;
DWORD dwBufferLength;
DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM ;
if((dwBufferLength = FormatMessageA(
dwFormatFlags,
NULL, // module to get message from (NULL == system)
dwLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(LPSTR) &MessageBuffer,
0,
NULL
)))
{
log_err("dynlibmod: %s (%ld)", MessageBuffer, dwLastError);
LocalFree(MessageBuffer);
}
}
HMODULE open_library(const char* fname) {
return LoadLibrary(fname);
}
void close_library(const char* fname, __DYNMOD handle) {
(void)fname;
(void)handle;
}
#else
#include <dlfcn.h>
#define __DYNMOD void*
#define __DYNSYM void*
#define __LOADSYM dlsym
void log_dlerror() {
log_err("dynlibmod: %s", dlerror());
}
void* open_library(const char* fname) {
return dlopen(fname, RTLD_LAZY | RTLD_GLOBAL);
}
void close_library(const char* fname, __DYNMOD handle) {
if(!handle) return;
if(dlclose(handle) != 0) {
log_err("dlclose %s: %s", fname, strerror(errno));
}
}
#endif
/** module counter for multiple dynlib modules */
static int dynlib_mod_count = 0;
/** dynlib module init */
int dynlibmod_init(struct module_env* env, int id) {
int dynlib_mod_idx = dynlib_mod_count++;
struct config_strlist* cfg_item = env->cfg->dynlib_file;
struct dynlibmod_env* de = (struct dynlibmod_env*)calloc(1, sizeof(struct dynlibmod_env));
__DYNMOD dynamic_library;
if (!de)
{
log_err("dynlibmod[%d]: malloc failure", dynlib_mod_idx);
return 0;
}
env->modinfo[id] = (void*) de;
de->fname = NULL;
for(int i = dynlib_mod_idx;
i != 0 && cfg_item != NULL;
i--, cfg_item = cfg_item->next) {}
if (cfg_item == NULL || cfg_item->str == NULL || cfg_item->str[0] == 0) {
log_err("dynlibmod[%d]: no dynamic library given.", dynlib_mod_idx);
return 0;
} else {
de->fname = cfg_item->str;
}
verbose(VERB_ALGO, "dynlibmod[%d]: Trying to load library %s", dynlib_mod_idx, de->fname);
dynamic_library = open_library(de->fname);
de->dynamic_library = (void*)dynamic_library;
if (dynamic_library == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
__DYNSYM initializer;
__DYNSYM deinitializer;
__DYNSYM operate;
__DYNSYM inform;
__DYNSYM clear;
__DYNSYM get_mem;
initializer = __LOADSYM(dynamic_library,"init");
if (initializer == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load init procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_init = (func_init_t)(void*)initializer;
}
deinitializer = __LOADSYM(dynamic_library,"deinit");
if (deinitializer == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load deinit procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_deinit = (func_deinit_t)(void*)deinitializer;
}
operate = __LOADSYM(dynamic_library,"operate");
if (operate == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load operate procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_operate = (func_operate_t)(void*)operate;
}
inform = __LOADSYM(dynamic_library,"inform_super");
if (inform == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load inform_super procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_inform = (func_inform_t)(void*)inform;
}
clear = __LOADSYM(dynamic_library,"clear");
if (clear == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load clear procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_clear = (func_clear_t)(void*)clear;
}
get_mem = __LOADSYM(dynamic_library,"get_mem");
if (get_mem == NULL) {
log_dlerror();
log_err("dynlibmod[%d]: unable to load get_mem procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
return 0;
} else {
de->func_get_mem = (func_get_mem_t)(void*)get_mem;
}
}
de->inplace_cb_delete_wrapped = &inplace_cb_delete_wrapped;
de->inplace_cb_register_wrapped = &inplace_cb_register_wrapped;
return de->func_init(env, id);
}
/** dynlib module deinit */
void dynlibmod_deinit(struct module_env* env, int id) {
struct dynlibmod_env* de = env->modinfo[id];
if(de == NULL)
return;
de->func_deinit(env, id);
close_library(de->fname, (__DYNMOD)de->dynamic_library);
dynlib_mod_count--;
de->fname = NULL;
free(de);
}
/** dynlib module operate on a query */
void dynlibmod_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* outbound) {
struct dynlibmod_env* de = qstate->env->modinfo[id];
de->func_operate(qstate, event, id, outbound);
}
/** dynlib module */
void dynlibmod_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super) {
struct dynlibmod_env* de = qstate->env->modinfo[id];
de->func_inform(qstate, id, super);
}
/** dynlib module cleanup query state */
void dynlibmod_clear(struct module_qstate* qstate, int id) {
struct dynlibmod_env* de = qstate->env->modinfo[id];
de->func_clear(qstate, id);
}
/** dynlib module alloc size routine */
size_t dynlibmod_get_mem(struct module_env* env, int id) {
struct dynlibmod_env* de = (struct dynlibmod_env*)env->modinfo[id];
size_t size;
verbose(VERB_ALGO, "dynlibmod: get_mem, id: %d, de:%p", id, de);
if(!de)
return 0;
size = de->func_get_mem(env, id);
return size + sizeof(*de);
}
int dynlib_inplace_cb_reply_generic(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out,
struct comm_reply* repinfo, struct regional* region, int id,
void* callback) {
struct cb_pair* cb_pair = (struct cb_pair*) callback;
return ((inplace_cb_reply_func_type*) cb_pair->cb)(qinfo, qstate, rep, rcode, edns, opt_list_out, repinfo, region, id, cb_pair->cb_arg);
}
int dynlib_inplace_cb_query_generic(struct query_info* qinfo, uint16_t flags,
struct module_qstate* qstate, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* zone, size_t zonelen, struct regional* region,
int id, void* callback) {
struct cb_pair* cb_pair = (struct cb_pair*) callback;
return ((inplace_cb_query_func_type*) cb_pair->cb)(qinfo, flags, qstate, addr, addrlen, zone, zonelen, region, id, cb_pair->cb_arg);
}
int dynlib_inplace_cb_edns_back_parsed(struct module_qstate* qstate,
int id, void* cb_args) {
struct cb_pair* cb_pair = (struct cb_pair*) cb_args;
return ((inplace_cb_edns_back_parsed_func_type*) cb_pair->cb)(qstate, id, cb_pair->cb_arg);
}
int dynlib_inplace_cb_query_response(struct module_qstate* qstate,
struct dns_msg* response, int id, void* cb_args) {
struct cb_pair* cb_pair = (struct cb_pair*) cb_args;
return ((inplace_cb_query_response_func_type*) cb_pair->cb)(qstate, response, id, cb_pair->cb_arg);
}
int
inplace_cb_register_wrapped(void* cb, enum inplace_cb_list_type type, void* cbarg,
struct module_env* env, int id) {
struct cb_pair* cb_pair = malloc(sizeof(struct cb_pair));
cb_pair->cb = cb;
cb_pair->cb_arg = cbarg;
if(type >= inplace_cb_reply && type <= inplace_cb_reply_servfail) {
return inplace_cb_register(&dynlib_inplace_cb_reply_generic, type, (void*) cb_pair, env, id);
} else if(type == inplace_cb_query) {
return inplace_cb_register(&dynlib_inplace_cb_query_generic, type, (void*) cb_pair, env, id);
} else if(type == inplace_cb_query_response) {
return inplace_cb_register(&dynlib_inplace_cb_query_response, type, (void*) cb_pair, env, id);
} else if(type == inplace_cb_edns_back_parsed) {
return inplace_cb_register(&dynlib_inplace_cb_edns_back_parsed, type, (void*) cb_pair, env, id);
} else {
return 0;
}
}
void
inplace_cb_delete_wrapped(struct module_env* env, enum inplace_cb_list_type type,
int id) {
struct inplace_cb* temp = env->inplace_cb_lists[type];
struct inplace_cb* prev = NULL;
while(temp) {
if(temp->id == id) {
if(!prev) {
env->inplace_cb_lists[type] = temp->next;
free(temp->cb_arg);
free(temp);
temp = env->inplace_cb_lists[type];
}
else {
prev->next = temp->next;
free(temp->cb_arg);
free(temp);
temp = prev->next;
}
}
else {
prev = temp;
temp = temp->next;
}
}
}
/**
* The module function block
*/
static struct module_func_block dynlibmod_block = {
"dynlib",
&dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate, &dynlibmod_inform_super,
&dynlibmod_clear, &dynlibmod_get_mem
};
struct module_func_block* dynlibmod_get_funcblock(void)
{
return &dynlibmod_block;
}

139
dynlibmod/dynlibmod.h Normal file
View File

@ -0,0 +1,139 @@
/*
* dynlibmod.h: module header file
*
* Copyright (c) 2019, Peter Munch-Ellingsen (peterme AT peterme.net)
*
* This software is open source.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the organization nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
* Dynamic loading module for unbound. Loads dynamic library.
*/
#ifndef DYNLIBMOD_H
#define DYNLIBMOD_H
#include "util/module.h"
#include "services/outbound_list.h"
/**
* Get the module function block.
* @return: function block with function pointers to module methods.
*/
struct module_func_block* dynlibmod_get_funcblock(void);
/** dynlib module init */
int dynlibmod_init(struct module_env* env, int id);
/** dynlib module deinit */
void dynlibmod_deinit(struct module_env* env, int id);
/** dynlib module operate on a query */
void dynlibmod_operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* outbound);
/** dynlib module */
void dynlibmod_inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super);
/** dynlib module cleanup query state */
void dynlibmod_clear(struct module_qstate* qstate, int id);
/** dynlib module alloc size routine */
size_t dynlibmod_get_mem(struct module_env* env, int id);
int dynlib_inplace_cb_reply_generic(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out,
struct comm_reply* repinfo, struct regional* region, int id,
void* callback);
int dynlib_inplace_cb_query_generic(struct query_info* qinfo, uint16_t flags,
struct module_qstate* qstate, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* zone, size_t zonelen, struct regional* region,
int id, void* callback);
int dynlib_inplace_cb_edns_back_parsed(struct module_qstate* qstate,
int id, void* cb_args);
int dynlib_inplace_cb_query_response(struct module_qstate* qstate,
struct dns_msg* response, int id, void* cb_args);
int
inplace_cb_register_wrapped(void* cb, enum inplace_cb_list_type type, void* cbarg,
struct module_env* env, int id);
void
inplace_cb_delete_wrapped(struct module_env* env, enum inplace_cb_list_type type,
int id);
struct cb_pair {
void *cb;
void *cb_arg;
};
/**
* Global state for the module.
*/
typedef int (*func_init_t)(struct module_env*, int);
typedef void (*func_deinit_t)(struct module_env*, int);
typedef void (*func_operate_t)(struct module_qstate*, enum module_ev, int, struct outbound_entry*);
typedef void (*func_inform_t)(struct module_qstate*, int, struct module_qstate*);
typedef void (*func_clear_t)(struct module_qstate*, int);
typedef size_t (*func_get_mem_t)(struct module_env*, int);
typedef void (*inplace_cb_delete_wrapped_t)(struct module_env*, enum inplace_cb_list_type, int);
typedef int (*inplace_cb_register_wrapped_t)(void*, enum inplace_cb_list_type, void*, struct module_env*, int);
struct dynlibmod_env {
/** Dynamic library filename. */
const char* fname;
/** dynamic library handle */
void* dynamic_library;
/** Module init function */
func_init_t func_init;
/** Module deinit function */
func_deinit_t func_deinit;
/** Module operate function */
func_operate_t func_operate;
/** Module super_inform function */
func_inform_t func_inform;
/** Module clear function */
func_clear_t func_clear;
/** Module get_mem function */
func_get_mem_t func_get_mem;
/** Wrapped inplace callback functions to circumvent callback whitelisting */
inplace_cb_delete_wrapped_t inplace_cb_delete_wrapped;
inplace_cb_register_wrapped_t inplace_cb_register_wrapped;
/** Pointer to any data the dynamic library might want to keep */
void *dyn_env;
};
#endif /* DYNLIBMOD_H */

View File

@ -0,0 +1,130 @@
/**
* \file
*
* This is an example to show how dynamic libraries can be made to work with
* unbound. To build a .so file simply run:
* gcc -I../.. -shared -Wall -Werror -fpic -o helloworld.so helloworld.c
* And to build for windows, first make unbound with the --with-dynlibmod
* switch, then use this command:
* x86_64-w64-mingw32-gcc -m64 -I../.. -shared -Wall -Werror -fpic
* -o helloworld.dll helloworld.c -L../.. -l:libunbound.a
* to cross-compile a 64-bit Windows DLL.
*/
#include "../../config.h"
#include "../../util/module.h"
#include "../../sldns/parseutil.h"
#include "../dynlibmod.h"
/* Declare the EXPORT macro that expands to exporting the symbol for DLLs when
* compiling for Windows. All procedures marked with EXPORT in this example are
* called directly by the dynlib module and must be present for the module to
* load correctly. */
#ifdef HAVE_WINDOWS_H
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
/* Forward declare a callback, implemented at the bottom of this file */
int reply_callback(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out,
struct comm_reply* repinfo, struct regional* region, int id,
void* callback);
/* Init is called when the module is first loaded. It should be used to set up
* the environment for this module and do any other initialisation required. */
EXPORT int init(struct module_env* env, int id) {
log_info("dynlib: hello world from init");
struct dynlibmod_env* de = (struct dynlibmod_env*) env->modinfo[id];
de->inplace_cb_register_wrapped(&reply_callback,
inplace_cb_reply,
NULL, env, id);
struct dynlibmod_env* local_env = env->modinfo[id];
local_env->dyn_env = NULL;
return 1;
}
/* Deinit is run as the program is shutting down. It should be used to clean up
* the environment and any left over data. */
EXPORT void deinit(struct module_env* env, int id) {
log_info("dynlib: hello world from deinit");
struct dynlibmod_env* de = (struct dynlibmod_env*) env->modinfo[id];
de->inplace_cb_delete_wrapped(env, inplace_cb_reply, id);
if (de->dyn_env != NULL) free(de->dyn_env);
}
/* Operate is called every time a query passes by this module. The event can be
* used to determine which direction in the module chain it came from. */
EXPORT void operate(struct module_qstate* qstate, enum module_ev event,
int id, struct outbound_entry* entry) {
log_info("dynlib: hello world from operate");
log_info("dynlib: incoming query: %s %s(%d) %s(%d)",
qstate->qinfo.qname,
sldns_lookup_by_id(sldns_rr_classes, qstate->qinfo.qclass)->name,
qstate->qinfo.qclass,
sldns_rr_descript(qstate->qinfo.qtype)->_name,
qstate->qinfo.qtype);
if (event == module_event_new || event == module_event_pass) {
qstate->ext_state[id] = module_wait_module;
struct dynlibmod_env* env = qstate->env->modinfo[id];
if (env->dyn_env == NULL) {
env->dyn_env = calloc(3, sizeof(int));
((int *)env->dyn_env)[0] = 42;
((int *)env->dyn_env)[1] = 102;
((int *)env->dyn_env)[2] = 192;
} else {
log_err("dynlib: already has data!");
qstate->ext_state[id] = module_error;
}
} else if (event == module_event_moddone) {
qstate->ext_state[id] = module_finished;
} else {
qstate->ext_state[id] = module_error;
}
}
/* Inform super is called when a query is completed or errors out, but only if
* a sub-query has been registered to it by this module. Look at
* mesh_attach_sub in services/mesh.h to see how this is done. */
EXPORT void inform_super(struct module_qstate* qstate, int id,
struct module_qstate* super) {
log_info("dynlib: hello world from inform_super");
}
/* Clear is called once a query is complete and the response has been sent
* back. It is used to clear up any per-query allocations. */
EXPORT void clear(struct module_qstate* qstate, int id) {
log_info("dynlib: hello world from clear");
struct dynlibmod_env* env = qstate->env->modinfo[id];
if (env->dyn_env != NULL) {
free(env->dyn_env);
env->dyn_env = NULL;
}
}
/* Get mem is called when Unbound is printing performance information. This
* only happens explicitly and is only used to show memory usage to the user. */
EXPORT size_t get_mem(struct module_env* env, int id) {
log_info("dynlib: hello world from get_mem");
return 0;
}
/* The callback that was forward declared earlier. It is registered in the init
* procedure to run when a query is being replied to. */
int reply_callback(struct query_info* qinfo,
struct module_qstate* qstate, struct reply_info* rep, int rcode,
struct edns_data* edns, struct edns_option** opt_list_out,
struct comm_reply* repinfo, struct regional* region, int id,
void* callback) {
log_info("dynlib: hello world from callback");
struct dynlibmod_env* env = qstate->env->modinfo[id];
if (env->dyn_env != NULL) {
log_info("dynlib: numbers gotten from query: %d, %d, and %d",
((int *)env->dyn_env)[0],
((int *)env->dyn_env)[1],
((int *)env->dyn_env)[2]);
}
return 0;
}

View File

@ -386,8 +386,7 @@ update_cache(struct module_qstate *qstate, int id)
rep->flags |= (BIT_RA | BIT_QR); /* fix flags to be sensible for */
rep->flags &= ~(BIT_AA | BIT_CD);/* a reply based on the cache */
addrtree_insert(tree, (addrkey_t*)edns->subnet_addr,
edns->subnet_source_mask,
sq->ecs_server_in.subnet_scope_mask, rep,
edns->subnet_source_mask, sq->max_scope, rep,
rep->ttl, *qstate->env->now);
lock_rw_unlock(&lru_entry->lock);
@ -543,7 +542,7 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
c_out->subnet_addr_fam = c_in->subnet_addr_fam;
c_out->subnet_source_mask = c_in->subnet_source_mask;
memcpy(&c_out->subnet_addr, &c_in->subnet_addr, INET6_SIZE);
c_out->subnet_scope_mask = s_in->subnet_scope_mask;
c_out->subnet_scope_mask = sq->max_scope;
/* Limit scope returned to client to scope used for caching. */
if(c_out->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4) {
if(c_out->subnet_scope_mask >
@ -648,6 +647,19 @@ ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
qstate->env->cfg->client_subnet_opcode);
sq->subnet_sent = 0;
memset(&sq->ecs_server_out, 0, sizeof(sq->ecs_server_out));
} else if (!sq->track_max_scope &&
FLAGS_GET_RCODE(response->rep->flags) == LDNS_RCODE_NOERROR &&
response->rep->an_numrrsets > 0
) {
struct ub_packed_rrset_key* s = response->rep->rrsets[0];
if(ntohs(s->rk.type) == LDNS_RR_TYPE_CNAME &&
query_dname_compare(qstate->qinfo.qname,
s->rk.dname) == 0) {
/* CNAME response for QNAME. From now on keep track of
* longest received ECS prefix for all queries on this
* qstate. */
sq->track_max_scope = 1;
}
}
return 1;
}
@ -663,16 +675,19 @@ ecs_edns_back_parsed(struct module_qstate* qstate, int id,
return 1;
if((ecs_opt = edns_opt_list_find(
qstate->edns_opts_back_in,
qstate->env->cfg->client_subnet_opcode))) {
if(parse_subnet_option(ecs_opt, &sq->ecs_server_in) &&
sq->subnet_sent &&
sq->ecs_server_in.subnet_validdata)
qstate->env->cfg->client_subnet_opcode)) &&
parse_subnet_option(ecs_opt, &sq->ecs_server_in) &&
sq->subnet_sent && sq->ecs_server_in.subnet_validdata) {
/* Only skip global cache store if we sent an ECS option
* and received one back. Answers from non-whitelisted
* servers will end up in global cache. Answers for
* queries with 0 source will not (unless nameserver
* does not support ECS). */
qstate->no_cache_store = 1;
if(!sq->track_max_scope || (sq->track_max_scope &&
sq->ecs_server_in.subnet_scope_mask >
sq->max_scope))
sq->max_scope = sq->ecs_server_in.subnet_scope_mask;
}
return 1;

View File

@ -45,6 +45,7 @@
#include "util/alloc.h"
#include "util/net_help.h"
#include "util/storage/slabhash.h"
#include "util/data/dname.h"
#include "edns-subnet/addrtree.h"
#include "edns-subnet/edns-subnet.h"
@ -83,6 +84,12 @@ struct subnet_qstate {
struct ecs_data ecs_server_out;
int subnet_downstream;
int subnet_sent;
/** keep track of longest received scope, set after receiving CNAME for
* incoming QNAME. */
int track_max_scope;
/** longest received scope mask since track_max_scope is set. This value
* is used for caching and answereing to client. */
uint8_t max_scope;
/** has the subnet module been started with no_cache_store? */
int started_no_cache_store;
};

View File

@ -484,6 +484,63 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
got_num = num4ok;
*selected_rtt = num4_lowrtt;
}
} else if (env->cfg->prefer_ip4) {
int got_num4 = 0;
int low_rtt4 = 0;
int i;
int attempt = -1; /* filter to make sure addresses have
less attempts on them than the first, to force round
robin when all the IPv4 addresses fail */
int num6ok = 0; /* number ip6 at low attempt count */
int num6_lowrtt = 0;
prev = NULL;
a = dp->result_list;
for(i = 0; i < got_num; i++) {
swap_to_front = 0;
if(a->addr.ss_family != AF_INET && attempt == -1) {
/* if we only have ip6 at low attempt count,
* then ip4 is failing, and we need to
* select one of the remaining IPv6 addrs */
attempt = a->attempts;
num6ok++;
num6_lowrtt = a->sel_rtt;
} else if(a->addr.ss_family != AF_INET && attempt == a->attempts) {
num6ok++;
if(num6_lowrtt == 0 || a->sel_rtt < num6_lowrtt) {
num6_lowrtt = a->sel_rtt;
}
}
if(a->addr.ss_family == AF_INET) {
if(attempt == -1) {
attempt = a->attempts;
} else if(a->attempts > attempt) {
break;
}
got_num4++;
swap_to_front = 1;
if(low_rtt4 == 0 || a->sel_rtt < low_rtt4) {
low_rtt4 = a->sel_rtt;
}
}
/* swap to front if IPv4, or move to next result */
if(swap_to_front && prev) {
n = a->next_result;
prev->next_result = n;
a->next_result = dp->result_list;
dp->result_list = a;
a = n;
} else {
prev = a;
a = a->next_result;
}
}
if(got_num4 > 0) {
got_num = got_num4;
*selected_rtt = low_rtt4;
} else if(num6ok > 0) {
got_num = num6ok;
*selected_rtt = num6_lowrtt;
}
}
return got_num;
}

View File

@ -162,7 +162,7 @@ iter_new(struct module_qstate* qstate, int id)
iq->qchase = qstate->qinfo;
outbound_list_init(&iq->outlist);
iq->minimise_count = 0;
iq->minimise_timeout_count = 0;
iq->timeout_count = 0;
if (qstate->env->cfg->qname_minimisation)
iq->minimisation_state = INIT_MINIMISE_STATE;
else
@ -2239,7 +2239,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->qinfo_out.qname = iq->qchase.qname;
iq->qinfo_out.qname_len = iq->qchase.qname_len;
iq->minimise_count++;
iq->minimise_timeout_count = 0;
iq->timeout_count = 0;
iter_dec_attempts(iq->dp, 1);
@ -2327,7 +2327,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
}
}
if(iq->minimisation_state == SKIP_MINIMISE_STATE) {
if(iq->minimise_timeout_count < MAX_MINIMISE_TIMEOUT_COUNT)
if(iq->timeout_count < MAX_MINIMISE_TIMEOUT_COUNT)
/* Do not increment qname, continue incrementing next
* iteration */
iq->minimisation_state = MINIMISE_STATE;
@ -2668,14 +2668,15 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
if(iq->response == NULL) {
/* Don't increment qname when QNAME minimisation is enabled */
if(qstate->env->cfg->qname_minimisation) {
iq->minimise_timeout_count++;
iq->minimisation_state = SKIP_MINIMISE_STATE;
}
iq->timeout_count++;
iq->chase_to_rd = 0;
iq->dnssec_lame_query = 0;
verbose(VERB_ALGO, "query response was timeout");
return next_state(iq, QUERYTARGETS_STATE);
}
iq->timeout_count = 0;
type = response_type_from_server(
(int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd),
iq->response, &iq->qinfo_out, iq->dp);
@ -3690,7 +3691,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
iq->response = NULL;
iq->state = QUERY_RESP_STATE;
if(event == module_event_noreply || event == module_event_error) {
if(event == module_event_noreply && iq->sent_count >= 3 &&
if(event == module_event_noreply && iq->timeout_count >= 3 &&
qstate->env->cfg->use_caps_bits_for_id &&
!iq->caps_fallback && !is_caps_whitelisted(ie, iq)) {
/* start fallback */

View File

@ -398,8 +398,9 @@ struct iter_qstate {
/**
* Count number of time-outs. Used to prevent resolving failures when
* the QNAME minimisation QTYPE is blocked. */
int minimise_timeout_count;
* the QNAME minimisation QTYPE is blocked. Used to determine if
* capsforid fallback should be started.*/
int timeout_count;
/** True if the current response is from auth_zone */
int auth_zone_response;

View File

@ -74,6 +74,14 @@
#include "sldns/sbuffer.h"
#include "sldns/str2wire.h"
#ifdef HAVE_TARGETCONDITIONALS_H
#include <TargetConditionals.h>
#endif
#if defined(TARGET_OS_TV) || defined(TARGET_OS_WATCH)
#undef HAVE_FORK
#endif
/** handle new query command for bg worker */
static void handle_newq(struct libworker* w, uint8_t* buf, uint32_t len);
@ -225,12 +233,12 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
w->back = outside_network_create(w->base, cfg->msg_buffer_size,
(size_t)cfg->outgoing_num_ports, cfg->out_ifs,
cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6,
cfg->do_tcp?cfg->outgoing_num_tcp:0,
cfg->do_tcp?cfg->outgoing_num_tcp:0, cfg->ip_dscp,
w->env->infra_cache, w->env->rnd, cfg->use_caps_bits_for_id,
ports, numports, cfg->unwanted_threshold,
cfg->outgoing_tcp_mss, &libworker_alloc_cleanup, w,
cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx,
cfg->delay_close, NULL);
cfg->delay_close, cfg->tls_use_sni, NULL);
w->env->outnet = w->back;
if(!w->is_bg || w->is_bg_thread) {
lock_basic_unlock(&ctx->cfglock);
@ -1047,3 +1055,19 @@ wsvc_cron_cb(void* ATTR_UNUSED(arg))
log_assert(0);
}
#endif /* UB_ON_WINDOWS */
#ifdef USE_DNSTAP
void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
#ifdef USE_DNSTAP
void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif

View File

@ -642,6 +642,7 @@ struct ub_shm_stat_info {
long long respip;
long long dnscrypt_shared_secret;
long long dnscrypt_nonce;
long long dynlib;
} mem;
};

View File

@ -502,10 +502,16 @@ copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region)
ck->entry.hash = key->entry.hash;
ck->entry.key = ck;
ck->rk = key->rk;
ck->rk.dname = regional_alloc_init(region, key->rk.dname,
key->rk.dname_len);
if(!ck->rk.dname)
return NULL;
if(key->rk.dname) {
ck->rk.dname = regional_alloc_init(region, key->rk.dname,
key->rk.dname_len);
if(!ck->rk.dname)
return NULL;
ck->rk.dname_len = key->rk.dname_len;
} else {
ck->rk.dname = NULL;
ck->rk.dname_len = 0;
}
if((unsigned)data->count >= 0xffff00U)
return NULL; /* guard against integer overflow in dsize */
@ -908,6 +914,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
int ret = 1;
struct ub_packed_rrset_key* redirect_rrset = NULL;
struct rpz* r;
struct auth_zone* a;
struct ub_packed_rrset_key* data = NULL;
int rpz_used = 0;
int rpz_log = 0;
@ -949,6 +956,10 @@ respip_rewrite_reply(const struct query_info* qinfo,
}
if(!raddr && !view->isfirst)
goto done;
if(!raddr && view->isfirst) {
lock_rw_unlock(&view->lock);
view = NULL;
}
}
if(!raddr && (raddr = respip_addr_lookup(rep, ipset,
&rrset_id))) {
@ -959,7 +970,9 @@ respip_rewrite_reply(const struct query_info* qinfo,
ipset->tagname, ipset->num_tags);
}
lock_rw_rdlock(&az->rpz_lock);
for(r = az->rpz_first; r && !raddr; r = r->next) {
for(a = az->rpz_first; a && !raddr; a = a->rpz_az_next) {
lock_rw_rdlock(&a->lock);
r = a->rpz;
if(!r->taglist || taglist_intersect(r->taglist,
r->taglistlen, ctaglist, ctaglen)) {
if((raddr = respip_addr_lookup(rep,
@ -969,16 +982,21 @@ respip_rewrite_reply(const struct query_info* qinfo,
region, &rpz_used)) {
log_err("out of memory");
lock_rw_unlock(&raddr->lock);
lock_rw_unlock(&a->lock);
lock_rw_unlock(&az->rpz_lock);
return 0;
}
if(!rpz_used) {
lock_rw_unlock(&raddr->lock);
raddr = NULL;
actinfo->rpz_disabled++;
if(rpz_used) {
/* break to make sure 'a' stays pointed
* to used auth_zone, and keeps lock */
break;
}
lock_rw_unlock(&raddr->lock);
raddr = NULL;
actinfo->rpz_disabled++;
}
}
}
lock_rw_unlock(&a->lock);
}
lock_rw_unlock(&az->rpz_lock);
if(raddr && !search_only) {
@ -1032,6 +1050,9 @@ respip_rewrite_reply(const struct query_info* qinfo,
if(raddr) {
lock_rw_unlock(&raddr->lock);
}
if(rpz_used) {
lock_rw_unlock(&a->lock);
}
return ret;
}

View File

@ -392,12 +392,12 @@ auth_zone_delete(struct auth_zone* z, struct auth_zones* az)
if(az && z->rpz) {
/* keep RPZ linked list intact */
lock_rw_wrlock(&az->rpz_lock);
if(z->rpz->prev)
z->rpz->prev->next = z->rpz->next;
if(z->rpz_az_prev)
z->rpz_az_prev->rpz_az_next = z->rpz_az_next;
else
az->rpz_first = z->rpz->next;
if(z->rpz->next)
z->rpz->next->prev = z->rpz->prev;
az->rpz_first = z->rpz_az_next;
if(z->rpz_az_next)
z->rpz_az_next->rpz_az_prev = z->rpz_az_prev;
lock_rw_unlock(&az->rpz_lock);
}
if(z->rpz)
@ -426,9 +426,11 @@ auth_zone_create(struct auth_zones* az, uint8_t* nm, size_t nmlen,
}
rbtree_init(&z->data, &auth_data_cmp);
lock_rw_init(&z->lock);
lock_protect(&z->lock, &z->name, sizeof(*z)-sizeof(rbnode_type));
lock_protect(&z->lock, &z->name, sizeof(*z)-sizeof(rbnode_type)-
sizeof(&z->rpz_az_next)-sizeof(&z->rpz_az_prev));
lock_rw_wrlock(&z->lock);
/* z lock protects all, except rbtree itself, which is az->lock */
/* z lock protects all, except rbtree itself and the rpz linked list
* pointers, which are protected using az->lock */
if(!rbtree_insert(&az->ztree, &z->node)) {
lock_rw_unlock(&z->lock);
auth_zone_delete(z, NULL);
@ -1178,9 +1180,9 @@ az_insert_rr(struct auth_zone* z, uint8_t* rr, size_t rr_len,
return 0;
}
if(z->rpz) {
if(!(rpz_insert_rr(z->rpz, z->namelen, dname, dname_len,
rr_type, rr_class, rr_ttl, rdata, rdatalen, rr,
rr_len)))
if(!(rpz_insert_rr(z->rpz, z->name, z->namelen, dname,
dname_len, rr_type, rr_class, rr_ttl, rdata, rdatalen,
rr, rr_len)))
return 0;
}
return 1;
@ -1864,15 +1866,26 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
struct auth_xfer* x = NULL;
/* create zone */
if(c->isrpz) {
/* if the rpz lock is needed, grab it before the other
* locks to avoid a lock dependency cycle */
lock_rw_wrlock(&az->rpz_lock);
}
lock_rw_wrlock(&az->lock);
if(!(z=auth_zones_find_or_add_zone(az, c->name))) {
lock_rw_unlock(&az->lock);
if(c->isrpz) {
lock_rw_unlock(&az->rpz_lock);
}
return 0;
}
if(c->masters || c->urls) {
if(!(x=auth_zones_find_or_add_xfer(az, z))) {
lock_rw_unlock(&az->lock);
lock_rw_unlock(&z->lock);
if(c->isrpz) {
lock_rw_unlock(&az->rpz_lock);
}
return 0;
}
}
@ -1887,6 +1900,9 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
lock_basic_unlock(&x->lock);
}
lock_rw_unlock(&z->lock);
if(c->isrpz) {
lock_rw_unlock(&az->rpz_lock);
}
return 0;
}
z->for_downstream = c->for_downstream;
@ -1897,11 +1913,14 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
fatal_exit("Could not setup RPZ zones");
return 0;
}
lock_rw_wrlock(&az->rpz_lock);
z->rpz->next = az->rpz_first;
lock_protect(&z->lock, &z->rpz->local_zones, sizeof(*z->rpz));
/* the az->rpz_lock is locked above */
z->rpz_az_next = az->rpz_first;
if(az->rpz_first)
az->rpz_first->prev = z->rpz;
az->rpz_first = z->rpz;
az->rpz_first->rpz_az_prev = z;
az->rpz_first = z;
}
if(c->isrpz) {
lock_rw_unlock(&az->rpz_lock);
}
@ -5331,7 +5350,7 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
log_assert(xfr->task_transfer);
lock_basic_lock(&xfr->lock);
env = xfr->task_transfer->env;
if(env->outnet->want_to_quit) {
if(!env || env->outnet->want_to_quit) {
lock_basic_unlock(&xfr->lock);
return; /* stop on quit */
}
@ -5770,7 +5789,7 @@ auth_xfer_transfer_timer_callback(void* arg)
log_assert(xfr->task_transfer);
lock_basic_lock(&xfr->lock);
env = xfr->task_transfer->env;
if(env->outnet->want_to_quit) {
if(!env || env->outnet->want_to_quit) {
lock_basic_unlock(&xfr->lock);
return; /* stop on quit */
}
@ -5812,7 +5831,7 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
log_assert(xfr->task_transfer);
lock_basic_lock(&xfr->lock);
env = xfr->task_transfer->env;
if(env->outnet->want_to_quit) {
if(!env || env->outnet->want_to_quit) {
lock_basic_unlock(&xfr->lock);
return 0; /* stop on quit */
}
@ -5893,7 +5912,7 @@ auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err,
log_assert(xfr->task_transfer);
lock_basic_lock(&xfr->lock);
env = xfr->task_transfer->env;
if(env->outnet->want_to_quit) {
if(!env || env->outnet->want_to_quit) {
lock_basic_unlock(&xfr->lock);
return 0; /* stop on quit */
}
@ -6107,7 +6126,7 @@ auth_xfer_probe_timer_callback(void* arg)
log_assert(xfr->task_probe);
lock_basic_lock(&xfr->lock);
env = xfr->task_probe->env;
if(env->outnet->want_to_quit) {
if(!env || env->outnet->want_to_quit) {
lock_basic_unlock(&xfr->lock);
return; /* stop on quit */
}
@ -6143,7 +6162,7 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
log_assert(xfr->task_probe);
lock_basic_lock(&xfr->lock);
env = xfr->task_probe->env;
if(env->outnet->want_to_quit) {
if(!env || env->outnet->want_to_quit) {
lock_basic_unlock(&xfr->lock);
return 0; /* stop on quit */
}
@ -6388,7 +6407,7 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
log_assert(xfr->task_probe);
lock_basic_lock(&xfr->lock);
env = xfr->task_probe->env;
if(env->outnet->want_to_quit) {
if(!env || env->outnet->want_to_quit) {
lock_basic_unlock(&xfr->lock);
return; /* stop on quit */
}
@ -6465,7 +6484,7 @@ auth_xfer_timer(void* arg)
log_assert(xfr->task_nextprobe);
lock_basic_lock(&xfr->lock);
env = xfr->task_nextprobe->env;
if(env->outnet->want_to_quit) {
if(!env || env->outnet->want_to_quit) {
lock_basic_unlock(&xfr->lock);
return; /* stop on quit */
}

View File

@ -82,8 +82,8 @@ struct auth_zones {
size_t num_query_up;
/** number of queries downstream */
size_t num_query_down;
/** first rpz item in linked list */
struct rpz* rpz_first;
/** first auth zone containing rpz item in linked list */
struct auth_zone* rpz_first;
/** rw lock for rpz linked list, needed when iterating or editing linked
* list. */
lock_rw_type rpz_lock;
@ -138,6 +138,11 @@ struct auth_zone {
int zone_deleted;
/** deletelist pointer, unused normally except during delete */
struct auth_zone* delete_next;
/* not protected by auth_zone lock, must be last items in struct */
/** next auth zone containing RPZ data, or NULL */
struct auth_zone* rpz_az_next;
/** previous auth zone containing RPZ data, or NULL */
struct auth_zone* rpz_az_prev;
};
/**

View File

@ -179,9 +179,10 @@ int
create_udp_sock(int family, int socktype, struct sockaddr* addr,
socklen_t addrlen, int v6only, int* inuse, int* noproto,
int rcv, int snd, int listen, int* reuseport, int transparent,
int freebind, int use_systemd)
int freebind, int use_systemd, int dscp)
{
int s;
char* err;
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_USE_MIN_MTU) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined (SO_BINDANY)
int on=1;
#endif
@ -451,6 +452,9 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
# endif
#endif /* SO_SNDBUF */
}
err = set_ip_dscp(s, family, dscp);
if(err != NULL)
log_warn("error setting IP DiffServ codepoint %d on UDP socket: %s", dscp, err);
if(family == AF_INET6) {
# if defined(IPV6_V6ONLY)
if(v6only) {
@ -638,9 +642,10 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
int
create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
int* reuseport, int transparent, int mss, int freebind, int use_systemd)
int* reuseport, int transparent, int mss, int freebind, int use_systemd, int dscp)
{
int s;
char* err;
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined(SO_BINDANY)
int on = 1;
#endif
@ -793,6 +798,9 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
strerror(errno));
}
#endif /* IP_TRANSPARENT || IP_BINDANY || SO_BINDANY */
err = set_ip_dscp(s, addr->ai_family, dscp);
if(err != NULL)
log_warn("error setting IP DiffServ codepoint %d on TCP socket: %s", dscp, err);
if(
#ifdef HAVE_SYSTEMD
!got_fd_from_systemd &&
@ -866,6 +874,55 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
return s;
}
char*
set_ip_dscp(int socket, int addrfamily, int dscp)
{
int ds;
if(dscp == 0)
return NULL;
ds = dscp << 2;
switch(addrfamily) {
case AF_INET6:
if(setsockopt(socket, IPPROTO_IPV6, IPV6_TCLASS, (void*)&ds, sizeof(ds)) < 0)
return sock_strerror(errno);
break;
default:
if(setsockopt(socket, IPPROTO_IP, IP_TOS, (void*)&ds, sizeof(ds)) < 0)
return sock_strerror(errno);
break;
}
return NULL;
}
# ifndef USE_WINSOCK
char*
sock_strerror(int errn)
{
return strerror(errn);
}
void
sock_close(int socket)
{
close(socket);
}
# else
char*
sock_strerror(int ATTR_UNUSED(errn))
{
return wsa_strerror(WSAGetLastError());
}
void
sock_close(int socket)
{
closesocket(socket);
}
# endif /* USE_WINSOCK */
int
create_local_accept_sock(const char *path, int* noproto, int use_systemd)
{
@ -952,7 +1009,7 @@ create_local_accept_sock(const char *path, int* noproto, int use_systemd)
static int
make_sock(int stype, const char* ifname, const char* port,
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd)
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd, int dscp)
{
struct addrinfo *res = NULL;
int r, s, inuse, noproto;
@ -980,7 +1037,7 @@ make_sock(int stype, const char* ifname, const char* port,
s = create_udp_sock(res->ai_family, res->ai_socktype,
(struct sockaddr*)res->ai_addr, res->ai_addrlen,
v6only, &inuse, &noproto, (int)rcv, (int)snd, 1,
reuseport, transparent, freebind, use_systemd);
reuseport, transparent, freebind, use_systemd, dscp);
if(s == -1 && inuse) {
log_err("bind: address already in use");
} else if(s == -1 && noproto && hints->ai_family == AF_INET6){
@ -988,7 +1045,7 @@ make_sock(int stype, const char* ifname, const char* port,
}
} else {
s = create_tcp_accept_sock(res, v6only, &noproto, reuseport,
transparent, tcp_mss, freebind, use_systemd);
transparent, tcp_mss, freebind, use_systemd, dscp);
if(s == -1 && noproto && hints->ai_family == AF_INET6){
*noip6 = 1;
}
@ -1001,7 +1058,7 @@ make_sock(int stype, const char* ifname, const char* port,
static int
make_sock_port(int stype, const char* ifname, const char* port,
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd)
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd, int dscp)
{
char* s = strchr(ifname, '@');
if(s) {
@ -1023,10 +1080,10 @@ make_sock_port(int stype, const char* ifname, const char* port,
(void)strlcpy(p, s+1, sizeof(p));
p[strlen(s+1)]=0;
return make_sock(stype, newif, p, hints, v6only, noip6,
rcv, snd, reuseport, transparent, tcp_mss, freebind, use_systemd);
rcv, snd, reuseport, transparent, tcp_mss, freebind, use_systemd, dscp);
}
return make_sock(stype, ifname, port, hints, v6only, noip6, rcv, snd,
reuseport, transparent, tcp_mss, freebind, use_systemd);
reuseport, transparent, tcp_mss, freebind, use_systemd, dscp);
}
/**
@ -1146,6 +1203,7 @@ if_is_ssl(const char* ifname, const char* port, int ssl_port,
* @param freebind: set IP_FREEBIND socket option.
* @param use_systemd: if true, fetch sockets from systemd.
* @param dnscrypt_port: dnscrypt service port number
* @param dscp: DSCP to use.
* @return: returns false on error.
*/
static int
@ -1154,7 +1212,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
size_t rcv, size_t snd, int ssl_port,
struct config_strlist* tls_additional_port, int* reuseport,
int transparent, int tcp_mss, int freebind, int use_systemd,
int dnscrypt_port)
int dnscrypt_port, int dscp)
{
int s, noip6=0;
#ifdef USE_DNSCRYPT
@ -1171,7 +1229,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
if(do_auto) {
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
&noip6, rcv, snd, reuseport, transparent,
tcp_mss, freebind, use_systemd)) == -1) {
tcp_mss, freebind, use_systemd, dscp)) == -1) {
if(noip6) {
log_warn("IPv6 protocol not available");
return 1;
@ -1200,7 +1258,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
/* regular udp socket */
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
&noip6, rcv, snd, reuseport, transparent,
tcp_mss, freebind, use_systemd)) == -1) {
tcp_mss, freebind, use_systemd, dscp)) == -1) {
if(noip6) {
log_warn("IPv6 protocol not available");
return 1;
@ -1222,7 +1280,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
tls_additional_port);
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
&noip6, 0, 0, reuseport, transparent, tcp_mss,
freebind, use_systemd)) == -1) {
freebind, use_systemd, dscp)) == -1) {
if(noip6) {
/*log_warn("IPv6 protocol not available");*/
return 1;
@ -1421,7 +1479,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
cfg->ssl_port, cfg->tls_additional_port,
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
cfg->dnscrypt_port, cfg->ip_dscp)) {
listening_ports_free(list);
return NULL;
}
@ -1435,7 +1493,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
cfg->ssl_port, cfg->tls_additional_port,
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
cfg->dnscrypt_port, cfg->ip_dscp)) {
listening_ports_free(list);
return NULL;
}
@ -1451,7 +1509,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
cfg->ssl_port, cfg->tls_additional_port,
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
cfg->dnscrypt_port, cfg->ip_dscp)) {
listening_ports_free(list);
return NULL;
}
@ -1465,7 +1523,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
cfg->ssl_port, cfg->tls_additional_port,
reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
cfg->dnscrypt_port)) {
cfg->dnscrypt_port, cfg->ip_dscp)) {
listening_ports_free(list);
return NULL;
}

View File

@ -205,11 +205,12 @@ void listen_start_accept(struct listen_dnsport* listen);
* @param transparent: set IP_TRANSPARENT socket option.
* @param freebind: set IP_FREEBIND socket option.
* @param use_systemd: if true, fetch sockets from systemd.
* @param dscp: DSCP to use.
* @return: the socket. -1 on error.
*/
int create_udp_sock(int family, int socktype, struct sockaddr* addr,
socklen_t addrlen, int v6only, int* inuse, int* noproto, int rcv,
int snd, int listen, int* reuseport, int transparent, int freebind, int use_systemd);
int snd, int listen, int* reuseport, int transparent, int freebind, int use_systemd, int dscp);
/**
* Create and bind TCP listening socket
@ -222,10 +223,11 @@ int create_udp_sock(int family, int socktype, struct sockaddr* addr,
* @param mss: maximum segment size of the socket. if zero, leaves the default.
* @param freebind: set IP_FREEBIND socket option.
* @param use_systemd: if true, fetch sockets from systemd.
* @param dscp: DSCP to use.
* @return: the socket. -1 on error.
*/
int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
int* reuseport, int transparent, int mss, int freebind, int use_systemd);
int* reuseport, int transparent, int mss, int freebind, int use_systemd, int dscp);
/**
* Create and bind local listening socket
@ -367,4 +369,7 @@ int tcp_req_info_handle_read_close(struct tcp_req_info* req);
/** get the size of currently used tcp stream wait buffers (in bytes) */
size_t tcp_req_info_get_stream_buffer_size(void);
char* set_ip_dscp(int socket, int addrfamily, int ds);
char* sock_strerror(int errn);
#endif /* LISTEN_DNSPORT_H */

View File

@ -518,7 +518,7 @@ local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen,
}
/** enter data RR into auth zone */
int
static int
lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr)
{
uint8_t* nm;

View File

@ -159,16 +159,28 @@ client_info_compare(const struct respip_client_info* ci_a,
return 1;
if(ci_a->taglen != ci_b->taglen)
return (ci_a->taglen < ci_b->taglen) ? -1 : 1;
cmp = memcmp(ci_a->taglist, ci_b->taglist, ci_a->taglen);
if(cmp != 0)
return cmp;
if(ci_a->taglist && !ci_b->taglist)
return -1;
if(!ci_a->taglist && ci_b->taglist)
return 1;
if(ci_a->taglist && ci_b->taglist) {
cmp = memcmp(ci_a->taglist, ci_b->taglist, ci_a->taglen);
if(cmp != 0)
return cmp;
}
if(ci_a->tag_actions_size != ci_b->tag_actions_size)
return (ci_a->tag_actions_size < ci_b->tag_actions_size) ?
-1 : 1;
cmp = memcmp(ci_a->tag_actions, ci_b->tag_actions,
ci_a->tag_actions_size);
if(cmp != 0)
return cmp;
if(ci_a->tag_actions && !ci_b->tag_actions)
return -1;
if(!ci_a->tag_actions && ci_b->tag_actions)
return 1;
if(ci_a->tag_actions && ci_b->tag_actions) {
cmp = memcmp(ci_a->tag_actions, ci_b->tag_actions,
ci_a->tag_actions_size);
if(cmp != 0)
return cmp;
}
if(ci_a->tag_datas != ci_b->tag_datas)
return ci_a->tag_datas < ci_b->tag_datas ? -1 : 1;
if(ci_a->view != ci_b->view)
@ -1284,7 +1296,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
void mesh_query_done(struct mesh_state* mstate)
{
struct mesh_reply* r, *reply_list = NULL;
struct mesh_reply* r;
struct mesh_reply* prev = NULL;
struct sldns_buffer* prev_buffer = NULL;
struct mesh_cb* c;
@ -1308,27 +1320,7 @@ void mesh_query_done(struct mesh_state* mstate)
free(err);
}
}
if(mstate->reply_list) {
/* set the reply_list to NULL during the mesh_query_done
* processing, so that calls back into the mesh from
* tcp_req_info (deciding to drop the reply and thus
* unregister the mesh_reply from the mstate) are stopped
* because the list is empty.
* The mstate is then likely not a reply_state, and maybe
* also a detached_state.
*/
reply_list = mstate->reply_list;
mstate->reply_list = NULL;
if(!mstate->reply_list && !mstate->cb_list) {
/* was a reply state, not anymore */
log_assert(mstate->s.env->mesh->num_reply_states > 0);
mstate->s.env->mesh->num_reply_states--;
}
if(!mstate->reply_list && !mstate->cb_list &&
mstate->super_set.count == 0)
mstate->s.env->mesh->num_detached_states++;
}
for(r = reply_list; r; r = r->next) {
for(r = mstate->reply_list; r; r = r->next) {
/* if a response-ip address block has been stored the
* information should be logged for each client. */
if(mstate->s.respip_action_info &&
@ -1352,15 +1344,31 @@ void mesh_query_done(struct mesh_state* mstate)
/* if this query is determined to be dropped during the
* mesh processing, this is the point to take that action. */
if(mstate->s.is_drop) {
/* 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;
mstate->reply_list = NULL;
comm_point_drop_reply(&r->query_reply);
mstate->reply_list = reply_list;
} else {
struct sldns_buffer* r_buffer = r->query_reply.c->buffer;
struct mesh_reply* rlist = mstate->reply_list;
if(r->query_reply.c->tcp_req_info) {
r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
prev_buffer = NULL;
}
/* briefly set the replylist to null in case the
* meshsendreply calls tcpreqinfo sendreply that
* comm_point_drops because of size, and then the
* null stops the mesh state remove and thus
* reply_list modification and accounting */
mstate->reply_list = NULL;
mesh_send_reply(mstate, mstate->s.return_rcode, rep,
r, r_buffer, prev, prev_buffer);
mstate->reply_list = rlist;
if(r->query_reply.c->tcp_req_info) {
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
r_buffer = NULL;
@ -1369,6 +1377,17 @@ void mesh_query_done(struct mesh_state* mstate)
prev_buffer = r_buffer;
}
}
if(mstate->reply_list) {
mstate->reply_list = NULL;
if(!mstate->reply_list && !mstate->cb_list) {
/* was a reply state, not anymore */
log_assert(mstate->s.env->mesh->num_reply_states > 0);
mstate->s.env->mesh->num_reply_states--;
}
if(!mstate->reply_list && !mstate->cb_list &&
mstate->super_set.count == 0)
mstate->s.env->mesh->num_detached_states++;
}
mstate->replies_sent = 1;
while((c = mstate->cb_list) != NULL) {
/* take this cb off the list; so that the list can be
@ -1863,7 +1882,7 @@ mesh_serve_expired_callback(void* arg)
{
struct mesh_state* mstate = (struct mesh_state*) arg;
struct module_qstate* qstate = &mstate->s;
struct mesh_reply* r;
struct mesh_reply* r, *rlist;
struct mesh_area* mesh = qstate->env->mesh;
struct dns_msg* msg;
struct mesh_cb* c;
@ -1946,16 +1965,7 @@ mesh_serve_expired_callback(void* arg)
if(verbosity >= VERB_ALGO)
log_dns_msg("Serve expired lookup", &qstate->qinfo, msg->rep);
r = mstate->reply_list;
mstate->reply_list = NULL;
if(!mstate->reply_list && !mstate->cb_list) {
log_assert(mesh->num_reply_states > 0);
mesh->num_reply_states--;
if(mstate->super_set.count == 0) {
mesh->num_detached_states++;
}
}
for(; r; r = r->next) {
for(r = mstate->reply_list; r; r = r->next) {
/* If address info is returned, it means the action should be an
* 'inform' variant and the information should be logged. */
if(actinfo.addrinfo) {
@ -1977,8 +1987,15 @@ mesh_serve_expired_callback(void* arg)
r_buffer = r->query_reply.c->buffer;
if(r->query_reply.c->tcp_req_info)
r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
/* briefly set the replylist to null in case the meshsendreply
* calls tcpreqinfo sendreply that comm_point_drops because
* of size, and then the null stops the mesh state remove and
* thus reply_list modification and accounting */
rlist = mstate->reply_list;
mstate->reply_list = NULL;
mesh_send_reply(mstate, LDNS_RCODE_NOERROR, msg->rep,
r, r_buffer, prev, prev_buffer);
mstate->reply_list = rlist;
if(r->query_reply.c->tcp_req_info)
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
prev = r;
@ -1988,6 +2005,16 @@ mesh_serve_expired_callback(void* arg)
mesh->ans_expired++;
}
if(mstate->reply_list) {
mstate->reply_list = NULL;
if(!mstate->reply_list && !mstate->cb_list) {
log_assert(mesh->num_reply_states > 0);
mesh->num_reply_states--;
if(mstate->super_set.count == 0) {
mesh->num_detached_states++;
}
}
}
while((c = mstate->cb_list) != NULL) {
/* take this cb off the list; so that the list can be
* changed, eg. by adds from the callback routine */

View File

@ -51,6 +51,9 @@
#ifdef WITH_PYTHONMODULE
#include "pythonmod/pythonmod.h"
#endif
#ifdef WITH_DYNLIBMODULE
#include "dynlibmod/dynlibmod.h"
#endif
#ifdef USE_CACHEDB
#include "cachedb/cachedb.h"
#endif
@ -140,6 +143,9 @@ module_list_avail(void)
#ifdef WITH_PYTHONMODULE
"python",
#endif
#ifdef WITH_DYNLIBMODULE
"dynlib",
#endif
#ifdef USE_CACHEDB
"cachedb",
#endif
@ -171,6 +177,9 @@ module_funcs_avail(void)
#ifdef WITH_PYTHONMODULE
&pythonmod_get_funcblock,
#endif
#ifdef WITH_DYNLIBMODULE
&dynlibmod_get_funcblock,
#endif
#ifdef USE_CACHEDB
&cachedb_get_funcblock,
#endif

View File

@ -205,18 +205,25 @@ pick_outgoing_tcp(struct waiting_tcp* w, int s)
/** get TCP file descriptor for address, returns -1 on failure,
* tcp_mss is 0 or maxseg size to set for TCP packets. */
int
outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss)
outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss, int dscp)
{
int s;
int af;
char* err;
#ifdef SO_REUSEADDR
int on = 1;
#endif
#ifdef INET6
if(addr_is_ip6(addr, addrlen))
if(addr_is_ip6(addr, addrlen)){
s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
else
af = AF_INET6;
} else {
#else
{
#endif
af = AF_INET;
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
}
if(s == -1) {
#ifndef USE_WINSOCK
log_err_addr("outgoing tcp: socket", strerror(errno),
@ -236,6 +243,12 @@ outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss)
}
#endif
err = set_ip_dscp(s, af, dscp);
if(err != NULL) {
verbose(VERB_ALGO, "outgoing tcp:"
"error setting IP DiffServ codepoint on socket");
}
if(tcp_mss > 0) {
#if defined(IPPROTO_TCP) && defined(TCP_MAXSEG)
if(setsockopt(s, IPPROTO_TCP, TCP_MAXSEG,
@ -291,7 +304,7 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
log_assert(pkt);
log_assert(w->addrlen > 0);
/* open socket */
s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss);
s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss, w->outnet->ip_dscp);
if(s == -1)
return 0;
@ -373,45 +386,16 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
#endif
pend->c->ssl_shake_state = comm_ssl_shake_write;
if(w->tls_auth_name) {
if(!set_auth_name_on_ssl(pend->c->ssl, w->tls_auth_name,
w->outnet->tls_use_sni)) {
pend->c->fd = s;
#ifdef HAVE_SSL
(void)SSL_set_tlsext_host_name(pend->c->ssl, w->tls_auth_name);
SSL_free(pend->c->ssl);
#endif
pend->c->ssl = NULL;
comm_point_close(pend->c);
return 0;
}
#ifdef HAVE_SSL_SET1_HOST
if(w->tls_auth_name) {
SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
/* setting the hostname makes openssl verify the
* host name in the x509 certificate in the
* SSL connection*/
if(!SSL_set1_host(pend->c->ssl, w->tls_auth_name)) {
log_err("SSL_set1_host failed");
pend->c->fd = s;
SSL_free(pend->c->ssl);
pend->c->ssl = NULL;
comm_point_close(pend->c);
return 0;
}
}
#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
/* openssl 1.0.2 has this function that can be used for
* set1_host like verification */
if(w->tls_auth_name) {
X509_VERIFY_PARAM* param = SSL_get0_param(pend->c->ssl);
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
if(!X509_VERIFY_PARAM_set1_host(param, w->tls_auth_name, strlen(w->tls_auth_name))) {
log_err("X509_VERIFY_PARAM_set1_host failed");
pend->c->fd = s;
SSL_free(pend->c->ssl);
pend->c->ssl = NULL;
comm_point_close(pend->c);
return 0;
}
SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
}
#else
verbose(VERB_ALGO, "the query has an auth_name, but libssl has no call to perform TLS authentication");
#endif /* HAVE_SSL_SET1_HOST */
}
w->pkt = NULL;
w->next_waiting = (void*)pend;
@ -512,7 +496,9 @@ portcomm_loweruse(struct outside_network* outnet, struct port_comm* pc)
comm_point_close(pc->cp);
pif = pc->pif;
log_assert(pif->inuse > 0);
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
pif->avail_ports[pif->avail_total - pif->inuse] = pc->number;
#endif
pif->inuse--;
pif->out[pc->index] = pif->out[pif->inuse];
pif->out[pc->index]->index = pc->index;
@ -725,10 +711,12 @@ create_pending_tcp(struct outside_network* outnet, size_t bufsize)
static int setup_if(struct port_if* pif, const char* addrstr,
int* avail, int numavail, size_t numfd)
{
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
pif->avail_total = numavail;
pif->avail_ports = (int*)memdup(avail, (size_t)numavail*sizeof(int));
if(!pif->avail_ports)
return 0;
#endif
if(!ipstrtoaddr(addrstr, UNBOUND_DNS_PORT, &pif->addr, &pif->addrlen) &&
!netblockstrtoaddr(addrstr, UNBOUND_DNS_PORT,
&pif->addr, &pif->addrlen, &pif->pfxlen))
@ -745,11 +733,11 @@ static int setup_if(struct port_if* pif, const char* addrstr,
struct outside_network*
outside_network_create(struct comm_base *base, size_t bufsize,
size_t num_ports, char** ifs, int num_ifs, int do_ip4,
int do_ip6, size_t num_tcp, struct infra_cache* infra,
int do_ip6, size_t num_tcp, int dscp, struct infra_cache* infra,
struct ub_randstate* rnd, int use_caps_for_id, int* availports,
int numavailports, size_t unwanted_threshold, int tcp_mss,
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
void* sslctx, int delayclose, struct dt_env* dtenv)
void* sslctx, int delayclose, int tls_use_sni, struct dt_env* dtenv)
{
struct outside_network* outnet = (struct outside_network*)
calloc(1, sizeof(struct outside_network));
@ -765,6 +753,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
outnet->infra = infra;
outnet->rnd = rnd;
outnet->sslctx = sslctx;
outnet->tls_use_sni = tls_use_sni;
#ifdef USE_DNSTAP
outnet->dtenv = dtenv;
#else
@ -778,6 +767,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
outnet->use_caps_for_id = use_caps_for_id;
outnet->do_udp = do_udp;
outnet->tcp_mss = tcp_mss;
outnet->ip_dscp = dscp;
#ifndef S_SPLINT_S
if(delayclose) {
outnet->delayclose = 1;
@ -955,7 +945,9 @@ outside_network_delete(struct outside_network* outnet)
comm_point_delete(pc->cp);
free(pc);
}
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
free(outnet->ip4_ifs[i].avail_ports);
#endif
free(outnet->ip4_ifs[i].out);
}
free(outnet->ip4_ifs);
@ -969,7 +961,9 @@ outside_network_delete(struct outside_network* outnet)
comm_point_delete(pc->cp);
free(pc);
}
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
free(outnet->ip6_ifs[i].avail_ports);
#endif
free(outnet->ip6_ifs[i].out);
}
free(outnet->ip6_ifs);
@ -1059,11 +1053,12 @@ sai6_putrandom(struct sockaddr_in6 *sa, int pfxlen, struct ub_randstate *rnd)
* @param port: port override for addr.
* @param inuse: if -1 is returned, this bool means the port was in use.
* @param rnd: random state (for address randomisation).
* @param dscp: DSCP to use.
* @return fd or -1
*/
static int
udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int pfxlen,
int port, int* inuse, struct ub_randstate* rnd)
int port, int* inuse, struct ub_randstate* rnd, int dscp)
{
int fd, noproto;
if(addr_is_ip6(addr, addrlen)) {
@ -1078,13 +1073,13 @@ udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int pfxlen,
}
fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
(struct sockaddr*)&sa, addrlen, 1, inuse, &noproto,
0, 0, 0, NULL, 0, freebind, 0);
0, 0, 0, NULL, 0, freebind, 0, dscp);
} else {
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
sa->sin_port = (in_port_t)htons((uint16_t)port);
fd = create_udp_sock(AF_INET, SOCK_DGRAM,
(struct sockaddr*)addr, addrlen, 1, inuse, &noproto,
0, 0, 0, NULL, 0, 0, 0);
0, 0, 0, NULL, 0, 0, 0, dscp);
}
return fd;
}
@ -1133,6 +1128,7 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
while(1) {
my_if = ub_random_max(outnet->rnd, num_if);
pif = &ifs[my_if];
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
my_port = ub_random_max(outnet->rnd, pif->avail_total);
if(my_port < pif->inuse) {
/* port already open */
@ -1144,8 +1140,11 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
/* try to open new port, if fails, loop to try again */
log_assert(pif->inuse < pif->maxout);
portno = pif->avail_ports[my_port - pif->inuse];
#else
my_port = portno = 0;
#endif
fd = udp_sockport(&pif->addr, pif->addrlen, pif->pfxlen,
portno, &inuse, outnet->rnd);
portno, &inuse, outnet->rnd, outnet->ip_dscp);
if(fd == -1 && !inuse) {
/* nonrecoverable error making socket */
return 0;
@ -1167,8 +1166,10 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
/* grab port in interface */
pif->out[pif->inuse] = pend->pc;
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
pif->avail_ports[my_port - pif->inuse] =
pif->avail_ports[pif->avail_total-pif->inuse-1];
#endif
pif->inuse++;
break;
}
@ -2192,10 +2193,11 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
{
struct sockaddr_storage* addr;
socklen_t addrlen;
int i, try, pnum;
int i, try, pnum, dscp;
struct port_if* pif;
/* create fd */
dscp = outnet->ip_dscp;
for(try = 0; try<1000; try++) {
int port = 0;
int freebind = 0;
@ -2225,6 +2227,7 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
}
addr = &pif->addr;
addrlen = pif->addrlen;
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
pnum = ub_random_max(outnet->rnd, pif->avail_total);
if(pnum < pif->inuse) {
/* port already open */
@ -2233,19 +2236,21 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
/* unused ports in start part of array */
port = pif->avail_ports[pnum - pif->inuse];
}
#else
pnum = port = 0;
#endif
if(addr_is_ip6(to_addr, to_addrlen)) {
struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
sa.sin6_port = (in_port_t)htons((uint16_t)port);
fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
(struct sockaddr*)&sa, addrlen, 1, &inuse, &noproto,
0, 0, 0, NULL, 0, freebind, 0);
0, 0, 0, NULL, 0, freebind, 0, dscp);
} else {
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
sa->sin_port = (in_port_t)htons((uint16_t)port);
fd = create_udp_sock(AF_INET, SOCK_DGRAM,
(struct sockaddr*)addr, addrlen, 1, &inuse, &noproto,
0, 0, 0, NULL, 0, freebind, 0);
0, 0, 0, NULL, 0, freebind, 0, dscp);
}
if(fd != -1) {
return fd;
@ -2294,6 +2299,11 @@ setup_comm_ssl(struct comm_point* cp, struct outside_network* outnet,
#endif
cp->ssl_shake_state = comm_ssl_shake_write;
/* https verification */
#ifdef HAVE_SSL
if(outnet->tls_use_sni) {
(void)SSL_set_tlsext_host_name(cp->ssl, host);
}
#endif
#ifdef HAVE_SSL_SET1_HOST
if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
/* because we set SSL_VERIFY_PEER, in netevent in
@ -2316,7 +2326,9 @@ setup_comm_ssl(struct comm_point* cp, struct outside_network* outnet,
* set1_host like verification */
if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
X509_VERIFY_PARAM* param = SSL_get0_param(cp->ssl);
# ifdef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
# endif
if(!X509_VERIFY_PARAM_set1_host(param, host, strlen(host))) {
log_err("X509_VERIFY_PARAM_set1_host failed");
return 0;
@ -2335,7 +2347,7 @@ outnet_comm_point_for_tcp(struct outside_network* outnet,
sldns_buffer* query, int timeout, int ssl, char* host)
{
struct comm_point* cp;
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss);
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss, outnet->ip_dscp);
if(fd == -1) {
return 0;
}
@ -2397,7 +2409,7 @@ outnet_comm_point_for_http(struct outside_network* outnet,
{
/* cp calls cb with err=NETEVENT_DONE when transfer is done */
struct comm_point* cp;
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss);
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss, outnet->ip_dscp);
if(fd == -1) {
return 0;
}
@ -2455,7 +2467,10 @@ if_get_mem(struct port_if* pif)
{
size_t s;
int i;
s = sizeof(*pif) + sizeof(int)*pif->avail_total +
s = sizeof(*pif) +
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
sizeof(int)*pif->avail_total +
#endif
sizeof(struct port_comm*)*pif->maxout;
for(i=0; i<pif->inuse; i++)
s += sizeof(*pif->out[i]) +

View File

@ -132,12 +132,16 @@ struct outside_network {
struct ub_randstate* rnd;
/** ssl context to create ssl wrapped TCP with DNS connections */
void* sslctx;
/** if SNI will be used for TLS connections */
int tls_use_sni;
#ifdef USE_DNSTAP
/** dnstap environment */
struct dt_env* dtenv;
#endif
/** maximum segment size of tcp socket */
int tcp_mss;
/** IP_TOS socket option requested on the sockets */
int ip_dscp;
/**
* Array of tcp pending used for outgoing TCP connections.
@ -172,11 +176,13 @@ struct port_if {
* if 0, no randomisation. */
int pfxlen;
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
/** the available ports array. These are unused.
* Only the first total-inuse part is filled. */
int* avail_ports;
/** the total number of available ports (size of the array) */
int avail_total;
#endif
/** array of the commpoints currently in use.
* allocated for max number of fds, first part in use. */
@ -399,6 +405,7 @@ struct serviced_query {
* @param do_ip4: service IP4.
* @param do_ip6: service IP6.
* @param num_tcp: number of outgoing tcp buffers to preallocate.
* @param dscp: DSCP to use.
* @param infra: pointer to infra cached used for serviced queries.
* @param rnd: stored to create random numbers for serviced queries.
* @param use_caps_for_id: enable to use 0x20 bits to encode id randomness.
@ -412,16 +419,17 @@ struct serviced_query {
* @param sslctx: context to create outgoing connections with (if enabled).
* @param delayclose: if not 0, udp sockets are delayed before timeout closure.
* msec to wait on timeouted udp sockets.
* @param tls_use_sni: if SNI is used for TLS connections.
* @param dtenv: environment to send dnstap events with (if enabled).
* @return: the new structure (with no pending answers) or NULL on error.
*/
struct outside_network* outside_network_create(struct comm_base* base,
size_t bufsize, size_t num_ports, char** ifs, int num_ifs,
int do_ip4, int do_ip6, size_t num_tcp, struct infra_cache* infra,
int do_ip4, int do_ip6, size_t num_tcp, int dscp, struct infra_cache* infra,
struct ub_randstate* rnd, int use_caps_for_id, int* availports,
int numavailports, size_t unwanted_threshold, int tcp_mss,
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
void* sslctx, int delayclose, struct dt_env *dtenv);
void* sslctx, int delayclose, int tls_use_sni, struct dt_env *dtenv);
/**
* Delete outside_network structure.
@ -540,7 +548,7 @@ size_t serviced_get_mem(struct serviced_query* sq);
/** get TCP file descriptor for address, returns -1 on failure,
* tcp_mss is 0 or maxseg size to set for TCP packets. */
int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss);
int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss, int dscp);
/**
* Create udp commpoint suitable for sending packets to the destination.

View File

@ -586,7 +586,7 @@ rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
}
int
rpz_insert_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
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)
{
@ -596,9 +596,17 @@ rpz_insert_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
enum rpz_action a;
uint8_t* policydname;
log_assert(dnamelen >= aznamelen);
if(!(policydname = calloc(1, (dnamelen-aznamelen)+1)))
if(!dname_subdomain_c(dname, azname)) {
log_err("RPZ: name of record to insert into RPZ is not a "
"subdomain of the configured name of the RPZ zone");
return 0;
}
log_assert(dnamelen >= aznamelen);
if(!(policydname = calloc(1, (dnamelen-aznamelen)+1))) {
log_err("malloc error while inserting RPZ RR");
return 0;
}
a = rpz_rr_to_action(rr_type, rdatawl, rdatalen);
if(!(policydnamelen = strip_dname_origin(dname, dnamelen, aznamelen,
@ -826,6 +834,8 @@ rpz_remove_qname_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
delete_zone = rpz_data_delete_rr(z, dname,
dnamelen, rr_type, rdatawl, rdatalen);
else if(a != localzone_type_to_rpz_action(z->type)) {
lock_rw_unlock(&z->lock);
lock_rw_unlock(&r->local_zones->lock);
return;
}
lock_rw_unlock(&z->lock);
@ -931,13 +941,16 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
struct regional* temp, struct comm_reply* repinfo,
uint8_t* taglist, size_t taglen, struct ub_server_stats* stats)
{
struct rpz* r;
struct rpz* r = NULL;
struct auth_zone* a;
int ret;
enum localzone_type lzt;
struct local_zone* z = NULL;
struct local_data* ld = NULL;
lock_rw_rdlock(&az->rpz_lock);
for(r = az->rpz_first; r; r = r->next) {
for(a = az->rpz_first; a; a = a->rpz_az_next) {
lock_rw_rdlock(&a->lock);
r = a->rpz;
if(!r->taglist || taglist_intersect(r->taglist,
r->taglistlen, taglist, taglen)) {
z = rpz_find_zone(r, qinfo->qname, qinfo->qname_len,
@ -955,13 +968,14 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
}
if(z)
break;
}
}
lock_rw_unlock(&a->lock); /* not found in this auth_zone */
}
lock_rw_unlock(&az->rpz_lock);
if(!z)
return 0;
return 0; /* not holding auth_zone.lock anymore */
log_assert(r);
if(r->action_override == RPZ_NO_OVERRIDE_ACTION)
lzt = z->type;
else
@ -972,6 +986,7 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
regional_alloc_zero(temp, sizeof(struct local_rrset));
if(!qinfo->local_alias) {
lock_rw_unlock(&z->lock);
lock_rw_unlock(&a->lock);
return 0; /* out of memory */
}
qinfo->local_alias->rrset =
@ -979,6 +994,7 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
sizeof(*r->cname_override));
if(!qinfo->local_alias->rrset) {
lock_rw_unlock(&z->lock);
lock_rw_unlock(&a->lock);
return 0; /* out of memory */
}
qinfo->local_alias->rrset->rk.dname = qinfo->qname;
@ -988,6 +1004,7 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
qinfo, repinfo, r->log_name);
stats->rpz_action[RPZ_CNAME_OVERRIDE_ACTION]++;
lock_rw_unlock(&z->lock);
lock_rw_unlock(&a->lock);
return 0;
}
@ -1000,6 +1017,7 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
repinfo, r->log_name);
stats->rpz_action[localzone_type_to_rpz_action(lzt)]++;
lock_rw_unlock(&z->lock);
lock_rw_unlock(&a->lock);
return !qinfo->local_alias;
}
@ -1010,6 +1028,7 @@ rpz_apply_qname_trigger(struct auth_zones* az, struct module_env* env,
qinfo, repinfo, r->log_name);
stats->rpz_action[localzone_type_to_rpz_action(lzt)]++;
lock_rw_unlock(&z->lock);
lock_rw_unlock(&a->lock);
return ret;
}

View File

@ -86,7 +86,8 @@ enum rpz_action {
/**
* RPZ containing policies. Pointed to from corresponding auth-zone. Part of a
* linked list to keep configuration order. Iterating or changing the linked
* list requires the rpz_lock from struct auth_zones.
* list requires the rpz_lock from struct auth_zones. Changing items in this
* struct require the lock from struct auth_zone.
*/
struct rpz {
struct local_zones* local_zones;
@ -97,14 +98,13 @@ struct rpz {
struct ub_packed_rrset_key* cname_override;
int log;
char* log_name;
struct rpz* next;
struct rpz* prev;
struct regional* region;
};
/**
* Create policy from RR and add to this RPZ.
* @param r: the rpz to add the policy to.
* @param azname: dname of the auth-zone
* @param aznamelen: the length of the auth-zone name
* @param dname: dname of the RR
* @param dnamelen: length of the dname
@ -117,7 +117,7 @@ struct rpz {
* @param rr_len: the length of the complete RR
* @return: 0 on error
*/
int rpz_insert_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
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);

View File

@ -167,7 +167,7 @@ sldns_gmtime64_r(int64_t clock, struct tm *result)
static int64_t
sldns_serial_arithmetics_time(int32_t time, time_t now)
{
int32_t offset = time - (int32_t) now;
int32_t offset = (int32_t)((uint32_t) time - (uint32_t) now);
return (int64_t) now + offset;
}

View File

@ -187,6 +187,7 @@ usage(void)
printf("-c file cert file, default %s\n", ROOT_CERT_FILE);
printf("-l list builtin key and cert on stdout\n");
printf("-u name server in https url, default %s\n", URLNAME);
printf("-S do not use SNI for the https connection\n");
printf("-x path pathname to xml in url, default %s\n", XMLNAME);
printf("-s path pathname to p7s in url, default %s\n", P7SNAME);
printf("-n name signer's subject emailAddress, default %s\n", P7SIGNER);
@ -245,9 +246,7 @@ get_builtin_ds(void)
return
/* The anchors must start on a new line with ". IN DS and end with \n"[;]
* because the makedist script greps on the source here */
/* anchor 19036 is from 2010 */
/* anchor 20326 is from 2017 */
". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5\n"
". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n";
}
@ -772,7 +771,7 @@ setup_sslctx(void)
/** initiate TLS on a connection */
static SSL*
TLS_initiate(SSL_CTX* sslctx, int fd)
TLS_initiate(SSL_CTX* sslctx, int fd, const char* urlname, int use_sni)
{
X509* x;
int r;
@ -788,6 +787,9 @@ TLS_initiate(SSL_CTX* sslctx, int fd)
SSL_free(ssl);
return NULL;
}
if(use_sni) {
(void)SSL_set_tlsext_host_name(ssl, urlname);
}
while(1) {
ERR_clear_error();
if( (r=SSL_do_handshake(ssl)) == 1)
@ -1123,7 +1125,7 @@ read_http_result(SSL* ssl)
/** https to an IP addr, return BIO with pathname or NULL */
static BIO*
https_to_ip(struct ip_list* ip, const char* pathname, const char* urlname,
struct ip_list* src)
struct ip_list* src, int use_sni)
{
int fd;
SSL* ssl;
@ -1137,7 +1139,7 @@ https_to_ip(struct ip_list* ip, const char* pathname, const char* urlname,
SSL_CTX_free(sslctx);
return NULL;
}
ssl = TLS_initiate(sslctx, fd);
ssl = TLS_initiate(sslctx, fd, urlname, use_sni);
if(!ssl) {
SSL_CTX_free(sslctx);
fd_close(fd);
@ -1161,11 +1163,12 @@ https_to_ip(struct ip_list* ip, const char* pathname, const char* urlname,
* @param pathname: pathname of file on server to GET.
* @param urlname: name to pass as the virtual host for this request.
* @param src: if nonNULL, source address to bind to.
* @param use_sni: if SNI will be used.
* @return a memory BIO with the file in it.
*/
static BIO*
https(struct ip_list* ip_list, const char* pathname, const char* urlname,
struct ip_list* src)
struct ip_list* src, int use_sni)
{
struct ip_list* ip;
BIO* bio = NULL;
@ -1173,7 +1176,7 @@ https(struct ip_list* ip_list, const char* pathname, const char* urlname,
wipe_ip_usage(ip_list);
while( (ip = pick_random_ip(ip_list)) ) {
ip->used = 1;
bio = https_to_ip(ip, pathname, urlname, src);
bio = https_to_ip(ip, pathname, urlname, src, use_sni);
if(bio) break;
}
if(!bio) {
@ -1929,7 +1932,7 @@ do_certupdate(const char* root_anchor_file, const char* root_cert_file,
const char* urlname, const char* xmlname, const char* p7sname,
const char* p7signer, const char* res_conf, const char* root_hints,
const char* debugconf, const char* srcaddr, int ip4only, int ip6only,
int port)
int port, int use_sni)
{
STACK_OF(X509)* cert;
@ -1963,8 +1966,8 @@ do_certupdate(const char* root_anchor_file, const char* root_cert_file,
#endif
/* fetch the necessary files over HTTPS */
xml = https(ip_list, xmlname, urlname, src);
p7s = https(ip_list, p7sname, urlname, src);
xml = https(ip_list, xmlname, urlname, src, use_sni);
p7s = https(ip_list, p7sname, urlname, src, use_sni);
/* verify and update the root anchor */
verify_and_update_anchor(root_anchor_file, xml, p7s, cert, p7signer);
@ -2235,7 +2238,7 @@ do_root_update_work(const char* root_anchor_file, const char* root_cert_file,
const char* urlname, const char* xmlname, const char* p7sname,
const char* p7signer, const char* res_conf, const char* root_hints,
const char* debugconf, const char* srcaddr, int ip4only, int ip6only,
int force, int res_conf_fallback, int port)
int force, int res_conf_fallback, int port, int use_sni)
{
struct ub_result* dnskey;
int used_builtin = 0;
@ -2278,7 +2281,7 @@ do_root_update_work(const char* root_anchor_file, const char* root_cert_file,
probe_date_allows_certupdate(root_anchor_file)) || force) {
if(do_certupdate(root_anchor_file, root_cert_file, urlname,
xmlname, p7sname, p7signer, res_conf, root_hints,
debugconf, srcaddr, ip4only, ip6only, port))
debugconf, srcaddr, ip4only, ip6only, port, use_sni))
return 1;
return used_builtin;
}
@ -2307,8 +2310,9 @@ int main(int argc, char* argv[])
const char* srcaddr = NULL;
int dolist=0, ip4only=0, ip6only=0, force=0, port = HTTPS_PORT;
int res_conf_fallback = 0;
int use_sni = 1;
/* parse the options */
while( (c=getopt(argc, argv, "46C:FRP:a:b:c:f:hln:r:s:u:vx:")) != -1) {
while( (c=getopt(argc, argv, "46C:FRSP:a:b:c:f:hln:r:s:u:vx:")) != -1) {
switch(c) {
case 'l':
dolist = 1;
@ -2331,6 +2335,9 @@ int main(int argc, char* argv[])
case 'u':
urlname = optarg;
break;
case 'S':
use_sni = 0;
break;
case 'x':
xmlname = optarg;
break;
@ -2397,5 +2404,5 @@ int main(int argc, char* argv[])
return do_root_update_work(root_anchor_file, root_cert_file, urlname,
xmlname, p7sname, p7signer, res_conf, root_hints, debugconf,
srcaddr, ip4only, ip6only, force, res_conf_fallback, port);
srcaddr, ip4only, ip6only, force, res_conf_fallback, port, use_sni);
}

View File

@ -58,6 +58,7 @@
#include "services/authzone.h"
#include "respip/respip.h"
#include "sldns/sbuffer.h"
#include "sldns/str2wire.h"
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
@ -194,6 +195,94 @@ localzonechecks(struct config_file* cfg)
local_zones_delete(zs);
}
/** checks for acl and views */
static void
acl_view_tag_checks(struct config_file* cfg, struct views* views)
{
int d;
struct sockaddr_storage a;
socklen_t alen;
struct config_str2list* acl;
struct config_str3list* s3;
struct config_strbytelist* sb;
/* acl_view */
for(acl=cfg->acl_view; acl; acl = acl->next) {
struct view* v;
if(!netblockstrtoaddr(acl->str, UNBOUND_DNS_PORT, &a, &alen,
&d)) {
fatal_exit("cannot parse access-control-view "
"address %s %s", acl->str, acl->str2);
}
v = views_find_view(views, acl->str2, 0);
if(!v) {
fatal_exit("cannot find view for "
"access-control-view: %s %s",
acl->str, acl->str2);
}
lock_rw_unlock(&v->lock);
}
/* acl_tags */
for(sb=cfg->acl_tags; sb; sb = sb->next) {
if(!netblockstrtoaddr(sb->str, UNBOUND_DNS_PORT, &a, &alen,
&d)) {
fatal_exit("cannot parse access-control-tags "
"address %s", sb->str);
}
}
/* acl_tag_actions */
for(s3=cfg->acl_tag_actions; s3; s3 = s3->next) {
enum localzone_type t;
if(!netblockstrtoaddr(s3->str, UNBOUND_DNS_PORT, &a, &alen,
&d)) {
fatal_exit("cannot parse access-control-tag-actions "
"address %s %s %s",
s3->str, s3->str2, s3->str3);
}
if(find_tag_id(cfg, s3->str2) == -1) {
fatal_exit("cannot parse tag %s (define-tag it), "
"for access-control-tag-actions: %s %s %s",
s3->str2, s3->str, s3->str2, s3->str3);
}
if(!local_zone_str2type(s3->str3, &t)) {
fatal_exit("cannot parse access control action type %s"
" for access-control-tag-actions: %s %s %s",
s3->str3, s3->str, s3->str2, s3->str3);
}
}
/* acl_tag_datas */
for(s3=cfg->acl_tag_datas; s3; s3 = s3->next) {
char buf[65536];
uint8_t rr[LDNS_RR_BUF_SIZE];
size_t len = sizeof(rr);
int res;
if(!netblockstrtoaddr(s3->str, UNBOUND_DNS_PORT, &a, &alen,
&d)) {
fatal_exit("cannot parse access-control-tag-datas address %s %s '%s'",
s3->str, s3->str2, s3->str3);
}
if(find_tag_id(cfg, s3->str2) == -1) {
fatal_exit("cannot parse tag %s (define-tag it), "
"for access-control-tag-datas: %s %s '%s'",
s3->str2, s3->str, s3->str2, s3->str3);
}
/* '.' is sufficient for validation, and it makes the call to
* sldns_wirerr_get_type() simpler below. */
snprintf(buf, sizeof(buf), "%s %s", ".", s3->str3);
res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, NULL,
0, NULL, 0);
if(res != 0) {
fatal_exit("cannot parse rr data [char %d] parse error %s, for access-control-tag-datas: %s %s '%s'",
(int)LDNS_WIREPARSE_OFFSET(res)-2,
sldns_get_errorstr_parse(res),
s3->str, s3->str2, s3->str3);
}
}
}
/** check view and response-ip configuration */
static void
view_and_respipchecks(struct config_file* cfg)
@ -211,6 +300,7 @@ view_and_respipchecks(struct config_file* cfg)
fatal_exit("Could not setup respip set");
if(!respip_views_apply_cfg(views, cfg, &ignored))
fatal_exit("Could not setup per-view respip sets");
acl_view_tag_checks(cfg, views);
views_delete(views);
respip_set_delete(respip);
}
@ -481,6 +571,8 @@ morechecks(struct config_file* cfg)
fatal_exit("num_threads value weird");
if(!cfg->do_ip4 && !cfg->do_ip6)
fatal_exit("ip4 and ip6 are both disabled, pointless");
if(!cfg->do_ip4 && cfg->prefer_ip4)
fatal_exit("cannot prefer and disable ip4, pointless");
if(!cfg->do_ip6 && cfg->prefer_ip6)
fatal_exit("cannot prefer and disable ip6, pointless");
if(!cfg->do_udp && !cfg->do_tcp)
@ -567,6 +659,64 @@ morechecks(struct config_file* cfg)
&& strcmp(cfg->module_conf, "python dns64 iterator") != 0
&& strcmp(cfg->module_conf, "python dns64 validator iterator") != 0
#endif
#ifdef WITH_DYNLIBMODULE
&& strcmp(cfg->module_conf, "dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dynlib dynlib iterator") != 0
&& strcmp(cfg->module_conf, "python dynlib iterator") != 0
&& strcmp(cfg->module_conf, "python dynlib dynlib iterator") != 0
&& strcmp(cfg->module_conf, "python dynlib dynlib dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip iterator") != 0
&& strcmp(cfg->module_conf, "dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dynlib dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "python dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "python dynlib dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "python dynlib dynlib dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip validator iterator") != 0
&& strcmp(cfg->module_conf, "validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dns64 dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dns64 dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "dns64 validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dns64 iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dns64 validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dns64 cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib dns64 validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dns64 dynlib cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dns64 dynlib validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "cachedb dynlib iterator") != 0
&& strcmp(cfg->module_conf, "respip cachedb dynlib iterator") != 0
&& strcmp(cfg->module_conf, "validator cachedb dynlib iterator") != 0
&& strcmp(cfg->module_conf, "respip validator cachedb dynlib iterator") != 0
&& strcmp(cfg->module_conf, "validator dynlib cachedb iterator") != 0
&& strcmp(cfg->module_conf, "respip validator dynlib cachedb iterator") != 0
&& strcmp(cfg->module_conf, "dynlib subnetcache iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip subnetcache iterator") != 0
&& strcmp(cfg->module_conf, "subnetcache dynlib iterator") != 0
&& strcmp(cfg->module_conf, "respip subnetcache dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib subnetcache validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib respip subnetcache validator iterator") != 0
&& strcmp(cfg->module_conf, "subnetcache dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "respip subnetcache dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "subnetcache validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "respip subnetcache validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "dynlib ipsecmod iterator") != 0
&& strcmp(cfg->module_conf, "dynlib ipsecmod respip iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod dynlib iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod dynlib respip iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod respip validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib ipsecmod validator iterator") != 0
&& strcmp(cfg->module_conf, "dynlib ipsecmod respip validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod dynlib validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod dynlib respip validator iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod validator dynlib iterator") != 0
&& strcmp(cfg->module_conf, "ipsecmod respip validator dynlib iterator") != 0
#endif
#ifdef USE_CACHEDB
&& strcmp(cfg->module_conf, "validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "respip validator cachedb iterator") != 0
@ -598,6 +748,8 @@ morechecks(struct config_file* cfg)
&& strcmp(cfg->module_conf, "respip subnetcache validator iterator") != 0
&& strcmp(cfg->module_conf, "dns64 subnetcache iterator") != 0
&& strcmp(cfg->module_conf, "dns64 subnetcache validator iterator") != 0
&& strcmp(cfg->module_conf, "dns64 subnetcache respip iterator") != 0
&& strcmp(cfg->module_conf, "dns64 subnetcache respip validator iterator") != 0
#endif
#if defined(WITH_PYTHONMODULE) && defined(CLIENT_SUBNET)
&& strcmp(cfg->module_conf, "python subnetcache iterator") != 0
@ -701,7 +853,7 @@ check_auth(struct config_file* cfg)
{
int is_rpz = 0;
struct auth_zones* az = auth_zones_create();
if(!az || !auth_zones_apply_cfg(az, cfg, 0i, &is_rpz)) {
if(!az || !auth_zones_apply_cfg(az, cfg, 0, &is_rpz)) {
fatal_exit("Could not setup authority zones");
}
auth_zones_delete(az);

View File

@ -5,22 +5,22 @@
# Copyright (c) 2008, NLnet Labs. All rights reserved.
#
# This software is open source.
#
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#
# Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
#
# Neither the name of the NLNET LABS nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
#
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@ -57,87 +57,144 @@ SVR_BASE=unbound_server
# base name for unbound-control keys
CTL_BASE=unbound_control
# flag to recreate generated certificates
RECREATE=0
# we want -rw-r----- access (say you run this as root: grp=yes (server), all=no).
umask 0027
# end of options
# functions:
error ( ) {
echo "$0 fatal error: $1"
exit 1
set -eu
cleanup() {
echo "removing artifacts"
rm -rf \
server.cnf \
client.cnf \
"${SVR_BASE}_trust.pem" \
"${CTL_BASE}_trust.pem" \
"${SVR_BASE}_trust.srl"
}
# check arguments:
while test $# -ne 0; do
case $1 in
-d)
if test $# -eq 1; then error "need argument for -d"; fi
DESTDIR="$2"
shift
;;
*)
echo "unbound-control-setup.sh - setup SSL keys for unbound-control"
echo " -d dir use directory to store keys and certificates."
echo " default: $DESTDIR"
echo "please run this command using the same user id that the "
echo "unbound daemon uses, it needs read privileges."
exit 1
;;
esac
shift
fatal() {
printf "fatal error: $*\n" >/dev/stderr
exit 1
}
usage() {
cat <<EOF
usage: $0 OPTIONS
OPTIONS
-d <dir> used directory to store keys and certificates (default: $DESTDIR)
-h show help notice
-r recreate certificates
EOF
}
OPTIND=1
while getopts 'd:hr' arg; do
case "$arg" in
d) DESTDIR="$OPTARG" ;;
h) usage; exit 1 ;;
r) RECREATE=1 ;;
?) fatal "'$arg' unknown option" ;;
esac
done
shift $((OPTIND - 1))
# go!:
echo "setup in directory $DESTDIR"
cd "$DESTDIR" || error "could not cd to $DESTDIR"
cd "$DESTDIR"
# create certificate keys; do not recreate if they already exist.
if test -f $SVR_BASE.key; then
echo "$SVR_BASE.key exists"
else
echo "generating $SVR_BASE.key"
openssl genrsa -out $SVR_BASE.key $BITS || error "could not genrsa"
fi
if test -f $CTL_BASE.key; then
echo "$CTL_BASE.key exists"
else
echo "generating $CTL_BASE.key"
openssl genrsa -out $CTL_BASE.key $BITS || error "could not genrsa"
trap cleanup INT
# ===
# Generate server certificate
# ===
# generate private key; do no recreate it if they already exist.
if [ ! -f "$SVR_BASE.key" ]; then
openssl genrsa -out "$SVR_BASE.key" "$BITS"
fi
# create self-signed cert for server
echo "[req]" > request.cfg
echo "default_bits=$BITS" >> request.cfg
echo "default_md=$HASH" >> request.cfg
echo "prompt=no" >> request.cfg
echo "distinguished_name=req_distinguished_name" >> request.cfg
echo "" >> request.cfg
echo "[req_distinguished_name]" >> request.cfg
echo "commonName=$SERVERNAME" >> request.cfg
cat >server.cnf <<EOF
default_bits=$BITS
default_md=$HASH
prompt=no
distinguished_name=req_distinguished_name
[req_distinguished_name]
commonName=$SERVERNAME
EOF
test -f request.cfg || error "could not create request.cfg"
[ -f server.cnf ] || fatal "cannot create openssl configuration"
echo "create $SVR_BASE.pem (self signed certificate)"
openssl req -key $SVR_BASE.key -config request.cfg -new -x509 -days $DAYS -out $SVR_BASE.pem || error "could not create $SVR_BASE.pem"
# create trusted usage pem
openssl x509 -in $SVR_BASE.pem -addtrust serverAuth -out $SVR_BASE"_trust.pem"
if [ ! -f "$SVR_BASE.pem" -o $RECREATE -eq 1 ]; then
openssl req \
-new -x509 \
-key "$SVR_BASE.key" \
-config server.cnf \
-days "$DAYS" \
-out "$SVR_BASE.pem"
# create client request and sign it, piped
echo "[req]" > request.cfg
echo "default_bits=$BITS" >> request.cfg
echo "default_md=$HASH" >> request.cfg
echo "prompt=no" >> request.cfg
echo "distinguished_name=req_distinguished_name" >> request.cfg
echo "" >> request.cfg
echo "[req_distinguished_name]" >> request.cfg
echo "commonName=$CLIENTNAME" >> request.cfg
[ ! -f "SVR_BASE.pem" ] || fatal "cannot create server certificate"
fi
test -f request.cfg || error "could not create request.cfg"
# ===
# Generate client certificate
# ===
# generate private key; do no recreate it if they already exist.
if [ ! -f "$CTL_BASE.key" ]; then
openssl genrsa -out "$CTL_BASE.key" "$BITS"
fi
cat >client.cnf <<EOF
[req]
default_bits=$BITS
default_md=$HASH
prompt=no
distinguished_name=req_distinguished_name
[req_distinguished_name]
commonName=$CLIENTNAME
EOF
[ -f client.cnf ] || fatal "cannot create openssl configuration"
if [ ! -f "$CTL_BASE.pem" -o $RECREATE -eq 1 ]; then
openssl x509 \
-addtrust serverAuth \
-in "$SVR_BASE.pem" \
-out "${SVR_BASE}_trust.pem"
openssl req \
-new \
-config client.cnf \
-key "$CTL_BASE.key" \
| openssl x509 \
-req \
-days "$DAYS" \
-CA "${SVR_BASE}_trust.pem" \
-CAkey "$SVR_BASE.key" \
-CAcreateserial \
-$HASH \
-out "$CTL_BASE.pem"
[ ! -f "CTL_BASE.pem" ] || fatal "cannot create signed client certificate"
fi
# remove unused permissions
chmod o-rw \
"$SVR_BASE.pem" \
"$SVR_BASE.key" \
"$CTL_BASE.pem" \
"$CTL_BASE.key"
cleanup
echo "Setup success. Certificates created. Enable in unbound.conf file to use"
echo "create $CTL_BASE.pem (signed client certificate)"
openssl req -key $CTL_BASE.key -config request.cfg -new | openssl x509 -req -days $DAYS -CA $SVR_BASE"_trust.pem" -CAkey $SVR_BASE.key -CAcreateserial -$HASH -out $CTL_BASE.pem
test -f $CTL_BASE.pem || error "could not create $CTL_BASE.pem"
# create trusted usage pem
# openssl x509 -in $CTL_BASE.pem -addtrust clientAuth -out $CTL_BASE"_trust.pem"
@ -148,13 +205,3 @@ test -f $CTL_BASE.pem || error "could not create $CTL_BASE.pem"
# echo "empty password is used, simply click OK on the password dialog box."
# openssl pkcs12 -export -in $CTL_BASE"_trust.pem" -inkey $CTL_BASE.key -name "unbound remote control client cert" -out $CTL_BASE"_browser.pfx" -password "pass:" || error "could not create browser certificate"
# set desired permissions
chmod 0640 $SVR_BASE.pem $SVR_BASE.key $CTL_BASE.pem $CTL_BASE.key
# remove crap
rm -f request.cfg
rm -f $CTL_BASE"_trust.pem" $SVR_BASE"_trust.pem" $SVR_BASE"_trust.srl"
echo "Setup success. Certificates created. Enable in unbound.conf file to use"
exit 0

View File

@ -74,6 +74,10 @@
#include <sys/un.h>
#endif
#ifdef HAVE_TARGETCONDITIONALS_H
#include <TargetConditionals.h>
#endif
static void usage(void) ATTR_NORETURN;
static void ssl_err(const char* s) ATTR_NORETURN;
static void ssl_path_err(const char* s, const char *path) ATTR_NORETURN;
@ -264,6 +268,9 @@ static void print_mem(struct ub_shm_stat_info* shm_stat,
#ifdef USE_IPSECMOD
PR_LL("mem.mod.ipsecmod", shm_stat->mem.ipsecmod);
#endif
#ifdef WITH_DYNLIBMODULE
PR_LL("mem.mod.dynlib", shm_stat->mem.dynlib);
#endif
#ifdef USE_DNSCRYPT
PR_LL("mem.cache.dnscrypt_shared_secret",
shm_stat->mem.dnscrypt_shared_secret);
@ -879,11 +886,16 @@ int main(int argc, char* argv[])
if(argc == 0)
usage();
if(argc >= 1 && strcmp(argv[0], "start")==0) {
#if defined(TARGET_OS_TV) || defined(TARGET_OS_WATCH)
fatal_exit("could not exec unbound: %s",
strerror(ENOSYS));
#else
if(execlp("unbound", "unbound", "-c", cfgfile,
(char*)NULL) < 0) {
fatal_exit("could not exec unbound: %s",
strerror(errno));
}
#endif
}
if(argc >= 1 && strcmp(argv[0], "stats_shm")==0) {
print_stats_shm(cfgfile);

View File

@ -248,3 +248,19 @@ void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#ifdef USE_DNSTAP
void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif
#ifdef USE_DNSTAP
void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
void* ATTR_UNUSED(arg))
{
log_assert(0);
}
#endif

View File

@ -1031,6 +1031,7 @@ outside_network_create(struct comm_base* base, size_t bufsize,
size_t ATTR_UNUSED(num_ports), char** ATTR_UNUSED(ifs),
int ATTR_UNUSED(num_ifs), int ATTR_UNUSED(do_ip4),
int ATTR_UNUSED(do_ip6), size_t ATTR_UNUSED(num_tcp),
int ATTR_UNUSED(dscp),
struct infra_cache* infra,
struct ub_randstate* ATTR_UNUSED(rnd),
int ATTR_UNUSED(use_caps_for_id), int* ATTR_UNUSED(availports),
@ -1038,7 +1039,8 @@ outside_network_create(struct comm_base* base, size_t bufsize,
int ATTR_UNUSED(outgoing_tcp_mss),
void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param),
int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx),
int ATTR_UNUSED(delayclose), struct dt_env* ATTR_UNUSED(dtenv))
int ATTR_UNUSED(delayclose), int ATTR_UNUSED(tls_use_sni),
struct dt_env* ATTR_UNUSED(dtenv))
{
struct replay_runtime* runtime = (struct replay_runtime*)base;
struct outside_network* outnet = calloc(1,
@ -1583,7 +1585,7 @@ int create_udp_sock(int ATTR_UNUSED(family), int ATTR_UNUSED(socktype),
int* ATTR_UNUSED(noproto), int ATTR_UNUSED(rcv), int ATTR_UNUSED(snd),
int ATTR_UNUSED(listen), int* ATTR_UNUSED(reuseport),
int ATTR_UNUSED(transparent), int ATTR_UNUSED(freebind),
int ATTR_UNUSED(use_systemd))
int ATTR_UNUSED(use_systemd), int ATTR_UNUSED(dscp))
{
/* if you actually print to this, it'll be stdout during test */
return 1;
@ -1790,7 +1792,7 @@ int comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
}
int outnet_get_tcp_fd(struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(tcp_mss))
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(tcp_mss), int ATTR_UNUSED(dscp))
{
log_assert(0);
return -1;

View File

@ -26,15 +26,20 @@ cd testdata
TPKG=../testcode/mini_tdir.sh
#RUNLIST=`(ls -1d *.tdir|grep -v '^0[016]')`
RUNLIST=`(ls -1d *.tdir)`
if test "$#" = "1"; then RUNLIST="$1"; fi
if test "$#" = "1"; then
RUNLIST="$1";
if echo "$RUNLIST" | grep '/$' >/dev/null; then
RUNLIST=`echo "$RUNLIST" | sed -e 's?/$??'`
fi
fi
# fix up tdir that was edited on keyboard interrupt.
cleanup() {
echo cleanup
if test -f "$t.bak"; then mv "$t.bak" "$t"; fi
if test -f "$t.bak"; then rm -fr "${t}"; mv "$t.bak" "$t"; fi
exit 0
}
trap cleanup SIGINT
trap cleanup INT
for t in $RUNLIST
do

View File

@ -200,6 +200,7 @@ write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id,
static void
recv_one(int fd, int udp, SSL* ssl, sldns_buffer* buf)
{
size_t i;
char* pktstr;
uint16_t len;
if(!udp) {
@ -270,7 +271,13 @@ recv_one(int fd, int udp, SSL* ssl, sldns_buffer* buf)
len = (size_t)l;
}
printf("\nnext received packet\n");
log_buf(0, "data", buf);
printf("data[%d] ", (int)sldns_buffer_limit(buf));
for(i=0; i<sldns_buffer_limit(buf); i++) {
const char* hex = "0123456789ABCDEF";
printf("%c%c", hex[(sldns_buffer_read_u8_at(buf, i)&0xf0)>>4],
hex[sldns_buffer_read_u8_at(buf, i)&0x0f]);
}
printf("\n");
pktstr = sldns_wire2str_pkt(sldns_buffer_begin(buf), len);
printf("%s", pktstr);

View File

@ -577,3 +577,13 @@ void wsvc_cron_cb(void* ATTR_UNUSED(arg))
}
#endif /* UB_ON_WINDOWS */
int tcp_connect_errno_needs_log(struct sockaddr* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen))
{
return 1;
}
int squelch_err_ssl_handshake(unsigned long ATTR_UNUSED(err))
{
return 0;
}

View File

@ -867,7 +867,13 @@ main(int argc, char* argv[])
printf("\tperforms unit tests.\n");
return 1;
}
/* Disable roundrobin for the unit tests */
RRSET_ROUNDROBIN = 0;
#ifdef USE_LIBEVENT
printf("Start of %s+libevent unit test.\n", PACKAGE_STRING);
#else
printf("Start of %s unit test.\n", PACKAGE_STRING);
#endif
#ifdef HAVE_SSL
# ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
ERR_load_crypto_strings();
@ -917,7 +923,9 @@ main(int argc, char* argv[])
# ifdef HAVE_EVP_CLEANUP
EVP_cleanup();
# endif
# if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE) && defined(HAVE_ENGINE_CLEANUP)
ENGINE_cleanup();
# endif
CONF_modules_free();
# endif
# ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA

View File

@ -2,6 +2,7 @@ server:
# to make sure the check doesn't fail on username or chrootdir.
username: ""
chroot: ""
directory: ""
forward-zone:
name: "example.com"

5
testdata/04-checkconf.tdir/bad.dscp vendored Normal file
View File

@ -0,0 +1,5 @@
include: "good.min"
server:
# an abnormal value for the option
ip-dscp: 500

View File

@ -0,0 +1,3 @@
include-toplevel: include.withoutclauses.*
server:
identity: "top 1"

View File

@ -0,0 +1,5 @@
include-toplevel: include.withclauses.*
server:
identity: "top 1"
include: include.withoutclauses.*
include-toplevel: include.withoutclauses.*

View File

@ -0,0 +1,6 @@
include-toplevel: include.withclauses.*
server:
identity: "top 1"
include: include.withoutclauses.*
include-toplevel: include.withclauses.*
include: include.withoutclauses.*

View File

@ -0,0 +1,7 @@
include-toplevel: include.withclauses.*
server:
identity: "top 1"
include: include.withoutclauses.*
include-toplevel: include.withclauses.*
include: include.withclauses.*
include-toplevel: include.withoutclauses.*

View File

@ -0,0 +1,8 @@
include-toplevel: include.withclauses.*
server:
identity: "top 1"
include: include.withoutclauses.*
include-toplevel: include.withsomeclauses.*
include: include.withclauses.*
include-toplevel: include.withclauses.*
server: identity: "top 2"

View File

@ -0,0 +1,10 @@
include-toplevel: include.withclauses.*
include-toplevel: include.withclauses.*
server:
identity: "top 1"
include: include.withoutclauses.*
include-toplevel: include.withclauses.*
include: include.withclauses.*
include-toplevel: include.withclauses.*
server: identity: "top 2"
include-toplevel: include.includetop.withoutclauses.*

View File

@ -0,0 +1,11 @@
include-toplevel: include.withclauses.*
include-toplevel: include.withclauses.*
server:
identity: "top 1"
include: include.withoutclauses.*
include-toplevel: include.withclauses.*
include: include.withclauses.*
include-toplevel: include.withclauses.*
server: identity: "top 2"
include-toplevel: include.includetop.withclauses.*
include-toplevel: include.include.withoutclauses.*

View File

@ -1,2 +1,4 @@
server:
username: blabla_noexist_user
chroot: ""
directory: ""

View File

@ -220,6 +220,10 @@ server:
# more slabs reduce lock contention, but fragment memory usage.
key-cache-slabs: 4
# the value of the Differentiated Services Codepoint (DSCP)
# in the differentiated services field (DS) of the outgoing
# IP packets
ip-dscp: 5
# Stub zones.
# Create entries like below, to make all queries for 'example.com' and

View File

@ -0,0 +1,16 @@
include-toplevel: include.withclauses.*
include-toplevel: include.withclauses.*
server:
identity: "top 1"
include: include.withoutclauses.*
include-toplevel: include.withclauses.*
include: include.withclauses.*
include-toplevel: include.withclauses.*
server: identity: "top 2"
include-toplevel: include.includetop.withclauses.*
include-toplevel: include.include.withclauses.*
include-toplevel: include.include.withclauses.*
server:
chroot: ""
directory: ""
username: ""

7
testdata/04-checkconf.tdir/good.min vendored Normal file
View File

@ -0,0 +1,7 @@
# the minimal passing config - include in your bad.x to verify that
# it is your option which triggers failure
server:
chroot: ""
username: ""
directory: "."
pidfile: ""

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