mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-20 13:42:54 -05:00
Merge branch 'master' into stream-reuse
This commit is contained in:
commit
a83f5d7260
231 changed files with 18252 additions and 7354 deletions
12
.github/FUNDING.yml
vendored
12
.github/FUNDING.yml
vendored
|
|
@ -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
1
.gitignore
vendored
|
|
@ -37,6 +37,7 @@
|
|||
/petal
|
||||
/pktview
|
||||
/streamtcp
|
||||
/unbound-dnstap-socket
|
||||
/testbound
|
||||
/unittest
|
||||
/contrib/libunbound.pc
|
||||
|
|
|
|||
342
.travis.yml
342
.travis.yml
|
|
@ -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
|
||||
|
|
|
|||
124
Makefile.in
124
Makefile.in
|
|
@ -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
278
README-Travis.md
Normal 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.
|
||||
|
|
@ -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
|
||||
#
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
875
config.guess
vendored
875
config.guess
vendored
File diff suppressed because it is too large
Load diff
15
config.h.in
15
config.h.in
|
|
@ -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
|
||||
|
||||
|
|
@ -590,6 +596,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 +814,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 +866,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
|
||||
|
||||
|
|
|
|||
2786
config.sub
vendored
2786
config.sub
vendored
File diff suppressed because it is too large
Load diff
219
configure
vendored
219
configure
vendored
|
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.10.0.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.10.2.
|
||||
#
|
||||
# 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.0'
|
||||
PACKAGE_STRING='unbound 1.10.0'
|
||||
PACKAGE_VERSION='1.10.2'
|
||||
PACKAGE_STRING='unbound 1.10.2'
|
||||
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.0 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.10.2 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.0:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.10.2:";;
|
||||
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.0
|
||||
unbound configure 1.10.2
|
||||
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.0, which was
|
||||
It was created by unbound $as_me 1.10.2, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
|
|
@ -2801,11 +2811,11 @@ UNBOUND_VERSION_MAJOR=1
|
|||
|
||||
UNBOUND_VERSION_MINOR=10
|
||||
|
||||
UNBOUND_VERSION_MICRO=0
|
||||
UNBOUND_VERSION_MICRO=2
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=7
|
||||
LIBUNBOUND_REVISION=9
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
|
|
@ -2880,6 +2890,8 @@ LIBUNBOUND_AGE=1
|
|||
# 1.9.5 had 9:5:1
|
||||
# 1.9.6 had 9:6:1
|
||||
# 1.10.0 had 9:7:1
|
||||
# 1.10.1 had 9:8:1
|
||||
# 1.10.2 had 9:9:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
|
|
@ -14728,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"
|
||||
|
|
@ -17170,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.
|
||||
|
|
@ -17311,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
|
||||
#
|
||||
|
|
@ -17416,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
|
||||
|
|
@ -18272,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 SSL_CTX_set_tlsext_ticket_key_cb 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"
|
||||
|
|
@ -19106,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
|
||||
|
|
@ -19143,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
|
||||
|
|
@ -20967,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 :
|
||||
|
|
@ -21107,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
|
||||
|
|
@ -21442,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; }
|
||||
|
|
@ -21598,7 +21619,7 @@ _ACEOF
|
|||
|
||||
|
||||
|
||||
version=1.10.0
|
||||
version=1.10.2
|
||||
|
||||
date=`date +'%b %e, %Y'`
|
||||
|
||||
|
|
@ -22117,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.0, which was
|
||||
This file was extended by unbound $as_me 1.10.2, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
|
@ -22183,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.0
|
||||
unbound config.status 1.10.2
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
|
|
|||
81
configure.ac
81
configure.ac
|
|
@ -11,14 +11,14 @@ sinclude(dnscrypt/dnscrypt.m4)
|
|||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[10])
|
||||
m4_define([VERSION_MICRO],[0])
|
||||
m4_define([VERSION_MICRO],[2])
|
||||
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=7
|
||||
LIBUNBOUND_REVISION=9
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
|
|
@ -93,6 +93,8 @@ LIBUNBOUND_AGE=1
|
|||
# 1.9.5 had 9:5:1
|
||||
# 1.9.6 had 9:6:1
|
||||
# 1.10.0 had 9:7:1
|
||||
# 1.10.1 had 9:8:1
|
||||
# 1.10.2 had 9:9:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
|
|
@ -398,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)
|
||||
|
|
@ -623,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],
|
||||
|
|
@ -674,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,7 +851,7 @@ else
|
|||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h],,, [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_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 SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback])
|
||||
|
||||
# these check_funcs need -lssl
|
||||
BAKLIBS="$LIBS"
|
||||
|
|
@ -1214,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
|
||||
|
|
@ -1248,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. ])
|
||||
|
|
@ -1687,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])
|
||||
|
|
@ -1777,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.
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ distribution but may be helpful.
|
|||
works like the BIND feature (removes AAAA records unless AAAA-only domain).
|
||||
Useful for certain 'broken IPv6 default route' scenarios.
|
||||
Patch from Stephane Lapie for ASAHI Net.
|
||||
* unbound_smf22.tar.gz: Solaris SMF installation/removal scripts.
|
||||
* unbound_smf23.tar.gz: Solaris SMF installation/removal scripts.
|
||||
Contributed by Yuri Voinov.
|
||||
* unbound.socket and unbound.service: systemd files for unbound, install them
|
||||
in /usr/lib/systemd/system. Contributed by Sami Kerola and Pavel Odintsov.
|
||||
|
|
@ -51,3 +51,5 @@ distribution but may be helpful.
|
|||
compile. From Saksham Manchanda (Secure64). Please note that we think
|
||||
this will drop DNSKEY and DS lookups for tlds and hence break DNSSEC
|
||||
lookups for downstream clients.
|
||||
* drop2rpz: perl script that converts the Spamhaus DROP-List in RPZ-Format,
|
||||
contributed by Andreas Schulze.
|
||||
|
|
|
|||
37
contrib/android/15-android.conf
Normal file
37
contrib/android/15-android.conf
Normal 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",
|
||||
},
|
||||
);
|
||||
51
contrib/android/install_expat.sh
Executable file
51
contrib/android/install_expat.sh
Executable 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
60
contrib/android/install_ndk.sh
Executable 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
|
||||
44
contrib/android/install_openssl.sh
Executable file
44
contrib/android/install_openssl.sh
Executable 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
|
||||
6
contrib/android/install_tools.sh
Executable file
6
contrib/android/install_tools.sh
Executable 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
203
contrib/android/setenv_android.sh
Executable 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
|
||||
39
contrib/drop2rpz
Normal file
39
contrib/drop2rpz
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# usage: curl --silent https://www.spamhaus.org/drop/drop.txt | $0 > /path/to/spamhaus-drop.rpz.local
|
||||
#
|
||||
# unbound.conf:
|
||||
# rpz:
|
||||
# name: "spamhaus-drop.rpz.local."
|
||||
# zonefile: "/path/tp/spamhaus-drop.rpz.local"
|
||||
# rpz-log: yes
|
||||
# rpz-log-name: "spamhaus-drop"
|
||||
#
|
||||
|
||||
use strict;
|
||||
use vars qw{$o1 $o2 $o3 $o4 $m};
|
||||
|
||||
# trailing dots required
|
||||
my $origin = 'drop.spamhaus.org.rpz.local.';
|
||||
my $mname = 'localhost.';
|
||||
my $rname = 'root.localhost.';
|
||||
my $ns = $mname;
|
||||
|
||||
my $rpz_action = '.'; # return NXDOMAIN
|
||||
#my $rpz_action = '*.'; # return NODATA
|
||||
#my $rpz_action = 'rpz-drop.'; # drop the query
|
||||
|
||||
print "$origin SOA $mname $rname 1 43200 7200 2419200 3600\n";
|
||||
print "$origin NS $ns\n";
|
||||
while(<>) {
|
||||
if(($o1, $o2, $o3, $o4, $m) = m{(\d+)\.(\d+)\.(\d+)\.(\d+)/(\d+)}) {
|
||||
print "$m.$o4.$o3.$o2.$o1.rpz-ip.$origin CNAME $rpz_action\n";
|
||||
} else {
|
||||
print "$_";
|
||||
}
|
||||
}
|
||||
|
||||
# add a testpoint: ask for "dns.google"
|
||||
# print "32.8.8.8.8.rpz-ip.$origin CNAME $rpz_action\n";
|
||||
|
||||
exit;
|
||||
41
contrib/ios/15-ios.conf
Normal file
41
contrib/ios/15-ios.conf
Normal 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
56
contrib/ios/install_expat.sh
Executable 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
52
contrib/ios/install_openssl.sh
Executable 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
8
contrib/ios/install_tools.sh
Executable 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
48
contrib/ios/openssl.patch
Normal 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
274
contrib/ios/setenv_ios.sh
Executable 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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Binary file not shown.
BIN
contrib/unbound_smf23.tar.gz
Normal file
BIN
contrib/unbound_smf23.tar.gz
Normal file
Binary file not shown.
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
208
dnstap/dnstap_fstrm.c
Normal file
208
dnstap/dnstap_fstrm.c
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* 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_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);
|
||||
}
|
||||
179
dnstap/dnstap_fstrm.h
Normal file
179
dnstap/dnstap_fstrm.h
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* 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 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 */
|
||||
1842
dnstap/dtstream.c
Normal file
1842
dnstap/dtstream.c
Normal file
File diff suppressed because it is too large
Load diff
307
dnstap/dtstream.h
Normal file
307
dnstap/dtstream.h
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
/*
|
||||
* 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** 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 */
|
||||
1580
dnstap/unbound-dnstap-socket.c
Normal file
1580
dnstap/unbound-dnstap-socket.c
Normal file
File diff suppressed because it is too large
Load diff
264
doc/Changelog
264
doc/Changelog
|
|
@ -1,3 +1,267 @@
|
|||
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.
|
||||
|
||||
17 February 2020: George
|
||||
- Remove unused variable.
|
||||
|
||||
17 February 2020: Wouter
|
||||
- contrib/drop2rpz: perl script that converts the Spamhaus DROP-List
|
||||
in RPZ-Format, contributed by Andreas Schulze.
|
||||
|
||||
14 February 2020: Wouter
|
||||
- Fix spelling in unbound.conf.5.in.
|
||||
- Stop unbound-checkconf from insisting that auth-zone and rpz
|
||||
zonefiles have to exist. They can not exist, and download later.
|
||||
|
||||
13 February 2020: Wouter
|
||||
- tag for 1.10.0rc1 release.
|
||||
|
||||
12 February 2020: Wouter
|
||||
- Fix with libnettle make test with dsa disabled.
|
||||
- Fix contrib/fastrpz.patch to apply cleanly. Fix for serve-stale
|
||||
|
|
|
|||
|
|
@ -70,6 +70,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 +119,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 +473,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 +746,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 +859,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 +1028,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 +1041,38 @@ 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
|
||||
# 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:
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ server:
|
|||
.SH "FILE FORMAT"
|
||||
There must be whitespace between keywords. Attribute keywords end with a
|
||||
colon ':'. An attribute is followed by a value, or its containing attributes
|
||||
in which case it is refered to as a clause. Clauses can be repeated throughout
|
||||
in which case it is referred to as a clause. Clauses can be repeated throughout
|
||||
the file (or included files) to group attributes under the same clause.
|
||||
.P
|
||||
Files can be included using the
|
||||
|
|
@ -126,9 +126,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 +326,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 +390,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 +546,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.
|
||||
|
|
@ -911,7 +932,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 +963,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
|
||||
|
|
@ -1809,6 +1832,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 +2101,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 +2160,90 @@ 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-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
|
||||
|
|
@ -2174,7 +2304,7 @@ Specify a string to be part of the log line, for easy referencing.
|
|||
.TP
|
||||
.B tags: \fI<list of tags>
|
||||
Limit the policies from this RPZ clause to clients with a matching tag. Tags
|
||||
need to be defined in \fBdefine\-tag\fR and can be assiged to client addresses
|
||||
need to be defined in \fBdefine\-tag\fR and can be assigned to client addresses
|
||||
using \fBaccess\-control\-tag\fR. Enclose list of tags in quotes ("") and put
|
||||
spaces between tags. If no tags are specified the policies from this clause will
|
||||
be applied for all clients.
|
||||
|
|
|
|||
295
dynlibmod/dynlibmod.c
Normal file
295
dynlibmod/dynlibmod.c
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
#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
139
dynlibmod/dynlibmod.h
Normal 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 */
|
||||
128
dynlibmod/examples/helloworld.c
Normal file
128
dynlibmod/examples/helloworld.c
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
|
|||
}
|
||||
for(a = dp->target_list; a; a = a->next_target) {
|
||||
if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen,
|
||||
a->bogus, a->lame, a->tls_auth_name))
|
||||
a->bogus, a->lame, a->tls_auth_name, NULL))
|
||||
return NULL;
|
||||
}
|
||||
return copy;
|
||||
|
|
@ -161,7 +161,7 @@ delegpt_find_addr(struct delegpt* dp, struct sockaddr_storage* addr,
|
|||
int
|
||||
delegpt_add_target(struct delegpt* dp, struct regional* region,
|
||||
uint8_t* name, size_t namelen, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame)
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions)
|
||||
{
|
||||
struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen);
|
||||
log_assert(!dp->dp_type_mlc);
|
||||
|
|
@ -176,13 +176,14 @@ delegpt_add_target(struct delegpt* dp, struct regional* region,
|
|||
if(ns->got4 && ns->got6)
|
||||
ns->resolved = 1;
|
||||
}
|
||||
return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL);
|
||||
return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL,
|
||||
additions);
|
||||
}
|
||||
|
||||
int
|
||||
delegpt_add_addr(struct delegpt* dp, struct regional* region,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus,
|
||||
uint8_t lame, char* tls_auth_name)
|
||||
uint8_t lame, char* tls_auth_name, int* additions)
|
||||
{
|
||||
struct delegpt_addr* a;
|
||||
log_assert(!dp->dp_type_mlc);
|
||||
|
|
@ -194,6 +195,8 @@ delegpt_add_addr(struct delegpt* dp, struct regional* region,
|
|||
a->lame = 0;
|
||||
return 1;
|
||||
}
|
||||
if(additions)
|
||||
*additions = 1;
|
||||
|
||||
a = (struct delegpt_addr*)regional_alloc(region,
|
||||
sizeof(struct delegpt_addr));
|
||||
|
|
@ -382,10 +385,10 @@ delegpt_from_message(struct dns_msg* msg, struct regional* region)
|
|||
continue;
|
||||
|
||||
if(ntohs(s->rk.type) == LDNS_RR_TYPE_A) {
|
||||
if(!delegpt_add_rrset_A(dp, region, s, 0))
|
||||
if(!delegpt_add_rrset_A(dp, region, s, 0, NULL))
|
||||
return NULL;
|
||||
} else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA) {
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, s, 0))
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, s, 0, NULL))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -416,7 +419,7 @@ delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region,
|
|||
|
||||
int
|
||||
delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
|
||||
struct ub_packed_rrset_key* ak, uint8_t lame)
|
||||
struct ub_packed_rrset_key* ak, uint8_t lame, int* additions)
|
||||
{
|
||||
struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
|
||||
size_t i;
|
||||
|
|
@ -432,7 +435,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
|
|||
memmove(&sa.sin_addr, d->rr_data[i]+2, INET_SIZE);
|
||||
if(!delegpt_add_target(dp, region, ak->rk.dname,
|
||||
ak->rk.dname_len, (struct sockaddr_storage*)&sa,
|
||||
len, (d->security==sec_status_bogus), lame))
|
||||
len, (d->security==sec_status_bogus), lame, additions))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
|
@ -440,7 +443,7 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
|
|||
|
||||
int
|
||||
delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
|
||||
struct ub_packed_rrset_key* ak, uint8_t lame)
|
||||
struct ub_packed_rrset_key* ak, uint8_t lame, int* additions)
|
||||
{
|
||||
struct packed_rrset_data* d=(struct packed_rrset_data*)ak->entry.data;
|
||||
size_t i;
|
||||
|
|
@ -456,7 +459,7 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
|
|||
memmove(&sa.sin6_addr, d->rr_data[i]+2, INET6_SIZE);
|
||||
if(!delegpt_add_target(dp, region, ak->rk.dname,
|
||||
ak->rk.dname_len, (struct sockaddr_storage*)&sa,
|
||||
len, (d->security==sec_status_bogus), lame))
|
||||
len, (d->security==sec_status_bogus), lame, additions))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
|
@ -464,20 +467,33 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
|
|||
|
||||
int
|
||||
delegpt_add_rrset(struct delegpt* dp, struct regional* region,
|
||||
struct ub_packed_rrset_key* rrset, uint8_t lame)
|
||||
struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions)
|
||||
{
|
||||
if(!rrset)
|
||||
return 1;
|
||||
if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NS)
|
||||
return delegpt_rrset_add_ns(dp, region, rrset, lame);
|
||||
else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A)
|
||||
return delegpt_add_rrset_A(dp, region, rrset, lame);
|
||||
return delegpt_add_rrset_A(dp, region, rrset, lame, additions);
|
||||
else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA)
|
||||
return delegpt_add_rrset_AAAA(dp, region, rrset, lame);
|
||||
return delegpt_add_rrset_AAAA(dp, region, rrset, lame,
|
||||
additions);
|
||||
log_warn("Unknown rrset type added to delegpt");
|
||||
return 1;
|
||||
}
|
||||
|
||||
void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype)
|
||||
{
|
||||
if(ns) {
|
||||
if(qtype == LDNS_RR_TYPE_A)
|
||||
ns->got4 = 2;
|
||||
else if(qtype == LDNS_RR_TYPE_AAAA)
|
||||
ns->got6 = 2;
|
||||
if(ns->got4 && ns->got6)
|
||||
ns->resolved = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg)
|
||||
{
|
||||
struct reply_info* rep = (struct reply_info*)msg->entry.data;
|
||||
|
|
@ -487,14 +503,7 @@ void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg)
|
|||
if(FLAGS_GET_RCODE(rep->flags) != 0 || rep->an_numrrsets == 0) {
|
||||
struct delegpt_ns* ns = delegpt_find_ns(dp, msg->key.qname,
|
||||
msg->key.qname_len);
|
||||
if(ns) {
|
||||
if(msg->key.qtype == LDNS_RR_TYPE_A)
|
||||
ns->got4 = 1;
|
||||
else if(msg->key.qtype == LDNS_RR_TYPE_AAAA)
|
||||
ns->got6 = 1;
|
||||
if(ns->got4 && ns->got6)
|
||||
ns->resolved = 1;
|
||||
}
|
||||
delegpt_mark_neg(ns, msg->key.qtype);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,9 +106,10 @@ struct delegpt_ns {
|
|||
* and marked true if got4 and got6 are both true.
|
||||
*/
|
||||
int resolved;
|
||||
/** if the ipv4 address is in the delegpt */
|
||||
/** if the ipv4 address is in the delegpt, 0=not, 1=yes 2=negative,
|
||||
* negative means it was done, but no content. */
|
||||
uint8_t got4;
|
||||
/** if the ipv6 address is in the delegpt */
|
||||
/** if the ipv6 address is in the delegpt, 0=not, 1=yes 2=negative */
|
||||
uint8_t got6;
|
||||
/**
|
||||
* If the name is parent-side only and thus dispreferred.
|
||||
|
|
@ -215,11 +216,12 @@ int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional,
|
|||
* @param addrlen: the length of addr.
|
||||
* @param bogus: security status for the address, pass true if bogus.
|
||||
* @param lame: address is lame.
|
||||
* @param additions: will be set to 1 if a new address is added
|
||||
* @return false on error.
|
||||
*/
|
||||
int delegpt_add_target(struct delegpt* dp, struct regional* regional,
|
||||
uint8_t* name, size_t namelen, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame);
|
||||
socklen_t addrlen, uint8_t bogus, uint8_t lame, int* additions);
|
||||
|
||||
/**
|
||||
* Add A RRset to delegpt.
|
||||
|
|
@ -227,10 +229,11 @@ int delegpt_add_target(struct delegpt* dp, struct regional* regional,
|
|||
* @param regional: where to allocate the info.
|
||||
* @param rrset: RRset A to add.
|
||||
* @param lame: rrset is lame, disprefer it.
|
||||
* @param additions: will be set to 1 if a new address is added
|
||||
* @return 0 on alloc error.
|
||||
*/
|
||||
int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional,
|
||||
struct ub_packed_rrset_key* rrset, uint8_t lame);
|
||||
struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);
|
||||
|
||||
/**
|
||||
* Add AAAA RRset to delegpt.
|
||||
|
|
@ -238,10 +241,11 @@ int delegpt_add_rrset_A(struct delegpt* dp, struct regional* regional,
|
|||
* @param regional: where to allocate the info.
|
||||
* @param rrset: RRset AAAA to add.
|
||||
* @param lame: rrset is lame, disprefer it.
|
||||
* @param additions: will be set to 1 if a new address is added
|
||||
* @return 0 on alloc error.
|
||||
*/
|
||||
int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional,
|
||||
struct ub_packed_rrset_key* rrset, uint8_t lame);
|
||||
struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);
|
||||
|
||||
/**
|
||||
* Add any RRset to delegpt.
|
||||
|
|
@ -250,10 +254,11 @@ int delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* regional,
|
|||
* @param regional: where to allocate the info.
|
||||
* @param rrset: RRset to add, NS, A, AAAA.
|
||||
* @param lame: rrset is lame, disprefer it.
|
||||
* @param additions: will be set to 1 if a new address is added
|
||||
* @return 0 on alloc error.
|
||||
*/
|
||||
int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
|
||||
struct ub_packed_rrset_key* rrset, uint8_t lame);
|
||||
struct ub_packed_rrset_key* rrset, uint8_t lame, int* additions);
|
||||
|
||||
/**
|
||||
* Add address to the delegation point. No servername is associated or checked.
|
||||
|
|
@ -264,11 +269,12 @@ int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
|
|||
* @param bogus: if address is bogus.
|
||||
* @param lame: if address is lame.
|
||||
* @param tls_auth_name: TLS authentication name (or NULL).
|
||||
* @param additions: will be set to 1 if a new address is added
|
||||
* @return false on error.
|
||||
*/
|
||||
int delegpt_add_addr(struct delegpt* dp, struct regional* regional,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t bogus, uint8_t lame, char* tls_auth_name);
|
||||
uint8_t bogus, uint8_t lame, char* tls_auth_name, int* additions);
|
||||
|
||||
/**
|
||||
* Find NS record in name list of delegation point.
|
||||
|
|
@ -341,6 +347,14 @@ size_t delegpt_count_targets(struct delegpt* dp);
|
|||
struct delegpt* delegpt_from_message(struct dns_msg* msg,
|
||||
struct regional* regional);
|
||||
|
||||
/**
|
||||
* Mark negative return in delegation point for specific nameserver.
|
||||
* sets the got4 or got6 to negative, updates the ns->resolved.
|
||||
* @param ns: the nameserver in the delegpt.
|
||||
* @param qtype: A or AAAA (host order).
|
||||
*/
|
||||
void delegpt_mark_neg(struct delegpt_ns* ns, uint16_t qtype);
|
||||
|
||||
/**
|
||||
* Add negative message to delegation point.
|
||||
* @param dp: delegation point.
|
||||
|
|
|
|||
|
|
@ -185,8 +185,9 @@ mark_additional_rrset(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
/** Get target name of a CNAME */
|
||||
static int
|
||||
parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname,
|
||||
size_t* snamelen)
|
||||
size_t* snamelen, sldns_buffer* pkt)
|
||||
{
|
||||
size_t oldpos, dlen;
|
||||
if(rrset->rr_count != 1) {
|
||||
struct rr_parse* sig;
|
||||
verbose(VERB_ALGO, "Found CNAME rrset with "
|
||||
|
|
@ -204,6 +205,19 @@ parse_get_cname_target(struct rrset_parse* rrset, uint8_t** sname,
|
|||
*sname = rrset->rr_first->ttl_data + sizeof(uint32_t)
|
||||
+ sizeof(uint16_t); /* skip ttl, rdatalen */
|
||||
*snamelen = rrset->rr_first->size - sizeof(uint16_t);
|
||||
|
||||
if(rrset->rr_first->outside_packet) {
|
||||
if(!dname_valid(*sname, *snamelen))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
oldpos = sldns_buffer_position(pkt);
|
||||
sldns_buffer_set_position(pkt, (size_t)(*sname - sldns_buffer_begin(pkt)));
|
||||
dlen = pkt_dname_len(pkt);
|
||||
sldns_buffer_set_position(pkt, oldpos);
|
||||
if(dlen == 0)
|
||||
return 0; /* parse fail on the rdata name */
|
||||
*snamelen = dlen;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -215,7 +229,7 @@ synth_cname(uint8_t* qname, size_t qnamelen, struct rrset_parse* dname_rrset,
|
|||
/* we already know that sname is a strict subdomain of DNAME owner */
|
||||
uint8_t* dtarg = NULL;
|
||||
size_t dtarglen;
|
||||
if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen))
|
||||
if(!parse_get_cname_target(dname_rrset, &dtarg, &dtarglen, pkt))
|
||||
return 0;
|
||||
if(qnamelen <= dname_rrset->dname_len)
|
||||
return 0;
|
||||
|
|
@ -388,7 +402,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
/* check next cname */
|
||||
uint8_t* t = NULL;
|
||||
size_t tlen = 0;
|
||||
if(!parse_get_cname_target(nx, &t, &tlen))
|
||||
if(!parse_get_cname_target(nx, &t, &tlen, pkt))
|
||||
return 0;
|
||||
if(dname_pkt_compare(pkt, alias, t) == 0) {
|
||||
/* it's OK and better capitalized */
|
||||
|
|
@ -439,7 +453,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
size_t tlen = 0;
|
||||
if(synth_cname(sname, snamelen, nx, alias,
|
||||
&aliaslen, pkt) &&
|
||||
parse_get_cname_target(rrset, &t, &tlen) &&
|
||||
parse_get_cname_target(rrset, &t, &tlen, pkt) &&
|
||||
dname_pkt_compare(pkt, alias, t) == 0) {
|
||||
/* the synthesized CNAME equals the
|
||||
* current CNAME. This CNAME is the
|
||||
|
|
@ -460,7 +474,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
|||
}
|
||||
|
||||
/* move to next name in CNAME chain */
|
||||
if(!parse_get_cname_target(rrset, &sname, &snamelen))
|
||||
if(!parse_get_cname_target(rrset, &sname, &snamelen, pkt))
|
||||
return 0;
|
||||
prev = rrset;
|
||||
rrset = rrset->rrset_all_next;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1142,7 +1199,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env,
|
|||
log_rrset_key(VERB_ALGO, "found parent-side", akey);
|
||||
ns->done_pside4 = 1;
|
||||
/* a negative-cache-element has no addresses it adds */
|
||||
if(!delegpt_add_rrset_A(dp, region, akey, 1))
|
||||
if(!delegpt_add_rrset_A(dp, region, akey, 1, NULL))
|
||||
log_err("malloc failure in lookup_parent_glue");
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
}
|
||||
|
|
@ -1154,7 +1211,7 @@ int iter_lookup_parent_glue_from_cache(struct module_env* env,
|
|||
log_rrset_key(VERB_ALGO, "found parent-side", akey);
|
||||
ns->done_pside6 = 1;
|
||||
/* a negative-cache-element has no addresses it adds */
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, 1))
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, 1, NULL))
|
||||
log_err("malloc failure in lookup_parent_glue");
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@
|
|||
/* in msec */
|
||||
int UNKNOWN_SERVER_NICENESS = 376;
|
||||
|
||||
static void target_count_increase_nx(struct iter_qstate* iq, int num);
|
||||
|
||||
int
|
||||
iter_init(struct module_env* env, int id)
|
||||
{
|
||||
|
|
@ -150,6 +152,7 @@ iter_new(struct module_qstate* qstate, int id)
|
|||
iq->sent_count = 0;
|
||||
iq->ratelimit_ok = 0;
|
||||
iq->target_count = NULL;
|
||||
iq->dp_target_count = 0;
|
||||
iq->wait_priming_stub = 0;
|
||||
iq->refetch_glue = 0;
|
||||
iq->dnssec_expected = 0;
|
||||
|
|
@ -159,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
|
||||
|
|
@ -221,6 +224,7 @@ final_state(struct iter_qstate* iq)
|
|||
static void
|
||||
error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
|
||||
{
|
||||
struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id];
|
||||
struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id];
|
||||
|
||||
if(qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
|
||||
|
|
@ -246,7 +250,11 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
|
|||
super->region, super_iq->dp))
|
||||
log_err("out of memory adding missing");
|
||||
}
|
||||
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
|
||||
dpns->resolved = 1; /* mark as failed */
|
||||
if((dpns->got4 == 2 || !ie->supports_ipv4) &&
|
||||
(dpns->got6 == 2 || !ie->supports_ipv6))
|
||||
target_count_increase_nx(super_iq, 1);
|
||||
}
|
||||
if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) {
|
||||
/* prime failed to get delegation */
|
||||
|
|
@ -621,7 +629,7 @@ static void
|
|||
target_count_create(struct iter_qstate* iq)
|
||||
{
|
||||
if(!iq->target_count) {
|
||||
iq->target_count = (int*)calloc(2, sizeof(int));
|
||||
iq->target_count = (int*)calloc(3, sizeof(int));
|
||||
/* if calloc fails we simply do not track this number */
|
||||
if(iq->target_count)
|
||||
iq->target_count[0] = 1;
|
||||
|
|
@ -634,6 +642,15 @@ target_count_increase(struct iter_qstate* iq, int num)
|
|||
target_count_create(iq);
|
||||
if(iq->target_count)
|
||||
iq->target_count[1] += num;
|
||||
iq->dp_target_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
target_count_increase_nx(struct iter_qstate* iq, int num)
|
||||
{
|
||||
target_count_create(iq);
|
||||
if(iq->target_count)
|
||||
iq->target_count[2] += num;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -656,13 +673,15 @@ target_count_increase(struct iter_qstate* iq, int num)
|
|||
* @param subq_ret: if newly allocated, the subquerystate, or NULL if it does
|
||||
* not need initialisation.
|
||||
* @param v: if true, validation is done on the subquery.
|
||||
* @param detached: true if this qstate should not attach to the subquery
|
||||
* @return false on error (malloc).
|
||||
*/
|
||||
static int
|
||||
generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
uint16_t qclass, struct module_qstate* qstate, int id,
|
||||
struct iter_qstate* iq, enum iter_state initial_state,
|
||||
enum iter_state finalstate, struct module_qstate** subq_ret, int v)
|
||||
enum iter_state finalstate, struct module_qstate** subq_ret, int v,
|
||||
int detached)
|
||||
{
|
||||
struct module_qstate* subq = NULL;
|
||||
struct iter_qstate* subiq = NULL;
|
||||
|
|
@ -689,11 +708,23 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
|||
valrec = 1;
|
||||
}
|
||||
|
||||
/* attach subquery, lookup existing or make a new one */
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec,
|
||||
&subq)) {
|
||||
return 0;
|
||||
if(detached) {
|
||||
struct mesh_state* sub = NULL;
|
||||
fptr_ok(fptr_whitelist_modenv_add_sub(
|
||||
qstate->env->add_sub));
|
||||
if(!(*qstate->env->add_sub)(qstate, &qinf,
|
||||
qflags, prime, valrec, &subq, &sub)){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* attach subquery, lookup existing or make a new one */
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(
|
||||
qstate->env->attach_sub));
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime,
|
||||
valrec, &subq)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
*subq_ret = subq;
|
||||
if(subq) {
|
||||
|
|
@ -716,6 +747,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
|||
subiq->target_count = iq->target_count;
|
||||
if(iq->target_count)
|
||||
iq->target_count[0] ++; /* extra reference */
|
||||
subiq->dp_target_count = 0;
|
||||
subiq->num_current_queries = 0;
|
||||
subiq->depth = iq->depth+1;
|
||||
outbound_list_init(&subiq->outlist);
|
||||
|
|
@ -759,7 +791,7 @@ prime_root(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
|||
* the normal INIT state logic (which would cause an infloop). */
|
||||
if(!generate_sub_request((uint8_t*)"\000", 1, LDNS_RR_TYPE_NS,
|
||||
qclass, qstate, id, iq, QUERYTARGETS_STATE, PRIME_RESP_STATE,
|
||||
&subq, 0)) {
|
||||
&subq, 0, 0)) {
|
||||
verbose(VERB_ALGO, "could not prime root");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -850,7 +882,7 @@ prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id,
|
|||
* redundant INIT state processing. */
|
||||
if(!generate_sub_request(stub_dp->name, stub_dp->namelen,
|
||||
LDNS_RR_TYPE_NS, qclass, qstate, id, iq,
|
||||
QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0)) {
|
||||
QUERYTARGETS_STATE, PRIME_RESP_STATE, &subq, 0, 0)) {
|
||||
verbose(VERB_ALGO, "could not prime stub");
|
||||
errinf(qstate, "could not generate lookup for stub prime");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
|
|
@ -1025,7 +1057,7 @@ generate_a_aaaa_check(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
if(!generate_sub_request(s->rk.dname, s->rk.dname_len,
|
||||
ntohs(s->rk.type), ntohs(s->rk.rrset_class),
|
||||
qstate, id, iq,
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
|
||||
verbose(VERB_ALGO, "could not generate addr check");
|
||||
return;
|
||||
}
|
||||
|
|
@ -1069,7 +1101,7 @@ generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
|||
iq->dp->name, LDNS_RR_TYPE_NS, iq->qchase.qclass);
|
||||
if(!generate_sub_request(iq->dp->name, iq->dp->namelen,
|
||||
LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq,
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
|
||||
verbose(VERB_ALGO, "could not generate ns check");
|
||||
return;
|
||||
}
|
||||
|
|
@ -1126,7 +1158,7 @@ generate_dnskey_prefetch(struct module_qstate* qstate,
|
|||
iq->dp->name, LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass);
|
||||
if(!generate_sub_request(iq->dp->name, iq->dp->namelen,
|
||||
LDNS_RR_TYPE_DNSKEY, iq->qchase.qclass, qstate, id, iq,
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) {
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) {
|
||||
/* we'll be slower, but it'll work */
|
||||
verbose(VERB_ALGO, "could not generate dnskey prefetch");
|
||||
return;
|
||||
|
|
@ -1315,6 +1347,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
iq->refetch_glue = 0;
|
||||
iq->query_restart_count++;
|
||||
iq->sent_count = 0;
|
||||
iq->dp_target_count = 0;
|
||||
sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
|
||||
if(qstate->env->cfg->qname_minimisation)
|
||||
iq->minimisation_state = INIT_MINIMISE_STATE;
|
||||
|
|
@ -1693,7 +1726,7 @@ generate_parentside_target_query(struct module_qstate* qstate,
|
|||
{
|
||||
struct module_qstate* subq;
|
||||
if(!generate_sub_request(name, namelen, qtype, qclass, qstate,
|
||||
id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0))
|
||||
id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0))
|
||||
return 0;
|
||||
if(subq) {
|
||||
struct iter_qstate* subiq =
|
||||
|
|
@ -1744,7 +1777,7 @@ generate_target_query(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
{
|
||||
struct module_qstate* subq;
|
||||
if(!generate_sub_request(name, namelen, qtype, qclass, qstate,
|
||||
id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0))
|
||||
id, iq, INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0))
|
||||
return 0;
|
||||
log_nametypeclass(VERB_QUERY, "new target", name, qtype, qclass);
|
||||
return 1;
|
||||
|
|
@ -1783,6 +1816,14 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
"number of glue fetches %d", s, iq->target_count[1]);
|
||||
return 0;
|
||||
}
|
||||
if(iq->dp_target_count > MAX_DP_TARGET_COUNT) {
|
||||
char s[LDNS_MAX_DOMAINLEN+1];
|
||||
dname_str(qstate->qinfo.qname, s);
|
||||
verbose(VERB_QUERY, "request %s has exceeded the maximum "
|
||||
"number of glue fetches %d to a single delegation point",
|
||||
s, iq->dp_target_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
iter_mark_cycle_targets(qstate, iq->dp);
|
||||
missing = (int)delegpt_count_missing_targets(iq->dp);
|
||||
|
|
@ -1896,7 +1937,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
for(a = p->target_list; a; a=a->next_target) {
|
||||
(void)delegpt_add_addr(iq->dp, qstate->region,
|
||||
&a->addr, a->addrlen, a->bogus,
|
||||
a->lame, a->tls_auth_name);
|
||||
a->lame, a->tls_auth_name, NULL);
|
||||
}
|
||||
}
|
||||
iq->dp->has_parent_side_NS = 1;
|
||||
|
|
@ -1913,6 +1954,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
iq->refetch_glue = 1;
|
||||
iq->query_restart_count++;
|
||||
iq->sent_count = 0;
|
||||
iq->dp_target_count = 0;
|
||||
if(qstate->env->cfg->qname_minimisation)
|
||||
iq->minimisation_state = INIT_MINIMISE_STATE;
|
||||
return next_state(iq, INIT_REQUEST_STATE);
|
||||
|
|
@ -2078,7 +2120,7 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
|||
iq->dsns_point, LDNS_RR_TYPE_NS, iq->qchase.qclass);
|
||||
if(!generate_sub_request(iq->dsns_point, iq->dsns_point_len,
|
||||
LDNS_RR_TYPE_NS, iq->qchase.qclass, qstate, id, iq,
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0)) {
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 0, 0)) {
|
||||
errinf_dname(qstate, "for DS query parent-child nameserver search, could not generate NS lookup for", iq->dsns_point);
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
|
@ -2136,6 +2178,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
errinf(qstate, "exceeded the maximum number of sends");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(iq->target_count && iq->target_count[2] > MAX_TARGET_NX) {
|
||||
verbose(VERB_QUERY, "request has exceeded the maximum "
|
||||
" number of nxdomain nameserver lookups with %d",
|
||||
iq->target_count[2]);
|
||||
errinf(qstate, "exceeded the maximum nameserver nxdomains");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
/* Make sure we have a delegation point, otherwise priming failed
|
||||
* or another failure occurred */
|
||||
|
|
@ -2190,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);
|
||||
|
||||
|
|
@ -2240,16 +2289,45 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
iq->qinfo_out.qtype, iq->qinfo_out.qclass,
|
||||
qstate->query_flags, qstate->region,
|
||||
qstate->env->scratch, 0);
|
||||
if(msg && msg->rep->an_numrrsets == 0
|
||||
&& FLAGS_GET_RCODE(msg->rep->flags) ==
|
||||
if(msg && FLAGS_GET_RCODE(msg->rep->flags) ==
|
||||
LDNS_RCODE_NOERROR)
|
||||
/* no need to send query if it is already
|
||||
* cached as NOERROR/NODATA */
|
||||
* cached as NOERROR */
|
||||
return 1;
|
||||
if(msg && FLAGS_GET_RCODE(msg->rep->flags) ==
|
||||
LDNS_RCODE_NXDOMAIN &&
|
||||
qstate->env->need_to_validate &&
|
||||
qstate->env->cfg->harden_below_nxdomain) {
|
||||
if(msg->rep->security == sec_status_secure) {
|
||||
iq->response = msg;
|
||||
return final_state(iq);
|
||||
}
|
||||
if(msg->rep->security == sec_status_unchecked) {
|
||||
struct module_qstate* subq = NULL;
|
||||
if(!generate_sub_request(
|
||||
iq->qinfo_out.qname,
|
||||
iq->qinfo_out.qname_len,
|
||||
iq->qinfo_out.qtype,
|
||||
iq->qinfo_out.qclass,
|
||||
qstate, id, iq,
|
||||
INIT_REQUEST_STATE,
|
||||
FINISHED_STATE, &subq, 1, 1))
|
||||
verbose(VERB_ALGO,
|
||||
"could not validate NXDOMAIN "
|
||||
"response");
|
||||
}
|
||||
}
|
||||
if(msg && FLAGS_GET_RCODE(msg->rep->flags) ==
|
||||
LDNS_RCODE_NXDOMAIN) {
|
||||
/* return and add a label in the next
|
||||
* minimisation iteration.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
|
@ -2321,6 +2399,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
* generated query will immediately be discarded due to depth and
|
||||
* that servfail is cached, which is not good as opportunism goes. */
|
||||
if(iq->depth < ie->max_dependency_depth
|
||||
&& iq->num_target_queries == 0
|
||||
&& (!iq->target_count || iq->target_count[2]==0)
|
||||
&& iq->sent_count < TARGET_FETCH_STOP) {
|
||||
tf_policy = ie->target_fetch_policy[iq->depth];
|
||||
}
|
||||
|
|
@ -2366,6 +2446,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
iq->num_current_queries++; /* RespState decrements it*/
|
||||
iq->referral_count++; /* make sure we don't loop */
|
||||
iq->sent_count = 0;
|
||||
iq->dp_target_count = 0;
|
||||
iq->state = QUERY_RESP_STATE;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -2453,6 +2534,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
iq->num_current_queries++; /* RespState decrements it*/
|
||||
iq->referral_count++; /* make sure we don't loop */
|
||||
iq->sent_count = 0;
|
||||
iq->dp_target_count = 0;
|
||||
iq->state = QUERY_RESP_STATE;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -2586,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);
|
||||
|
|
@ -2747,7 +2830,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
/* Make subrequest to validate intermediate
|
||||
* NXDOMAIN if harden-below-nxdomain is
|
||||
* enabled. */
|
||||
if(qstate->env->cfg->harden_below_nxdomain) {
|
||||
if(qstate->env->cfg->harden_below_nxdomain &&
|
||||
qstate->env->need_to_validate) {
|
||||
struct module_qstate* subq = NULL;
|
||||
log_query_info(VERB_QUERY,
|
||||
"schedule NXDOMAIN validation:",
|
||||
|
|
@ -2759,16 +2843,10 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
iq->response->qinfo.qclass,
|
||||
qstate, id, iq,
|
||||
INIT_REQUEST_STATE,
|
||||
FINISHED_STATE, &subq, 1))
|
||||
FINISHED_STATE, &subq, 1, 1))
|
||||
verbose(VERB_ALGO,
|
||||
"could not validate NXDOMAIN "
|
||||
"response");
|
||||
outbound_list_clear(&iq->outlist);
|
||||
iq->num_current_queries = 0;
|
||||
fptr_ok(fptr_whitelist_modenv_detach_subs(
|
||||
qstate->env->detach_subs));
|
||||
(*qstate->env->detach_subs)(qstate);
|
||||
iq->num_target_queries = 0;
|
||||
}
|
||||
}
|
||||
return next_state(iq, QUERYTARGETS_STATE);
|
||||
|
|
@ -2852,6 +2930,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
/* Count this as a referral. */
|
||||
iq->referral_count++;
|
||||
iq->sent_count = 0;
|
||||
iq->dp_target_count = 0;
|
||||
/* see if the next dp is a trust anchor, or a DS was sent
|
||||
* along, indicating dnssec is expected for next zone */
|
||||
iq->dnssec_expected = iter_indicates_dnssec(qstate->env,
|
||||
|
|
@ -2928,6 +3007,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
iq->dsns_point = NULL;
|
||||
iq->auth_zone_response = 0;
|
||||
iq->sent_count = 0;
|
||||
iq->dp_target_count = 0;
|
||||
if(iq->minimisation_state != MINIMISE_STATE)
|
||||
/* Only count as query restart when it is not an extra
|
||||
* query as result of qname minimisation. */
|
||||
|
|
@ -3120,7 +3200,7 @@ processPrimeResponse(struct module_qstate* qstate, int id)
|
|||
if(!generate_sub_request(qstate->qinfo.qname,
|
||||
qstate->qinfo.qname_len, qstate->qinfo.qtype,
|
||||
qstate->qinfo.qclass, qstate, id, iq,
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
|
||||
INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
|
||||
verbose(VERB_ALGO, "could not generate prime check");
|
||||
}
|
||||
generate_a_aaaa_check(qstate, iq, id);
|
||||
|
|
@ -3148,6 +3228,7 @@ static void
|
|||
processTargetResponse(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* forq)
|
||||
{
|
||||
struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id];
|
||||
struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];
|
||||
struct iter_qstate* foriq = (struct iter_qstate*)forq->minfo[id];
|
||||
struct ub_packed_rrset_key* rrset;
|
||||
|
|
@ -3185,7 +3266,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
|||
log_rrset_key(VERB_ALGO, "add parentside glue to dp",
|
||||
iq->pside_glue);
|
||||
if(!delegpt_add_rrset(foriq->dp, forq->region,
|
||||
iq->pside_glue, 1))
|
||||
iq->pside_glue, 1, NULL))
|
||||
log_err("out of memory adding pside glue");
|
||||
}
|
||||
|
||||
|
|
@ -3196,6 +3277,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
|||
* response type was ANSWER. */
|
||||
rrset = reply_find_answer_rrset(&iq->qchase, qstate->return_msg->rep);
|
||||
if(rrset) {
|
||||
int additions = 0;
|
||||
/* if CNAMEs have been followed - add new NS to delegpt. */
|
||||
/* BTW. RFC 1918 says NS should not have got CNAMEs. Robust. */
|
||||
if(!delegpt_find_ns(foriq->dp, rrset->rk.dname,
|
||||
|
|
@ -3207,13 +3289,23 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
|||
}
|
||||
/* if dpns->lame then set the address(es) lame too */
|
||||
if(!delegpt_add_rrset(foriq->dp, forq->region, rrset,
|
||||
dpns->lame))
|
||||
dpns->lame, &additions))
|
||||
log_err("out of memory adding targets");
|
||||
if(!additions) {
|
||||
/* no new addresses, increase the nxns counter, like
|
||||
* this could be a list of wildcards with no new
|
||||
* addresses */
|
||||
target_count_increase_nx(foriq, 1);
|
||||
}
|
||||
verbose(VERB_ALGO, "added target response");
|
||||
delegpt_log(VERB_ALGO, foriq->dp);
|
||||
} else {
|
||||
verbose(VERB_ALGO, "iterator TargetResponse failed");
|
||||
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
|
||||
dpns->resolved = 1; /* fail the target */
|
||||
if((dpns->got4 == 2 || !ie->supports_ipv4) &&
|
||||
(dpns->got6 == 2 || !ie->supports_ipv6))
|
||||
target_count_increase_nx(foriq, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3387,7 +3479,7 @@ processCollectClass(struct module_qstate* qstate, int id)
|
|||
qstate->qinfo.qname_len, qstate->qinfo.qtype,
|
||||
c, qstate, id, iq, INIT_REQUEST_STATE,
|
||||
FINISHED_STATE, &subq,
|
||||
(int)!(qstate->query_flags&BIT_CD))) {
|
||||
(int)!(qstate->query_flags&BIT_CD), 0)) {
|
||||
errinf(qstate, "could not generate class ANY"
|
||||
" lookup query");
|
||||
return error_response(qstate, id,
|
||||
|
|
@ -3599,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 */
|
||||
|
|
|
|||
|
|
@ -55,6 +55,11 @@ struct rbtree_type;
|
|||
|
||||
/** max number of targets spawned for a query and its subqueries */
|
||||
#define MAX_TARGET_COUNT 64
|
||||
/** max number of target lookups per qstate, per delegation point */
|
||||
#define MAX_DP_TARGET_COUNT 16
|
||||
/** max number of nxdomains allowed for target lookups for a query and
|
||||
* its subqueries */
|
||||
#define MAX_TARGET_NX 5
|
||||
/** max number of query restarts. Determines max number of CNAME chain. */
|
||||
#define MAX_RESTART_COUNT 8
|
||||
/** max number of referrals. Makes sure resolver does not run away */
|
||||
|
|
@ -305,9 +310,14 @@ struct iter_qstate {
|
|||
int sent_count;
|
||||
|
||||
/** number of target queries spawned in [1], for this query and its
|
||||
* subqueries, the malloced-array is shared, [0] refcount. */
|
||||
* subqueries, the malloced-array is shared, [0] refcount.
|
||||
* in [2] the number of nxdomains is counted. */
|
||||
int* target_count;
|
||||
|
||||
/** number of target lookups per delegation point. Reset to 0 after
|
||||
* receiving referral answer. Not shared with subqueries. */
|
||||
int dp_target_count;
|
||||
|
||||
/** if true, already tested for ratelimiting and passed the test */
|
||||
int ratelimit_ok;
|
||||
|
||||
|
|
@ -388,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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
21
makedist.sh
21
makedist.sh
|
|
@ -464,6 +464,20 @@ rm -rf .git || error_cleanup "Failed to remove .git tracking information"
|
|||
info "Adding libtool utils (libtoolize)."
|
||||
libtoolize -c --install || libtoolize -c || error_cleanup "Libtoolize failed."
|
||||
|
||||
# https://www.gnu.org/software/gettext/manual/html_node/config_002eguess.html
|
||||
info "Updating config.guess and config.sub"
|
||||
wget -O config.guess 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'
|
||||
wget -O config.sub 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'
|
||||
chmod a+x config.guess config.sub
|
||||
|
||||
# Remove quarantine bit on Apple platforms
|
||||
if [ `uname -s | grep -i -c darwin` -ne 0 ]; then
|
||||
if [ -n `command -v xattr` ]; then
|
||||
xattr -d com.apple.quarantine config.guess
|
||||
xattr -d com.apple.quarantine config.sub
|
||||
fi
|
||||
fi
|
||||
|
||||
info "Building configure script (autoreconf)."
|
||||
autoreconf || error_cleanup "Autoconf failed."
|
||||
|
||||
|
|
@ -542,9 +556,8 @@ cleanup
|
|||
|
||||
storehash unbound-$version.tar.gz
|
||||
echo "create unbound-$version.tar.gz.asc with:"
|
||||
echo " gpg --armor --detach-sign unbound-$version.tar.gz"
|
||||
echo " gpg --armor --detach-sign unbound-$version.zip"
|
||||
echo " gpg --armor --detach-sign unbound_setup_$version.exe"
|
||||
echo " gpg --armor --detach-sign --digest-algo SHA256 unbound-$version.tar.gz"
|
||||
echo " gpg --armor --detach-sign --digest-algo SHA256 unbound-$version.zip"
|
||||
echo " gpg --armor --detach-sign --digest-algo SHA256 unbound_setup_$version.exe"
|
||||
|
||||
info "Unbound distribution created successfully."
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -1897,11 +1899,12 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
|
|||
fatal_exit("Could not setup RPZ zones");
|
||||
return 0;
|
||||
}
|
||||
lock_protect(&z->lock, &z->rpz->local_zones, sizeof(*z->rpz));
|
||||
lock_rw_wrlock(&az->rpz_lock);
|
||||
z->rpz->next = az->rpz_first;
|
||||
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;
|
||||
lock_rw_unlock(&az->rpz_lock);
|
||||
}
|
||||
|
||||
|
|
@ -5331,7 +5334,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 +5773,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 +5815,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 +5896,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 +6110,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 +6146,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 +6391,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 +6468,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 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
10
services/cache/dns.c
vendored
10
services/cache/dns.c
vendored
|
|
@ -273,7 +273,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
|
|||
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
||||
ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0);
|
||||
if(akey) {
|
||||
if(!delegpt_add_rrset_A(dp, region, akey, 0)) {
|
||||
if(!delegpt_add_rrset_A(dp, region, akey, 0, NULL)) {
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -293,7 +293,7 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
|
|||
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
||||
ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
||||
if(akey) {
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, 0)) {
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, 0, NULL)) {
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -327,7 +327,8 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
|
|||
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
||||
ns->namelen, LDNS_RR_TYPE_A, qclass, 0, now, 0);
|
||||
if(akey) {
|
||||
if(!delegpt_add_rrset_A(dp, region, akey, ns->lame)) {
|
||||
if(!delegpt_add_rrset_A(dp, region, akey, ns->lame,
|
||||
NULL)) {
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -347,7 +348,8 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
|
|||
akey = rrset_cache_lookup(env->rrset_cache, ns->name,
|
||||
ns->namelen, LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
||||
if(akey) {
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame)) {
|
||||
if(!delegpt_add_rrset_AAAA(dp, region, akey, ns->lame,
|
||||
NULL)) {
|
||||
lock_rw_unlock(&akey->entry.lock);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 @@ err:
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -1948,7 +1960,7 @@ mesh_serve_expired_callback(void* arg)
|
|||
|
||||
r = mstate->reply_list;
|
||||
mstate->reply_list = NULL;
|
||||
if(!mstate->reply_list && !mstate->cb_list) {
|
||||
if(!mstate->reply_list && !mstate->cb_list && r) {
|
||||
log_assert(mesh->num_reply_states > 0);
|
||||
mesh->num_reply_states--;
|
||||
if(mstate->super_set.count == 0) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -233,18 +233,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),
|
||||
|
|
@ -264,6 +271,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,
|
||||
|
|
@ -333,7 +346,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;
|
||||
|
|
@ -415,45 +428,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;
|
||||
|
|
@ -624,7 +608,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;
|
||||
|
|
@ -837,10 +823,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))
|
||||
|
|
@ -857,11 +845,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));
|
||||
|
|
@ -877,6 +865,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
|
||||
|
|
@ -890,6 +879,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;
|
||||
|
|
@ -1069,7 +1059,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);
|
||||
|
|
@ -1083,7 +1075,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);
|
||||
|
|
@ -1179,11 +1173,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)) {
|
||||
|
|
@ -1198,13 +1193,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;
|
||||
}
|
||||
|
|
@ -1253,6 +1248,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 */
|
||||
|
|
@ -1264,8 +1260,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;
|
||||
|
|
@ -1287,8 +1286,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;
|
||||
}
|
||||
|
|
@ -2234,7 +2235,6 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
|||
|
||||
sq->pending = NULL; /* removed after callback */
|
||||
if(error == NETEVENT_TIMEOUT) {
|
||||
int rto = 0;
|
||||
if(sq->status == serviced_query_UDP_EDNS && sq->last_rtt < 5000) {
|
||||
/* fallback to 1480/1280 */
|
||||
sq->status = serviced_query_UDP_EDNS_FRAG;
|
||||
|
|
@ -2250,9 +2250,9 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
|||
sq->status = serviced_query_UDP_EDNS;
|
||||
}
|
||||
sq->retry++;
|
||||
if(!(rto=infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
|
||||
sq->zone, sq->zonelen, sq->qtype, -1, sq->last_rtt,
|
||||
(time_t)now.tv_sec)))
|
||||
(time_t)now.tv_sec))
|
||||
log_err("out of memory in UDP exponential backoff");
|
||||
if(sq->retry < OUTBOUND_UDP_RETRY) {
|
||||
log_name_addr(VERB_ALGO, "retry query", sq->qbuf+10,
|
||||
|
|
@ -2453,10 +2453,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;
|
||||
|
|
@ -2486,6 +2487,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 */
|
||||
|
|
@ -2494,19 +2496,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;
|
||||
|
|
@ -2555,6 +2559,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
|
||||
|
|
@ -2577,7 +2586,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;
|
||||
|
|
@ -2596,7 +2607,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;
|
||||
}
|
||||
|
|
@ -2658,7 +2669,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;
|
||||
}
|
||||
|
|
@ -2716,7 +2727,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]) +
|
||||
|
|
|
|||
|
|
@ -133,12 +133,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.
|
||||
|
|
@ -188,11 +192,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. */
|
||||
|
|
@ -464,6 +470,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.
|
||||
|
|
@ -477,16 +484,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.
|
||||
|
|
@ -605,7 +613,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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -469,7 +469,6 @@ check_modules_exist(const char* module_conf)
|
|||
static void
|
||||
morechecks(struct config_file* cfg)
|
||||
{
|
||||
struct config_auth* auth;
|
||||
warn_hosts("stub-host", cfg->stubs);
|
||||
warn_hosts("forward-host", cfg->forwards);
|
||||
interfacechecks(cfg);
|
||||
|
|
@ -482,6 +481,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)
|
||||
|
|
@ -535,12 +536,6 @@ morechecks(struct config_file* cfg)
|
|||
cfg->trusted_keys_file_list, cfg->chrootdir, cfg);
|
||||
check_chroot_string("dlv-anchor-file", &cfg->dlv_anchor_file,
|
||||
cfg->chrootdir, cfg);
|
||||
for(auth = cfg->auths; auth; auth = auth->next) {
|
||||
char* az = (auth->isrpz) ? "rpz zonefile" :
|
||||
"auth-zone zonefile";
|
||||
check_chroot_string(az, &auth->zonefile,
|
||||
cfg->chrootdir, cfg);
|
||||
}
|
||||
#ifdef USE_IPSECMOD
|
||||
if(cfg->ipsecmod_enabled && strstr(cfg->module_conf, "ipsecmod")) {
|
||||
/* only check hook if enabled */
|
||||
|
|
@ -555,10 +550,7 @@ morechecks(struct config_file* cfg)
|
|||
/* check that the modules listed in module_conf exist */
|
||||
check_modules_exist(cfg->module_conf);
|
||||
|
||||
/* There should be no reason for 'respip' module not to work with
|
||||
* dns64, but it's not explicitly confirmed, so the combination is
|
||||
* excluded below. It's simply unknown yet for the combination of
|
||||
* respip and other modules. */
|
||||
/* Respip is known to *not* work with dns64. */
|
||||
if(strcmp(cfg->module_conf, "iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 validator iterator") != 0
|
||||
|
|
@ -567,7 +559,9 @@ morechecks(struct config_file* cfg)
|
|||
&& strcmp(cfg->module_conf, "respip validator iterator") != 0
|
||||
#ifdef WITH_PYTHONMODULE
|
||||
&& strcmp(cfg->module_conf, "python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python respip validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 python validator iterator") != 0
|
||||
|
|
@ -575,9 +569,69 @@ 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
|
||||
&& strcmp(cfg->module_conf, "cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 cachedb iterator") != 0
|
||||
#endif
|
||||
|
|
@ -587,39 +641,63 @@ morechecks(struct config_file* cfg)
|
|||
&& strcmp(cfg->module_conf, "dns64 python cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 python validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python respip cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python respip validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "cachedb python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip cachedb python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator cachedb python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip validator cachedb python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator python cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip validator python cachedb iterator") != 0
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
&& strcmp(cfg->module_conf, "subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache validator iterator") != 0
|
||||
&& 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
|
||||
&& strcmp(cfg->module_conf, "python respip subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip subnetcache python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python respip subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache python validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip subnetcache python validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache validator python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip subnetcache validator python iterator") != 0
|
||||
#endif
|
||||
#ifdef USE_IPSECMOD
|
||||
&& strcmp(cfg->module_conf, "ipsecmod iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod respip validator iterator") != 0
|
||||
#endif
|
||||
#if defined(WITH_PYTHONMODULE) && defined(USE_IPSECMOD)
|
||||
&& strcmp(cfg->module_conf, "python ipsecmod iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python ipsecmod respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod python respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod respip validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python ipsecmod validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python ipsecmod respip validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod python validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod python respip validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod validator python iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod respip validator python iterator") != 0
|
||||
#endif
|
||||
#ifdef USE_IPSET
|
||||
&& strcmp(cfg->module_conf, "validator ipset iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator ipset respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipset iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipset respip iterator") != 0
|
||||
#endif
|
||||
) {
|
||||
fatal_exit("module conf '%s' is not known to work",
|
||||
|
|
@ -685,7 +763,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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -1589,7 +1591,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;
|
||||
|
|
@ -1796,7 +1798,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;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ cleanup() {
|
|||
if test -f "$t.bak"; then mv "$t.bak" "$t"; fi
|
||||
exit 0
|
||||
}
|
||||
trap cleanup SIGINT
|
||||
trap cleanup INT
|
||||
|
||||
for t in $RUNLIST
|
||||
do
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
5
testdata/04-checkconf.tdir/bad.dscp
vendored
Normal file
5
testdata/04-checkconf.tdir/bad.dscp
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
include: "good.min"
|
||||
|
||||
server:
|
||||
# an abnormal value for the option
|
||||
ip-dscp: 500
|
||||
4
testdata/04-checkconf.tdir/good.all
vendored
4
testdata/04-checkconf.tdir/good.all
vendored
|
|
@ -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
|
||||
|
|
|
|||
7
testdata/04-checkconf.tdir/good.min
vendored
Normal file
7
testdata/04-checkconf.tdir/good.min
vendored
Normal 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: ""
|
||||
1
testdata/autotrust_10key.rpl
vendored
1
testdata/autotrust_10key.rpl
vendored
|
|
@ -106,7 +106,6 @@ www.example.com. IN A
|
|||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
|
|
|
|||
1
testdata/autotrust_revtp.rpl
vendored
1
testdata/autotrust_revtp.rpl
vendored
|
|
@ -97,7 +97,6 @@ www.example.com. IN A
|
|||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
|
|
|
|||
1
testdata/autotrust_revtp_read.rpl
vendored
1
testdata/autotrust_revtp_read.rpl
vendored
|
|
@ -85,7 +85,6 @@ www.example.com. IN A
|
|||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
|
|
|
|||
1
testdata/black_data.rpl
vendored
1
testdata/black_data.rpl
vendored
|
|
@ -8,6 +8,7 @@ server:
|
|||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
minimal-responses: no
|
||||
rrset-roundrobin: no
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
|
|
|
|||
1
testdata/black_prime.rpl
vendored
1
testdata/black_prime.rpl
vendored
|
|
@ -8,6 +8,7 @@ server:
|
|||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
minimal-responses: no
|
||||
rrset-roundrobin: no
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
|
|
|
|||
40
testdata/dnstap.tdir/dnstap.conf
vendored
Normal file
40
testdata/dnstap.tdir/dnstap.conf
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
server:
|
||||
verbosity: 2
|
||||
num-threads: 3
|
||||
outgoing-range: 16
|
||||
interface: 127.0.0.1
|
||||
port: @PORT@
|
||||
use-syslog: no
|
||||
directory: ""
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
local-zone: "example.net." redirect
|
||||
local-data: "example.net. IN A 10.20.30.41"
|
||||
remote-control:
|
||||
control-enable: yes
|
||||
control-interface: 127.0.0.1
|
||||
# control-interface: ::1
|
||||
control-port: @CONTROL_PORT@
|
||||
server-key-file: "unbound_server.key"
|
||||
server-cert-file: "unbound_server.pem"
|
||||
control-key-file: "unbound_control.key"
|
||||
control-cert-file: "unbound_control.pem"
|
||||
forward-zone:
|
||||
name: "."
|
||||
forward-addr: "127.0.0.1@@TOPORT@"
|
||||
dnstap:
|
||||
dnstap-enable: yes
|
||||
dnstap-socket-path: "dnstap.socket"
|
||||
dnstap-send-identity: yes
|
||||
dnstap-send-version: yes
|
||||
#dnstap-identity
|
||||
#dnstap-version
|
||||
dnstap-log-resolver-query-messages: yes
|
||||
dnstap-log-resolver-response-messages: yes
|
||||
dnstap-log-client-query-messages: yes
|
||||
dnstap-log-client-response-messages: yes
|
||||
dnstap-log-forwarder-query-messages: yes
|
||||
dnstap-log-forwarder-response-messages: yes
|
||||
|
||||
16
testdata/dnstap.tdir/dnstap.dsc
vendored
Normal file
16
testdata/dnstap.tdir/dnstap.dsc
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
BaseName: dnstap
|
||||
Version: 1.0
|
||||
Description: test dnstap socket communication
|
||||
CreationDate: Tue Jan 21 13:00:38 CET 2020
|
||||
Maintainer: dr. W.C.A. Wijngaards
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: dnstap.pre
|
||||
Post: dnstap.post
|
||||
Test: dnstap.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
16
testdata/dnstap.tdir/dnstap.post
vendored
Normal file
16
testdata/dnstap.tdir/dnstap.post
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# #-- dnstap.post --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# source the test var file when it's there
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
#
|
||||
# do your teardown here
|
||||
. ../common.sh
|
||||
PRE="../.."
|
||||
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
|
||||
kill_pid $DNSTAP_SOCKET_PID
|
||||
kill_pid $FWD_PID
|
||||
kill $UNBOUND_PID
|
||||
kill $UNBOUND_PID >/dev/null 2>&1
|
||||
cat unbound.log
|
||||
exit 0
|
||||
55
testdata/dnstap.tdir/dnstap.pre
vendored
Normal file
55
testdata/dnstap.tdir/dnstap.pre
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# #-- dnstap.pre--#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
. ../common.sh
|
||||
|
||||
PRE="../.."
|
||||
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
|
||||
|
||||
get_random_port 3
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
FWD_PORT=$(($RND_PORT + 1))
|
||||
CONTROL_PORT=$(($RND_PORT + 2))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test
|
||||
echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test
|
||||
|
||||
# start forwarder
|
||||
get_ldns_testns
|
||||
$LDNS_TESTNS -p $FWD_PORT dnstap.testns >fwd.log 2>&1 &
|
||||
FWD_PID=$!
|
||||
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
|
||||
|
||||
# start the dnstap log server
|
||||
# the -vvvv flag prints protocol and connection information from the
|
||||
# unbound-dnstap-socket server.
|
||||
# the -l flag prints the DNS info in the DNSTAP packet in multiline output.
|
||||
# stderr is the '-vvvv' server logs and errors.
|
||||
# stdout is the one-line packet logs (or with -l, multiline).
|
||||
$PRE/unbound-dnstap-socket -u dnstap.socket -l -vvvv 2>tap.errlog >tap.log &
|
||||
if test $? -ne 0; then
|
||||
echo "could not start unbound-dnstap-socket server"
|
||||
exit 1
|
||||
fi
|
||||
DNSTAP_SOCKET_PID=$!
|
||||
echo "DNSTAP_SOCKET_PID=$DNSTAP_SOCKET_PID" >> .tpkg.var.test
|
||||
# wait for the server to go up and make the dnstap.socket file
|
||||
wait_server_up "tap.errlog" "creating unix socket"
|
||||
if test ! -S dnstap.socket; then
|
||||
echo "the dnstap.socket file does not exist!"
|
||||
fi
|
||||
|
||||
# make config file
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < dnstap.conf > ub.conf
|
||||
# start unbound in the background
|
||||
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||
|
||||
cat .tpkg.var.test
|
||||
wait_ldns_testns_up fwd.log
|
||||
wait_unbound_up unbound.log
|
||||
|
||||
86
testdata/dnstap.tdir/dnstap.test
vendored
Normal file
86
testdata/dnstap.tdir/dnstap.test
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
# #-- dnstap.test --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
. ../common.sh
|
||||
PRE="../.."
|
||||
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
|
||||
|
||||
# test if the server is up.
|
||||
echo "> dig www.example.com."
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
echo "> check answer"
|
||||
if grep "10.20.30.40" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "> cat logfiles"
|
||||
cat tap.log
|
||||
cat tap.errlog
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "> check tap.log for dnstap info"
|
||||
# see if it logged the information in tap.log
|
||||
# wait for a moment for filesystem to catch up.
|
||||
if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi
|
||||
if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi
|
||||
if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi
|
||||
if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi
|
||||
if grep "www.example.com" tap.log >/dev/null; then :; else sleep 1; fi
|
||||
if grep "www.example.com" tap.log >/dev/null; then :; else sleep 10; fi
|
||||
if grep "www.example.com" tap.log; then echo "yes it is in tap.log";
|
||||
else
|
||||
echo "information not in tap.log"
|
||||
echo "failed"
|
||||
echo "> cat logfiles"
|
||||
cat tap.log
|
||||
cat tap.errlog
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "> make 10 queries to spread them over threads"
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT q1.example.net.
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT q2.example.net.
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT q3.example.net.
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT q4.example.net.
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT q5.example.net.
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT q6.example.net.
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT q7.example.net.
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT q8.example.net.
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT q9.example.net.
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT q10.example.net.
|
||||
for x in q1 q2 q3 q4 5 q6 q7 q8 q9 q10; do
|
||||
if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 1; fi
|
||||
if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 1; fi
|
||||
if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 1; fi
|
||||
if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 1; fi
|
||||
if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 1; fi
|
||||
if grep "$x.example.net" tap.log >/dev/null; then :; else sleep 10; fi
|
||||
if grep "$x.example.net" tap.log; then echo "yes it is in tap.log";
|
||||
else
|
||||
echo "$x.example.net. information not in tap.log"
|
||||
echo "failed"
|
||||
echo "> cat logfiles"
|
||||
cat tap.log
|
||||
cat tap.errlog
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo "> cat logfiles"
|
||||
cat tap.log
|
||||
cat tap.errlog
|
||||
cat fwd.log
|
||||
echo "> OK"
|
||||
exit 0
|
||||
22
testdata/dnstap.tdir/dnstap.testns
vendored
Normal file
22
testdata/dnstap.tdir/dnstap.testns
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
; nameserver test file
|
||||
$ORIGIN example.com.
|
||||
$TTL 3600
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
REPLY QR AA NOERROR
|
||||
ADJUST copy_id
|
||||
SECTION QUESTION
|
||||
www IN A
|
||||
SECTION ANSWER
|
||||
www IN A 10.20.30.40
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
REPLY QR AA SERVFAIL
|
||||
ADJUST copy_id
|
||||
SECTION QUESTION
|
||||
www.example.net. IN A
|
||||
ENTRY_END
|
||||
|
||||
15
testdata/dnstap.tdir/unbound_control.key
vendored
Normal file
15
testdata/dnstap.tdir/unbound_control.key
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQDD6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBa
|
||||
rzPA0vlyuNtUsEN3qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvH
|
||||
ST6JwUdIg0Lzg/USJ81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQAB
|
||||
AoGAFT3e35MIgI4uDJJ8X0RfHp2NCO2LUg4TKbWical/C0W9vlR1/x80G1pE1d2Z
|
||||
WotqJVWTrOq6eBox19RCgtLg2wPGk9uD62+9SDT37heWFlUCElWq50pQG6k9ThiG
|
||||
DDypkZyZ/52+DdWybiaQJkuK6O5qQXuNAtVJMpghu4GnHAECQQDsupnZUQDpapzr
|
||||
4FC4MSkL2+A1PRt6g4VhwoqOpJXaHfVnH6F7AwUuOLNwGdR5Cvv70pfJ7Jqg8L2m
|
||||
Kxyl5bORAkEA09rn34YQ0pHJdHidbl2kInIuYTz09+TO3LWwan17nISH9aaYvVDr
|
||||
p9x1B4Qzw9qyxT9oll7ze/5Rw/7C3AQj4QJAT2B2a+b8bkgAXBs4FbruL3rHoDJg
|
||||
P2FQXSpVOWU4lg2LlsuFYvDtUMVUbZdLplanjZXcral3Y9W1Ub2M+ped8QJAYQN+
|
||||
aRpge7ys7vwIw7B36Bo3aOncF+ScYe+FkM5Tm7II/JHEofT7ZQwMP1vnxIlSkgbe
|
||||
YvWqNB6a3NC99LikoQJBAM4UhDdRg63Tr6Idky6CQaH///zAN7nArJfffKGWFdw9
|
||||
DKrWpNqvYZtX/cfEJucKcRCm5YL8CKFYbQy4VoCxUcE=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
11
testdata/dnstap.tdir/unbound_control.pem
vendored
Normal file
11
testdata/dnstap.tdir/unbound_control.pem
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIBozCCAQwCCQD6XaN6FzW/4DANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd1
|
||||
bmJvdW5kMB4XDTA4MDkxMTA5MDk0MFoXDTI4MDUyOTA5MDk0MFowGjEYMBYGA1UE
|
||||
AxMPdW5ib3VuZC1jb250cm9sMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDD
|
||||
6DogNCsSeEa1u99+6PUVbGzjMzzei9MIK6s94+zcpp7OAOBarzPA0vlyuNtUsEN3
|
||||
qwPomQQQmIgbT7OXkzC1wqioxwa609xoL8oW/I7e336rEyvHST6JwUdIg0Lzg/US
|
||||
J81eTwMnzYSd4Bpsqr9eP33ubaR7Gh/6o76loLOlcQIDAQABMA0GCSqGSIb3DQEB
|
||||
BQUAA4GBAGFAXmaQHuFgAuc6HVhYZJdToxLBhfxGpot4oZNjcb1Cdoz3OL34MU1B
|
||||
9E5psj2PpGPIi8/RwoqBtAJHJ+J5cWngo03o4ZmdwKNSzaxlp141z/3rUtFqEHEC
|
||||
iO6gPCT3U7dt6MyC7r6vdMqyW6aldP3CtwD0gQziKAMoj+TAfAcq
|
||||
-----END CERTIFICATE-----
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue