Vendor import of Unbound 1.11.0.
This commit is contained in:
parent
6a53c00e64
commit
7973006f41
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;
|
||||
|
895
config.guess
vendored
895
config.guess
vendored
File diff suppressed because it is too large
Load Diff
23
config.h.in
23
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
|
||||
|
||||
@ -380,6 +386,9 @@
|
||||
/* Define to 1 if you have the <openssl/conf.h> header file. */
|
||||
#undef HAVE_OPENSSL_CONF_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/core_names.h> header file. */
|
||||
#undef HAVE_OPENSSL_CORE_NAMES_H
|
||||
|
||||
/* Define to 1 if you have the <openssl/dh.h> header file. */
|
||||
#undef HAVE_OPENSSL_DH_H
|
||||
|
||||
@ -494,8 +503,9 @@
|
||||
/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
|
||||
#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_cb' function. */
|
||||
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_CB
|
||||
/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_evp_cb'
|
||||
function. */
|
||||
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
|
||||
|
||||
/* Define to 1 if you have the `SSL_get0_peername' function. */
|
||||
#undef HAVE_SSL_GET0_PEERNAME
|
||||
@ -590,6 +600,9 @@
|
||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define to 1 if you have the <TargetConditionals.h> header file. */
|
||||
#undef HAVE_TARGETCONDITIONALS_H
|
||||
|
||||
/* Define to 1 if you have the <time.h> header file. */
|
||||
#undef HAVE_TIME_H
|
||||
|
||||
@ -805,6 +818,9 @@
|
||||
/* Define to 1 to use ipset support */
|
||||
#undef USE_IPSET
|
||||
|
||||
/* Define if you enable libevent */
|
||||
#undef USE_LIBEVENT
|
||||
|
||||
/* Define if you want to use internal select based events */
|
||||
#undef USE_MINI_EVENT
|
||||
|
||||
@ -854,6 +870,9 @@
|
||||
/* the version of the windows API enabled */
|
||||
#undef WINVER
|
||||
|
||||
/* Define if you want dynlib module. */
|
||||
#undef WITH_DYNLIBMODULE
|
||||
|
||||
/* Define if you want Python module. */
|
||||
#undef WITH_PYTHONMODULE
|
||||
|
||||
|
2874
config.sub
vendored
2874
config.sub
vendored
File diff suppressed because it is too large
Load Diff
224
configure
vendored
224
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.1.
|
||||
# Generated by GNU Autoconf 2.69 for unbound 1.11.0.
|
||||
#
|
||||
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
|
||||
#
|
||||
@ -591,8 +591,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='unbound'
|
||||
PACKAGE_TARNAME='unbound'
|
||||
PACKAGE_VERSION='1.10.1'
|
||||
PACKAGE_STRING='unbound 1.10.1'
|
||||
PACKAGE_VERSION='1.11.0'
|
||||
PACKAGE_STRING='unbound 1.11.0'
|
||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@ -649,6 +649,7 @@ ENABLE_DNSCRYPT
|
||||
ENABLE_DNSCRYPT_XCHACHA20
|
||||
DNSTAP_OBJ
|
||||
DNSTAP_SRC
|
||||
DNSTAP_SOCKET_PATH
|
||||
opt_dnstap_socket_path
|
||||
ENABLE_DNSTAP
|
||||
PROTOC_C
|
||||
@ -699,6 +700,10 @@ PYTHON_LDFLAGS
|
||||
PYTHON_CPPFLAGS
|
||||
PYTHON
|
||||
PYTHON_VERSION
|
||||
DYNLIBMOD_EXTRALIBS
|
||||
DYNLIBMOD_HEADER
|
||||
DYNLIBMOD_OBJ
|
||||
WITH_DYNLIBMODULE
|
||||
PTHREAD_CFLAGS_ONLY
|
||||
PTHREAD_CFLAGS
|
||||
PTHREAD_LIBS
|
||||
@ -855,6 +860,7 @@ enable_alloc_nonregional
|
||||
with_pthreads
|
||||
with_solaris_threads
|
||||
with_syslog_facility
|
||||
with_dynlibmodule
|
||||
with_pyunbound
|
||||
with_pythonmodule
|
||||
enable_swig_version_check
|
||||
@ -883,13 +889,13 @@ enable_allsymbols
|
||||
enable_dnstap
|
||||
with_dnstap_socket_path
|
||||
with_protobuf_c
|
||||
with_libfstrm
|
||||
enable_dnscrypt
|
||||
with_libsodium
|
||||
enable_cachedb
|
||||
enable_ipsecmod
|
||||
enable_ipset
|
||||
with_libmnl
|
||||
enable_explicit_port_randomisation
|
||||
with_libunbound_only
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
@ -1452,7 +1458,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures unbound 1.10.1 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.11.0 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1517,7 +1523,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of unbound 1.10.1:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.11.0:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1572,13 +1578,16 @@ Optional Features:
|
||||
--enable-allsymbols export all symbols from libunbound and link binaries
|
||||
to it, smaller install size but libunbound export
|
||||
table is polluted by internal symbols
|
||||
--enable-dnstap Enable dnstap support (requires fstrm, protobuf-c)
|
||||
--enable-dnstap Enable dnstap support (requires protobuf-c)
|
||||
--enable-dnscrypt Enable dnscrypt support (requires libsodium)
|
||||
--enable-cachedb enable cachedb module that can use external cache
|
||||
storage
|
||||
--enable-ipsecmod Enable ipsecmod module that facilitates
|
||||
opportunistic IPsec
|
||||
--enable-ipset enable ipset module
|
||||
--disable-explicit-port-randomisation
|
||||
disable explicit source port randomisation and rely
|
||||
on the kernel to provide random source ports
|
||||
|
||||
Optional Packages:
|
||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||
@ -1614,6 +1623,8 @@ Optional Packages:
|
||||
--with-solaris-threads use solaris native thread library.
|
||||
--with-syslog-facility=LOCAL0 - LOCAL7
|
||||
set SYSLOG_FACILITY, default DAEMON
|
||||
--with-dynlibmodule build dynamic library module, or
|
||||
--without-dynlibmodule to disable it. (default=no)
|
||||
--with-pyunbound build PyUnbound, or --without-pyunbound to skip it.
|
||||
(default=no)
|
||||
--with-pythonmodule build Python module, or --without-pythonmodule to
|
||||
@ -1634,7 +1645,6 @@ Optional Packages:
|
||||
--with-dnstap-socket-path=pathname
|
||||
set default dnstap socket path
|
||||
--with-protobuf-c=path Path where protobuf-c is installed, for dnstap
|
||||
--with-libfstrm=path Path where libfstrm is installed, for dnstap
|
||||
--with-libsodium=path Path where libsodium is installed, for dnscrypt
|
||||
--with-libmnl=path specify explicit path for libmnl.
|
||||
--with-libunbound-only do not build daemon and tool programs
|
||||
@ -1740,7 +1750,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
unbound configure 1.10.1
|
||||
unbound configure 1.11.0
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@ -2449,7 +2459,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by unbound $as_me 1.10.1, which was
|
||||
It was created by unbound $as_me 1.11.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@ -2799,13 +2809,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
UNBOUND_VERSION_MAJOR=1
|
||||
|
||||
UNBOUND_VERSION_MINOR=10
|
||||
UNBOUND_VERSION_MINOR=11
|
||||
|
||||
UNBOUND_VERSION_MICRO=1
|
||||
UNBOUND_VERSION_MICRO=0
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=8
|
||||
LIBUNBOUND_REVISION=9
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@ -2881,6 +2891,7 @@ LIBUNBOUND_AGE=1
|
||||
# 1.9.6 had 9:6:1
|
||||
# 1.10.0 had 9:7:1
|
||||
# 1.10.1 had 9:8:1
|
||||
# 1.11.0 had 9:9:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@ -14729,6 +14740,20 @@ fi
|
||||
done
|
||||
|
||||
|
||||
# Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH
|
||||
for ac_header in TargetConditionals.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "TargetConditionals.h" "ac_cv_header_TargetConditionals_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_TargetConditionals_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_TARGETCONDITIONALS_H 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
||||
# check for types.
|
||||
# Using own tests for int64* because autoconf builtin only give 32bit.
|
||||
ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default"
|
||||
@ -17171,6 +17196,34 @@ cat >>confdefs.h <<_ACEOF
|
||||
_ACEOF
|
||||
|
||||
|
||||
# Check for dynamic library module
|
||||
|
||||
# Check whether --with-dynlibmodule was given.
|
||||
if test "${with_dynlibmodule+set}" = set; then :
|
||||
withval=$with_dynlibmodule;
|
||||
else
|
||||
withval="no"
|
||||
fi
|
||||
|
||||
|
||||
if test x_$withval != x_no; then
|
||||
|
||||
$as_echo "#define WITH_DYNLIBMODULE 1" >>confdefs.h
|
||||
|
||||
WITH_DYNLIBMODULE=yes
|
||||
|
||||
DYNLIBMOD_OBJ="dynlibmod.lo"
|
||||
|
||||
DYNLIBMOD_HEADER='$(srcdir)/dynlibmod/dynlibmod.h'
|
||||
|
||||
if test $on_mingw = "no"; then
|
||||
DYNLIBMOD_EXTRALIBS="-ldl -export-dynamic"
|
||||
else
|
||||
DYNLIBMOD_EXTRALIBS="-Wl,--export-all-symbols,--out-implib,libunbound.a"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# Check for PyUnbound
|
||||
|
||||
# Check whether --with-pyunbound was given.
|
||||
@ -17312,6 +17365,11 @@ $as_echo_n "checking for Python library path... " >&6; }
|
||||
$as_echo "$PYTHON_LDFLAGS" >&6; }
|
||||
|
||||
|
||||
if test -z "$PYTHON_LIBDIR"; then
|
||||
PYTHON_LIBDIR=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
print(get_config_var('LIBDIR'));"`
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for site packages
|
||||
#
|
||||
@ -17417,6 +17475,15 @@ $as_echo "#define HAVE_PYTHON 1" >>confdefs.h
|
||||
else
|
||||
CPPFLAGS="$PYTHON_CPPFLAGS"
|
||||
fi
|
||||
if test "$PYTHON_LIBDIR" != "/usr/lib" -a "$PYTHON_LIBDIR" != "" -a "$PYTHON_LIBDIR" != "/usr/lib64"; then
|
||||
|
||||
if test "x$enable_rpath" = xyes; then
|
||||
if echo "$PYTHON_LIBDIR" | grep "^/" >/dev/null; then
|
||||
RUNTIME_PATH="$RUNTIME_PATH -R$PYTHON_LIBDIR"
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
ub_have_python=yes
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\"python\${PY_MAJOR_VERSION}\"\""; } >&5
|
||||
@ -18259,7 +18326,7 @@ else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
for ac_header in openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h
|
||||
for ac_header in openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h
|
||||
do :
|
||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
|
||||
@ -18273,7 +18340,7 @@ fi
|
||||
|
||||
done
|
||||
|
||||
for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback
|
||||
for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
@ -18289,7 +18356,7 @@ done
|
||||
# these check_funcs need -lssl
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites
|
||||
for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb
|
||||
do :
|
||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||
@ -19107,31 +19174,34 @@ esac
|
||||
if test "${with_libevent+set}" = set; then :
|
||||
withval=$with_libevent;
|
||||
else
|
||||
withval="no"
|
||||
with_libevent="no"
|
||||
fi
|
||||
|
||||
if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
if test "x_$with_libevent" != x_no; then
|
||||
|
||||
$as_echo "#define USE_LIBEVENT 1" >>confdefs.h
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libevent" >&5
|
||||
$as_echo_n "checking for libevent... " >&6; }
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
if test "x_$with_libevent" = x_ -o "x_$with_libevent" = x_yes; then
|
||||
with_libevent="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval; do
|
||||
for dir in $with_libevent; do
|
||||
thedir="$dir"
|
||||
if test -f "$dir/include/event.h" -o -f "$dir/include/event2/event.h"; then
|
||||
found_libevent="yes"
|
||||
if test "$thedir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir/include"
|
||||
fi
|
||||
break;
|
||||
fi
|
||||
if test "$thedir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir/include"
|
||||
fi
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libevent != x_yes; then
|
||||
if test -f "$dir/event.h" -a \( -f "$dir/libevent.la" -o -f "$dir/libev.la" \) ; then
|
||||
# libevent source directory
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $thedir" >&5
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $thedir" >&5
|
||||
$as_echo "found in $thedir" >&6; }
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir -I$thedir/include"
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir -I$thedir/include"
|
||||
BAK_LDFLAGS_SET="1"
|
||||
BAK_LDFLAGS="$LDFLAGS"
|
||||
# remove evdns from linking
|
||||
@ -19144,10 +19214,10 @@ $as_echo "found in $thedir" >&6; }
|
||||
cp $ev_files_o build/libevent
|
||||
cp $ev_files_lo build/libevent
|
||||
cp $ev_files_libso build/libevent/.libs
|
||||
LATE_LDFLAGS="build/libevent/*.lo -lm"
|
||||
LATE_LDFLAGS="build/libevent/*.lo -lm"
|
||||
LDFLAGS="build/libevent/*.o $LDFLAGS -lm"
|
||||
else
|
||||
as_fn_error $? "Cannot find the libevent library in $withval
|
||||
as_fn_error $? "Cannot find the libevent library in $with_libevent
|
||||
You can restart ./configure --with-libevent=no to use a builtin alternative.
|
||||
Please note that this alternative is not as capable as libevent when using
|
||||
large outgoing port ranges. " "$LINENO" 5
|
||||
@ -20968,73 +21038,6 @@ else
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# Check whether --with-libfstrm was given.
|
||||
if test "${with_libfstrm+set}" = set; then :
|
||||
withval=$with_libfstrm;
|
||||
CFLAGS="$CFLAGS -I$withval/include"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fstrm_iothr_init" >&5
|
||||
$as_echo_n "checking for library containing fstrm_iothr_init... " >&6; }
|
||||
if ${ac_cv_search_fstrm_iothr_init+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_func_search_save_LIBS=$LIBS
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char fstrm_iothr_init ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return fstrm_iothr_init ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
for ac_lib in '' fstrm; do
|
||||
if test -z "$ac_lib"; then
|
||||
ac_res="none required"
|
||||
else
|
||||
ac_res=-l$ac_lib
|
||||
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
|
||||
fi
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_search_fstrm_iothr_init=$ac_res
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext
|
||||
if ${ac_cv_search_fstrm_iothr_init+:} false; then :
|
||||
break
|
||||
fi
|
||||
done
|
||||
if ${ac_cv_search_fstrm_iothr_init+:} false; then :
|
||||
|
||||
else
|
||||
ac_cv_search_fstrm_iothr_init=no
|
||||
fi
|
||||
rm conftest.$ac_ext
|
||||
LIBS=$ac_func_search_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fstrm_iothr_init" >&5
|
||||
$as_echo "$ac_cv_search_fstrm_iothr_init" >&6; }
|
||||
ac_res=$ac_cv_search_fstrm_iothr_init
|
||||
if test "$ac_res" != no; then :
|
||||
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
||||
|
||||
else
|
||||
as_fn_error $? "The fstrm library was not found. Please install fstrm!" "$LINENO" 5
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing protobuf_c_message_pack" >&5
|
||||
$as_echo_n "checking for library containing protobuf_c_message_pack... " >&6; }
|
||||
if ${ac_cv_search_protobuf_c_message_pack+:} false; then :
|
||||
@ -21108,10 +21111,12 @@ cat >>confdefs.h <<_ACEOF
|
||||
#define DNSTAP_SOCKET_PATH "$hdr_dnstap_socket_path"
|
||||
_ACEOF
|
||||
|
||||
DNSTAP_SOCKET_PATH="$hdr_dnstap_socket_path"
|
||||
|
||||
DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c"
|
||||
|
||||
DNSTAP_OBJ="dnstap.lo dnstap.pb-c.lo"
|
||||
DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c"
|
||||
|
||||
DNSTAP_OBJ="dnstap.lo dnstap.pb-c.lo dnstap_fstrm.lo dtstream.lo"
|
||||
|
||||
|
||||
else
|
||||
@ -21443,6 +21448,21 @@ $as_echo "found in $dir" >&6; }
|
||||
# nothing
|
||||
;;
|
||||
esac
|
||||
# Check whether --enable-explicit-port-randomisation was given.
|
||||
if test "${enable_explicit_port_randomisation+set}" = set; then :
|
||||
enableval=$enable_explicit_port_randomisation;
|
||||
fi
|
||||
|
||||
case "$enable_explicit_port_randomisation" in
|
||||
no)
|
||||
|
||||
$as_echo "#define DISABLE_EXPLICIT_PORT_RANDOMISATION 1" >>confdefs.h
|
||||
|
||||
;;
|
||||
yes|*)
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${MAKE:-make} supports $< with implicit rule in scope" >&5
|
||||
$as_echo_n "checking if ${MAKE:-make} supports $< with implicit rule in scope... " >&6; }
|
||||
@ -21599,7 +21619,7 @@ _ACEOF
|
||||
|
||||
|
||||
|
||||
version=1.10.1
|
||||
version=1.11.0
|
||||
|
||||
date=`date +'%b %e, %Y'`
|
||||
|
||||
@ -22118,7 +22138,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by unbound $as_me 1.10.1, which was
|
||||
This file was extended by unbound $as_me 1.11.0, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -22184,7 +22204,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
unbound config.status 1.10.1
|
||||
unbound config.status 1.11.0
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
86
configure.ac
86
configure.ac
@ -10,15 +10,15 @@ sinclude(dnscrypt/dnscrypt.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[10])
|
||||
m4_define([VERSION_MICRO],[1])
|
||||
m4_define([VERSION_MINOR],[11])
|
||||
m4_define([VERSION_MICRO],[0])
|
||||
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues, unbound)
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=8
|
||||
LIBUNBOUND_REVISION=9
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@ -94,6 +94,7 @@ LIBUNBOUND_AGE=1
|
||||
# 1.9.6 had 9:6:1
|
||||
# 1.10.0 had 9:7:1
|
||||
# 1.10.1 had 9:8:1
|
||||
# 1.11.0 had 9:9:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@ -399,6 +400,9 @@ PKG_PROG_PKG_CONFIG
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
# Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH
|
||||
AC_CHECK_HEADERS([TargetConditionals.h])
|
||||
|
||||
# check for types.
|
||||
# Using own tests for int64* because autoconf builtin only give 32bit.
|
||||
AC_CHECK_TYPE(int8_t, signed char)
|
||||
@ -624,6 +628,28 @@ case "${UNBOUND_SYSLOG_FACILITY}" in
|
||||
esac
|
||||
AC_DEFINE_UNQUOTED(UB_SYSLOG_FACILITY,${UNBOUND_SYSLOG_FACILITY},[the SYSLOG_FACILITY to use, default LOG_DAEMON])
|
||||
|
||||
# Check for dynamic library module
|
||||
AC_ARG_WITH(dynlibmodule,
|
||||
AC_HELP_STRING([--with-dynlibmodule],
|
||||
[build dynamic library module, or --without-dynlibmodule to disable it. (default=no)]),
|
||||
[], [ withval="no" ])
|
||||
|
||||
if test x_$withval != x_no; then
|
||||
AC_DEFINE(WITH_DYNLIBMODULE, 1, [Define if you want dynlib module.])
|
||||
WITH_DYNLIBMODULE=yes
|
||||
AC_SUBST(WITH_DYNLIBMODULE)
|
||||
DYNLIBMOD_OBJ="dynlibmod.lo"
|
||||
AC_SUBST(DYNLIBMOD_OBJ)
|
||||
DYNLIBMOD_HEADER='$(srcdir)/dynlibmod/dynlibmod.h'
|
||||
AC_SUBST(DYNLIBMOD_HEADER)
|
||||
if test $on_mingw = "no"; then
|
||||
DYNLIBMOD_EXTRALIBS="-ldl -export-dynamic"
|
||||
else
|
||||
DYNLIBMOD_EXTRALIBS="-Wl,--export-all-symbols,--out-implib,libunbound.a"
|
||||
fi
|
||||
AC_SUBST(DYNLIBMOD_EXTRALIBS)
|
||||
fi
|
||||
|
||||
# Check for PyUnbound
|
||||
AC_ARG_WITH(pyunbound,
|
||||
AC_HELP_STRING([--with-pyunbound],
|
||||
@ -675,6 +701,9 @@ if test x_$ub_test_python != x_no; then
|
||||
else
|
||||
CPPFLAGS="$PYTHON_CPPFLAGS"
|
||||
fi
|
||||
if test "$PYTHON_LIBDIR" != "/usr/lib" -a "$PYTHON_LIBDIR" != "" -a "$PYTHON_LIBDIR" != "/usr/lib64"; then
|
||||
ACX_RUNTIME_PATH_ADD([$PYTHON_LIBDIR])
|
||||
fi
|
||||
ub_have_python=yes
|
||||
PKG_CHECK_EXISTS(["python${PY_MAJOR_VERSION}"],
|
||||
[PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"],
|
||||
@ -821,13 +850,13 @@ if grep VERSION_TEXT $ssldir/include/openssl/opensslv.h | grep "LibreSSL" >/dev/
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback])
|
||||
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback])
|
||||
|
||||
# these check_funcs need -lssl
|
||||
BAKLIBS="$LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites])
|
||||
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb])
|
||||
LIBS="$BAKLIBS"
|
||||
|
||||
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
|
||||
@ -1215,28 +1244,29 @@ esac
|
||||
# check for libevent
|
||||
AC_ARG_WITH(libevent, AC_HELP_STRING([--with-libevent=pathname],
|
||||
[use libevent (will check /usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr or you can specify an explicit path). Slower, but allows use of large outgoing port ranges.]),
|
||||
[ ],[ withval="no" ])
|
||||
if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
[ ],[ with_libevent="no" ])
|
||||
if test "x_$with_libevent" != x_no; then
|
||||
AC_DEFINE([USE_LIBEVENT], [1], [Define if you enable libevent])
|
||||
AC_MSG_CHECKING(for libevent)
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
if test "x_$with_libevent" = x_ -o "x_$with_libevent" = x_yes; then
|
||||
with_libevent="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval; do
|
||||
for dir in $with_libevent; do
|
||||
thedir="$dir"
|
||||
if test -f "$dir/include/event.h" -o -f "$dir/include/event2/event.h"; then
|
||||
found_libevent="yes"
|
||||
dnl assume /usr is in default path.
|
||||
if test "$thedir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir/include"
|
||||
fi
|
||||
break;
|
||||
fi
|
||||
dnl assume /usr is in default path.
|
||||
if test "$thedir" != "/usr"; then
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir/include"
|
||||
fi
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libevent != x_yes; then
|
||||
if test -f "$dir/event.h" -a \( -f "$dir/libevent.la" -o -f "$dir/libev.la" \) ; then
|
||||
# libevent source directory
|
||||
AC_MSG_RESULT(found in $thedir)
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir -I$thedir/include"
|
||||
AC_MSG_RESULT(found in $thedir)
|
||||
CPPFLAGS="$CPPFLAGS -I$thedir -I$thedir/include"
|
||||
BAK_LDFLAGS_SET="1"
|
||||
BAK_LDFLAGS="$LDFLAGS"
|
||||
# remove evdns from linking
|
||||
@ -1249,10 +1279,10 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
cp $ev_files_o build/libevent
|
||||
cp $ev_files_lo build/libevent
|
||||
cp $ev_files_libso build/libevent/.libs
|
||||
LATE_LDFLAGS="build/libevent/*.lo -lm"
|
||||
LATE_LDFLAGS="build/libevent/*.lo -lm"
|
||||
LDFLAGS="build/libevent/*.o $LDFLAGS -lm"
|
||||
else
|
||||
AC_MSG_ERROR([Cannot find the libevent library in $withval
|
||||
AC_MSG_ERROR([Cannot find the libevent library in $with_libevent
|
||||
You can restart ./configure --with-libevent=no to use a builtin alternative.
|
||||
Please note that this alternative is not as capable as libevent when using
|
||||
large outgoing port ranges. ])
|
||||
@ -1688,9 +1718,10 @@ dt_DNSTAP([$UNBOUND_RUN_DIR/dnstap.sock],
|
||||
ACX_ESCAPE_BACKSLASH($opt_dnstap_socket_path, hdr_dnstap_socket_path)
|
||||
AC_DEFINE_UNQUOTED(DNSTAP_SOCKET_PATH,
|
||||
["$hdr_dnstap_socket_path"], [default dnstap socket path])
|
||||
AC_SUBST(DNSTAP_SOCKET_PATH,["$hdr_dnstap_socket_path"])
|
||||
|
||||
AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c"])
|
||||
AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo"])
|
||||
AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c"])
|
||||
AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo dnstap_fstrm.lo dtstream.lo"])
|
||||
],
|
||||
[
|
||||
AC_SUBST([ENABLE_DNSTAP], [0])
|
||||
@ -1778,6 +1809,15 @@ case "$enable_ipset" in
|
||||
# nothing
|
||||
;;
|
||||
esac
|
||||
AC_ARG_ENABLE(explicit-port-randomisation, AC_HELP_STRING([--disable-explicit-port-randomisation], [disable explicit source port randomisation and rely on the kernel to provide random source ports]))
|
||||
case "$enable_explicit_port_randomisation" in
|
||||
no)
|
||||
AC_DEFINE([DISABLE_EXPLICIT_PORT_RANDOMISATION], [1], [Define this to enable kernel based UDP source port randomization.])
|
||||
;;
|
||||
yes|*)
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
|
||||
# on openBSD, the implicit rule make $< work.
|
||||
|
@ -13,9 +13,9 @@ Index: trunk/doc/unbound.conf.5.in
|
||||
+This also causes an additional A query to be sent for each AAAA query.
|
||||
+This breaks DNSSEC!
|
||||
+.TP
|
||||
.B private\-address: \fI<IP address or subnet>
|
||||
Give IPv4 of IPv6 addresses or classless subnets. These are addresses
|
||||
on your private network, and are not allowed to be returned for
|
||||
.B aggressive\-nsec: \fI<yes or no>
|
||||
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
|
||||
and other denials, using information from previous NXDOMAINs answers.
|
||||
Index: trunk/iterator/iter_scrub.c
|
||||
===================================================================
|
||||
--- trunk/iterator/iter_scrub.c (revision 4357)
|
||||
@ -125,7 +125,7 @@ Index: trunk/iterator/iterator.c
|
||||
+ * ASN: This event state was added as an intermediary step between
|
||||
+ * QUERYTARGETS_STATE and the next step, in order to cast a subquery for the
|
||||
+ * purpose of caching A records for the queried name.
|
||||
+ *
|
||||
+ *
|
||||
+ * @param qstate: query state.
|
||||
+ * @param iq: iterator query state.
|
||||
+ * @param ie: iterator shared global environment.
|
||||
@ -147,9 +147,9 @@ Index: trunk/iterator/iterator.c
|
||||
+
|
||||
+ /* re-throw same query, but with a different type */
|
||||
+ if(!generate_sub_request(iq->qchase.qname,
|
||||
+ iq->qchase.qname_len, LDNS_RR_TYPE_A,
|
||||
+ iq->qchase.qname_len, LDNS_RR_TYPE_A,
|
||||
+ iq->qchase.qclass, qstate, id, iq,
|
||||
+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
|
||||
+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
|
||||
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: failed "
|
||||
+ "preloading of A record for",
|
||||
+ iq->qchase.qname, LDNS_RR_TYPE_A,
|
||||
@ -188,7 +188,7 @@ Index: trunk/iterator/iterator.c
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+/**
|
||||
+ * ASN: Do final processing on responses to A queries originated from AAAA
|
||||
+ * queries. Events reach this state after the iterative resolution algorithm
|
||||
+ * terminates.
|
||||
|
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
|
@ -2,7 +2,7 @@ Description: based on the included patch contrib/fastrpz.patch
|
||||
Author: fastrpz@farsightsecurity.com
|
||||
---
|
||||
diff --git a/Makefile.in b/Makefile.in
|
||||
index a20058cc..495779cc 100644
|
||||
index bac212df..4824927f 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c
|
||||
@ -13,8 +13,8 @@ index a20058cc..495779cc 100644
|
||||
+FASTRPZ_OBJ=@FASTRPZ_OBJ@
|
||||
DNSCRYPT_SRC=@DNSCRYPT_SRC@
|
||||
DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
|
||||
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
|
||||
@@ -127,7 +129,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
|
||||
WITH_DYNLIBMODULE=@WITH_DYNLIBMODULE@
|
||||
@@ -134,7 +136,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
|
||||
edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
|
||||
edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
|
||||
cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
|
||||
@ -23,16 +23,16 @@ index a20058cc..495779cc 100644
|
||||
COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
|
||||
as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
|
||||
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
|
||||
@@ -140,7 +142,7 @@ autotrust.lo val_anchor.lo rpz.lo \
|
||||
@@ -147,7 +149,7 @@ autotrust.lo val_anchor.lo rpz.lo \
|
||||
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
|
||||
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
|
||||
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
|
||||
-$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
|
||||
+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
|
||||
-$(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
|
||||
+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
|
||||
COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
|
||||
outside_network.lo
|
||||
COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
|
||||
@@ -410,6 +412,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
|
||||
@@ -428,6 +430,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/netevent.h
|
||||
|
||||
@ -45,10 +45,10 @@ index a20058cc..495779cc 100644
|
||||
pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
|
||||
pythonmod/interface.h \
|
||||
diff --git a/config.h.in b/config.h.in
|
||||
index 78d47fed..e33073e4 100644
|
||||
index f7a4095e..d5a4fa01 100644
|
||||
--- a/config.h.in
|
||||
+++ b/config.h.in
|
||||
@@ -1345,4 +1345,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
@@ -1364,4 +1364,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
/** the version of unbound-control that this software implements */
|
||||
#define UNBOUND_CONTROL_VERSION 1
|
||||
|
||||
@ -62,7 +62,7 @@ index 78d47fed..e33073e4 100644
|
||||
+/** turn on fastrpz response policy zones */
|
||||
+#undef ENABLE_FASTRPZ
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 2b91dd3c..e6063d17 100644
|
||||
index 5c373d9d..e45abd89 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -6,6 +6,7 @@ sinclude(ax_pthread.m4)
|
||||
@ -73,10 +73,10 @@ index 2b91dd3c..e6063d17 100644
|
||||
sinclude(dnscrypt/dnscrypt.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
@@ -1778,6 +1779,9 @@ case "$enable_ipset" in
|
||||
;;
|
||||
@@ -1819,6 +1820,9 @@ case "$enable_explicit_port_randomisation" in
|
||||
esac
|
||||
|
||||
|
||||
+# check for Fastrpz with fastrpz/rpz.m4
|
||||
+ck_FASTRPZ
|
||||
+
|
||||
@ -84,7 +84,7 @@ index 2b91dd3c..e6063d17 100644
|
||||
# on openBSD, the implicit rule make $< work.
|
||||
# on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
|
||||
diff --git a/daemon/daemon.c b/daemon/daemon.c
|
||||
index 8b0fc348..7ffb9221 100644
|
||||
index 5d427925..f89f1437 100644
|
||||
--- a/daemon/daemon.c
|
||||
+++ b/daemon/daemon.c
|
||||
@@ -91,6 +91,9 @@
|
||||
@ -97,8 +97,8 @@ index 8b0fc348..7ffb9221 100644
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
#include <systemd/sd-daemon.h>
|
||||
@@ -458,6 +461,14 @@ daemon_create_workers(struct daemon* daemon)
|
||||
dt_apply_cfg(daemon->dtenv, daemon->cfg);
|
||||
@@ -456,6 +459,14 @@ daemon_create_workers(struct daemon* daemon)
|
||||
fatal_exit("dt_create failed");
|
||||
#else
|
||||
fatal_exit("dnstap enabled in config but not built with dnstap support");
|
||||
+#endif
|
||||
@ -112,7 +112,7 @@ index 8b0fc348..7ffb9221 100644
|
||||
#endif
|
||||
}
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
@@ -731,6 +742,9 @@ daemon_cleanup(struct daemon* daemon)
|
||||
@@ -729,6 +740,9 @@ daemon_cleanup(struct daemon* daemon)
|
||||
#ifdef USE_DNSCRYPT
|
||||
dnsc_delete(daemon->dnscenv);
|
||||
daemon->dnscenv = NULL;
|
||||
@ -139,7 +139,7 @@ index 3effbafb..4d4c34da 100644
|
||||
|
||||
/**
|
||||
diff --git a/daemon/worker.c b/daemon/worker.c
|
||||
index eb7fdf2f..1982228d 100644
|
||||
index 23e3244c..b63d49b7 100644
|
||||
--- a/daemon/worker.c
|
||||
+++ b/daemon/worker.c
|
||||
@@ -76,6 +76,9 @@
|
||||
@ -152,7 +152,7 @@ index eb7fdf2f..1982228d 100644
|
||||
#include "sldns/wire2str.h"
|
||||
#include "util/shm_side/shm_main.h"
|
||||
#include "dnscrypt/dnscrypt.h"
|
||||
@@ -534,8 +537,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
@@ -535,8 +538,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
/* not secure */
|
||||
secure = 0;
|
||||
break;
|
||||
@ -180,7 +180,7 @@ index eb7fdf2f..1982228d 100644
|
||||
/* return this delegation from the cache */
|
||||
edns_bak = *edns;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
@@ -710,6 +732,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
@@ -711,6 +733,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
||||
*is_secure_answer = 0;
|
||||
}
|
||||
} else *is_secure_answer = 0;
|
||||
@ -204,7 +204,7 @@ index eb7fdf2f..1982228d 100644
|
||||
|
||||
edns_bak = *edns;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
@@ -1435,6 +1474,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
@@ -1436,6 +1475,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
|
||||
&repinfo->addr, repinfo->addrlen);
|
||||
goto send_reply;
|
||||
@ -220,7 +220,7 @@ index eb7fdf2f..1982228d 100644
|
||||
}
|
||||
|
||||
/* If we've found a local alias, replace the qname with the alias
|
||||
@@ -1485,12 +1533,21 @@ lookup_cache:
|
||||
@@ -1486,12 +1534,21 @@ lookup_cache:
|
||||
h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
|
||||
if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
|
||||
/* answer from cache - we have acquired a readlock on it */
|
||||
@ -244,7 +244,7 @@ index eb7fdf2f..1982228d 100644
|
||||
/* prefetch it if the prefetch TTL expired.
|
||||
* Note that if there is more than one pass
|
||||
* its qname must be that used for cache
|
||||
@@ -1547,11 +1604,19 @@ lookup_cache:
|
||||
@@ -1548,11 +1605,19 @@ lookup_cache:
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
|
||||
@ -267,10 +267,10 @@ index eb7fdf2f..1982228d 100644
|
||||
}
|
||||
verbose(VERB_ALGO, "answer norec from cache -- "
|
||||
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
|
||||
index 38c2d298..3b07f392 100644
|
||||
index cd43f04e..b92a1af8 100644
|
||||
--- a/doc/unbound.conf.5.in
|
||||
+++ b/doc/unbound.conf.5.in
|
||||
@@ -1828,6 +1828,81 @@ List domain for which the AAAA records are ignored and the A record is
|
||||
@@ -1878,6 +1878,81 @@ List domain for which the AAAA records are ignored and the A record is
|
||||
used by dns64 processing instead. Can be entered multiple times, list a
|
||||
new domain for which it applies, one per line. Applies also to names
|
||||
underneath the name given.
|
||||
@ -2888,7 +2888,7 @@ index 00000000..21235355
|
||||
+ fi
|
||||
+])
|
||||
diff --git a/iterator/iterator.c b/iterator/iterator.c
|
||||
index 1e0113a8..2fcbf547 100644
|
||||
index 23b07ea9..c3d31a33 100644
|
||||
--- a/iterator/iterator.c
|
||||
+++ b/iterator/iterator.c
|
||||
@@ -68,6 +68,9 @@
|
||||
@ -2901,7 +2901,7 @@ index 1e0113a8..2fcbf547 100644
|
||||
|
||||
/* in msec */
|
||||
int UNKNOWN_SERVER_NICENESS = 376;
|
||||
@@ -555,6 +558,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
@@ -563,6 +566,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if(ntohs(r->rk.type) == LDNS_RR_TYPE_CNAME &&
|
||||
query_dname_compare(*mname, r->rk.dname) == 0 &&
|
||||
!iter_find_rrset_in_prepend_answer(iq, r)) {
|
||||
@ -2925,7 +2925,7 @@ index 1e0113a8..2fcbf547 100644
|
||||
/* Add this relevant CNAME rrset to the prepend list.*/
|
||||
if(!iter_add_prepend_answer(qstate, iq, r))
|
||||
return 0;
|
||||
@@ -563,6 +583,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
@@ -571,6 +591,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
|
||||
/* Other rrsets in the section are ignored. */
|
||||
}
|
||||
@ -2935,7 +2935,7 @@ index 1e0113a8..2fcbf547 100644
|
||||
/* add authority rrsets to authority prepend, for wildcarded CNAMEs */
|
||||
for(i=msg->rep->an_numrrsets; i<msg->rep->an_numrrsets +
|
||||
msg->rep->ns_numrrsets; i++) {
|
||||
@@ -1199,6 +1222,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
@@ -1231,6 +1254,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
uint8_t* delname;
|
||||
size_t delnamelen;
|
||||
struct dns_msg* msg = NULL;
|
||||
@ -2943,7 +2943,7 @@ index 1e0113a8..2fcbf547 100644
|
||||
|
||||
log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
|
||||
/* check effort */
|
||||
@@ -1285,8 +1309,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
@@ -1317,8 +1341,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
if(msg) {
|
||||
/* handle positive cache response */
|
||||
@ -2953,7 +2953,7 @@ index 1e0113a8..2fcbf547 100644
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
log_dns_msg("msg from cache lookup", &msg->qinfo,
|
||||
msg->rep);
|
||||
@@ -1294,7 +1317,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
@@ -1326,7 +1349,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
(int)msg->rep->ttl,
|
||||
(int)msg->rep->prefetch_ttl);
|
||||
}
|
||||
@ -2976,7 +2976,7 @@ index 1e0113a8..2fcbf547 100644
|
||||
if(type == RESPONSE_TYPE_CNAME) {
|
||||
uint8_t* sname = 0;
|
||||
size_t slen = 0;
|
||||
@@ -2718,6 +2756,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
@@ -2801,6 +2839,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
sock_list_insert(&qstate->reply_origin,
|
||||
&qstate->reply->addr, qstate->reply->addrlen,
|
||||
qstate->region);
|
||||
@ -3039,7 +3039,7 @@ index 1e0113a8..2fcbf547 100644
|
||||
if(iq->minimisation_state != DONOT_MINIMISE_STATE
|
||||
&& !(iq->chase_flags & BIT_RD)) {
|
||||
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
|
||||
@@ -3471,12 +3565,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
@@ -3563,12 +3657,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* but only if we did recursion. The nonrecursion referral
|
||||
* from cache does not need to be stored in the msg cache. */
|
||||
if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
|
||||
@ -3085,10 +3085,10 @@ index 1e0113a8..2fcbf547 100644
|
||||
qstate->return_msg = iq->response;
|
||||
return 0;
|
||||
diff --git a/iterator/iterator.h b/iterator/iterator.h
|
||||
index a2f1b570..e1e4a738 100644
|
||||
index 342ac207..49b0ecdd 100644
|
||||
--- a/iterator/iterator.h
|
||||
+++ b/iterator/iterator.h
|
||||
@@ -386,6 +386,16 @@ struct iter_qstate {
|
||||
@@ -396,6 +396,16 @@ struct iter_qstate {
|
||||
*/
|
||||
int minimise_count;
|
||||
|
||||
@ -3104,12 +3104,12 @@ index a2f1b570..e1e4a738 100644
|
||||
+
|
||||
/**
|
||||
* Count number of time-outs. Used to prevent resolving failures when
|
||||
* the QNAME minimisation QTYPE is blocked. */
|
||||
* the QNAME minimisation QTYPE is blocked. Used to determine if
|
||||
diff --git a/services/cache/dns.c b/services/cache/dns.c
|
||||
index 2a5bca4a..6de8863a 100644
|
||||
index 7b6e142c..6d7449f5 100644
|
||||
--- a/services/cache/dns.c
|
||||
+++ b/services/cache/dns.c
|
||||
@@ -967,6 +967,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
@@ -969,6 +969,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
|
||||
struct regional* region, uint32_t flags)
|
||||
{
|
||||
struct reply_info* rep = NULL;
|
||||
@ -3125,7 +3125,7 @@ index 2a5bca4a..6de8863a 100644
|
||||
rep = reply_info_copy(msgrep, env->alloc, NULL);
|
||||
if(!rep)
|
||||
diff --git a/services/mesh.c b/services/mesh.c
|
||||
index 9114ef4c..3dc518e5 100644
|
||||
index 4b0c5db4..eb9cfa5b 100644
|
||||
--- a/services/mesh.c
|
||||
+++ b/services/mesh.c
|
||||
@@ -61,6 +61,9 @@
|
||||
@ -3138,7 +3138,7 @@ index 9114ef4c..3dc518e5 100644
|
||||
#include "respip/respip.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
|
||||
@@ -1195,6 +1198,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
@@ -1207,6 +1210,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
else secure = 0;
|
||||
if(!rep && rcode == LDNS_RCODE_NOERROR)
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
@ -3152,7 +3152,7 @@ index 9114ef4c..3dc518e5 100644
|
||||
/* send the reply */
|
||||
/* We don't reuse the encoded answer if either the previous or current
|
||||
* response has a local alias. We could compare the alias records
|
||||
@@ -1415,6 +1425,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
|
||||
@@ -1434,6 +1444,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
|
||||
key.s.is_valrec = valrec;
|
||||
key.s.qinfo = *qinfo;
|
||||
key.s.query_flags = qflags;
|
||||
@ -3160,7 +3160,7 @@ index 9114ef4c..3dc518e5 100644
|
||||
/* We are searching for a similar mesh state when we DO want to
|
||||
* aggregate the state. Thus unique is set to NULL. (default when we
|
||||
* desire aggregation).*/
|
||||
@@ -1461,6 +1472,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||
@@ -1480,6 +1491,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||
if(!r)
|
||||
return 0;
|
||||
r->query_reply = *rep;
|
||||
@ -3172,11 +3172,11 @@ index 9114ef4c..3dc518e5 100644
|
||||
if(edns->opt_list) {
|
||||
r->edns.opt_list = edns_opt_copy_region(edns->opt_list,
|
||||
diff --git a/util/config_file.c b/util/config_file.c
|
||||
index 52ca5a18..0660248f 100644
|
||||
index 0e9ee471..a5fd72e0 100644
|
||||
--- a/util/config_file.c
|
||||
+++ b/util/config_file.c
|
||||
@@ -1460,6 +1460,8 @@ config_delete(struct config_file* cfg)
|
||||
free(cfg->dnstap_socket_path);
|
||||
@@ -1495,6 +1495,8 @@ config_delete(struct config_file* cfg)
|
||||
free(cfg->dnstap_tls_client_cert_file);
|
||||
free(cfg->dnstap_identity);
|
||||
free(cfg->dnstap_version);
|
||||
+ if (cfg->rpz_cstr)
|
||||
@ -3185,10 +3185,10 @@ index 52ca5a18..0660248f 100644
|
||||
config_deldblstrlist(cfg->ratelimit_below_domain);
|
||||
config_delstrlist(cfg->python_script);
|
||||
diff --git a/util/config_file.h b/util/config_file.h
|
||||
index 8739ca2a..a2dcf215 100644
|
||||
index 66e5025d..504f4f92 100644
|
||||
--- a/util/config_file.h
|
||||
+++ b/util/config_file.h
|
||||
@@ -499,6 +499,11 @@ struct config_file {
|
||||
@@ -522,6 +522,11 @@ struct config_file {
|
||||
/** true to disable DNSSEC lameness check in iterator */
|
||||
int disable_dnssec_lame_check;
|
||||
|
||||
@ -3201,10 +3201,10 @@ index 8739ca2a..a2dcf215 100644
|
||||
int ip_ratelimit;
|
||||
/** number of slabs for ip_ratelimit cache */
|
||||
diff --git a/util/configlexer.lex b/util/configlexer.lex
|
||||
index deedffa5..301458a3 100644
|
||||
index 83cea4b9..9a7feea4 100644
|
||||
--- a/util/configlexer.lex
|
||||
+++ b/util/configlexer.lex
|
||||
@@ -446,6 +446,10 @@ dnstap-log-forwarder-query-messages{COLON} {
|
||||
@@ -467,6 +467,10 @@ dnstap-log-forwarder-query-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
|
||||
dnstap-log-forwarder-response-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
|
||||
@ -3216,18 +3216,18 @@ index deedffa5..301458a3 100644
|
||||
ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
|
||||
ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) }
|
||||
diff --git a/util/configparser.y b/util/configparser.y
|
||||
index d471babe..cb6b1d63 100644
|
||||
index fe600a99..ce43390f 100644
|
||||
--- a/util/configparser.y
|
||||
+++ b/util/configparser.y
|
||||
@@ -125,6 +125,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
@@ -128,6 +128,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
|
||||
+%token VAR_RPZ VAR_RPZ_ENABLE VAR_RPZ_ZONE VAR_RPZ_OPTION
|
||||
%token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
|
||||
%token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
|
||||
%token VAR_DISABLE_DNSSEC_LAME_CHECK
|
||||
@@ -173,7 +174,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_IP_DSCP
|
||||
@@ -179,7 +180,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
@ -3236,7 +3236,7 @@ index d471babe..cb6b1d63 100644
|
||||
forwardstart contents_forward | pythonstart contents_py |
|
||||
rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
|
||||
dnscstart contents_dnsc | cachedbstart contents_cachedb |
|
||||
@@ -2837,6 +2838,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
|
||||
@@ -2939,6 +2940,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
@ -3384,7 +3384,7 @@ index 729877ba..ccd1a0c2 100644
|
||||
|
||||
/**
|
||||
diff --git a/util/netevent.c b/util/netevent.c
|
||||
index 9fe5da2d..037e70d1 100644
|
||||
index 3e7a433e..f20d806f 100644
|
||||
--- a/util/netevent.c
|
||||
+++ b/util/netevent.c
|
||||
@@ -57,6 +57,9 @@
|
||||
@ -3397,7 +3397,7 @@ index 9fe5da2d..037e70d1 100644
|
||||
|
||||
/* -------- Start of local definitions -------- */
|
||||
/** if CMSG_ALIGN is not defined on this platform, a workaround */
|
||||
@@ -590,6 +593,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
|
||||
@@ -596,6 +599,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
|
||||
struct cmsghdr* cmsg;
|
||||
#endif /* S_SPLINT_S */
|
||||
|
||||
@ -3407,7 +3407,7 @@ index 9fe5da2d..037e70d1 100644
|
||||
rep.c = (struct comm_point*)arg;
|
||||
log_assert(rep.c->type == comm_udp);
|
||||
|
||||
@@ -679,6 +685,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
|
||||
@@ -685,6 +691,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
|
||||
int i;
|
||||
struct sldns_buffer *buffer;
|
||||
|
||||
@ -3417,7 +3417,7 @@ index 9fe5da2d..037e70d1 100644
|
||||
rep.c = (struct comm_point*)arg;
|
||||
log_assert(rep.c->type == comm_udp);
|
||||
|
||||
@@ -722,6 +731,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
|
||||
@@ -728,6 +737,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
|
||||
(void)comm_point_send_udp_msg(rep.c, buffer,
|
||||
(struct sockaddr*)&rep.addr, rep.addrlen);
|
||||
}
|
||||
@ -3427,7 +3427,7 @@ index 9fe5da2d..037e70d1 100644
|
||||
if(!rep.c || rep.c->fd != fd) /* commpoint closed to -1 or reused for
|
||||
another UDP port. Note rep.c cannot be reused with TCP fd. */
|
||||
break;
|
||||
@@ -3192,6 +3204,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
|
||||
@@ -3175,6 +3187,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
|
||||
repinfo->c->tcp_timeout_msec);
|
||||
}
|
||||
}
|
||||
@ -3437,7 +3437,7 @@ index 9fe5da2d..037e70d1 100644
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3201,6 +3216,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
|
||||
@@ -3184,6 +3199,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
|
||||
return;
|
||||
log_assert(repinfo->c);
|
||||
log_assert(repinfo->c->type != comm_tcp_accept);
|
||||
@ -3447,7 +3447,7 @@ index 9fe5da2d..037e70d1 100644
|
||||
if(repinfo->c->type == comm_udp)
|
||||
return;
|
||||
if(repinfo->c->tcp_req_info)
|
||||
@@ -3222,6 +3240,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
|
||||
@@ -3205,6 +3223,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
|
||||
{
|
||||
verbose(VERB_ALGO, "comm point start listening %d (%d msec)",
|
||||
c->fd==-1?newfd:c->fd, msec);
|
||||
@ -3458,7 +3458,7 @@ index 9fe5da2d..037e70d1 100644
|
||||
/* no use to start listening no free slots. */
|
||||
return;
|
||||
diff --git a/util/netevent.h b/util/netevent.h
|
||||
index d80c72b3..0233292f 100644
|
||||
index bb2cd1e5..666067e8 100644
|
||||
--- a/util/netevent.h
|
||||
+++ b/util/netevent.h
|
||||
@@ -120,6 +120,10 @@ struct comm_reply {
|
||||
|
41
contrib/ios/15-ios.conf
Normal file
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
|
@ -7,8 +7,7 @@ Name: unbound
|
||||
Description: Library with validating, recursive, and caching DNS resolver
|
||||
URL: http://www.unbound.net
|
||||
Version: @PACKAGE_VERSION@
|
||||
Requires: @PC_CRYPTO_DEPENDENCY@ @PC_LIBEVENT_DEPENDENCY@
|
||||
Requires.private: @PC_PY_DEPENDENCY@ @PC_LIBBSD_DEPENDENCY@
|
||||
Requires.private: @PC_PY_DEPENDENCY@ @PC_LIBBSD_DEPENDENCY@ @PC_CRYPTO_DEPENDENCY@ @PC_LIBEVENT_DEPENDENCY@
|
||||
Libs: -L${libdir} -lunbound
|
||||
Libs.private: @SSLLIB@ @LIBS@
|
||||
Cflags: -I${includedir}
|
||||
|
@ -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
|
||||
|
@ -273,7 +273,7 @@ check_data(const char* data, const struct config_strlist* head)
|
||||
if(res == 0)
|
||||
return 1;
|
||||
log_err("rr data [char %d] parse error %s",
|
||||
(int)LDNS_WIREPARSE_OFFSET(res)-13,
|
||||
(int)LDNS_WIREPARSE_OFFSET(res)-2,
|
||||
sldns_get_errorstr_parse(res));
|
||||
return 0;
|
||||
}
|
||||
|
@ -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)
|
||||
@ -526,6 +534,8 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0)
|
||||
log_warn("unable to setusercontext %s: %s",
|
||||
cfg->username, strerror(errno));
|
||||
#else
|
||||
(void)pwd;
|
||||
#endif /* HAVE_SETUSERCONTEXT */
|
||||
}
|
||||
#endif /* HAVE_GETPWNAM */
|
||||
|
@ -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
|
||||
|
236
dnstap/dnstap_fstrm.c
Normal file
236
dnstap/dnstap_fstrm.c
Normal file
@ -0,0 +1,236 @@
|
||||
/*
|
||||
* dnstap/dnstap_fstrm.c - Frame Streams protocol for dnstap
|
||||
*
|
||||
* Copyright (c) 2020, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Definitions for the Frame Streams data transport protocol for
|
||||
* dnstap message logs.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "dnstap/dnstap_fstrm.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/wire2str.h"
|
||||
|
||||
void* fstrm_create_control_frame_start(char* contenttype, size_t* len)
|
||||
{
|
||||
uint32_t* control;
|
||||
size_t n;
|
||||
/* start framestream message:
|
||||
* 4byte 0: control indicator.
|
||||
* 4byte bigendian: length of control frame
|
||||
* 4byte bigendian: type START
|
||||
* 4byte bigendian: option: content-type
|
||||
* 4byte bigendian: length of string
|
||||
* string of content type (dnstap)
|
||||
*/
|
||||
n = 4+4+4+4+4+strlen(contenttype);
|
||||
control = malloc(n);
|
||||
if(!control)
|
||||
return NULL;
|
||||
control[0] = 0;
|
||||
control[1] = htonl(4+4+4+strlen(contenttype));
|
||||
control[2] = htonl(FSTRM_CONTROL_FRAME_START);
|
||||
control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
|
||||
control[4] = htonl(strlen(contenttype));
|
||||
memmove(&control[5], contenttype, strlen(contenttype));
|
||||
*len = n;
|
||||
return control;
|
||||
}
|
||||
|
||||
void* fstrm_create_control_frame_stop(size_t* len)
|
||||
{
|
||||
uint32_t* control;
|
||||
size_t n;
|
||||
/* stop framestream message:
|
||||
* 4byte 0: control indicator.
|
||||
* 4byte bigendian: length of control frame
|
||||
* 4byte bigendian: type STOP
|
||||
*/
|
||||
n = 4+4+4;
|
||||
control = malloc(n);
|
||||
if(!control)
|
||||
return NULL;
|
||||
control[0] = 0;
|
||||
control[1] = htonl(4);
|
||||
control[2] = htonl(FSTRM_CONTROL_FRAME_STOP);
|
||||
*len = n;
|
||||
return control;
|
||||
}
|
||||
|
||||
void* fstrm_create_control_frame_ready(char* contenttype, size_t* len)
|
||||
{
|
||||
uint32_t* control;
|
||||
size_t n;
|
||||
/* start bidirectional stream:
|
||||
* 4 bytes 0 escape
|
||||
* 4 bytes bigendian length of frame
|
||||
* 4 bytes bigendian type READY
|
||||
* 4 bytes bigendian frame option content type
|
||||
* 4 bytes bigendian length of string
|
||||
* string of content type.
|
||||
*/
|
||||
/* len includes the escape and framelength */
|
||||
n = 4+4+4+4+4+strlen(contenttype);
|
||||
control = malloc(n);
|
||||
if(!control) {
|
||||
return NULL;
|
||||
}
|
||||
control[0] = 0;
|
||||
control[1] = htonl(4+4+4+strlen(contenttype));
|
||||
control[2] = htonl(FSTRM_CONTROL_FRAME_READY);
|
||||
control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
|
||||
control[4] = htonl(strlen(contenttype));
|
||||
memmove(&control[5], contenttype, strlen(contenttype));
|
||||
*len = n;
|
||||
return control;
|
||||
}
|
||||
|
||||
void* fstrm_create_control_frame_accept(char* contenttype, size_t* len)
|
||||
{
|
||||
uint32_t* control;
|
||||
size_t n;
|
||||
/* control frame on reply:
|
||||
* 4 bytes 0 escape
|
||||
* 4 bytes bigendian length of frame
|
||||
* 4 bytes bigendian type ACCEPT
|
||||
* 4 bytes bigendian frame option content type
|
||||
* 4 bytes bigendian length of string
|
||||
* string of content type.
|
||||
*/
|
||||
/* len includes the escape and framelength */
|
||||
n = 4+4+4+4+4+strlen(contenttype);
|
||||
control = malloc(n);
|
||||
if(!control) {
|
||||
return NULL;
|
||||
}
|
||||
control[0] = 0;
|
||||
control[1] = htonl(4+4+4+strlen(contenttype));
|
||||
control[2] = htonl(FSTRM_CONTROL_FRAME_ACCEPT);
|
||||
control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE);
|
||||
control[4] = htonl(strlen(contenttype));
|
||||
memmove(&control[5], contenttype, strlen(contenttype));
|
||||
*len = n;
|
||||
return control;
|
||||
}
|
||||
|
||||
void* fstrm_create_control_frame_finish(size_t* len)
|
||||
{
|
||||
uint32_t* control;
|
||||
size_t n;
|
||||
/* control frame on reply:
|
||||
* 4 bytes 0 escape
|
||||
* 4 bytes bigendian length of frame
|
||||
* 4 bytes bigendian type FINISH
|
||||
*/
|
||||
/* len includes the escape and framelength */
|
||||
n = 4+4+4;
|
||||
control = malloc(n);
|
||||
if(!control) {
|
||||
return NULL;
|
||||
}
|
||||
control[0] = 0;
|
||||
control[1] = htonl(4);
|
||||
control[2] = htonl(FSTRM_CONTROL_FRAME_FINISH);
|
||||
*len = n;
|
||||
return control;
|
||||
}
|
||||
|
||||
char* fstrm_describe_control(void* pkt, size_t len)
|
||||
{
|
||||
uint32_t frametype = 0;
|
||||
char buf[512];
|
||||
char* str = buf;
|
||||
size_t remain, slen = sizeof(buf);
|
||||
uint8_t* pos;
|
||||
|
||||
buf[0]=0;
|
||||
if(len < 4) {
|
||||
snprintf(buf, sizeof(buf), "malformed control frame, "
|
||||
"too short, len=%u", (unsigned int)len);
|
||||
return strdup(buf);
|
||||
}
|
||||
frametype = sldns_read_uint32(pkt);
|
||||
if(frametype == FSTRM_CONTROL_FRAME_ACCEPT) {
|
||||
(void)sldns_str_print(&str, &slen, "accept");
|
||||
} else if(frametype == FSTRM_CONTROL_FRAME_START) {
|
||||
(void)sldns_str_print(&str, &slen, "start");
|
||||
} else if(frametype == FSTRM_CONTROL_FRAME_STOP) {
|
||||
(void)sldns_str_print(&str, &slen, "stop");
|
||||
} else if(frametype == FSTRM_CONTROL_FRAME_READY) {
|
||||
(void)sldns_str_print(&str, &slen, "ready");
|
||||
} else if(frametype == FSTRM_CONTROL_FRAME_FINISH) {
|
||||
(void)sldns_str_print(&str, &slen, "finish");
|
||||
} else {
|
||||
(void)sldns_str_print(&str, &slen, "type%d", (int)frametype);
|
||||
}
|
||||
|
||||
/* show the content type options */
|
||||
pos = pkt + 4;
|
||||
remain = len - 4;
|
||||
while(remain >= 8) {
|
||||
uint32_t field_type = sldns_read_uint32(pos);
|
||||
uint32_t field_len = sldns_read_uint32(pos+4);
|
||||
if(remain < field_len) {
|
||||
(void)sldns_str_print(&str, &slen, "malformed_field");
|
||||
break;
|
||||
}
|
||||
if(field_type == FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE) {
|
||||
char tempf[512];
|
||||
(void)sldns_str_print(&str, &slen, " content-type(");
|
||||
if(field_len < sizeof(tempf)-1) {
|
||||
memmove(tempf, pos+8, field_len);
|
||||
tempf[field_len] = 0;
|
||||
(void)sldns_str_print(&str, &slen, "%s", tempf);
|
||||
} else {
|
||||
(void)sldns_str_print(&str, &slen, "<error-too-long>");
|
||||
}
|
||||
(void)sldns_str_print(&str, &slen, ")");
|
||||
} else {
|
||||
(void)sldns_str_print(&str, &slen,
|
||||
" field(type %u, length %u)",
|
||||
(unsigned int)field_type,
|
||||
(unsigned int)field_len);
|
||||
}
|
||||
pos += 8 + field_len;
|
||||
remain -= (8 + field_len);
|
||||
}
|
||||
if(remain > 0)
|
||||
(void)sldns_str_print(&str, &slen, " trailing-bytes"
|
||||
"(length %u)", (unsigned int)remain);
|
||||
return strdup(buf);
|
||||
}
|
194
dnstap/dnstap_fstrm.h
Normal file
194
dnstap/dnstap_fstrm.h
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* dnstap/dnstap_fstrm.h - Frame Streams protocol for dnstap
|
||||
*
|
||||
* Copyright (c) 2020, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Definitions for the Frame Streams data transport protocol for
|
||||
* dnstap message logs.
|
||||
*/
|
||||
|
||||
#ifndef DNSTAP_FSTRM_H
|
||||
#define DNSTAP_FSTRM_H
|
||||
|
||||
/* Frame Streams data transfer protocol encode for DNSTAP messages.
|
||||
* The protocol looks to be specified in the libfstrm library.
|
||||
*
|
||||
* Quick writeup for DNSTAP usage, from reading fstrm/control.h eloquent
|
||||
* comments and fstrm/control.c for some bytesize details (the content type
|
||||
* length).
|
||||
*
|
||||
* The Frame Streams can be unidirectional or bi-directional.
|
||||
* bi-directional streams use control frame types READY, ACCEPT and FINISH.
|
||||
* uni-directional streams use control frame types START and STOP.
|
||||
* unknown control frame types should be ignored by the receiver, they
|
||||
* do not change the data frame encoding.
|
||||
*
|
||||
* bi-directional control frames implement a simple handshake protocol
|
||||
* between sender and receiver.
|
||||
*
|
||||
* The uni-directional control frames have one start and one stop frame,
|
||||
* before and after the data. The start frame can have a content type.
|
||||
* The start and stop frames are not optional.
|
||||
*
|
||||
* data frames are preceded by 4byte length, bigendian.
|
||||
* zero length data frames are not possible, they are an escape that
|
||||
* signals the presence of a control frame.
|
||||
*
|
||||
* a control frame consists of 0 value in 4byte bigendian, this is really
|
||||
* the data frame length, with 0 the escape sequence that indicates one
|
||||
* control frame follows.
|
||||
* Then, 4byte bigendian, length of the control frame message.
|
||||
* Then, the control frame payload (of that length). with in it:
|
||||
* 4byte bigendian, control type (eg. START, STOP, READY, ACCEPT, FINISH).
|
||||
* perhaps nothing more (STOP, FINISH), but for other types maybe
|
||||
* control fields
|
||||
* 4byte bigendian, the control-field-type, currently only content-type.
|
||||
* 4byte bigendian, length of the string for this option.
|
||||
* .. bytes of that string.
|
||||
*
|
||||
* The START type can have only one field. Field max len 256.
|
||||
* control frame max frame length 512 (excludes the 0-escape and control
|
||||
* frame length bytes).
|
||||
*
|
||||
* the bidirectional type of transmission is like this:
|
||||
* client sends READY (with content type included),
|
||||
* client waits for ACCEPT (with content type included),
|
||||
* client sends START (with matched content type from ACCEPT)
|
||||
* .. data frames
|
||||
* client sends STOP.
|
||||
* client waits for FINISH frame.
|
||||
*
|
||||
*/
|
||||
|
||||
/** max length of Frame Streams content type field string */
|
||||
#define FSTRM_CONTENT_TYPE_LENGTH_MAX 256
|
||||
/** control frame value to denote the control frame ACCEPT */
|
||||
#define FSTRM_CONTROL_FRAME_ACCEPT 0x01
|
||||
/** control frame value to denote the control frame START */
|
||||
#define FSTRM_CONTROL_FRAME_START 0x02
|
||||
/** control frame value to denote the control frame STOP */
|
||||
#define FSTRM_CONTROL_FRAME_STOP 0x03
|
||||
/** control frame value to denote the control frame READY */
|
||||
#define FSTRM_CONTROL_FRAME_READY 0x04
|
||||
/** control frame value to denote the control frame FINISH */
|
||||
#define FSTRM_CONTROL_FRAME_FINISH 0x05
|
||||
/** the constant that denotes the control field type that is the
|
||||
* string for the content type of the stream. */
|
||||
#define FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE 0x01
|
||||
/** the content type for DNSTAP frame streams */
|
||||
#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap"
|
||||
|
||||
/**
|
||||
* This creates an FSTRM control frame of type START.
|
||||
* @param contenttype: a zero delimited string with the content type.
|
||||
* eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as
|
||||
* "protobuf:dnstap.Dnstap", for a dnstap frame stream.
|
||||
* @param len: if a buffer is returned this is the length of that buffer.
|
||||
* @return NULL on malloc failure. Returns a malloced buffer with the
|
||||
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
|
||||
* a control frame. The buffer should be sent without preceding it with
|
||||
* the 'len' variable (like data frames are), but straight the content of the
|
||||
* buffer, because the lengths are included in the buffer. This is so that
|
||||
* the zero control indicator can be included before the control frame length.
|
||||
*/
|
||||
void* fstrm_create_control_frame_start(char* contenttype, size_t* len);
|
||||
|
||||
/**
|
||||
* This creates an FSTRM control frame of type READY.
|
||||
* @param contenttype: a zero delimited string with the content type.
|
||||
* eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as
|
||||
* "protobuf:dnstap.Dnstap", for a dnstap frame stream.
|
||||
* @param len: if a buffer is returned this is the length of that buffer.
|
||||
* @return NULL on malloc failure. Returns a malloced buffer with the
|
||||
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
|
||||
* a control frame. The buffer should be sent without preceding it with
|
||||
* the 'len' variable (like data frames are), but straight the content of the
|
||||
* buffer, because the lengths are included in the buffer. This is so that
|
||||
* the zero control indicator can be included before the control frame length.
|
||||
*/
|
||||
void* fstrm_create_control_frame_ready(char* contenttype, size_t* len);
|
||||
|
||||
/**
|
||||
* This creates an FSTRM control frame of type STOP.
|
||||
* @param len: if a buffer is returned this is the length of that buffer.
|
||||
* @return NULL on malloc failure. Returns a malloced buffer with the
|
||||
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
|
||||
* a control frame. The buffer should be sent without preceding it with
|
||||
* the 'len' variable (like data frames are), but straight the content of the
|
||||
* buffer, because the lengths are included in the buffer. This is so that
|
||||
* the zero control indicator can be included before the control frame length.
|
||||
*/
|
||||
void* fstrm_create_control_frame_stop(size_t* len);
|
||||
|
||||
/**
|
||||
* This creates an FSTRM control frame of type ACCEPT.
|
||||
* @param contenttype: a zero delimited string with the content type.
|
||||
* for dnstap streams use DNSTAP_CONTENT_TYPE.
|
||||
* @param len: if a buffer is returned this is the length of that buffer.
|
||||
* @return NULL on malloc failure. Returns a malloced buffer with the
|
||||
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
|
||||
* a control frame. The buffer should be sent without preceding it with
|
||||
* the 'len' variable (like data frames are), but straight the content of the
|
||||
* buffer, because the lengths are included in the buffer. This is so that
|
||||
* the zero control indicator can be included before the control frame length.
|
||||
*/
|
||||
void* fstrm_create_control_frame_accept(char* contenttype, size_t* len);
|
||||
|
||||
/**
|
||||
* This creates an FSTRM control frame of type FINISH.
|
||||
* @param len: if a buffer is returned this is the length of that buffer.
|
||||
* @return NULL on malloc failure. Returns a malloced buffer with the
|
||||
* protocol message. The buffer starts with the 4 bytes of 0 that indicate
|
||||
* a control frame. The buffer should be sent without preceding it with
|
||||
* the 'len' variable (like data frames are), but straight the content of the
|
||||
* buffer, because the lengths are included in the buffer. This is so that
|
||||
* the zero control indicator can be included before the control frame length.
|
||||
*/
|
||||
void* fstrm_create_control_frame_finish(size_t* len);
|
||||
|
||||
/**
|
||||
* Return string that describes a control packet. For debug, logs.
|
||||
* Like 'start content-type(protobuf:dnstap.Dnstap)' or 'stop'.
|
||||
* @param pkt: the packet data, that is the data after the 4 zero start
|
||||
* bytes and 4 length bytes.
|
||||
* @param len: the length of the control packet data, in pkt. This is the
|
||||
* ntohl of the 4 bytes length preceding the data.
|
||||
* @return zero delimited string, malloced. Or NULL on malloc failure.
|
||||
*/
|
||||
char* fstrm_describe_control(void* pkt, size_t len);
|
||||
|
||||
#endif /* DNSTAP_FSTRM_H */
|
2128
dnstap/dtstream.c
Normal file
2128
dnstap/dtstream.c
Normal file
File diff suppressed because it is too large
Load Diff
341
dnstap/dtstream.h
Normal file
341
dnstap/dtstream.h
Normal file
@ -0,0 +1,341 @@
|
||||
/*
|
||||
* dnstap/dtstream.h - Frame Streams thread for unbound DNSTAP
|
||||
*
|
||||
* Copyright (c) 2020, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* An implementation of the Frame Streams data transport protocol for
|
||||
* the Unbound DNSTAP message logging facility.
|
||||
*/
|
||||
|
||||
#ifndef DTSTREAM_H
|
||||
#define DTSTREAM_H
|
||||
|
||||
#include "util/locks.h"
|
||||
struct dt_msg_entry;
|
||||
struct dt_io_list_item;
|
||||
struct dt_io_thread;
|
||||
struct config_file;
|
||||
|
||||
/**
|
||||
* A message buffer with dnstap messages queued up. It is per-worker.
|
||||
* It has locks to synchronize. If the buffer is full, a new message
|
||||
* cannot be added and is discarded. A thread reads the messages and sends
|
||||
* them.
|
||||
*/
|
||||
struct dt_msg_queue {
|
||||
/** lock of the buffer structure. Hold this lock to add or remove
|
||||
* entries to the buffer. Release it so that other threads can also
|
||||
* put messages to log, or a message can be taken out to send away
|
||||
* by the writer thread.
|
||||
*/
|
||||
lock_basic_type lock;
|
||||
/** the maximum size of the buffer, in bytes */
|
||||
size_t maxsize;
|
||||
/** current size of the buffer, in bytes. data bytes of messages.
|
||||
* If a new message make it more than maxsize, the buffer is full */
|
||||
size_t cursize;
|
||||
/** list of messages. The messages are added to the back and taken
|
||||
* out from the front. */
|
||||
struct dt_msg_entry* first, *last;
|
||||
/** reference to the io thread to wakeup */
|
||||
struct dt_io_thread* dtio;
|
||||
};
|
||||
|
||||
/**
|
||||
* An entry in the dt_msg_queue. contains one DNSTAP message.
|
||||
* It is malloced.
|
||||
*/
|
||||
struct dt_msg_entry {
|
||||
/** next in the list. */
|
||||
struct dt_msg_entry* next;
|
||||
/** the buffer with the data to send, an encoded DNSTAP message */
|
||||
void* buf;
|
||||
/** the length to send. */
|
||||
size_t len;
|
||||
};
|
||||
|
||||
/**
|
||||
* Containing buffer and counter for reading DNSTAP frames.
|
||||
*/
|
||||
struct dt_frame_read_buf {
|
||||
/** Buffer containing frame, except length counter(s). */
|
||||
void* buf;
|
||||
/** Number of bytes written to buffer. */
|
||||
size_t buf_count;
|
||||
/** Capacity of the buffer. */
|
||||
size_t buf_cap;
|
||||
|
||||
/** Frame length field. Will contain the 2nd length field for control
|
||||
* frames. */
|
||||
uint32_t frame_len;
|
||||
/** Number of bytes that have been written to the frame_length field. */
|
||||
size_t frame_len_done;
|
||||
|
||||
/** Set to 1 if this is a control frame, 0 otherwise (ie data frame). */
|
||||
int control_frame;
|
||||
};
|
||||
|
||||
/**
|
||||
* IO thread that reads from the queues and writes them.
|
||||
*/
|
||||
struct dt_io_thread {
|
||||
/** the thread number for the dtio thread,
|
||||
* must be first to cast thread arg to int* in checklock code. */
|
||||
int threadnum;
|
||||
/** event base, for event handling */
|
||||
void* event_base;
|
||||
/** list of queues that is registered to get written */
|
||||
struct dt_io_list_item* io_list;
|
||||
/** iterator point in the io_list, to pick from them in a
|
||||
* round-robin fashion, instead of only from the first when busy.
|
||||
* if NULL it means start at the start of the list. */
|
||||
struct dt_io_list_item* io_list_iter;
|
||||
/** thread id, of the io thread */
|
||||
ub_thread_type tid;
|
||||
/** if the io processing has started */
|
||||
int started;
|
||||
/** ssl context for the io thread, for tls connections. type SSL_CTX* */
|
||||
void* ssl_ctx;
|
||||
/** if SNI will be used for TLS connections. */
|
||||
int tls_use_sni;
|
||||
|
||||
/** file descriptor that the thread writes to */
|
||||
int fd;
|
||||
/** event structure that the thread uses */
|
||||
void* event;
|
||||
/** the event is added */
|
||||
int event_added;
|
||||
/** event added is a write event */
|
||||
int event_added_is_write;
|
||||
/** check for nonblocking connect errors on fd */
|
||||
int check_nb_connect;
|
||||
/** ssl for current connection, type SSL* */
|
||||
void* ssl;
|
||||
/** true if the handshake for SSL is done, 0 if not */
|
||||
int ssl_handshake_done;
|
||||
/** true if briefly the SSL wants a read event, 0 if not.
|
||||
* This happens during negotiation, we then do not want to write,
|
||||
* but wait for a read event. */
|
||||
int ssl_brief_read;
|
||||
/** true if SSL_read is waiting for a write event. Set back to 0 after
|
||||
* single write event is handled. */
|
||||
int ssl_brief_write;
|
||||
|
||||
/** the buffer that currently getting written, or NULL if no
|
||||
* (partial) message written now */
|
||||
void* cur_msg;
|
||||
/** length of the current message */
|
||||
size_t cur_msg_len;
|
||||
/** number of bytes written for the current message */
|
||||
size_t cur_msg_done;
|
||||
/** number of bytes of the length that have been written,
|
||||
* for the current message length that precedes the frame */
|
||||
size_t cur_msg_len_done;
|
||||
|
||||
/** command pipe that stops the pipe if closed. Used to quit
|
||||
* the program. [0] is read, [1] is written to. */
|
||||
int commandpipe[2];
|
||||
/** the event to listen to the commandpipe */
|
||||
void* command_event;
|
||||
/** the io thread wants to exit */
|
||||
int want_to_exit;
|
||||
|
||||
/** in stop flush, this is nonNULL and references the stop_ev */
|
||||
void* stop_flush_event;
|
||||
|
||||
/** the timer event for connection retries */
|
||||
void* reconnect_timer;
|
||||
/** if the reconnect timer is added to the event base */
|
||||
int reconnect_is_added;
|
||||
/** the current reconnection timeout, it is increased with
|
||||
* exponential backoff, in msec */
|
||||
int reconnect_timeout;
|
||||
|
||||
/** If the log server is connected to over unix domain sockets,
|
||||
* eg. a file is named that is created to log onto. */
|
||||
int upstream_is_unix;
|
||||
/** if the log server is connected to over TCP. The ip address and
|
||||
* port are used */
|
||||
int upstream_is_tcp;
|
||||
/** if the log server is connected to over TLS. ip address, port,
|
||||
* and client certificates can be used for authentication. */
|
||||
int upstream_is_tls;
|
||||
|
||||
/** Perform bidirectional Frame Streams handshake before sending
|
||||
* messages. */
|
||||
int is_bidirectional;
|
||||
/** Set if the READY control frame has been sent. */
|
||||
int ready_frame_sent;
|
||||
/** Set if valid ACCEPT frame is received. */
|
||||
int accept_frame_received;
|
||||
/** (partially) read frame */
|
||||
struct dt_frame_read_buf read_frame;
|
||||
|
||||
/** the file path for unix socket (or NULL) */
|
||||
char* socket_path;
|
||||
/** the ip address and port number (or NULL) */
|
||||
char* ip_str;
|
||||
/** is the TLS upstream authenticated by name, if nonNULL,
|
||||
* we use the same cert bundle as used by other TLS streams. */
|
||||
char* tls_server_name;
|
||||
/** are client certificates in use */
|
||||
int use_client_certs;
|
||||
/** client cert files: the .key file */
|
||||
char* client_key_file;
|
||||
/** client cert files: the .pem file */
|
||||
char* client_cert_file;
|
||||
};
|
||||
|
||||
/**
|
||||
* IO thread list of queues list item
|
||||
* lists a worker queue that should be looked at and sent to the log server.
|
||||
*/
|
||||
struct dt_io_list_item {
|
||||
/** next in the list of buffers to inspect */
|
||||
struct dt_io_list_item* next;
|
||||
/** buffer of this worker */
|
||||
struct dt_msg_queue* queue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create new (empty) worker message queue. Limit set to default on max.
|
||||
* @return NULL on malloc failure or a new queue (not locked).
|
||||
*/
|
||||
struct dt_msg_queue* dt_msg_queue_create(void);
|
||||
|
||||
/**
|
||||
* Delete a worker message queue. It has to be unlinked from access,
|
||||
* so it can be deleted without lock worries. The queue is emptied (deleted).
|
||||
* @param mq: message queue.
|
||||
*/
|
||||
void dt_msg_queue_delete(struct dt_msg_queue* mq);
|
||||
|
||||
/**
|
||||
* Submit a message to the queue. The queue is locked by the routine,
|
||||
* the message is inserted, and then the queue is unlocked so the
|
||||
* message can be picked up by the writer thread.
|
||||
* @param mq: message queue.
|
||||
* @param buf: buffer with message (dnstap contents).
|
||||
* The buffer must have been malloced by caller. It is linked in
|
||||
* the queue, and is free()d after use. If the routine fails
|
||||
* the buffer is freed as well (and nothing happens, the item
|
||||
* could not be logged).
|
||||
* @param len: length of buffer.
|
||||
*/
|
||||
void dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len);
|
||||
|
||||
/**
|
||||
* Create IO thread.
|
||||
* @return new io thread object. not yet started. or NULL malloc failure.
|
||||
*/
|
||||
struct dt_io_thread* dt_io_thread_create(void);
|
||||
|
||||
/**
|
||||
* Delete the IO thread structure.
|
||||
* @param dtio: the io thread that is deleted. It must not be running.
|
||||
*/
|
||||
void dt_io_thread_delete(struct dt_io_thread* dtio);
|
||||
|
||||
/**
|
||||
* Apply config to the dtio thread
|
||||
* @param dtio: io thread, not yet started.
|
||||
* @param cfg: config file struct.
|
||||
* @return false on malloc failure.
|
||||
*/
|
||||
int dt_io_thread_apply_cfg(struct dt_io_thread* dtio,
|
||||
struct config_file *cfg);
|
||||
|
||||
/**
|
||||
* Register a msg queue to the io thread. It will be polled to see if
|
||||
* there are messages and those then get removed and sent, when the thread
|
||||
* is running.
|
||||
* @param dtio: the io thread.
|
||||
* @param mq: message queue to register.
|
||||
* @return false on failure (malloc failure).
|
||||
*/
|
||||
int dt_io_thread_register_queue(struct dt_io_thread* dtio,
|
||||
struct dt_msg_queue* mq);
|
||||
|
||||
/**
|
||||
* Unregister queue from io thread.
|
||||
* @param dtio: the io thread.
|
||||
* @param mq: message queue.
|
||||
*/
|
||||
void dt_io_thread_unregister_queue(struct dt_io_thread* dtio,
|
||||
struct dt_msg_queue* mq);
|
||||
|
||||
/**
|
||||
* Start the io thread
|
||||
* @param dtio: the io thread.
|
||||
* @param event_base_nothr: the event base to attach the events to, in case
|
||||
* we are running without threads. With threads, this is ignored
|
||||
* and a thread is started to process the dnstap log messages.
|
||||
* @param numworkers: number of worker threads. The dnstap io thread is
|
||||
* that number +1 as the threadnumber (in logs).
|
||||
* @return false on failure.
|
||||
*/
|
||||
int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr,
|
||||
int numworkers);
|
||||
|
||||
/**
|
||||
* Stop the io thread
|
||||
* @param dtio: the io thread.
|
||||
*/
|
||||
void dt_io_thread_stop(struct dt_io_thread* dtio);
|
||||
|
||||
/** callback for the dnstap reconnect, to start reconnecting to output */
|
||||
void dtio_reconnect_timeout_cb(int fd, short bits, void* arg);
|
||||
|
||||
/** callback for the dnstap events, to write to the output */
|
||||
void dtio_output_cb(int fd, short bits, void* arg);
|
||||
|
||||
/** callback for the dnstap commandpipe, to stop the dnstap IO */
|
||||
void dtio_cmd_cb(int fd, short bits, void* arg);
|
||||
|
||||
/** callback for the timer when the thread stops and wants to finish up */
|
||||
void dtio_stop_timer_cb(int fd, short bits, void* arg);
|
||||
|
||||
/** callback for the output when the thread stops and wants to finish up */
|
||||
void dtio_stop_ev_cb(int fd, short bits, void* arg);
|
||||
|
||||
/** callback for unbound-dnstap-socket */
|
||||
void dtio_tap_callback(int fd, short bits, void* arg);
|
||||
|
||||
/** callback for unbound-dnstap-socket */
|
||||
void dtio_mainfdcallback(int fd, short bits, void* arg);
|
||||
|
||||
#endif /* DTSTREAM_H */
|
1594
dnstap/unbound-dnstap-socket.c
Normal file
1594
dnstap/unbound-dnstap-socket.c
Normal file
File diff suppressed because it is too large
Load Diff
324
doc/Changelog
324
doc/Changelog
@ -1,6 +1,330 @@
|
||||
20 July 2020: Wouter
|
||||
- Fix streamtcp to print packet data to stdout. This makes the
|
||||
stdout and stderr not mix together lines, when parsing its output.
|
||||
- Fix contrib/fastrpz.patch to apply cleanly. It fixes for changes
|
||||
due to added libdynmod, but it does not compile, it conflicts with
|
||||
new rpz code.
|
||||
- branch now named 1.11.0 and 1.11.0rc1 tag.
|
||||
|
||||
17 July 2020: Wouter
|
||||
- Fix libnettle compile for session ticket key callback function
|
||||
changes.
|
||||
- Fix lock dependency cycle in rpz zone config setup.
|
||||
|
||||
17 July 2020: Ralph
|
||||
- Merge PR #234 - Ensure proper alignment of cmsg buffers by Jérémie
|
||||
Courrèges-Anglas.
|
||||
- Fix PR #234 log_assert sizeof to use union buffer.
|
||||
|
||||
16 July 2020: Wouter
|
||||
- Fix check conf test for referencing installation paths.
|
||||
- Fix unused variable warning for clang analyzer.
|
||||
|
||||
16 July 2020: George
|
||||
- Introduce 'include-toplevel:' configuration option.
|
||||
|
||||
16 July 2020: Ralph
|
||||
- Add bidirectional frame streams support.
|
||||
|
||||
8 July 2020: Wouter
|
||||
- Fix add missing DSA header, for compilation without deprecated
|
||||
OpenSSL APIs.
|
||||
- Fix to use SSL_CTX_set_tlsext_ticket_key_evp_cb in OpenSSL
|
||||
3.0.0-alpha4.
|
||||
- Longer keys for the test set, this avoids weak crypto errors.
|
||||
|
||||
7 July 2020: Wouter
|
||||
- Fix #259: Fix unbound-checkconf does not check view existence.
|
||||
unbound-checkconf checks access-control-view, access-control-tags,
|
||||
access-control-tag-actions and access-control-tag-datas.
|
||||
- Fix offset of error printout for access-control-tag-datas.
|
||||
- Review fixes for checkconf #259 change.
|
||||
|
||||
6 July 2020: Wouter
|
||||
- run_vm cleanup better and removes trailing slash on single argument.
|
||||
|
||||
29 June 2020: Wouter
|
||||
- Move reply list clean for serve expired mesh callback to after
|
||||
the reply is sent, so that script callbacks have reply_info.
|
||||
- Also move reply list clean for mesh callbacks to the scrip callback
|
||||
can see the reply_info.
|
||||
- Fix for mesh accounting if the reply list already empty to begin
|
||||
with.
|
||||
- Fix for mesh accounting when rpz decides to drop a reply with a
|
||||
tcp stream waiting for it.
|
||||
- Review fix for number of detached states due to use of variable
|
||||
after end of loop.
|
||||
- Fix tcp req info drop due to size call into mesh accounting
|
||||
removal of mesh state during mesh send reply.
|
||||
|
||||
24 June 2020: Wouter
|
||||
- iana portlist updated.
|
||||
- doxygen file comments for dynlibmodule.
|
||||
|
||||
17 June 2020: Wouter
|
||||
- Fix default explanation in man page for qname-minimisation-strict.
|
||||
- Fix display of event loop method with libev.
|
||||
|
||||
8 June 2020: Wouter
|
||||
- Mention tls name possible when tls is enabled for stub-addr in the
|
||||
man page.
|
||||
|
||||
27 May 2020: George
|
||||
- Merge PR #241 by Robert Edmonds: contrib/libunbound.pc.in: Do not use
|
||||
"Requires:".
|
||||
|
||||
25 May 2020: George
|
||||
- Update contrib/aaaa-filter-iterator.patch for the recent
|
||||
generate_sub_request() change and to apply cleanly.
|
||||
|
||||
21 May 2020: George
|
||||
- Fix for integer overflow when printing RDF_TYPE_TIME.
|
||||
|
||||
19 May 2020: Wouter
|
||||
- CVE-2020-12662 Unbound can be tricked into amplifying an incoming
|
||||
query into a large number of queries directed to a target.
|
||||
- CVE-2020-12663 Malformed answers from upstream name servers can be
|
||||
used to make Unbound unresponsive.
|
||||
- Release 1.10.1 is 1.10.0 with fixes, code repository continues,
|
||||
including those fixes, towards the next release. Configure has
|
||||
version 1.10.2 version number in it.
|
||||
- For PR #93: windows compile warnings removal
|
||||
- windows compile warnings removal for ip dscp option code.
|
||||
- For PR #93: unit test for dynlib module.
|
||||
|
||||
18 May 2020: Wouter
|
||||
- For PR #93: dynlibmod can handle reloads and deinit and inits again,
|
||||
with dlclose and dlopen of the library again. Also for multiple
|
||||
modules. Fix memory leak by not closing dlopened content. Fix
|
||||
to allow one dynlibmod instance by unbound-checkconf.
|
||||
- For PR #93: checkconf allows multiple dynlib in module-config, for
|
||||
a couple cases.
|
||||
- For PR #93: checkconf allows python dynlib in module-config, for
|
||||
a couple cases.
|
||||
- For PR #93: man page spelling reference fix.
|
||||
- For PR #93: fix link of other executables for dynlibmod dependency.
|
||||
|
||||
15 May 2020: Wouter
|
||||
- Merge PR #93: Add dynamic library support.
|
||||
- Fixed conflicts for PR #93 and make configure, yacc, lex.
|
||||
- For PR #93: Fix warnings for dynlibmodule.
|
||||
|
||||
15 May 2020: Ralph
|
||||
- Cache ECS answers with longest scope of CNAME chain.
|
||||
|
||||
22 April 2020: George
|
||||
- Explicitly use 'rrset-roundrobin: no' for test cases.
|
||||
|
||||
21 April 2020: Wouter
|
||||
- Merge #225 from akhait: KSK-2010 has been revoked. It removes the
|
||||
KSK-2010 from the default list in unbound-anchor, now that the
|
||||
revocation period is over. KSK-2017 is the only trust anchor in
|
||||
the shipped default now.
|
||||
|
||||
21 April 2020: George
|
||||
- Change default value for 'rrset-roundrobin' to yes.
|
||||
- Fix tests for new rrset-roundrobin default.
|
||||
|
||||
20 April 2020: Wouter
|
||||
- Fix #222: --enable-rpath, fails to rpath python lib.
|
||||
- Fix for count of reply states in the mesh.
|
||||
- Remove unneeded was_mesh_reply check.
|
||||
|
||||
17 April 2020: George
|
||||
- Add SNI support on more TLS connections (fixes #193).
|
||||
- Add SNI support to unbound-anchor.
|
||||
|
||||
16 April 2020: George
|
||||
- Add doxygen documentation for DSCP.
|
||||
|
||||
16 April 2020: Wouter
|
||||
- Fix help return code in unbound-control-setup script.
|
||||
- Fix for posix shell syntax for trap in nsd-control-setup.
|
||||
- Fix for posix shell syntax for trap in run_msg.sh test script.
|
||||
|
||||
15 April 2020: George
|
||||
- Fix #220: auth-zone section in config may lead to segfault.
|
||||
|
||||
7 April 2020: Wouter
|
||||
- Merge PR #214 from gearnode: unbound-control-setup recreate
|
||||
certificates. With the -r option the certificates are created
|
||||
again, without it, only the files that do not exist are created.
|
||||
|
||||
6 April 2020: Ralph
|
||||
- Keep track of number of timeouts. Use this counter to determine if
|
||||
capsforid fallback should be started.
|
||||
|
||||
6 April 2020: George
|
||||
- More documentation for redis-expire-records option.
|
||||
|
||||
1 April 2020: George
|
||||
- Merge PR #206: Redis TTL, by Talkabout.
|
||||
|
||||
30 March 2020: Wouter
|
||||
- Merge PR #207: Clarify if-automatic listens on 0.0.0.0 and ::
|
||||
- Merge PR #208: Fix uncached CLIENT_RESPONSE'es on stateful
|
||||
transports.
|
||||
|
||||
27 March 2020: Wouter
|
||||
- Merge PR #203 from noloader: Update README-Travis.md with current
|
||||
procedures.
|
||||
|
||||
27 March 2020: Ralph
|
||||
- Make unbound-control error returned on missing domain name more user
|
||||
friendly.
|
||||
|
||||
26 March 2020: Ralph
|
||||
- Fix RPZ concurrency issue when using auth_zone_reload.
|
||||
|
||||
25 March 2020: George
|
||||
- Merge PR #201 from noloader: Fix OpenSSL cross-compaile warnings.
|
||||
- Fix on #201.
|
||||
|
||||
24 March 2020: Wouter
|
||||
- Merge PR #200 from yarikk: add ip-dscp option to specify the DSCP
|
||||
tag for outgoing packets.
|
||||
- Fixes on #200.
|
||||
- Travis fix for ios by omitting tools from install.
|
||||
|
||||
23 March 2020: Wouter
|
||||
- Fix compile on Solaris for unbound-checkconf.
|
||||
|
||||
20 March 2020: George
|
||||
- Merge PR #198 from fobser: Declare lz_enter_rr_into_zone() static, it's
|
||||
only used in this file.
|
||||
|
||||
20 March 2020: Wouter
|
||||
- Merge PR #197 from fobser: Make log_ident_revert_to_default() a
|
||||
proper prototype.
|
||||
|
||||
19 March 2020: Ralph
|
||||
- Merge PR#191: Update iOS testing on Travis, by Jeffrey Walton.
|
||||
- Fix #158: open tls-session-ticket-keys as binary, for Windows. By
|
||||
Daisuke HIGASHI.
|
||||
- Merge PR#134, Allow the kernel to provide random source ports. By
|
||||
Florian Obser.
|
||||
- Log warning when using outgoing-port-permit and outgoing-port-avoid
|
||||
while explicit port randomisation is disabled.
|
||||
- Merge PR#194: Add libevent testing to Travis, by Jeffrey Walton.
|
||||
- Fix .travis.yml error, missing 'env' option.
|
||||
|
||||
16 March 2020: Wouter
|
||||
- Fix #192: In the unbound-checkconf tool, the module config of
|
||||
dns64 subnetcache respip validator iterator is whitelisted, it was
|
||||
reported it seems to work.
|
||||
|
||||
12 March 2020: Wouter
|
||||
- Fix compile of test tools without protobuf.
|
||||
|
||||
11 March 2020: Ralph
|
||||
- Add check to make sure RPZ records are subdomains of configured
|
||||
zone origin.
|
||||
|
||||
11 March 2020: George
|
||||
- Fix #189: mini_event.h:142:17: error: field 'ev_timeout' has incomplete
|
||||
type, by noloader.
|
||||
- Changelog entry for (Fix #189, Merge PR #190).
|
||||
|
||||
11 March 2020: Wouter
|
||||
- Fix #188: unbound-control.c:882:6: error: 'execlp' is
|
||||
unavailable: not available on tvOS.
|
||||
|
||||
6 March 2020: George
|
||||
- Merge PR #186, fix #183: Fix unrecognized 'echo -n' option on OS X, by
|
||||
noloader
|
||||
|
||||
5 March 2020: Wouter
|
||||
- Fix PR #182 from noloader: Add iOS testing to Travis.
|
||||
|
||||
4 March 2020: Ralph
|
||||
- Update README-Travis.md (from PR #179), by Jeffrey Walton.
|
||||
|
||||
4 March 2020: George
|
||||
- Merge PR #181 from noloader: Fix OpenSSL -pie warning on Android.
|
||||
|
||||
4 March 2020: Wouter
|
||||
- Merge PR #180 from noloader: Avoid calling exit in Travis script.
|
||||
|
||||
3 March 2020: George
|
||||
- Upgrade config.guess(2020-01-01) and config.sub(2020-01-01).
|
||||
|
||||
2 March 2020: Ralph
|
||||
- Fix #175, Merge PR #176: fix link error when OpenSSL is configured
|
||||
with no-engine, thanks noloader.
|
||||
|
||||
2 March 2020: George
|
||||
- Fix compiler warning in dns64/dns64.c
|
||||
- Merge PR #174: Add Android to Travis testing, by noloader.
|
||||
- Move android build scripts to contrib/ and allow android tests to fail.
|
||||
|
||||
2 March 2020: Wouter
|
||||
- Fix #177: dnstap does not build on macOS.
|
||||
|
||||
28 February 2020: Ralph
|
||||
- Merge PR #172: Add IBM s390x arch for testing, by noloader.
|
||||
|
||||
28 February 2020: Wouter
|
||||
- Merge PR #173: updated makedist.sh for config.guess and
|
||||
config.sub and sha256 digest for gpg, by noloader.
|
||||
- Merge PR #164: Framestreams, this branch implements dnstap
|
||||
unidirectional connectivity in unbound. This has a number of
|
||||
new features.
|
||||
|
||||
The dependency on libfstrm is removed. The fstrm protocol code
|
||||
resides in dnstap/dnstap_fstrm.h and dnstap/dnstap_fstrm.c. This
|
||||
contains a brief definition of what unbound needs.
|
||||
|
||||
The make unbound-dnstap-socket builds a debug tool,
|
||||
unbound-dnstap-socket. It can listen, accept multiple DNSTAP
|
||||
streams and print information. Commandline options control it.
|
||||
|
||||
Unbound can reconnect if the unix domain socket file socket is
|
||||
closed. This uses exponential backoff after which it uses a
|
||||
one second timer to throttle cpu down. There is also support
|
||||
to use TCP and TLS for connecting to the log server. There
|
||||
are new config options to turn them on, in the dnstap section
|
||||
in the man page and example config file. dnstap-ip with IP
|
||||
address of server for TCP or TLS use. dnstap-tls to turn
|
||||
on TLS. And dnstap-tls-server-name, dnstap-tls-cert-bundle,
|
||||
dnstap-tls-client-key-file and dnstap-tls-client-cert-file
|
||||
to configure the certificates for server authentication and
|
||||
client authentication, or leave at "" to not use that.
|
||||
|
||||
27 February 2020: George
|
||||
- Merge PR #171: Add additional compilers and platforms to Travis
|
||||
testing, by noloader.
|
||||
|
||||
27 February 2020: Wouter
|
||||
- Fix #169: Fix warning for daemon/remote.c output may be truncated
|
||||
from snprintf.
|
||||
- Fix #170: Fix gcc undefined sanitizer signed integer overflow
|
||||
warning in signature expiry RFC1982 serial number arithmetic.
|
||||
- Fix more undefined sanitizer issues, in respip copy_rrset null
|
||||
dname, and in the client_info_compare routine for null memcmp.
|
||||
|
||||
26 February 2020: Wouter
|
||||
- iana portlist updated.
|
||||
|
||||
25 February 2020: Wouter
|
||||
- Fix #165: Add prefer-ip4: yesno config option to prefer ipv4 for
|
||||
using ipv4 filters, because the hosts ip6 netblock /64 is not owned
|
||||
by one operator, and thus reputation is shared.
|
||||
|
||||
24 February 2020: George
|
||||
- Merge PR #166: Fix typo in unbound.service.in, by glitsj16.
|
||||
|
||||
20 February 2020: Wouter
|
||||
- Updated contrib/unbound_smf23.tar.gz with Solaris SMF service for
|
||||
Unbound from Yuri Voinov.
|
||||
- master branch has 1.10.1 version.
|
||||
|
||||
18 February 2020: Wouter
|
||||
- protect X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS with ifdef for
|
||||
different openssl versions.
|
||||
|
||||
17 February 2020: Wouter
|
||||
- changelog point where the tag for 1.10.0rc2 release is. And with
|
||||
the unbound_smf23 commit added to it, that is the 1.10.0 release.
|
||||
|
||||
17 February 2020: Ralph
|
||||
- Add respip to supported module-config options in unbound-checkconf.
|
||||
|
@ -1,4 +1,4 @@
|
||||
README for Unbound 1.10.1
|
||||
README for Unbound 1.11.0
|
||||
Copyright 2007 NLnet Labs
|
||||
http://unbound.net
|
||||
|
||||
|
@ -1,13 +1,17 @@
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
# See unbound.conf(5) man page, version 1.10.1.
|
||||
# See unbound.conf(5) man page, version 1.11.0.
|
||||
#
|
||||
# this is a comment.
|
||||
|
||||
#Use this to include other text into the file.
|
||||
# Use this anywhere in the file to include other text into this file.
|
||||
#include: "otherfile.conf"
|
||||
|
||||
# Use this anywhere in the file to include other text, that explicitly starts a
|
||||
# clause, into this file. Text after this directive needs to start a clause.
|
||||
#include-toplevel: "otherfile.conf"
|
||||
|
||||
# The server clause sets the main parameters.
|
||||
server:
|
||||
# whitespace is not necessary, but looks cleaner.
|
||||
@ -70,6 +74,9 @@ server:
|
||||
# Set this to yes to prefer ipv6 upstream servers over ipv4.
|
||||
# prefer-ip6: no
|
||||
|
||||
# Prefer ipv4 upstream servers, even if ipv6 is available.
|
||||
# prefer-ip4: no
|
||||
|
||||
# number of ports to allocate per thread, determines the size of the
|
||||
# port range that can be open simultaneously. About double the
|
||||
# num-queries-per-thread, or, use as many as the OS will allow you.
|
||||
@ -116,6 +123,11 @@ server:
|
||||
# Linux only. On Linux you also have ip-transparent that is similar.
|
||||
# ip-freebind: no
|
||||
|
||||
# the value of the Differentiated Services Codepoint (DSCP)
|
||||
# in the differentiated services field (DS) of the outgoing
|
||||
# IP packets
|
||||
# ip-dscp: 0
|
||||
|
||||
# EDNS reassembly buffer to advertise to UDP peers (the actual buffer
|
||||
# is set with msg-buffer-size). 1472 can solve fragmentation (timeouts)
|
||||
# edns-buffer-size: 4096
|
||||
@ -465,7 +477,7 @@ server:
|
||||
# deny-any: no
|
||||
|
||||
# if yes, Unbound rotates RRSet order in response.
|
||||
# rrset-roundrobin: no
|
||||
# rrset-roundrobin: yes
|
||||
|
||||
# if yes, Unbound doesn't insert authority/additional sections
|
||||
# into response messages when those sections are not required.
|
||||
@ -738,6 +750,10 @@ server:
|
||||
# cipher setting for TLSv1.3
|
||||
# tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
|
||||
|
||||
# Use the SNI extension for TLS connections. Default is yes.
|
||||
# Changing the value requires a reload.
|
||||
# tls-use-sni: yes
|
||||
|
||||
# Add the secret file for TLS Session Ticket.
|
||||
# Secret file must be 80 bytes of random data.
|
||||
# First key use to encrypt and decrypt TLS session tickets.
|
||||
@ -847,6 +863,17 @@ python:
|
||||
# Script file to load
|
||||
# python-script: "@UNBOUND_SHARE_DIR@/ubmodule-tst.py"
|
||||
|
||||
# Dynamic library config section. To enable:
|
||||
# o use --with-dynlibmodule to configure before compiling.
|
||||
# o list dynlib in the module-config string (above) to enable.
|
||||
# It can be placed anywhere, the dynlib module is only a very thin wrapper
|
||||
# to load modules dynamically.
|
||||
# o and give a dynlib-file to run. If more than one dynlib entry is listed in
|
||||
# the module-config then you need one dynlib-file per instance.
|
||||
dynlib:
|
||||
# Script file to load
|
||||
# dynlib-file: "@UNBOUND_SHARE_DIR@/dynlib.so"
|
||||
|
||||
# Remote control config section.
|
||||
remote-control:
|
||||
# Enable remote control with unbound-control(8) here.
|
||||
@ -1005,10 +1032,12 @@ remote-control:
|
||||
# redis-server-port: 6379
|
||||
# # timeout (in ms) for communication with the redis server
|
||||
# redis-timeout: 100
|
||||
# # set timeout on redis records based on DNS response TTL
|
||||
# redis-expire-records: no
|
||||
|
||||
# IPSet
|
||||
# Add specify domain into set via ipset.
|
||||
# Note: To enable ipset needs run unbound as root user.
|
||||
# Note: To enable ipset unbound needs to run as root user.
|
||||
# ipset:
|
||||
# # set name for ip v4 addresses
|
||||
# name-v4: "list-v4"
|
||||
@ -1016,6 +1045,40 @@ remote-control:
|
||||
# name-v6: "list-v6"
|
||||
#
|
||||
|
||||
# Dnstap logging support, if compiled in. To enable, set the dnstap-enable
|
||||
# to yes and also some of dnstap-log-..-messages to yes. And select an
|
||||
# upstream log destination, by socket path, TCP or TLS destination.
|
||||
# dnstap:
|
||||
# dnstap-enable: no
|
||||
# # if set to yes frame streams will be used in bidirectional mode
|
||||
# dnstap-bidirectional: yes
|
||||
# dnstap-socket-path: "@DNSTAP_SOCKET_PATH@"
|
||||
# # if "" use the unix socket in dnstap-socket-path, otherwise,
|
||||
# # set it to "IPaddress[@port]" of the destination.
|
||||
# dnstap-ip: ""
|
||||
# # if set to yes if you want to use TLS to dnstap-ip, no for TCP.
|
||||
# dnstap-tls: yes
|
||||
# # name for authenticating the upstream server. or "" disabled.
|
||||
# dnstap-tls-server-name: ""
|
||||
# # if "", it uses the cert bundle from the main unbound config.
|
||||
# dnstap-tls-cert-bundle: ""
|
||||
# # key file for client authentication, or "" disabled.
|
||||
# dnstap-tls-client-key-file: ""
|
||||
# # cert file for client authentication, or "" disabled.
|
||||
# dnstap-tls-client-cert-file: ""
|
||||
# dnstap-send-identity: no
|
||||
# dnstap-send-version: no
|
||||
# # if "" it uses the hostname.
|
||||
# dnstap-identity: ""
|
||||
# # if "" it uses the package version.
|
||||
# dnstap-version: ""
|
||||
# dnstap-log-resolver-query-messages: no
|
||||
# dnstap-log-resolver-response-messages: no
|
||||
# dnstap-log-client-query-messages: no
|
||||
# dnstap-log-client-response-messages: no
|
||||
# dnstap-log-forwarder-query-messages: no
|
||||
# dnstap-log-forwarder-response-messages: no
|
||||
|
||||
# Response Policy Zones
|
||||
# RPZ policies. Applied in order of configuration. QNAME and Response IP
|
||||
# Address trigger are the only supported triggers. Supported actions are:
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "libunbound" "3" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
|
||||
.TH "libunbound" "3" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
|
||||
.\"
|
||||
.\" libunbound.3 -- unbound library functions manual
|
||||
.\"
|
||||
@ -44,7 +44,7 @@
|
||||
.B ub_ctx_zone_remove,
|
||||
.B ub_ctx_data_add,
|
||||
.B ub_ctx_data_remove
|
||||
\- Unbound DNS validating resolver 1.10.1 functions.
|
||||
\- Unbound DNS validating resolver 1.11.0 functions.
|
||||
.SH "SYNOPSIS"
|
||||
.B #include <unbound.h>
|
||||
.LP
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-anchor" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
|
||||
.TH "unbound-anchor" "8" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
|
||||
.\"
|
||||
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
|
||||
.\"
|
||||
@ -69,6 +69,9 @@ The server name, it connects to https://name. Specify without https:// prefix.
|
||||
The default is "data.iana.org". It connects to the port specified with \-P.
|
||||
You can pass an IPv4 address or IPv6 address (no brackets) if you want.
|
||||
.TP
|
||||
.B \-S
|
||||
Do not use SNI for the HTTPS connection. Default is to use SNI.
|
||||
.TP
|
||||
.B \-b \fIaddress
|
||||
The source address to bind to for domain resolution and contacting the server
|
||||
on https. May be either an IPv4 address or IPv6 address (no brackets).
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-checkconf" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
|
||||
.TH "unbound-checkconf" "8" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
|
||||
.\"
|
||||
.\" unbound-checkconf.8 -- unbound configuration checker manual
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound-control" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
|
||||
.TH "unbound-control" "8" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
|
||||
.\"
|
||||
.\" unbound-control.8 -- unbound remote control manual
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound\-host" "1" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
|
||||
.TH "unbound\-host" "1" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
|
||||
.\"
|
||||
.\" unbound-host.1 -- unbound DNS lookup utility
|
||||
.\"
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound" "8" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
|
||||
.TH "unbound" "8" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
|
||||
.\"
|
||||
.\" unbound.8 -- unbound manual
|
||||
.\"
|
||||
@ -9,7 +9,7 @@
|
||||
.\"
|
||||
.SH "NAME"
|
||||
.B unbound
|
||||
\- Unbound DNS validating resolver 1.10.1.
|
||||
\- Unbound DNS validating resolver 1.11.0.
|
||||
.SH "SYNOPSIS"
|
||||
.B unbound
|
||||
.RB [ \-h ]
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH "unbound.conf" "5" "May 19, 2020" "NLnet Labs" "unbound 1.10.1"
|
||||
.TH "unbound.conf" "5" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
|
||||
.\"
|
||||
.\" unbound.conf.5 -- unbound.conf manual
|
||||
.\"
|
||||
@ -77,6 +77,12 @@ for the included files works, relative pathnames for the included names work
|
||||
if the directory where the daemon is started equals its chroot/working
|
||||
directory or is specified before the include statement with directory: dir.
|
||||
Wildcards can be used to include multiple files, see \fIglob\fR(7).
|
||||
.P
|
||||
For a more structural include option, the
|
||||
.B include\-toplevel:
|
||||
directive can be used. This closes whatever clause is currently active (if any)
|
||||
and forces the use of clauses in the included files and right after this
|
||||
directive.
|
||||
.SS "Server Options"
|
||||
These options are part of the
|
||||
.B server:
|
||||
@ -126,9 +132,12 @@ interface and port number), if not specified the default port (from
|
||||
Same as interface: (for ease of compatibility with nsd.conf).
|
||||
.TP
|
||||
.B interface\-automatic: \fI<yes or no>
|
||||
Detect source interface on UDP queries and copy them to replies. This
|
||||
feature is experimental, and needs support in your OS for particular socket
|
||||
options. Default value is no.
|
||||
Listen on all addresses on all (current and future) interfaces, detect the
|
||||
source interface on UDP queries and copy them to replies. This is a lot like
|
||||
ip\-transparent, but this option services all interfaces whilst with
|
||||
ip\-transparent you can select which (future) interfaces unbound provides
|
||||
service on. This feature is experimental, and needs support in your OS for
|
||||
particular socket options. Default value is no.
|
||||
.TP
|
||||
.B outgoing\-interface: \fI<ip address or ip6 netblock>
|
||||
Interface to use to connect to the network. This interface is used to send
|
||||
@ -323,6 +332,12 @@ IP addresses that are nonlocal or do not exist, like when the network
|
||||
interface or IP address is down. Exists only on Linux, where the similar
|
||||
ip\-transparent option is also available.
|
||||
.TP
|
||||
.B ip-dscp: \fI<number>
|
||||
The value of the Differentiated Services Codepoint (DSCP) in the
|
||||
differentiated services field (DS) of the outgoing IP packet headers.
|
||||
The field replaces the outdated IPv4 Type-Of-Service field and the
|
||||
IPV6 traffic class field.
|
||||
.TP
|
||||
.B rrset\-cache\-size: \fI<number>
|
||||
Number of bytes size of the RRset cache. Default is 4 megabytes.
|
||||
A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes, megabytes
|
||||
@ -381,6 +396,13 @@ IPv6 to the internet nameservers. With this option you can disable the
|
||||
ipv6 transport for sending DNS traffic, it does not impact the contents of
|
||||
the DNS traffic, which may have ip4 and ip6 addresses in it.
|
||||
.TP
|
||||
.B prefer\-ip4: \fI<yes or no>
|
||||
If enabled, prefer IPv4 transport for sending DNS queries to internet
|
||||
nameservers. Default is no. Useful if the IPv6 netblock the server has,
|
||||
the entire /64 of that is not owned by one operator and the reputation of
|
||||
the netblock /64 is an issue, using IPv4 then uses the IPv4 filters that
|
||||
the upstream servers have.
|
||||
.TP
|
||||
.B prefer\-ip6: \fI<yes or no>
|
||||
If enabled, prefer IPv6 transport for sending DNS queries to internet
|
||||
nameservers. Default is no.
|
||||
@ -530,6 +552,11 @@ and that is the default.
|
||||
Set the list of ciphersuites to allow when serving TLS. This is for newer
|
||||
TLS 1.3 connections. Use "" for defaults, and that is the default.
|
||||
.TP
|
||||
.B tls\-use\-sni: \fI<yes or no>
|
||||
Enable or disable sending the SNI extension on TLS connections.
|
||||
Default is yes.
|
||||
Changing the value requires a reload.
|
||||
.TP
|
||||
.B use\-systemd: \fI<yes or no>
|
||||
Enable or disable systemd socket activation.
|
||||
Default is no.
|
||||
@ -843,7 +870,7 @@ NXDOMAIN from a DNSSEC signed zone. Default is yes.
|
||||
QNAME minimisation in strict mode. Do not fall-back to sending full QNAME to
|
||||
potentially broken nameservers. A lot of domains will not be resolvable when
|
||||
this option in enabled. Only use if you know what you are doing.
|
||||
This option only has effect when qname-minimisation is enabled. Default is off.
|
||||
This option only has effect when qname-minimisation is enabled. Default is no.
|
||||
.TP
|
||||
.B aggressive\-nsec: \fI<yes or no>
|
||||
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
|
||||
@ -911,7 +938,7 @@ are none.
|
||||
.TP
|
||||
.B rrset\-roundrobin: \fI<yes or no>
|
||||
If yes, Unbound rotates RRSet order in response (the random number is taken
|
||||
from the query ID, for speed and thread safety). Default is no.
|
||||
from the query ID, for speed and thread safety). Default is yes.
|
||||
.TP
|
||||
.B minimal-responses: \fI<yes or no>
|
||||
If yes, Unbound doesn't insert authority/additional sections into response
|
||||
@ -942,7 +969,9 @@ EDNS client subnet support the default is "subnetcache validator iterator".
|
||||
Most modules that need to be listed here have to be listed at the beginning
|
||||
of the line. The cachedb module has to be listed just before the iterator.
|
||||
The python module can be listed in different places, it then processes the
|
||||
output of the module it is just before.
|
||||
output of the module it is just before. The dynlib module can be listed pretty
|
||||
much anywhere, it is only a very thin wrapper that allows dynamic libraries to
|
||||
run in its place.
|
||||
.TP
|
||||
.B trust\-anchor\-file: \fI<filename>
|
||||
File with trusted keys for validation. Both DS and DNSKEY entries can appear
|
||||
@ -1591,6 +1620,9 @@ Name of stub zone nameserver. Is itself resolved before it is used.
|
||||
.B stub\-addr: \fI<IP address>
|
||||
IP address of stub zone nameserver. Can be IP 4 or IP 6.
|
||||
To use a nondefault port for DNS communication append '@' with the port number.
|
||||
If tls is enabled, then you can append a '#' and a name, then it'll check
|
||||
the tls authentication certificates with that name. If you combine
|
||||
the '@' and '#', the '@' comes first.
|
||||
.TP
|
||||
.B stub\-prime: \fI<yes or no>
|
||||
This option is by default no. If enabled it performs NS set priming,
|
||||
@ -1809,6 +1841,24 @@ directory.
|
||||
.B python\-script: \fI<python file>\fR
|
||||
The script file to load. Repeat this option for every python module instance
|
||||
added to the \fBmodule\-config:\fR option.
|
||||
.SS "Dynamic Library Module Options"
|
||||
.LP
|
||||
The
|
||||
.B dynlib:
|
||||
clause gives the settings for the \fIdynlib\fR module. This module is only
|
||||
a very small wrapper that allows dynamic modules to be loaded on runtime
|
||||
instead of being compiled into the application. To enable the dynlib module it
|
||||
has to be compiled into the daemon, and the word "dynlib" has to be put in the
|
||||
\fBmodule\-config:\fR option. Multiple instances of dynamic libraries are
|
||||
supported by adding the word "dynlib" more than once.
|
||||
.LP
|
||||
The \fBdynlib\-file:\fR path should be specified as an absolute path relative
|
||||
to the new path set by \fBchroot:\fR option, or as a relative path to the
|
||||
working directory.
|
||||
.TP
|
||||
.B dynlib\-file: \fI<dynlib file>\fR
|
||||
The dynamic library file to load. Repeat this option for every dynlib module
|
||||
instance added to the \fBmodule\-config:\fR option.
|
||||
.SS "DNS64 Module Options"
|
||||
.LP
|
||||
The dns64 module must be configured in the \fBmodule\-config:\fR "dns64
|
||||
@ -2060,6 +2110,11 @@ even if some data have expired in terms of DNS TTL or the Redis server has
|
||||
cached too much data;
|
||||
if necessary the Redis server must be configured to limit the cache size,
|
||||
preferably with some kind of least-recently-used eviction policy.
|
||||
Additionaly, the \fBredis\-expire\-records\fR option can be used in order to
|
||||
set the relative DNS TTL of the message as timeout to the Redis records; keep
|
||||
in mind that some additional memory is used per key and that the expire
|
||||
information is stored as absolute Unix timestamps in Redis (computer time must
|
||||
be stable).
|
||||
This backend uses synchronous communication with the Redis server
|
||||
based on the assumption that the communication is stable and sufficiently
|
||||
fast.
|
||||
@ -2114,6 +2169,94 @@ If this timeout expires Unbound closes the connection, treats it as
|
||||
if the Redis server does not have the requested data, and will try to
|
||||
re-establish a new connection later.
|
||||
This option defaults to 100 milliseconds.
|
||||
.TP
|
||||
.B redis-expire-records: \fI<yes or no>
|
||||
If Redis record expiration is enabled. If yes, unbound sets timeout for Redis
|
||||
records so that Redis can evict keys that have expired automatically. If
|
||||
unbound is configured with \fBserve-expired\fR and \fBserve-expired-ttl\fR is 0,
|
||||
this option is internally reverted to "no". Redis SETEX support is required
|
||||
for this option (Redis >= 2.0.0).
|
||||
This option defaults to no.
|
||||
.SS DNSTAP Logging Options
|
||||
DNSTAP support, when compiled in, is enabled in the \fBdnstap:\fR section.
|
||||
This starts an extra thread (when compiled with threading) that writes
|
||||
the log information to the destination. If unbound is compiled without
|
||||
threading it does not spawn a thread, but connects per-process to the
|
||||
destination.
|
||||
.TP
|
||||
.B dnstap-enable: \fI<yes or no>
|
||||
If dnstap is enabled. Default no. If yes, it connects to the dnstap server
|
||||
and if any of the dnstap-log-..-messages options is enabled it sends logs
|
||||
for those messages to the server.
|
||||
.TP
|
||||
.B dnstap-bidirectional: \fI<yes or no>
|
||||
Use frame streams in bidirectional mode to transfer DNSTAP messages. Default is
|
||||
yes.
|
||||
.TP
|
||||
.B dnstap-socket-path: \fI<file name>
|
||||
Sets the unix socket file name for connecting to the server that is
|
||||
listening on that socket. Default is "@DNSTAP_SOCKET_PATH@".
|
||||
.TP
|
||||
.B dnstap-ip: \fI<IPaddress[@port]>
|
||||
If "", the unix socket is used, if set with an IP address (IPv4 or IPv6)
|
||||
that address is used to connect to the server.
|
||||
.TP
|
||||
.B dnstap-tls: \fI<yes or no>
|
||||
Set this to use TLS to connect to the server specified in \fBdnstap-ip\fR.
|
||||
The default is yes. If set to no, TCP is used to connect to the server.
|
||||
.TP
|
||||
.B dnstap-tls-server-name: \fI<name of TLS authentication>
|
||||
The TLS server name to authenticate the server with. Used when \fBdnstap-tls\fR is enabled. If "" it is ignored, default "".
|
||||
.TP
|
||||
.B dnstap-tls-cert-bundle: \fI<file name of cert bundle>
|
||||
The pem file with certs to verify the TLS server certificate. If "" the
|
||||
server default cert bundle is used, or the windows cert bundle on windows.
|
||||
Default is "".
|
||||
.TP
|
||||
.B dnstap-tls-client-key-file: \fI<file name>
|
||||
The client key file for TLS client authentication. If "" client
|
||||
authentication is not used. Default is "".
|
||||
.TP
|
||||
.B dnstap-tls-client-cert-file: \fI<file name>
|
||||
The client cert file for TLS client authentication. Default is "".
|
||||
.TP
|
||||
.B dnstap-send-identity: \fI<yes or no>
|
||||
If enabled, the server identity is included in the log messages.
|
||||
Default is no.
|
||||
.TP
|
||||
.B dnstap-send-version: \fI<yes or no>
|
||||
If enabled, the server version if included in the log messages.
|
||||
Default is no.
|
||||
.TP
|
||||
.B dnstap-identity: \fI<string>
|
||||
The identity to send with messages, if "" the hostname is used.
|
||||
Default is "".
|
||||
.TP
|
||||
.B dnstap-version: \fI<string>
|
||||
The version to send with messages, if "" the package version is used.
|
||||
Default is "".
|
||||
.TP
|
||||
.B dnstap-log-resolver-query-messages: \fI<yes or no>
|
||||
Enable to log resolver query messages. Default is no.
|
||||
These are messages from unbound to upstream servers.
|
||||
.TP
|
||||
.B dnstap-log-resolver-response-messages: \fI<yes or no>
|
||||
Enable to log resolver response messages. Default is no.
|
||||
These are replies from upstream servers to unbound.
|
||||
.TP
|
||||
.B dnstap-log-client-query-messages: \fI<yes or no>
|
||||
Enable to log client query messages. Default is no.
|
||||
These are client queries to unbound.
|
||||
.TP
|
||||
.B dnstap-log-client-response-messages: \fI<yes or no>
|
||||
Enable to log client response messages. Default is no.
|
||||
These are responses from unbound to clients.
|
||||
.TP
|
||||
.B dnstap-log-forwarder-query-messages: \fI<yes or no>
|
||||
Enable to log forwarder query messages. Default is no.
|
||||
.TP
|
||||
.B dnstap-log-forwarder-response-messages: \fI<yes or no>
|
||||
Enable to log forwarder response messages. Default is no.
|
||||
.SS Response Policy Zone Options
|
||||
.LP
|
||||
Response Policy Zones are configured with \fBrpz:\fR, and each one must have a
|
||||
|
301
dynlibmod/dynlibmod.c
Normal file
301
dynlibmod/dynlibmod.c
Normal file
@ -0,0 +1,301 @@
|
||||
/**
|
||||
* \file
|
||||
* This file contains the dynamic library module for Unbound.
|
||||
* This loads a dynamic library (.dll, .so) and calls that for the
|
||||
* module actions.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "util/module.h"
|
||||
#include "util/config_file.h"
|
||||
#include "dynlibmod/dynlibmod.h"
|
||||
|
||||
#if HAVE_WINDOWS_H
|
||||
#include <windows.h>
|
||||
#define __DYNMOD HMODULE
|
||||
#define __DYNSYM FARPROC
|
||||
#define __LOADSYM GetProcAddress
|
||||
void log_dlerror() {
|
||||
DWORD dwLastError = GetLastError();
|
||||
LPSTR MessageBuffer;
|
||||
DWORD dwBufferLength;
|
||||
DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM ;
|
||||
if((dwBufferLength = FormatMessageA(
|
||||
dwFormatFlags,
|
||||
NULL, // module to get message from (NULL == system)
|
||||
dwLastError,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
|
||||
(LPSTR) &MessageBuffer,
|
||||
0,
|
||||
NULL
|
||||
)))
|
||||
{
|
||||
log_err("dynlibmod: %s (%ld)", MessageBuffer, dwLastError);
|
||||
LocalFree(MessageBuffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HMODULE open_library(const char* fname) {
|
||||
return LoadLibrary(fname);
|
||||
}
|
||||
|
||||
void close_library(const char* fname, __DYNMOD handle) {
|
||||
(void)fname;
|
||||
(void)handle;
|
||||
}
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#define __DYNMOD void*
|
||||
#define __DYNSYM void*
|
||||
#define __LOADSYM dlsym
|
||||
void log_dlerror() {
|
||||
log_err("dynlibmod: %s", dlerror());
|
||||
}
|
||||
|
||||
void* open_library(const char* fname) {
|
||||
return dlopen(fname, RTLD_LAZY | RTLD_GLOBAL);
|
||||
}
|
||||
|
||||
void close_library(const char* fname, __DYNMOD handle) {
|
||||
if(!handle) return;
|
||||
if(dlclose(handle) != 0) {
|
||||
log_err("dlclose %s: %s", fname, strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** module counter for multiple dynlib modules */
|
||||
static int dynlib_mod_count = 0;
|
||||
|
||||
/** dynlib module init */
|
||||
int dynlibmod_init(struct module_env* env, int id) {
|
||||
int dynlib_mod_idx = dynlib_mod_count++;
|
||||
struct config_strlist* cfg_item = env->cfg->dynlib_file;
|
||||
struct dynlibmod_env* de = (struct dynlibmod_env*)calloc(1, sizeof(struct dynlibmod_env));
|
||||
__DYNMOD dynamic_library;
|
||||
if (!de)
|
||||
{
|
||||
log_err("dynlibmod[%d]: malloc failure", dynlib_mod_idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
env->modinfo[id] = (void*) de;
|
||||
|
||||
de->fname = NULL;
|
||||
for(int i = dynlib_mod_idx;
|
||||
i != 0 && cfg_item != NULL;
|
||||
i--, cfg_item = cfg_item->next) {}
|
||||
|
||||
if (cfg_item == NULL || cfg_item->str == NULL || cfg_item->str[0] == 0) {
|
||||
log_err("dynlibmod[%d]: no dynamic library given.", dynlib_mod_idx);
|
||||
return 0;
|
||||
} else {
|
||||
de->fname = cfg_item->str;
|
||||
}
|
||||
verbose(VERB_ALGO, "dynlibmod[%d]: Trying to load library %s", dynlib_mod_idx, de->fname);
|
||||
dynamic_library = open_library(de->fname);
|
||||
de->dynamic_library = (void*)dynamic_library;
|
||||
if (dynamic_library == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
__DYNSYM initializer;
|
||||
__DYNSYM deinitializer;
|
||||
__DYNSYM operate;
|
||||
__DYNSYM inform;
|
||||
__DYNSYM clear;
|
||||
__DYNSYM get_mem;
|
||||
initializer = __LOADSYM(dynamic_library,"init");
|
||||
if (initializer == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load init procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
de->func_init = (func_init_t)(void*)initializer;
|
||||
}
|
||||
deinitializer = __LOADSYM(dynamic_library,"deinit");
|
||||
if (deinitializer == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load deinit procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
de->func_deinit = (func_deinit_t)(void*)deinitializer;
|
||||
}
|
||||
operate = __LOADSYM(dynamic_library,"operate");
|
||||
if (operate == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load operate procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
de->func_operate = (func_operate_t)(void*)operate;
|
||||
}
|
||||
inform = __LOADSYM(dynamic_library,"inform_super");
|
||||
if (inform == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load inform_super procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
de->func_inform = (func_inform_t)(void*)inform;
|
||||
}
|
||||
clear = __LOADSYM(dynamic_library,"clear");
|
||||
if (clear == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load clear procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
de->func_clear = (func_clear_t)(void*)clear;
|
||||
}
|
||||
get_mem = __LOADSYM(dynamic_library,"get_mem");
|
||||
if (get_mem == NULL) {
|
||||
log_dlerror();
|
||||
log_err("dynlibmod[%d]: unable to load get_mem procedure from dynamic library \"%s\".", dynlib_mod_idx, de->fname);
|
||||
return 0;
|
||||
} else {
|
||||
de->func_get_mem = (func_get_mem_t)(void*)get_mem;
|
||||
}
|
||||
}
|
||||
de->inplace_cb_delete_wrapped = &inplace_cb_delete_wrapped;
|
||||
de->inplace_cb_register_wrapped = &inplace_cb_register_wrapped;
|
||||
return de->func_init(env, id);
|
||||
}
|
||||
|
||||
/** dynlib module deinit */
|
||||
void dynlibmod_deinit(struct module_env* env, int id) {
|
||||
struct dynlibmod_env* de = env->modinfo[id];
|
||||
if(de == NULL)
|
||||
return;
|
||||
de->func_deinit(env, id);
|
||||
close_library(de->fname, (__DYNMOD)de->dynamic_library);
|
||||
dynlib_mod_count--;
|
||||
de->fname = NULL;
|
||||
free(de);
|
||||
}
|
||||
|
||||
/** dynlib module operate on a query */
|
||||
void dynlibmod_operate(struct module_qstate* qstate, enum module_ev event,
|
||||
int id, struct outbound_entry* outbound) {
|
||||
struct dynlibmod_env* de = qstate->env->modinfo[id];
|
||||
|
||||
de->func_operate(qstate, event, id, outbound);
|
||||
}
|
||||
|
||||
/** dynlib module */
|
||||
void dynlibmod_inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super) {
|
||||
struct dynlibmod_env* de = qstate->env->modinfo[id];
|
||||
|
||||
de->func_inform(qstate, id, super);
|
||||
}
|
||||
|
||||
/** dynlib module cleanup query state */
|
||||
void dynlibmod_clear(struct module_qstate* qstate, int id) {
|
||||
struct dynlibmod_env* de = qstate->env->modinfo[id];
|
||||
|
||||
de->func_clear(qstate, id);
|
||||
}
|
||||
|
||||
/** dynlib module alloc size routine */
|
||||
size_t dynlibmod_get_mem(struct module_env* env, int id) {
|
||||
struct dynlibmod_env* de = (struct dynlibmod_env*)env->modinfo[id];
|
||||
size_t size;
|
||||
verbose(VERB_ALGO, "dynlibmod: get_mem, id: %d, de:%p", id, de);
|
||||
if(!de)
|
||||
return 0;
|
||||
|
||||
size = de->func_get_mem(env, id);
|
||||
return size + sizeof(*de);
|
||||
}
|
||||
|
||||
int dynlib_inplace_cb_reply_generic(struct query_info* qinfo,
|
||||
struct module_qstate* qstate, struct reply_info* rep, int rcode,
|
||||
struct edns_data* edns, struct edns_option** opt_list_out,
|
||||
struct comm_reply* repinfo, struct regional* region, int id,
|
||||
void* callback) {
|
||||
struct cb_pair* cb_pair = (struct cb_pair*) callback;
|
||||
return ((inplace_cb_reply_func_type*) cb_pair->cb)(qinfo, qstate, rep, rcode, edns, opt_list_out, repinfo, region, id, cb_pair->cb_arg);
|
||||
}
|
||||
|
||||
int dynlib_inplace_cb_query_generic(struct query_info* qinfo, uint16_t flags,
|
||||
struct module_qstate* qstate, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen, struct regional* region,
|
||||
int id, void* callback) {
|
||||
struct cb_pair* cb_pair = (struct cb_pair*) callback;
|
||||
return ((inplace_cb_query_func_type*) cb_pair->cb)(qinfo, flags, qstate, addr, addrlen, zone, zonelen, region, id, cb_pair->cb_arg);
|
||||
}
|
||||
|
||||
int dynlib_inplace_cb_edns_back_parsed(struct module_qstate* qstate,
|
||||
int id, void* cb_args) {
|
||||
struct cb_pair* cb_pair = (struct cb_pair*) cb_args;
|
||||
return ((inplace_cb_edns_back_parsed_func_type*) cb_pair->cb)(qstate, id, cb_pair->cb_arg);
|
||||
}
|
||||
|
||||
int dynlib_inplace_cb_query_response(struct module_qstate* qstate,
|
||||
struct dns_msg* response, int id, void* cb_args) {
|
||||
struct cb_pair* cb_pair = (struct cb_pair*) cb_args;
|
||||
return ((inplace_cb_query_response_func_type*) cb_pair->cb)(qstate, response, id, cb_pair->cb_arg);
|
||||
}
|
||||
|
||||
int
|
||||
inplace_cb_register_wrapped(void* cb, enum inplace_cb_list_type type, void* cbarg,
|
||||
struct module_env* env, int id) {
|
||||
struct cb_pair* cb_pair = malloc(sizeof(struct cb_pair));
|
||||
cb_pair->cb = cb;
|
||||
cb_pair->cb_arg = cbarg;
|
||||
if(type >= inplace_cb_reply && type <= inplace_cb_reply_servfail) {
|
||||
return inplace_cb_register(&dynlib_inplace_cb_reply_generic, type, (void*) cb_pair, env, id);
|
||||
} else if(type == inplace_cb_query) {
|
||||
return inplace_cb_register(&dynlib_inplace_cb_query_generic, type, (void*) cb_pair, env, id);
|
||||
} else if(type == inplace_cb_query_response) {
|
||||
return inplace_cb_register(&dynlib_inplace_cb_query_response, type, (void*) cb_pair, env, id);
|
||||
} else if(type == inplace_cb_edns_back_parsed) {
|
||||
return inplace_cb_register(&dynlib_inplace_cb_edns_back_parsed, type, (void*) cb_pair, env, id);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
inplace_cb_delete_wrapped(struct module_env* env, enum inplace_cb_list_type type,
|
||||
int id) {
|
||||
struct inplace_cb* temp = env->inplace_cb_lists[type];
|
||||
struct inplace_cb* prev = NULL;
|
||||
|
||||
while(temp) {
|
||||
if(temp->id == id) {
|
||||
if(!prev) {
|
||||
env->inplace_cb_lists[type] = temp->next;
|
||||
free(temp->cb_arg);
|
||||
free(temp);
|
||||
temp = env->inplace_cb_lists[type];
|
||||
}
|
||||
else {
|
||||
prev->next = temp->next;
|
||||
free(temp->cb_arg);
|
||||
free(temp);
|
||||
temp = prev->next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
prev = temp;
|
||||
temp = temp->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The module function block
|
||||
*/
|
||||
static struct module_func_block dynlibmod_block = {
|
||||
"dynlib",
|
||||
&dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate, &dynlibmod_inform_super,
|
||||
&dynlibmod_clear, &dynlibmod_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block* dynlibmod_get_funcblock(void)
|
||||
{
|
||||
return &dynlibmod_block;
|
||||
}
|
139
dynlibmod/dynlibmod.h
Normal file
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 */
|
130
dynlibmod/examples/helloworld.c
Normal file
130
dynlibmod/examples/helloworld.c
Normal file
@ -0,0 +1,130 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This is an example to show how dynamic libraries can be made to work with
|
||||
* unbound. To build a .so file simply run:
|
||||
* gcc -I../.. -shared -Wall -Werror -fpic -o helloworld.so helloworld.c
|
||||
* And to build for windows, first make unbound with the --with-dynlibmod
|
||||
* switch, then use this command:
|
||||
* x86_64-w64-mingw32-gcc -m64 -I../.. -shared -Wall -Werror -fpic
|
||||
* -o helloworld.dll helloworld.c -L../.. -l:libunbound.a
|
||||
* to cross-compile a 64-bit Windows DLL.
|
||||
*/
|
||||
|
||||
#include "../../config.h"
|
||||
#include "../../util/module.h"
|
||||
#include "../../sldns/parseutil.h"
|
||||
#include "../dynlibmod.h"
|
||||
|
||||
/* Declare the EXPORT macro that expands to exporting the symbol for DLLs when
|
||||
* compiling for Windows. All procedures marked with EXPORT in this example are
|
||||
* called directly by the dynlib module and must be present for the module to
|
||||
* load correctly. */
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
#define EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define EXPORT
|
||||
#endif
|
||||
|
||||
/* Forward declare a callback, implemented at the bottom of this file */
|
||||
int reply_callback(struct query_info* qinfo,
|
||||
struct module_qstate* qstate, struct reply_info* rep, int rcode,
|
||||
struct edns_data* edns, struct edns_option** opt_list_out,
|
||||
struct comm_reply* repinfo, struct regional* region, int id,
|
||||
void* callback);
|
||||
|
||||
/* Init is called when the module is first loaded. It should be used to set up
|
||||
* the environment for this module and do any other initialisation required. */
|
||||
EXPORT int init(struct module_env* env, int id) {
|
||||
log_info("dynlib: hello world from init");
|
||||
struct dynlibmod_env* de = (struct dynlibmod_env*) env->modinfo[id];
|
||||
de->inplace_cb_register_wrapped(&reply_callback,
|
||||
inplace_cb_reply,
|
||||
NULL, env, id);
|
||||
struct dynlibmod_env* local_env = env->modinfo[id];
|
||||
local_env->dyn_env = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Deinit is run as the program is shutting down. It should be used to clean up
|
||||
* the environment and any left over data. */
|
||||
EXPORT void deinit(struct module_env* env, int id) {
|
||||
log_info("dynlib: hello world from deinit");
|
||||
struct dynlibmod_env* de = (struct dynlibmod_env*) env->modinfo[id];
|
||||
de->inplace_cb_delete_wrapped(env, inplace_cb_reply, id);
|
||||
if (de->dyn_env != NULL) free(de->dyn_env);
|
||||
}
|
||||
|
||||
/* Operate is called every time a query passes by this module. The event can be
|
||||
* used to determine which direction in the module chain it came from. */
|
||||
EXPORT void operate(struct module_qstate* qstate, enum module_ev event,
|
||||
int id, struct outbound_entry* entry) {
|
||||
log_info("dynlib: hello world from operate");
|
||||
log_info("dynlib: incoming query: %s %s(%d) %s(%d)",
|
||||
qstate->qinfo.qname,
|
||||
sldns_lookup_by_id(sldns_rr_classes, qstate->qinfo.qclass)->name,
|
||||
qstate->qinfo.qclass,
|
||||
sldns_rr_descript(qstate->qinfo.qtype)->_name,
|
||||
qstate->qinfo.qtype);
|
||||
if (event == module_event_new || event == module_event_pass) {
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
struct dynlibmod_env* env = qstate->env->modinfo[id];
|
||||
if (env->dyn_env == NULL) {
|
||||
env->dyn_env = calloc(3, sizeof(int));
|
||||
((int *)env->dyn_env)[0] = 42;
|
||||
((int *)env->dyn_env)[1] = 102;
|
||||
((int *)env->dyn_env)[2] = 192;
|
||||
} else {
|
||||
log_err("dynlib: already has data!");
|
||||
qstate->ext_state[id] = module_error;
|
||||
}
|
||||
} else if (event == module_event_moddone) {
|
||||
qstate->ext_state[id] = module_finished;
|
||||
} else {
|
||||
qstate->ext_state[id] = module_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* Inform super is called when a query is completed or errors out, but only if
|
||||
* a sub-query has been registered to it by this module. Look at
|
||||
* mesh_attach_sub in services/mesh.h to see how this is done. */
|
||||
EXPORT void inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super) {
|
||||
log_info("dynlib: hello world from inform_super");
|
||||
}
|
||||
|
||||
/* Clear is called once a query is complete and the response has been sent
|
||||
* back. It is used to clear up any per-query allocations. */
|
||||
EXPORT void clear(struct module_qstate* qstate, int id) {
|
||||
log_info("dynlib: hello world from clear");
|
||||
struct dynlibmod_env* env = qstate->env->modinfo[id];
|
||||
if (env->dyn_env != NULL) {
|
||||
free(env->dyn_env);
|
||||
env->dyn_env = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get mem is called when Unbound is printing performance information. This
|
||||
* only happens explicitly and is only used to show memory usage to the user. */
|
||||
EXPORT size_t get_mem(struct module_env* env, int id) {
|
||||
log_info("dynlib: hello world from get_mem");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The callback that was forward declared earlier. It is registered in the init
|
||||
* procedure to run when a query is being replied to. */
|
||||
int reply_callback(struct query_info* qinfo,
|
||||
struct module_qstate* qstate, struct reply_info* rep, int rcode,
|
||||
struct edns_data* edns, struct edns_option** opt_list_out,
|
||||
struct comm_reply* repinfo, struct regional* region, int id,
|
||||
void* callback) {
|
||||
log_info("dynlib: hello world from callback");
|
||||
struct dynlibmod_env* env = qstate->env->modinfo[id];
|
||||
if (env->dyn_env != NULL) {
|
||||
log_info("dynlib: numbers gotten from query: %d, %d, and %d",
|
||||
((int *)env->dyn_env)[0],
|
||||
((int *)env->dyn_env)[1],
|
||||
((int *)env->dyn_env)[2]);
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ iter_new(struct module_qstate* qstate, int id)
|
||||
iq->qchase = qstate->qinfo;
|
||||
outbound_list_init(&iq->outlist);
|
||||
iq->minimise_count = 0;
|
||||
iq->minimise_timeout_count = 0;
|
||||
iq->timeout_count = 0;
|
||||
if (qstate->env->cfg->qname_minimisation)
|
||||
iq->minimisation_state = INIT_MINIMISE_STATE;
|
||||
else
|
||||
@ -2239,7 +2239,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->qinfo_out.qname = iq->qchase.qname;
|
||||
iq->qinfo_out.qname_len = iq->qchase.qname_len;
|
||||
iq->minimise_count++;
|
||||
iq->minimise_timeout_count = 0;
|
||||
iq->timeout_count = 0;
|
||||
|
||||
iter_dec_attempts(iq->dp, 1);
|
||||
|
||||
@ -2327,7 +2327,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
}
|
||||
if(iq->minimisation_state == SKIP_MINIMISE_STATE) {
|
||||
if(iq->minimise_timeout_count < MAX_MINIMISE_TIMEOUT_COUNT)
|
||||
if(iq->timeout_count < MAX_MINIMISE_TIMEOUT_COUNT)
|
||||
/* Do not increment qname, continue incrementing next
|
||||
* iteration */
|
||||
iq->minimisation_state = MINIMISE_STATE;
|
||||
@ -2668,14 +2668,15 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if(iq->response == NULL) {
|
||||
/* Don't increment qname when QNAME minimisation is enabled */
|
||||
if(qstate->env->cfg->qname_minimisation) {
|
||||
iq->minimise_timeout_count++;
|
||||
iq->minimisation_state = SKIP_MINIMISE_STATE;
|
||||
}
|
||||
iq->timeout_count++;
|
||||
iq->chase_to_rd = 0;
|
||||
iq->dnssec_lame_query = 0;
|
||||
verbose(VERB_ALGO, "query response was timeout");
|
||||
return next_state(iq, QUERYTARGETS_STATE);
|
||||
}
|
||||
iq->timeout_count = 0;
|
||||
type = response_type_from_server(
|
||||
(int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd),
|
||||
iq->response, &iq->qinfo_out, iq->dp);
|
||||
@ -3690,7 +3691,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->response = NULL;
|
||||
iq->state = QUERY_RESP_STATE;
|
||||
if(event == module_event_noreply || event == module_event_error) {
|
||||
if(event == module_event_noreply && iq->sent_count >= 3 &&
|
||||
if(event == module_event_noreply && iq->timeout_count >= 3 &&
|
||||
qstate->env->cfg->use_caps_bits_for_id &&
|
||||
!iq->caps_fallback && !is_caps_whitelisted(ie, iq)) {
|
||||
/* start fallback */
|
||||
|
@ -398,8 +398,9 @@ struct iter_qstate {
|
||||
|
||||
/**
|
||||
* Count number of time-outs. Used to prevent resolving failures when
|
||||
* the QNAME minimisation QTYPE is blocked. */
|
||||
int minimise_timeout_count;
|
||||
* the QNAME minimisation QTYPE is blocked. Used to determine if
|
||||
* capsforid fallback should be started.*/
|
||||
int timeout_count;
|
||||
|
||||
/** True if the current response is from auth_zone */
|
||||
int auth_zone_response;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
@ -1864,15 +1866,26 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
|
||||
struct auth_xfer* x = NULL;
|
||||
|
||||
/* create zone */
|
||||
if(c->isrpz) {
|
||||
/* if the rpz lock is needed, grab it before the other
|
||||
* locks to avoid a lock dependency cycle */
|
||||
lock_rw_wrlock(&az->rpz_lock);
|
||||
}
|
||||
lock_rw_wrlock(&az->lock);
|
||||
if(!(z=auth_zones_find_or_add_zone(az, c->name))) {
|
||||
lock_rw_unlock(&az->lock);
|
||||
if(c->isrpz) {
|
||||
lock_rw_unlock(&az->rpz_lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(c->masters || c->urls) {
|
||||
if(!(x=auth_zones_find_or_add_xfer(az, z))) {
|
||||
lock_rw_unlock(&az->lock);
|
||||
lock_rw_unlock(&z->lock);
|
||||
if(c->isrpz) {
|
||||
lock_rw_unlock(&az->rpz_lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1887,6 +1900,9 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
|
||||
lock_basic_unlock(&x->lock);
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
if(c->isrpz) {
|
||||
lock_rw_unlock(&az->rpz_lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
z->for_downstream = c->for_downstream;
|
||||
@ -1897,11 +1913,14 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
|
||||
fatal_exit("Could not setup RPZ zones");
|
||||
return 0;
|
||||
}
|
||||
lock_rw_wrlock(&az->rpz_lock);
|
||||
z->rpz->next = az->rpz_first;
|
||||
lock_protect(&z->lock, &z->rpz->local_zones, sizeof(*z->rpz));
|
||||
/* the az->rpz_lock is locked above */
|
||||
z->rpz_az_next = az->rpz_first;
|
||||
if(az->rpz_first)
|
||||
az->rpz_first->prev = z->rpz;
|
||||
az->rpz_first = z->rpz;
|
||||
az->rpz_first->rpz_az_prev = z;
|
||||
az->rpz_first = z;
|
||||
}
|
||||
if(c->isrpz) {
|
||||
lock_rw_unlock(&az->rpz_lock);
|
||||
}
|
||||
|
||||
@ -5331,7 +5350,7 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
log_assert(xfr->task_transfer);
|
||||
lock_basic_lock(&xfr->lock);
|
||||
env = xfr->task_transfer->env;
|
||||
if(env->outnet->want_to_quit) {
|
||||
if(!env || env->outnet->want_to_quit) {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return; /* stop on quit */
|
||||
}
|
||||
@ -5770,7 +5789,7 @@ auth_xfer_transfer_timer_callback(void* arg)
|
||||
log_assert(xfr->task_transfer);
|
||||
lock_basic_lock(&xfr->lock);
|
||||
env = xfr->task_transfer->env;
|
||||
if(env->outnet->want_to_quit) {
|
||||
if(!env || env->outnet->want_to_quit) {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return; /* stop on quit */
|
||||
}
|
||||
@ -5812,7 +5831,7 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
|
||||
log_assert(xfr->task_transfer);
|
||||
lock_basic_lock(&xfr->lock);
|
||||
env = xfr->task_transfer->env;
|
||||
if(env->outnet->want_to_quit) {
|
||||
if(!env || env->outnet->want_to_quit) {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return 0; /* stop on quit */
|
||||
}
|
||||
@ -5893,7 +5912,7 @@ auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err,
|
||||
log_assert(xfr->task_transfer);
|
||||
lock_basic_lock(&xfr->lock);
|
||||
env = xfr->task_transfer->env;
|
||||
if(env->outnet->want_to_quit) {
|
||||
if(!env || env->outnet->want_to_quit) {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return 0; /* stop on quit */
|
||||
}
|
||||
@ -6107,7 +6126,7 @@ auth_xfer_probe_timer_callback(void* arg)
|
||||
log_assert(xfr->task_probe);
|
||||
lock_basic_lock(&xfr->lock);
|
||||
env = xfr->task_probe->env;
|
||||
if(env->outnet->want_to_quit) {
|
||||
if(!env || env->outnet->want_to_quit) {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return; /* stop on quit */
|
||||
}
|
||||
@ -6143,7 +6162,7 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
|
||||
log_assert(xfr->task_probe);
|
||||
lock_basic_lock(&xfr->lock);
|
||||
env = xfr->task_probe->env;
|
||||
if(env->outnet->want_to_quit) {
|
||||
if(!env || env->outnet->want_to_quit) {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return 0; /* stop on quit */
|
||||
}
|
||||
@ -6388,7 +6407,7 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
log_assert(xfr->task_probe);
|
||||
lock_basic_lock(&xfr->lock);
|
||||
env = xfr->task_probe->env;
|
||||
if(env->outnet->want_to_quit) {
|
||||
if(!env || env->outnet->want_to_quit) {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return; /* stop on quit */
|
||||
}
|
||||
@ -6465,7 +6484,7 @@ auth_xfer_timer(void* arg)
|
||||
log_assert(xfr->task_nextprobe);
|
||||
lock_basic_lock(&xfr->lock);
|
||||
env = xfr->task_nextprobe->env;
|
||||
if(env->outnet->want_to_quit) {
|
||||
if(!env || env->outnet->want_to_quit) {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return; /* stop on quit */
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -179,9 +179,10 @@ int
|
||||
create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
socklen_t addrlen, int v6only, int* inuse, int* noproto,
|
||||
int rcv, int snd, int listen, int* reuseport, int transparent,
|
||||
int freebind, int use_systemd)
|
||||
int freebind, int use_systemd, int dscp)
|
||||
{
|
||||
int s;
|
||||
char* err;
|
||||
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_USE_MIN_MTU) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined (SO_BINDANY)
|
||||
int on=1;
|
||||
#endif
|
||||
@ -451,6 +452,9 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
# endif
|
||||
#endif /* SO_SNDBUF */
|
||||
}
|
||||
err = set_ip_dscp(s, family, dscp);
|
||||
if(err != NULL)
|
||||
log_warn("error setting IP DiffServ codepoint %d on UDP socket: %s", dscp, err);
|
||||
if(family == AF_INET6) {
|
||||
# if defined(IPV6_V6ONLY)
|
||||
if(v6only) {
|
||||
@ -638,9 +642,10 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
|
||||
int
|
||||
create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
int* reuseport, int transparent, int mss, int freebind, int use_systemd)
|
||||
int* reuseport, int transparent, int mss, int freebind, int use_systemd, int dscp)
|
||||
{
|
||||
int s;
|
||||
char* err;
|
||||
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined(SO_BINDANY)
|
||||
int on = 1;
|
||||
#endif
|
||||
@ -793,6 +798,9 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
strerror(errno));
|
||||
}
|
||||
#endif /* IP_TRANSPARENT || IP_BINDANY || SO_BINDANY */
|
||||
err = set_ip_dscp(s, addr->ai_family, dscp);
|
||||
if(err != NULL)
|
||||
log_warn("error setting IP DiffServ codepoint %d on TCP socket: %s", dscp, err);
|
||||
if(
|
||||
#ifdef HAVE_SYSTEMD
|
||||
!got_fd_from_systemd &&
|
||||
@ -866,6 +874,55 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
return s;
|
||||
}
|
||||
|
||||
char*
|
||||
set_ip_dscp(int socket, int addrfamily, int dscp)
|
||||
{
|
||||
int ds;
|
||||
|
||||
if(dscp == 0)
|
||||
return NULL;
|
||||
ds = dscp << 2;
|
||||
switch(addrfamily) {
|
||||
case AF_INET6:
|
||||
if(setsockopt(socket, IPPROTO_IPV6, IPV6_TCLASS, (void*)&ds, sizeof(ds)) < 0)
|
||||
return sock_strerror(errno);
|
||||
break;
|
||||
default:
|
||||
if(setsockopt(socket, IPPROTO_IP, IP_TOS, (void*)&ds, sizeof(ds)) < 0)
|
||||
return sock_strerror(errno);
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
# ifndef USE_WINSOCK
|
||||
char*
|
||||
sock_strerror(int errn)
|
||||
{
|
||||
return strerror(errn);
|
||||
}
|
||||
|
||||
void
|
||||
sock_close(int socket)
|
||||
{
|
||||
close(socket);
|
||||
}
|
||||
|
||||
# else
|
||||
char*
|
||||
sock_strerror(int ATTR_UNUSED(errn))
|
||||
{
|
||||
return wsa_strerror(WSAGetLastError());
|
||||
}
|
||||
|
||||
void
|
||||
sock_close(int socket)
|
||||
{
|
||||
closesocket(socket);
|
||||
}
|
||||
|
||||
# endif /* USE_WINSOCK */
|
||||
|
||||
int
|
||||
create_local_accept_sock(const char *path, int* noproto, int use_systemd)
|
||||
{
|
||||
@ -952,7 +1009,7 @@ create_local_accept_sock(const char *path, int* noproto, int use_systemd)
|
||||
static int
|
||||
make_sock(int stype, const char* ifname, const char* port,
|
||||
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
|
||||
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd)
|
||||
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd, int dscp)
|
||||
{
|
||||
struct addrinfo *res = NULL;
|
||||
int r, s, inuse, noproto;
|
||||
@ -980,7 +1037,7 @@ make_sock(int stype, const char* ifname, const char* port,
|
||||
s = create_udp_sock(res->ai_family, res->ai_socktype,
|
||||
(struct sockaddr*)res->ai_addr, res->ai_addrlen,
|
||||
v6only, &inuse, &noproto, (int)rcv, (int)snd, 1,
|
||||
reuseport, transparent, freebind, use_systemd);
|
||||
reuseport, transparent, freebind, use_systemd, dscp);
|
||||
if(s == -1 && inuse) {
|
||||
log_err("bind: address already in use");
|
||||
} else if(s == -1 && noproto && hints->ai_family == AF_INET6){
|
||||
@ -988,7 +1045,7 @@ make_sock(int stype, const char* ifname, const char* port,
|
||||
}
|
||||
} else {
|
||||
s = create_tcp_accept_sock(res, v6only, &noproto, reuseport,
|
||||
transparent, tcp_mss, freebind, use_systemd);
|
||||
transparent, tcp_mss, freebind, use_systemd, dscp);
|
||||
if(s == -1 && noproto && hints->ai_family == AF_INET6){
|
||||
*noip6 = 1;
|
||||
}
|
||||
@ -1001,7 +1058,7 @@ make_sock(int stype, const char* ifname, const char* port,
|
||||
static int
|
||||
make_sock_port(int stype, const char* ifname, const char* port,
|
||||
struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
|
||||
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd)
|
||||
int* reuseport, int transparent, int tcp_mss, int freebind, int use_systemd, int dscp)
|
||||
{
|
||||
char* s = strchr(ifname, '@');
|
||||
if(s) {
|
||||
@ -1023,10 +1080,10 @@ make_sock_port(int stype, const char* ifname, const char* port,
|
||||
(void)strlcpy(p, s+1, sizeof(p));
|
||||
p[strlen(s+1)]=0;
|
||||
return make_sock(stype, newif, p, hints, v6only, noip6,
|
||||
rcv, snd, reuseport, transparent, tcp_mss, freebind, use_systemd);
|
||||
rcv, snd, reuseport, transparent, tcp_mss, freebind, use_systemd, dscp);
|
||||
}
|
||||
return make_sock(stype, ifname, port, hints, v6only, noip6, rcv, snd,
|
||||
reuseport, transparent, tcp_mss, freebind, use_systemd);
|
||||
reuseport, transparent, tcp_mss, freebind, use_systemd, dscp);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1146,6 +1203,7 @@ if_is_ssl(const char* ifname, const char* port, int ssl_port,
|
||||
* @param freebind: set IP_FREEBIND socket option.
|
||||
* @param use_systemd: if true, fetch sockets from systemd.
|
||||
* @param dnscrypt_port: dnscrypt service port number
|
||||
* @param dscp: DSCP to use.
|
||||
* @return: returns false on error.
|
||||
*/
|
||||
static int
|
||||
@ -1154,7 +1212,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
size_t rcv, size_t snd, int ssl_port,
|
||||
struct config_strlist* tls_additional_port, int* reuseport,
|
||||
int transparent, int tcp_mss, int freebind, int use_systemd,
|
||||
int dnscrypt_port)
|
||||
int dnscrypt_port, int dscp)
|
||||
{
|
||||
int s, noip6=0;
|
||||
#ifdef USE_DNSCRYPT
|
||||
@ -1171,7 +1229,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
if(do_auto) {
|
||||
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6, rcv, snd, reuseport, transparent,
|
||||
tcp_mss, freebind, use_systemd)) == -1) {
|
||||
tcp_mss, freebind, use_systemd, dscp)) == -1) {
|
||||
if(noip6) {
|
||||
log_warn("IPv6 protocol not available");
|
||||
return 1;
|
||||
@ -1200,7 +1258,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
/* regular udp socket */
|
||||
if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6, rcv, snd, reuseport, transparent,
|
||||
tcp_mss, freebind, use_systemd)) == -1) {
|
||||
tcp_mss, freebind, use_systemd, dscp)) == -1) {
|
||||
if(noip6) {
|
||||
log_warn("IPv6 protocol not available");
|
||||
return 1;
|
||||
@ -1222,7 +1280,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
tls_additional_port);
|
||||
if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
|
||||
&noip6, 0, 0, reuseport, transparent, tcp_mss,
|
||||
freebind, use_systemd)) == -1) {
|
||||
freebind, use_systemd, dscp)) == -1) {
|
||||
if(noip6) {
|
||||
/*log_warn("IPv6 protocol not available");*/
|
||||
return 1;
|
||||
@ -1421,7 +1479,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@ -1435,7 +1493,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@ -1451,7 +1509,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
@ -1465,7 +1523,7 @@ listening_ports_open(struct config_file* cfg, int* reuseport)
|
||||
cfg->ssl_port, cfg->tls_additional_port,
|
||||
reuseport, cfg->ip_transparent,
|
||||
cfg->tcp_mss, cfg->ip_freebind, cfg->use_systemd,
|
||||
cfg->dnscrypt_port)) {
|
||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||
listening_ports_free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -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;
|
||||
|
107
services/mesh.c
107
services/mesh.c
@ -159,16 +159,28 @@ client_info_compare(const struct respip_client_info* ci_a,
|
||||
return 1;
|
||||
if(ci_a->taglen != ci_b->taglen)
|
||||
return (ci_a->taglen < ci_b->taglen) ? -1 : 1;
|
||||
cmp = memcmp(ci_a->taglist, ci_b->taglist, ci_a->taglen);
|
||||
if(cmp != 0)
|
||||
return cmp;
|
||||
if(ci_a->taglist && !ci_b->taglist)
|
||||
return -1;
|
||||
if(!ci_a->taglist && ci_b->taglist)
|
||||
return 1;
|
||||
if(ci_a->taglist && ci_b->taglist) {
|
||||
cmp = memcmp(ci_a->taglist, ci_b->taglist, ci_a->taglen);
|
||||
if(cmp != 0)
|
||||
return cmp;
|
||||
}
|
||||
if(ci_a->tag_actions_size != ci_b->tag_actions_size)
|
||||
return (ci_a->tag_actions_size < ci_b->tag_actions_size) ?
|
||||
-1 : 1;
|
||||
cmp = memcmp(ci_a->tag_actions, ci_b->tag_actions,
|
||||
ci_a->tag_actions_size);
|
||||
if(cmp != 0)
|
||||
return cmp;
|
||||
if(ci_a->tag_actions && !ci_b->tag_actions)
|
||||
return -1;
|
||||
if(!ci_a->tag_actions && ci_b->tag_actions)
|
||||
return 1;
|
||||
if(ci_a->tag_actions && ci_b->tag_actions) {
|
||||
cmp = memcmp(ci_a->tag_actions, ci_b->tag_actions,
|
||||
ci_a->tag_actions_size);
|
||||
if(cmp != 0)
|
||||
return cmp;
|
||||
}
|
||||
if(ci_a->tag_datas != ci_b->tag_datas)
|
||||
return ci_a->tag_datas < ci_b->tag_datas ? -1 : 1;
|
||||
if(ci_a->view != ci_b->view)
|
||||
@ -1284,7 +1296,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
|
||||
void mesh_query_done(struct mesh_state* mstate)
|
||||
{
|
||||
struct mesh_reply* r, *reply_list = NULL;
|
||||
struct mesh_reply* r;
|
||||
struct mesh_reply* prev = NULL;
|
||||
struct sldns_buffer* prev_buffer = NULL;
|
||||
struct mesh_cb* c;
|
||||
@ -1308,27 +1320,7 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
free(err);
|
||||
}
|
||||
}
|
||||
if(mstate->reply_list) {
|
||||
/* set the reply_list to NULL during the mesh_query_done
|
||||
* processing, so that calls back into the mesh from
|
||||
* tcp_req_info (deciding to drop the reply and thus
|
||||
* unregister the mesh_reply from the mstate) are stopped
|
||||
* because the list is empty.
|
||||
* The mstate is then likely not a reply_state, and maybe
|
||||
* also a detached_state.
|
||||
*/
|
||||
reply_list = mstate->reply_list;
|
||||
mstate->reply_list = NULL;
|
||||
if(!mstate->reply_list && !mstate->cb_list) {
|
||||
/* was a reply state, not anymore */
|
||||
log_assert(mstate->s.env->mesh->num_reply_states > 0);
|
||||
mstate->s.env->mesh->num_reply_states--;
|
||||
}
|
||||
if(!mstate->reply_list && !mstate->cb_list &&
|
||||
mstate->super_set.count == 0)
|
||||
mstate->s.env->mesh->num_detached_states++;
|
||||
}
|
||||
for(r = reply_list; r; r = r->next) {
|
||||
for(r = mstate->reply_list; r; r = r->next) {
|
||||
/* if a response-ip address block has been stored the
|
||||
* information should be logged for each client. */
|
||||
if(mstate->s.respip_action_info &&
|
||||
@ -1352,15 +1344,31 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
/* if this query is determined to be dropped during the
|
||||
* mesh processing, this is the point to take that action. */
|
||||
if(mstate->s.is_drop) {
|
||||
/* briefly set the reply_list to NULL, so that the
|
||||
* tcp req info cleanup routine that calls the mesh
|
||||
* to deregister the meshstate for it is not done
|
||||
* because the list is NULL and also accounting is not
|
||||
* done there, but instead we do that here. */
|
||||
struct mesh_reply* reply_list = mstate->reply_list;
|
||||
mstate->reply_list = NULL;
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
} else {
|
||||
struct sldns_buffer* r_buffer = r->query_reply.c->buffer;
|
||||
struct mesh_reply* rlist = mstate->reply_list;
|
||||
if(r->query_reply.c->tcp_req_info) {
|
||||
r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
|
||||
prev_buffer = NULL;
|
||||
}
|
||||
/* briefly set the replylist to null in case the
|
||||
* meshsendreply calls tcpreqinfo sendreply that
|
||||
* comm_point_drops because of size, and then the
|
||||
* null stops the mesh state remove and thus
|
||||
* reply_list modification and accounting */
|
||||
mstate->reply_list = NULL;
|
||||
mesh_send_reply(mstate, mstate->s.return_rcode, rep,
|
||||
r, r_buffer, prev, prev_buffer);
|
||||
mstate->reply_list = rlist;
|
||||
if(r->query_reply.c->tcp_req_info) {
|
||||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||
r_buffer = NULL;
|
||||
@ -1369,6 +1377,17 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
prev_buffer = r_buffer;
|
||||
}
|
||||
}
|
||||
if(mstate->reply_list) {
|
||||
mstate->reply_list = NULL;
|
||||
if(!mstate->reply_list && !mstate->cb_list) {
|
||||
/* was a reply state, not anymore */
|
||||
log_assert(mstate->s.env->mesh->num_reply_states > 0);
|
||||
mstate->s.env->mesh->num_reply_states--;
|
||||
}
|
||||
if(!mstate->reply_list && !mstate->cb_list &&
|
||||
mstate->super_set.count == 0)
|
||||
mstate->s.env->mesh->num_detached_states++;
|
||||
}
|
||||
mstate->replies_sent = 1;
|
||||
while((c = mstate->cb_list) != NULL) {
|
||||
/* take this cb off the list; so that the list can be
|
||||
@ -1863,7 +1882,7 @@ mesh_serve_expired_callback(void* arg)
|
||||
{
|
||||
struct mesh_state* mstate = (struct mesh_state*) arg;
|
||||
struct module_qstate* qstate = &mstate->s;
|
||||
struct mesh_reply* r;
|
||||
struct mesh_reply* r, *rlist;
|
||||
struct mesh_area* mesh = qstate->env->mesh;
|
||||
struct dns_msg* msg;
|
||||
struct mesh_cb* c;
|
||||
@ -1946,16 +1965,7 @@ mesh_serve_expired_callback(void* arg)
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg("Serve expired lookup", &qstate->qinfo, msg->rep);
|
||||
|
||||
r = mstate->reply_list;
|
||||
mstate->reply_list = NULL;
|
||||
if(!mstate->reply_list && !mstate->cb_list) {
|
||||
log_assert(mesh->num_reply_states > 0);
|
||||
mesh->num_reply_states--;
|
||||
if(mstate->super_set.count == 0) {
|
||||
mesh->num_detached_states++;
|
||||
}
|
||||
}
|
||||
for(; r; r = r->next) {
|
||||
for(r = mstate->reply_list; r; r = r->next) {
|
||||
/* If address info is returned, it means the action should be an
|
||||
* 'inform' variant and the information should be logged. */
|
||||
if(actinfo.addrinfo) {
|
||||
@ -1977,8 +1987,15 @@ mesh_serve_expired_callback(void* arg)
|
||||
r_buffer = r->query_reply.c->buffer;
|
||||
if(r->query_reply.c->tcp_req_info)
|
||||
r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
|
||||
/* briefly set the replylist to null in case the meshsendreply
|
||||
* calls tcpreqinfo sendreply that comm_point_drops because
|
||||
* of size, and then the null stops the mesh state remove and
|
||||
* thus reply_list modification and accounting */
|
||||
rlist = mstate->reply_list;
|
||||
mstate->reply_list = NULL;
|
||||
mesh_send_reply(mstate, LDNS_RCODE_NOERROR, msg->rep,
|
||||
r, r_buffer, prev, prev_buffer);
|
||||
mstate->reply_list = rlist;
|
||||
if(r->query_reply.c->tcp_req_info)
|
||||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||
prev = r;
|
||||
@ -1988,6 +2005,16 @@ mesh_serve_expired_callback(void* arg)
|
||||
mesh->ans_expired++;
|
||||
|
||||
}
|
||||
if(mstate->reply_list) {
|
||||
mstate->reply_list = NULL;
|
||||
if(!mstate->reply_list && !mstate->cb_list) {
|
||||
log_assert(mesh->num_reply_states > 0);
|
||||
mesh->num_reply_states--;
|
||||
if(mstate->super_set.count == 0) {
|
||||
mesh->num_detached_states++;
|
||||
}
|
||||
}
|
||||
}
|
||||
while((c = mstate->cb_list) != NULL) {
|
||||
/* take this cb off the list; so that the list can be
|
||||
* changed, eg. by adds from the callback routine */
|
||||
|
@ -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
|
||||
|
@ -205,18 +205,25 @@ pick_outgoing_tcp(struct waiting_tcp* w, int s)
|
||||
/** get TCP file descriptor for address, returns -1 on failure,
|
||||
* tcp_mss is 0 or maxseg size to set for TCP packets. */
|
||||
int
|
||||
outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss)
|
||||
outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss, int dscp)
|
||||
{
|
||||
int s;
|
||||
int af;
|
||||
char* err;
|
||||
#ifdef SO_REUSEADDR
|
||||
int on = 1;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
if(addr_is_ip6(addr, addrlen))
|
||||
if(addr_is_ip6(addr, addrlen)){
|
||||
s = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
|
||||
else
|
||||
af = AF_INET6;
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
af = AF_INET;
|
||||
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
}
|
||||
if(s == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err_addr("outgoing tcp: socket", strerror(errno),
|
||||
@ -236,6 +243,12 @@ outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss)
|
||||
}
|
||||
#endif
|
||||
|
||||
err = set_ip_dscp(s, af, dscp);
|
||||
if(err != NULL) {
|
||||
verbose(VERB_ALGO, "outgoing tcp:"
|
||||
"error setting IP DiffServ codepoint on socket");
|
||||
}
|
||||
|
||||
if(tcp_mss > 0) {
|
||||
#if defined(IPPROTO_TCP) && defined(TCP_MAXSEG)
|
||||
if(setsockopt(s, IPPROTO_TCP, TCP_MAXSEG,
|
||||
@ -291,7 +304,7 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
log_assert(pkt);
|
||||
log_assert(w->addrlen > 0);
|
||||
/* open socket */
|
||||
s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss);
|
||||
s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss, w->outnet->ip_dscp);
|
||||
|
||||
if(s == -1)
|
||||
return 0;
|
||||
@ -373,45 +386,16 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
||||
comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
|
||||
#endif
|
||||
pend->c->ssl_shake_state = comm_ssl_shake_write;
|
||||
if(w->tls_auth_name) {
|
||||
if(!set_auth_name_on_ssl(pend->c->ssl, w->tls_auth_name,
|
||||
w->outnet->tls_use_sni)) {
|
||||
pend->c->fd = s;
|
||||
#ifdef HAVE_SSL
|
||||
(void)SSL_set_tlsext_host_name(pend->c->ssl, w->tls_auth_name);
|
||||
SSL_free(pend->c->ssl);
|
||||
#endif
|
||||
pend->c->ssl = NULL;
|
||||
comm_point_close(pend->c);
|
||||
return 0;
|
||||
}
|
||||
#ifdef HAVE_SSL_SET1_HOST
|
||||
if(w->tls_auth_name) {
|
||||
SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
|
||||
/* setting the hostname makes openssl verify the
|
||||
* host name in the x509 certificate in the
|
||||
* SSL connection*/
|
||||
if(!SSL_set1_host(pend->c->ssl, w->tls_auth_name)) {
|
||||
log_err("SSL_set1_host failed");
|
||||
pend->c->fd = s;
|
||||
SSL_free(pend->c->ssl);
|
||||
pend->c->ssl = NULL;
|
||||
comm_point_close(pend->c);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
|
||||
/* openssl 1.0.2 has this function that can be used for
|
||||
* set1_host like verification */
|
||||
if(w->tls_auth_name) {
|
||||
X509_VERIFY_PARAM* param = SSL_get0_param(pend->c->ssl);
|
||||
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
|
||||
if(!X509_VERIFY_PARAM_set1_host(param, w->tls_auth_name, strlen(w->tls_auth_name))) {
|
||||
log_err("X509_VERIFY_PARAM_set1_host failed");
|
||||
pend->c->fd = s;
|
||||
SSL_free(pend->c->ssl);
|
||||
pend->c->ssl = NULL;
|
||||
comm_point_close(pend->c);
|
||||
return 0;
|
||||
}
|
||||
SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
|
||||
}
|
||||
#else
|
||||
verbose(VERB_ALGO, "the query has an auth_name, but libssl has no call to perform TLS authentication");
|
||||
#endif /* HAVE_SSL_SET1_HOST */
|
||||
}
|
||||
w->pkt = NULL;
|
||||
w->next_waiting = (void*)pend;
|
||||
@ -512,7 +496,9 @@ portcomm_loweruse(struct outside_network* outnet, struct port_comm* pc)
|
||||
comm_point_close(pc->cp);
|
||||
pif = pc->pif;
|
||||
log_assert(pif->inuse > 0);
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
pif->avail_ports[pif->avail_total - pif->inuse] = pc->number;
|
||||
#endif
|
||||
pif->inuse--;
|
||||
pif->out[pc->index] = pif->out[pif->inuse];
|
||||
pif->out[pc->index]->index = pc->index;
|
||||
@ -725,10 +711,12 @@ create_pending_tcp(struct outside_network* outnet, size_t bufsize)
|
||||
static int setup_if(struct port_if* pif, const char* addrstr,
|
||||
int* avail, int numavail, size_t numfd)
|
||||
{
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
pif->avail_total = numavail;
|
||||
pif->avail_ports = (int*)memdup(avail, (size_t)numavail*sizeof(int));
|
||||
if(!pif->avail_ports)
|
||||
return 0;
|
||||
#endif
|
||||
if(!ipstrtoaddr(addrstr, UNBOUND_DNS_PORT, &pif->addr, &pif->addrlen) &&
|
||||
!netblockstrtoaddr(addrstr, UNBOUND_DNS_PORT,
|
||||
&pif->addr, &pif->addrlen, &pif->pfxlen))
|
||||
@ -745,11 +733,11 @@ static int setup_if(struct port_if* pif, const char* addrstr,
|
||||
struct outside_network*
|
||||
outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
size_t num_ports, char** ifs, int num_ifs, int do_ip4,
|
||||
int do_ip6, size_t num_tcp, struct infra_cache* infra,
|
||||
int do_ip6, size_t num_tcp, int dscp, struct infra_cache* infra,
|
||||
struct ub_randstate* rnd, int use_caps_for_id, int* availports,
|
||||
int numavailports, size_t unwanted_threshold, int tcp_mss,
|
||||
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
|
||||
void* sslctx, int delayclose, struct dt_env* dtenv)
|
||||
void* sslctx, int delayclose, int tls_use_sni, struct dt_env* dtenv)
|
||||
{
|
||||
struct outside_network* outnet = (struct outside_network*)
|
||||
calloc(1, sizeof(struct outside_network));
|
||||
@ -765,6 +753,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
outnet->infra = infra;
|
||||
outnet->rnd = rnd;
|
||||
outnet->sslctx = sslctx;
|
||||
outnet->tls_use_sni = tls_use_sni;
|
||||
#ifdef USE_DNSTAP
|
||||
outnet->dtenv = dtenv;
|
||||
#else
|
||||
@ -778,6 +767,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
outnet->use_caps_for_id = use_caps_for_id;
|
||||
outnet->do_udp = do_udp;
|
||||
outnet->tcp_mss = tcp_mss;
|
||||
outnet->ip_dscp = dscp;
|
||||
#ifndef S_SPLINT_S
|
||||
if(delayclose) {
|
||||
outnet->delayclose = 1;
|
||||
@ -955,7 +945,9 @@ outside_network_delete(struct outside_network* outnet)
|
||||
comm_point_delete(pc->cp);
|
||||
free(pc);
|
||||
}
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
free(outnet->ip4_ifs[i].avail_ports);
|
||||
#endif
|
||||
free(outnet->ip4_ifs[i].out);
|
||||
}
|
||||
free(outnet->ip4_ifs);
|
||||
@ -969,7 +961,9 @@ outside_network_delete(struct outside_network* outnet)
|
||||
comm_point_delete(pc->cp);
|
||||
free(pc);
|
||||
}
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
free(outnet->ip6_ifs[i].avail_ports);
|
||||
#endif
|
||||
free(outnet->ip6_ifs[i].out);
|
||||
}
|
||||
free(outnet->ip6_ifs);
|
||||
@ -1059,11 +1053,12 @@ sai6_putrandom(struct sockaddr_in6 *sa, int pfxlen, struct ub_randstate *rnd)
|
||||
* @param port: port override for addr.
|
||||
* @param inuse: if -1 is returned, this bool means the port was in use.
|
||||
* @param rnd: random state (for address randomisation).
|
||||
* @param dscp: DSCP to use.
|
||||
* @return fd or -1
|
||||
*/
|
||||
static int
|
||||
udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int pfxlen,
|
||||
int port, int* inuse, struct ub_randstate* rnd)
|
||||
int port, int* inuse, struct ub_randstate* rnd, int dscp)
|
||||
{
|
||||
int fd, noproto;
|
||||
if(addr_is_ip6(addr, addrlen)) {
|
||||
@ -1078,13 +1073,13 @@ udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int pfxlen,
|
||||
}
|
||||
fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
|
||||
(struct sockaddr*)&sa, addrlen, 1, inuse, &noproto,
|
||||
0, 0, 0, NULL, 0, freebind, 0);
|
||||
0, 0, 0, NULL, 0, freebind, 0, dscp);
|
||||
} else {
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
|
||||
sa->sin_port = (in_port_t)htons((uint16_t)port);
|
||||
fd = create_udp_sock(AF_INET, SOCK_DGRAM,
|
||||
(struct sockaddr*)addr, addrlen, 1, inuse, &noproto,
|
||||
0, 0, 0, NULL, 0, 0, 0);
|
||||
0, 0, 0, NULL, 0, 0, 0, dscp);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
@ -1133,6 +1128,7 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
|
||||
while(1) {
|
||||
my_if = ub_random_max(outnet->rnd, num_if);
|
||||
pif = &ifs[my_if];
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
my_port = ub_random_max(outnet->rnd, pif->avail_total);
|
||||
if(my_port < pif->inuse) {
|
||||
/* port already open */
|
||||
@ -1144,8 +1140,11 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
|
||||
/* try to open new port, if fails, loop to try again */
|
||||
log_assert(pif->inuse < pif->maxout);
|
||||
portno = pif->avail_ports[my_port - pif->inuse];
|
||||
#else
|
||||
my_port = portno = 0;
|
||||
#endif
|
||||
fd = udp_sockport(&pif->addr, pif->addrlen, pif->pfxlen,
|
||||
portno, &inuse, outnet->rnd);
|
||||
portno, &inuse, outnet->rnd, outnet->ip_dscp);
|
||||
if(fd == -1 && !inuse) {
|
||||
/* nonrecoverable error making socket */
|
||||
return 0;
|
||||
@ -1167,8 +1166,10 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
|
||||
|
||||
/* grab port in interface */
|
||||
pif->out[pif->inuse] = pend->pc;
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
pif->avail_ports[my_port - pif->inuse] =
|
||||
pif->avail_ports[pif->avail_total-pif->inuse-1];
|
||||
#endif
|
||||
pif->inuse++;
|
||||
break;
|
||||
}
|
||||
@ -2192,10 +2193,11 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
|
||||
{
|
||||
struct sockaddr_storage* addr;
|
||||
socklen_t addrlen;
|
||||
int i, try, pnum;
|
||||
int i, try, pnum, dscp;
|
||||
struct port_if* pif;
|
||||
|
||||
/* create fd */
|
||||
dscp = outnet->ip_dscp;
|
||||
for(try = 0; try<1000; try++) {
|
||||
int port = 0;
|
||||
int freebind = 0;
|
||||
@ -2225,6 +2227,7 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
|
||||
}
|
||||
addr = &pif->addr;
|
||||
addrlen = pif->addrlen;
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
pnum = ub_random_max(outnet->rnd, pif->avail_total);
|
||||
if(pnum < pif->inuse) {
|
||||
/* port already open */
|
||||
@ -2233,19 +2236,21 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
|
||||
/* unused ports in start part of array */
|
||||
port = pif->avail_ports[pnum - pif->inuse];
|
||||
}
|
||||
|
||||
#else
|
||||
pnum = port = 0;
|
||||
#endif
|
||||
if(addr_is_ip6(to_addr, to_addrlen)) {
|
||||
struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
|
||||
sa.sin6_port = (in_port_t)htons((uint16_t)port);
|
||||
fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
|
||||
(struct sockaddr*)&sa, addrlen, 1, &inuse, &noproto,
|
||||
0, 0, 0, NULL, 0, freebind, 0);
|
||||
0, 0, 0, NULL, 0, freebind, 0, dscp);
|
||||
} else {
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
|
||||
sa->sin_port = (in_port_t)htons((uint16_t)port);
|
||||
fd = create_udp_sock(AF_INET, SOCK_DGRAM,
|
||||
(struct sockaddr*)addr, addrlen, 1, &inuse, &noproto,
|
||||
0, 0, 0, NULL, 0, freebind, 0);
|
||||
0, 0, 0, NULL, 0, freebind, 0, dscp);
|
||||
}
|
||||
if(fd != -1) {
|
||||
return fd;
|
||||
@ -2294,6 +2299,11 @@ setup_comm_ssl(struct comm_point* cp, struct outside_network* outnet,
|
||||
#endif
|
||||
cp->ssl_shake_state = comm_ssl_shake_write;
|
||||
/* https verification */
|
||||
#ifdef HAVE_SSL
|
||||
if(outnet->tls_use_sni) {
|
||||
(void)SSL_set_tlsext_host_name(cp->ssl, host);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_SSL_SET1_HOST
|
||||
if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
|
||||
/* because we set SSL_VERIFY_PEER, in netevent in
|
||||
@ -2316,7 +2326,9 @@ setup_comm_ssl(struct comm_point* cp, struct outside_network* outnet,
|
||||
* set1_host like verification */
|
||||
if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
|
||||
X509_VERIFY_PARAM* param = SSL_get0_param(cp->ssl);
|
||||
# ifdef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS
|
||||
X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
|
||||
# endif
|
||||
if(!X509_VERIFY_PARAM_set1_host(param, host, strlen(host))) {
|
||||
log_err("X509_VERIFY_PARAM_set1_host failed");
|
||||
return 0;
|
||||
@ -2335,7 +2347,7 @@ outnet_comm_point_for_tcp(struct outside_network* outnet,
|
||||
sldns_buffer* query, int timeout, int ssl, char* host)
|
||||
{
|
||||
struct comm_point* cp;
|
||||
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss);
|
||||
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss, outnet->ip_dscp);
|
||||
if(fd == -1) {
|
||||
return 0;
|
||||
}
|
||||
@ -2397,7 +2409,7 @@ outnet_comm_point_for_http(struct outside_network* outnet,
|
||||
{
|
||||
/* cp calls cb with err=NETEVENT_DONE when transfer is done */
|
||||
struct comm_point* cp;
|
||||
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss);
|
||||
int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss, outnet->ip_dscp);
|
||||
if(fd == -1) {
|
||||
return 0;
|
||||
}
|
||||
@ -2455,7 +2467,10 @@ if_get_mem(struct port_if* pif)
|
||||
{
|
||||
size_t s;
|
||||
int i;
|
||||
s = sizeof(*pif) + sizeof(int)*pif->avail_total +
|
||||
s = sizeof(*pif) +
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
sizeof(int)*pif->avail_total +
|
||||
#endif
|
||||
sizeof(struct port_comm*)*pif->maxout;
|
||||
for(i=0; i<pif->inuse; i++)
|
||||
s += sizeof(*pif->out[i]) +
|
||||
|
@ -132,12 +132,16 @@ struct outside_network {
|
||||
struct ub_randstate* rnd;
|
||||
/** ssl context to create ssl wrapped TCP with DNS connections */
|
||||
void* sslctx;
|
||||
/** if SNI will be used for TLS connections */
|
||||
int tls_use_sni;
|
||||
#ifdef USE_DNSTAP
|
||||
/** dnstap environment */
|
||||
struct dt_env* dtenv;
|
||||
#endif
|
||||
/** maximum segment size of tcp socket */
|
||||
int tcp_mss;
|
||||
/** IP_TOS socket option requested on the sockets */
|
||||
int ip_dscp;
|
||||
|
||||
/**
|
||||
* Array of tcp pending used for outgoing TCP connections.
|
||||
@ -172,11 +176,13 @@ struct port_if {
|
||||
* if 0, no randomisation. */
|
||||
int pfxlen;
|
||||
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
/** the available ports array. These are unused.
|
||||
* Only the first total-inuse part is filled. */
|
||||
int* avail_ports;
|
||||
/** the total number of available ports (size of the array) */
|
||||
int avail_total;
|
||||
#endif
|
||||
|
||||
/** array of the commpoints currently in use.
|
||||
* allocated for max number of fds, first part in use. */
|
||||
@ -399,6 +405,7 @@ struct serviced_query {
|
||||
* @param do_ip4: service IP4.
|
||||
* @param do_ip6: service IP6.
|
||||
* @param num_tcp: number of outgoing tcp buffers to preallocate.
|
||||
* @param dscp: DSCP to use.
|
||||
* @param infra: pointer to infra cached used for serviced queries.
|
||||
* @param rnd: stored to create random numbers for serviced queries.
|
||||
* @param use_caps_for_id: enable to use 0x20 bits to encode id randomness.
|
||||
@ -412,16 +419,17 @@ struct serviced_query {
|
||||
* @param sslctx: context to create outgoing connections with (if enabled).
|
||||
* @param delayclose: if not 0, udp sockets are delayed before timeout closure.
|
||||
* msec to wait on timeouted udp sockets.
|
||||
* @param tls_use_sni: if SNI is used for TLS connections.
|
||||
* @param dtenv: environment to send dnstap events with (if enabled).
|
||||
* @return: the new structure (with no pending answers) or NULL on error.
|
||||
*/
|
||||
struct outside_network* outside_network_create(struct comm_base* base,
|
||||
size_t bufsize, size_t num_ports, char** ifs, int num_ifs,
|
||||
int do_ip4, int do_ip6, size_t num_tcp, struct infra_cache* infra,
|
||||
int do_ip4, int do_ip6, size_t num_tcp, int dscp, struct infra_cache* infra,
|
||||
struct ub_randstate* rnd, int use_caps_for_id, int* availports,
|
||||
int numavailports, size_t unwanted_threshold, int tcp_mss,
|
||||
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
|
||||
void* sslctx, int delayclose, struct dt_env *dtenv);
|
||||
void* sslctx, int delayclose, int tls_use_sni, struct dt_env *dtenv);
|
||||
|
||||
/**
|
||||
* Delete outside_network structure.
|
||||
@ -540,7 +548,7 @@ size_t serviced_get_mem(struct serviced_query* sq);
|
||||
|
||||
/** get TCP file descriptor for address, returns -1 on failure,
|
||||
* tcp_mss is 0 or maxseg size to set for TCP packets. */
|
||||
int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss);
|
||||
int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss, int dscp);
|
||||
|
||||
/**
|
||||
* Create udp commpoint suitable for sending packets to the destination.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -167,7 +167,7 @@ sldns_gmtime64_r(int64_t clock, struct tm *result)
|
||||
static int64_t
|
||||
sldns_serial_arithmetics_time(int32_t time, time_t now)
|
||||
{
|
||||
int32_t offset = time - (int32_t) now;
|
||||
int32_t offset = (int32_t)((uint32_t) time - (uint32_t) now);
|
||||
return (int64_t) now + offset;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include "services/authzone.h"
|
||||
#include "respip/respip.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/str2wire.h"
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
@ -194,6 +195,94 @@ localzonechecks(struct config_file* cfg)
|
||||
local_zones_delete(zs);
|
||||
}
|
||||
|
||||
/** checks for acl and views */
|
||||
static void
|
||||
acl_view_tag_checks(struct config_file* cfg, struct views* views)
|
||||
{
|
||||
int d;
|
||||
struct sockaddr_storage a;
|
||||
socklen_t alen;
|
||||
struct config_str2list* acl;
|
||||
struct config_str3list* s3;
|
||||
struct config_strbytelist* sb;
|
||||
|
||||
/* acl_view */
|
||||
for(acl=cfg->acl_view; acl; acl = acl->next) {
|
||||
struct view* v;
|
||||
if(!netblockstrtoaddr(acl->str, UNBOUND_DNS_PORT, &a, &alen,
|
||||
&d)) {
|
||||
fatal_exit("cannot parse access-control-view "
|
||||
"address %s %s", acl->str, acl->str2);
|
||||
}
|
||||
v = views_find_view(views, acl->str2, 0);
|
||||
if(!v) {
|
||||
fatal_exit("cannot find view for "
|
||||
"access-control-view: %s %s",
|
||||
acl->str, acl->str2);
|
||||
}
|
||||
lock_rw_unlock(&v->lock);
|
||||
}
|
||||
|
||||
/* acl_tags */
|
||||
for(sb=cfg->acl_tags; sb; sb = sb->next) {
|
||||
if(!netblockstrtoaddr(sb->str, UNBOUND_DNS_PORT, &a, &alen,
|
||||
&d)) {
|
||||
fatal_exit("cannot parse access-control-tags "
|
||||
"address %s", sb->str);
|
||||
}
|
||||
}
|
||||
|
||||
/* acl_tag_actions */
|
||||
for(s3=cfg->acl_tag_actions; s3; s3 = s3->next) {
|
||||
enum localzone_type t;
|
||||
if(!netblockstrtoaddr(s3->str, UNBOUND_DNS_PORT, &a, &alen,
|
||||
&d)) {
|
||||
fatal_exit("cannot parse access-control-tag-actions "
|
||||
"address %s %s %s",
|
||||
s3->str, s3->str2, s3->str3);
|
||||
}
|
||||
if(find_tag_id(cfg, s3->str2) == -1) {
|
||||
fatal_exit("cannot parse tag %s (define-tag it), "
|
||||
"for access-control-tag-actions: %s %s %s",
|
||||
s3->str2, s3->str, s3->str2, s3->str3);
|
||||
}
|
||||
if(!local_zone_str2type(s3->str3, &t)) {
|
||||
fatal_exit("cannot parse access control action type %s"
|
||||
" for access-control-tag-actions: %s %s %s",
|
||||
s3->str3, s3->str, s3->str2, s3->str3);
|
||||
}
|
||||
}
|
||||
|
||||
/* acl_tag_datas */
|
||||
for(s3=cfg->acl_tag_datas; s3; s3 = s3->next) {
|
||||
char buf[65536];
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
size_t len = sizeof(rr);
|
||||
int res;
|
||||
if(!netblockstrtoaddr(s3->str, UNBOUND_DNS_PORT, &a, &alen,
|
||||
&d)) {
|
||||
fatal_exit("cannot parse access-control-tag-datas address %s %s '%s'",
|
||||
s3->str, s3->str2, s3->str3);
|
||||
}
|
||||
if(find_tag_id(cfg, s3->str2) == -1) {
|
||||
fatal_exit("cannot parse tag %s (define-tag it), "
|
||||
"for access-control-tag-datas: %s %s '%s'",
|
||||
s3->str2, s3->str, s3->str2, s3->str3);
|
||||
}
|
||||
/* '.' is sufficient for validation, and it makes the call to
|
||||
* sldns_wirerr_get_type() simpler below. */
|
||||
snprintf(buf, sizeof(buf), "%s %s", ".", s3->str3);
|
||||
res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, NULL,
|
||||
0, NULL, 0);
|
||||
if(res != 0) {
|
||||
fatal_exit("cannot parse rr data [char %d] parse error %s, for access-control-tag-datas: %s %s '%s'",
|
||||
(int)LDNS_WIREPARSE_OFFSET(res)-2,
|
||||
sldns_get_errorstr_parse(res),
|
||||
s3->str, s3->str2, s3->str3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** check view and response-ip configuration */
|
||||
static void
|
||||
view_and_respipchecks(struct config_file* cfg)
|
||||
@ -211,6 +300,7 @@ view_and_respipchecks(struct config_file* cfg)
|
||||
fatal_exit("Could not setup respip set");
|
||||
if(!respip_views_apply_cfg(views, cfg, &ignored))
|
||||
fatal_exit("Could not setup per-view respip sets");
|
||||
acl_view_tag_checks(cfg, views);
|
||||
views_delete(views);
|
||||
respip_set_delete(respip);
|
||||
}
|
||||
@ -481,6 +571,8 @@ morechecks(struct config_file* cfg)
|
||||
fatal_exit("num_threads value weird");
|
||||
if(!cfg->do_ip4 && !cfg->do_ip6)
|
||||
fatal_exit("ip4 and ip6 are both disabled, pointless");
|
||||
if(!cfg->do_ip4 && cfg->prefer_ip4)
|
||||
fatal_exit("cannot prefer and disable ip4, pointless");
|
||||
if(!cfg->do_ip6 && cfg->prefer_ip6)
|
||||
fatal_exit("cannot prefer and disable ip6, pointless");
|
||||
if(!cfg->do_udp && !cfg->do_tcp)
|
||||
@ -567,6 +659,64 @@ morechecks(struct config_file* cfg)
|
||||
&& strcmp(cfg->module_conf, "python dns64 iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python dns64 validator iterator") != 0
|
||||
#endif
|
||||
#ifdef WITH_DYNLIBMODULE
|
||||
&& strcmp(cfg->module_conf, "dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib dynlib dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python dynlib dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python dynlib dynlib dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib dynlib validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib dynlib dynlib validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python dynlib validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python dynlib dynlib validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "python dynlib dynlib dynlib validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib respip validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 dynlib validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 validator dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib dns64 iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib dns64 validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib dns64 cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib dns64 validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 dynlib cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 dynlib validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib respip cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib respip validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "cachedb dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip cachedb dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator cachedb dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip validator cachedb dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "validator dynlib cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip validator dynlib cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib respip subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip subnetcache dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib respip subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache dynlib validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip subnetcache dynlib validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "subnetcache validator dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip subnetcache validator dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib ipsecmod iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib ipsecmod respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod dynlib respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod respip validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib ipsecmod validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dynlib ipsecmod respip validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod dynlib validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod dynlib respip validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod validator dynlib iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "ipsecmod respip validator dynlib iterator") != 0
|
||||
#endif
|
||||
#ifdef USE_CACHEDB
|
||||
&& strcmp(cfg->module_conf, "validator cachedb iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "respip validator cachedb iterator") != 0
|
||||
@ -598,6 +748,8 @@ morechecks(struct config_file* cfg)
|
||||
&& strcmp(cfg->module_conf, "respip subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 subnetcache iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 subnetcache validator iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 subnetcache respip iterator") != 0
|
||||
&& strcmp(cfg->module_conf, "dns64 subnetcache respip validator iterator") != 0
|
||||
#endif
|
||||
#if defined(WITH_PYTHONMODULE) && defined(CLIENT_SUBNET)
|
||||
&& strcmp(cfg->module_conf, "python subnetcache iterator") != 0
|
||||
@ -701,7 +853,7 @@ check_auth(struct config_file* cfg)
|
||||
{
|
||||
int is_rpz = 0;
|
||||
struct auth_zones* az = auth_zones_create();
|
||||
if(!az || !auth_zones_apply_cfg(az, cfg, 0i, &is_rpz)) {
|
||||
if(!az || !auth_zones_apply_cfg(az, cfg, 0, &is_rpz)) {
|
||||
fatal_exit("Could not setup authority zones");
|
||||
}
|
||||
auth_zones_delete(az);
|
||||
|
@ -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,
|
||||
@ -1583,7 +1585,7 @@ int create_udp_sock(int ATTR_UNUSED(family), int ATTR_UNUSED(socktype),
|
||||
int* ATTR_UNUSED(noproto), int ATTR_UNUSED(rcv), int ATTR_UNUSED(snd),
|
||||
int ATTR_UNUSED(listen), int* ATTR_UNUSED(reuseport),
|
||||
int ATTR_UNUSED(transparent), int ATTR_UNUSED(freebind),
|
||||
int ATTR_UNUSED(use_systemd))
|
||||
int ATTR_UNUSED(use_systemd), int ATTR_UNUSED(dscp))
|
||||
{
|
||||
/* if you actually print to this, it'll be stdout during test */
|
||||
return 1;
|
||||
@ -1790,7 +1792,7 @@ int comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
|
||||
}
|
||||
|
||||
int outnet_get_tcp_fd(struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(tcp_mss))
|
||||
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(tcp_mss), int ATTR_UNUSED(dscp))
|
||||
{
|
||||
log_assert(0);
|
||||
return -1;
|
||||
|
@ -26,15 +26,20 @@ cd testdata
|
||||
TPKG=../testcode/mini_tdir.sh
|
||||
#RUNLIST=`(ls -1d *.tdir|grep -v '^0[016]')`
|
||||
RUNLIST=`(ls -1d *.tdir)`
|
||||
if test "$#" = "1"; then RUNLIST="$1"; fi
|
||||
if test "$#" = "1"; then
|
||||
RUNLIST="$1";
|
||||
if echo "$RUNLIST" | grep '/$' >/dev/null; then
|
||||
RUNLIST=`echo "$RUNLIST" | sed -e 's?/$??'`
|
||||
fi
|
||||
fi
|
||||
|
||||
# fix up tdir that was edited on keyboard interrupt.
|
||||
cleanup() {
|
||||
echo cleanup
|
||||
if test -f "$t.bak"; then mv "$t.bak" "$t"; fi
|
||||
if test -f "$t.bak"; then rm -fr "${t}"; mv "$t.bak" "$t"; fi
|
||||
exit 0
|
||||
}
|
||||
trap cleanup SIGINT
|
||||
trap cleanup INT
|
||||
|
||||
for t in $RUNLIST
|
||||
do
|
||||
|
@ -200,6 +200,7 @@ write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id,
|
||||
static void
|
||||
recv_one(int fd, int udp, SSL* ssl, sldns_buffer* buf)
|
||||
{
|
||||
size_t i;
|
||||
char* pktstr;
|
||||
uint16_t len;
|
||||
if(!udp) {
|
||||
@ -270,7 +271,13 @@ recv_one(int fd, int udp, SSL* ssl, sldns_buffer* buf)
|
||||
len = (size_t)l;
|
||||
}
|
||||
printf("\nnext received packet\n");
|
||||
log_buf(0, "data", buf);
|
||||
printf("data[%d] ", (int)sldns_buffer_limit(buf));
|
||||
for(i=0; i<sldns_buffer_limit(buf); i++) {
|
||||
const char* hex = "0123456789ABCDEF";
|
||||
printf("%c%c", hex[(sldns_buffer_read_u8_at(buf, i)&0xf0)>>4],
|
||||
hex[sldns_buffer_read_u8_at(buf, i)&0x0f]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
pktstr = sldns_wire2str_pkt(sldns_buffer_begin(buf), len);
|
||||
printf("%s", pktstr);
|
||||
|
@ -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
|
||||
|
1
testdata/04-checkconf.tdir/bad.badfwd
vendored
1
testdata/04-checkconf.tdir/bad.badfwd
vendored
@ -2,6 +2,7 @@ server:
|
||||
# to make sure the check doesn't fail on username or chrootdir.
|
||||
username: ""
|
||||
chroot: ""
|
||||
directory: ""
|
||||
|
||||
forward-zone:
|
||||
name: "example.com"
|
||||
|
5
testdata/04-checkconf.tdir/bad.dscp
vendored
Normal file
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
|
3
testdata/04-checkconf.tdir/bad.include-toplevel.1
vendored
Normal file
3
testdata/04-checkconf.tdir/bad.include-toplevel.1
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
include-toplevel: include.withoutclauses.*
|
||||
server:
|
||||
identity: "top 1"
|
5
testdata/04-checkconf.tdir/bad.include-toplevel.2
vendored
Normal file
5
testdata/04-checkconf.tdir/bad.include-toplevel.2
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
include-toplevel: include.withclauses.*
|
||||
server:
|
||||
identity: "top 1"
|
||||
include: include.withoutclauses.*
|
||||
include-toplevel: include.withoutclauses.*
|
6
testdata/04-checkconf.tdir/bad.include-toplevel.3
vendored
Normal file
6
testdata/04-checkconf.tdir/bad.include-toplevel.3
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
include-toplevel: include.withclauses.*
|
||||
server:
|
||||
identity: "top 1"
|
||||
include: include.withoutclauses.*
|
||||
include-toplevel: include.withclauses.*
|
||||
include: include.withoutclauses.*
|
7
testdata/04-checkconf.tdir/bad.include-toplevel.4
vendored
Normal file
7
testdata/04-checkconf.tdir/bad.include-toplevel.4
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
include-toplevel: include.withclauses.*
|
||||
server:
|
||||
identity: "top 1"
|
||||
include: include.withoutclauses.*
|
||||
include-toplevel: include.withclauses.*
|
||||
include: include.withclauses.*
|
||||
include-toplevel: include.withoutclauses.*
|
8
testdata/04-checkconf.tdir/bad.include-toplevel.5
vendored
Normal file
8
testdata/04-checkconf.tdir/bad.include-toplevel.5
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
include-toplevel: include.withclauses.*
|
||||
server:
|
||||
identity: "top 1"
|
||||
include: include.withoutclauses.*
|
||||
include-toplevel: include.withsomeclauses.*
|
||||
include: include.withclauses.*
|
||||
include-toplevel: include.withclauses.*
|
||||
server: identity: "top 2"
|
10
testdata/04-checkconf.tdir/bad.include-toplevel.6
vendored
Normal file
10
testdata/04-checkconf.tdir/bad.include-toplevel.6
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
include-toplevel: include.withclauses.*
|
||||
include-toplevel: include.withclauses.*
|
||||
server:
|
||||
identity: "top 1"
|
||||
include: include.withoutclauses.*
|
||||
include-toplevel: include.withclauses.*
|
||||
include: include.withclauses.*
|
||||
include-toplevel: include.withclauses.*
|
||||
server: identity: "top 2"
|
||||
include-toplevel: include.includetop.withoutclauses.*
|
11
testdata/04-checkconf.tdir/bad.include-toplevel.7
vendored
Normal file
11
testdata/04-checkconf.tdir/bad.include-toplevel.7
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
include-toplevel: include.withclauses.*
|
||||
include-toplevel: include.withclauses.*
|
||||
server:
|
||||
identity: "top 1"
|
||||
include: include.withoutclauses.*
|
||||
include-toplevel: include.withclauses.*
|
||||
include: include.withclauses.*
|
||||
include-toplevel: include.withclauses.*
|
||||
server: identity: "top 2"
|
||||
include-toplevel: include.includetop.withclauses.*
|
||||
include-toplevel: include.include.withoutclauses.*
|
2
testdata/04-checkconf.tdir/bad.user
vendored
2
testdata/04-checkconf.tdir/bad.user
vendored
@ -1,2 +1,4 @@
|
||||
server:
|
||||
username: blabla_noexist_user
|
||||
chroot: ""
|
||||
directory: ""
|
||||
|
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
|
||||
|
16
testdata/04-checkconf.tdir/good.include-toplevel
vendored
Normal file
16
testdata/04-checkconf.tdir/good.include-toplevel
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
include-toplevel: include.withclauses.*
|
||||
include-toplevel: include.withclauses.*
|
||||
server:
|
||||
identity: "top 1"
|
||||
include: include.withoutclauses.*
|
||||
include-toplevel: include.withclauses.*
|
||||
include: include.withclauses.*
|
||||
include-toplevel: include.withclauses.*
|
||||
server: identity: "top 2"
|
||||
include-toplevel: include.includetop.withclauses.*
|
||||
include-toplevel: include.include.withclauses.*
|
||||
include-toplevel: include.include.withclauses.*
|
||||
server:
|
||||
chroot: ""
|
||||
directory: ""
|
||||
username: ""
|
7
testdata/04-checkconf.tdir/good.min
vendored
Normal file
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: ""
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user